思路:

  只保留奇数

  (1)由输入的整数n确定存储奇数(不包括1)的数组大小:

n=(n%2==0)?(n/2-1):((n-1)/2);//n为存储奇数的数组大小,不包括基数1

  (2)由数组大小n、进程号id和进程数p,确定每个进程负责的基数数组的第一个数、最后一个数和数组维度:

low_value = 3 + 2*(id*(n)/p);//进程的第一个数

  high_value = 3 + 2*((id+1)*(n)/p-1);//进程的最后一个数

  size = (high_value - low_value)/2 + 1;  //进程处理的数组大小

  (3)寻找奇数的第一个倍数的下标,经过反复思考,有如下规律:

  if (prime * prime > low_value)

  first = (prime * prime - low_value)/2;

  else {

  if (!(low_value % prime))

first = 0;

  else

first=((prime-low_value%prime)%2==0)?((prime-low_value%prime)/2):((prime-low_value%prime+prime)/2);

}

  code:

 #include "mpi.h"
#include <math.h>
#include <stdio.h>
#define MIN(a,b) ((a)<(b)?(a):(b)) int main (int argc, char *argv[])
{
int count; /* Local prime count */
double elapsed_time; /* Parallel execution time */
int first; /* Index of first multiple */
int global_count; /* Global prime count */
int high_value; /* Highest value on this proc */
int i;
int id; /* Process ID number */
int index; /* Index of current prime */
int low_value; /* Lowest value on this proc */
char *marked; /* Portion of 2,...,'n' */
int n,m; /* Sieving from 2, ..., 'n' */
int p; /* Number of processes */
int proc0_size; /* Size of proc 0's subarray */
int prime; /* Current prime */
int size; /* Elements in 'marked' */ MPI_Init (&argc, &argv); /* Start the timer */ MPI_Comm_rank (MPI_COMM_WORLD, &id);
MPI_Comm_size (MPI_COMM_WORLD, &p);
MPI_Barrier(MPI_COMM_WORLD);
elapsed_time = -MPI_Wtime(); if (argc != ) {
if (!id) printf ("Command line: %s <m>\n", argv[]);
MPI_Finalize();
exit ();
} n = atoi(argv[]);
m=n;//
n=(n%==)?(n/-):((n-)/);//将输入的整数n转换为存储奇数的数组大小,不包括奇数1
//if (!id) printf ("Number of odd integers:%d Maximum value of odd integers:%d\n",n+1,3+2*(n-1));
if (n==) {//输入2时,输出1 prime,结束
if (!id) printf ("There are 1 prime less than or equal to %d\n",m);
MPI_Finalize();
exit ();
}
/* Figure out this process's share of the array, as
well as the integers represented by the first and
last array elements */ low_value = + *(id*(n)/p);//进程的第一个数
high_value = + *((id+)*(n)/p-);//进程的最后一个数
size = (high_value - low_value)/ + ; //进程处理的数组大小 /* Bail out if all the primes used for sieving are
not all held by process 0 */ proc0_size = (n-)/p; if (( + *(proc0_size-)) < (int) sqrt((double) (+*(n-)))) {//
if (!id) printf ("Too many processes\n");
MPI_Finalize();
exit ();
} /* Allocate this process's share of the array. */ marked = (char *) malloc (size); if (marked == NULL) {
printf ("Cannot allocate enough memory\n");
MPI_Finalize();
exit ();
} for (i = ; i < size; i++) marked[i] = ;
if (!id) index = ;
prime = ;//从素数3开始
do {
//确定奇数的第一个倍数的下标
if (prime * prime > low_value)
first = (prime * prime - low_value)/;
else {
if (!(low_value % prime))
first = ;
else
first=((prime-low_value%prime)%==)?((prime-low_value%prime)/):((prime-low_value%prime+prime)/);
} for (i = first; i < size; i += prime) marked[i] = ;
if (!id) {
while (marked[++index]);
prime = *index + ;//下一个未被标记的素数
}
if (p > ) MPI_Bcast (&prime, , MPI_INT, , MPI_COMM_WORLD);
} while (prime * prime <= +*(n-));// count = ;
for (i = ; i < size; i++)
if (!marked[i]) count++;
if (p > ) MPI_Reduce (&count, &global_count, , MPI_INT, MPI_SUM,
, MPI_COMM_WORLD); /* Stop the timer */ elapsed_time += MPI_Wtime(); /* Print the results */ if (!id) {
printf ("There are %d primes less than or equal to %d\n",
global_count+, m);//前面程序是从素数3开始标记,忽略了素数2,所以素数个数要加1
printf ("SIEVE (%d) %10.6f\n", p, elapsed_time);
}
MPI_Finalize ();
return ;
}

查找素数Eratosthenes筛法的mpi程序的更多相关文章

  1. 用C++实现的增强Eratosthenes筛法程序

    运行示例 PS H:\Read\num\x64\Release> .\eSievePro Eratosthenes sieve: a method to find out all primes ...

  2. 用C++实现的Eratosthenes筛法程序

    运行示例 只输出素数总数的运行示例 PS H:\Read\num\x64\Release> .\esieve.exe Eratosthenes sieve: a method to find o ...

  3. 素数筛法(Eratosthenes筛法)

    介绍 Eratosthenes筛法,又名埃氏筛法,对于求1~n区间内的素数,时间复杂度为n log n,对于10^6^ 以内的数比较合适,再超出此范围的就不建议用该方法了. 筛法的思想特别简单: 对于 ...

  4. 素数筛 : Eratosthenes 筛法, 线性筛法

    这是两种简单的素数筛法, 好不容易理解了以后写篇博客加深下记忆 首先, 这两种算法用于解决的问题是 : 求小于n的所有素数 ( 个数 ) 比如 这道题 在不了解这两个素数筛算法的同学, 可能会这么写一 ...

  5. 由Eratosthenes筛法演变出的一种素数新筛法

    这两天和walls老师交流讨论了一个中学竞赛题,我把原题稍作增强和变形,得到如下一个题: 从105到204这100个数中至少要选取多少个数才能保证选出的数中必有两个不是互素的? 我们知道最小的几个素数 ...

  6. 【NYOJ-187】快速查找素数—— 枚举法、筛选法、打表法

    快速查找素数 时间限制:1000 ms  |  内存限制:65535 KB 难度:3   描述 现在给你一个正整数N,要你快速的找出在2.....N这些数里面所有的素数. 输入 给出一个正整数数N(N ...

  7. nyoj_187_快速查找素数_201312042102

    快速查找素数 时间限制:1000 ms  |           内存限制:65535 KB 难度:3   描述 现在给你一个正整数N,要你快速的找出在2.....N这些数里面所有的素数.   输入 ...

  8. NYOJ--187--快速查找素数(筛选法,素数打表)

    快速查找素数 时间限制:1000 ms  |  内存限制:65535 KB 难度:3   描述 现在给你一个正整数N,要你快速的找出在2.....N这些数里面所有的素数.   输入 给出一个正整数数N ...

  9. nyoj---快速查找素数

    快速查找素数 时间限制:1000 ms  |  内存限制:65535 KB 难度:3   描述 现在给你一个正整数N,要你快速的找出在2.....N这些数里面所有的素数.   输入 给出一个正整数数N ...

随机推荐

  1. 根据xml文件名获取xml数据并转化为实体。

    1.定义一个xml文件. <?xml version="1.0" encoding="utf-8" ?> <UserManager xmlns ...

  2. JSP页面跳转的几种实现方法

    使用href超链接标记      客户端跳转 使用JavaScript               客户端跳转 提交表单                        客户端跳转 使用response ...

  3. Android线程管理之Thread使用总结

    前言 最近在一直准备总结一下Android上的线程管理,今天先来总结一下Thread使用. 线程管理相关文章地址: Android线程管理之Thread使用总结 Android线程管理之Executo ...

  4. javascript中的函数式声明与变量式声明

    观察下面两段代码,试写出hello('word');的运行结果: // 变量式声明 function hello(msg){ alert(msg); var msg = function(){}; a ...

  5. EntityFramework 7 Migrations 迁移命令

    示例代码: using Microsoft.Data.Entity; using System.Collections.Generic; namespace ClassLibrary1 { publi ...

  6. (转)构建自己的AngularJS,第一部分:Scope和Digest

    原翻译链接:https://github.com/xufei/Make-Your-Own-AngularJS/edit/master/01.md 原文链接:http://teropa.info/blo ...

  7. 使用UICollectionView实现首页的滚动效果

    实现类似这样的效果,可以滚动大概有两种实现方案 1. 使用scrollview来实现 2. 使用UICollectionView来实现 第一种比较简单,而且相对于性能来说不太好,于是我们使用第二种方案 ...

  8. Vertica 安装,建库,新建测试用户并授予权限,建表,入库

    测试环境:RHEL 6.4 + Vertica 6.1.3-7 需求:搭建Vertica数据库3节点的测试环境,建立测试用户,建表,测试数据入库. 1.各节点关闭防火墙和SELinux,配置主机名,I ...

  9. 欢迎阅读daxnet的新博客:一个基于Microsoft Azure、ASP.NET Core和Docker的博客系统

    2008年11月,我在博客园开通了个人帐号,并在博客园发表了自己的第一篇博客.当然,我写博客也不是从2008年才开始的,在更早时候,也在CSDN和系统分析员协会(之后名为"希赛网" ...

  10. [占位-未完成]scikit-learn一般实例之十:核岭回归和SVR的比较

    [占位-未完成]scikit-learn一般实例之十:核岭回归和SVR的比较