从1到n生成素数,n> 3亿崩溃

冰人

关于如何使该程序在n = 1万亿的基础上运行,有什么建议(除了进行升级/购买新计算机)?

错误如下:构建后,正在执行的程序(弹出命令行样式输出窗口),然后迅速关闭,并且出现以下错误“ ProjectPrimes.exe停止工作(Windows正在寻找解决方案:这个问题。”我怀疑这与内存问题有关,因为我最初在n = 2000万时遇到它,但这是在我选择malloc / free'sieve'数组(即,我的'sieve'数组是大数组)之前尺寸为nx 1,且每个元素由1或0组成)。

该程序需要约35秒的时间来运行前3亿个整数(16,252,325个素数),所以还可以,但没什么特别的。正如我所提到的,目标是能够生成低于1万亿的素数,因此还有很长的路要走...

如果相关,这是我的机器规格(如果目标在这台机器上不合理):2.40ghz i5、4GB RAM,64位Windows 7。

对于不熟悉的人,方法学概述:我们使用Sundaram筛法。在不涉及证明的情况下,我们首先使用筛分函数消除整数“ n”以下的所有奇数非素数:[2 *(i + j + 2 * i * j)+1 | i <-[1..n / 2],j <-[i ..一个优化的上限]]。然后我们划掉偶数(当然不包括两个)。这让我们充满了素数。

为什么质数函数返回n之下的完整素数集(指向包含数组的指针)?好吧,我们的目标是能够识别(i)n以下的质数以及(ii)列出n以下的质数。这也是为什么我选择传递一个小于n的素数计数的指针作为参数的原因。

这是不太令人兴奋的“主要”功能:

int main() {
    long ceiling = 300*1000*1000;
    long *numPrimes;
    long *primes;

    primes = primesToSS(ceiling+1, numPrimes);
    printf("\n\nThere are %d primes below %d.\n\n",*numPrimes,ceiling);

    free(primes);
    return 0;
}

这是肉:

//n represents the ceiling, i.e., the integer below which we will generate primes
//cnt* is a pointer which will point the number of primes below n

long* primesToSS( long n, long* cnt ) {

    //initialize sieve by setting all elements equal to 1 (except for 0 and 1)
    long *sieve = malloc(n*sizeof(long));
    initArray(sieve, n, 1);
    sieve[0] = 0; sieve[1] = 0;

    //eliminate all odd composite numbers
    for (int i = 1; i <= n/2; ++i)
        for (int j = i; j <= (n-2*i)/(2*(2*i+1)); ++j)
            sieve[ 2*(i+j+2*i*j)+1 ] = 0;

    //eliminate all even numbers greater than two 
    //and count total number of primes below n
    long numPrimes = 1;
    for (int i = 3; i < n; ++i) {
        if (i % 2 == 0) sieve[i] = 0;
        numPrimes += sieve[i];
    }
    *cnt = numPrimes;

    //create array of primes
    long *primes = malloc(numPrimes*sizeof(int));
    long counter = 0;
    for (int i = 0; i < n; ++i) {
        if (sieve[i] == 1) {
            primes[counter] = i;
            counter++; } 
    }
    free(sieve);
    return primes;
}

void initArray( int* arr, int len, int n ) {
    for( int i = 0; i < len; ++i) arr[i] = n; }
纳赫德

让我们观察一下:

  • 正如人们在评论和答案中提到的那样,您只需要一位即可存储数字是否为质数。因此,您可以将8个数字的数据打包为1个字节。实现自己的位集数据结构以使代码更整洁。
  • 注释中还提到,由于所有大于2的质数都是奇数,因此无需存储偶数数据。这使您可以将16个数字打包为1个字节。
  • 按照车轮分解的思想,如果仅存储与1或5模6一致的数字的位,则可以将24个数字进一步打包到1个字节中。更高的模数将节省更多的空间(收益递减),但逻辑是访问位集数据结构可能会使算法变慢。
  • 筛选一下,要使该程序能够处理1万亿(10 12)个数字,您只需收集小于100万(10 6的质数列表不需要更大的数字,因为该列表中已经涵盖了小于1万亿的复合数字中的其他因素。
  • 以16个数字/字节的包装数量(您应该做的最基本的设置),您需要约58 GiB的RAM。但是,无需分配整个范围。只需分配几亿到几十亿的较小范围(尝试更改数字以获得最高性能),最多转换为几百个MiB,然后使用小于100万的素数列表进行筛选范围。

    此步骤可以并行完成-您只需要共享小于100万的素数列表。

    顺便说一句,这种技术称为分段筛。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

对于n = 1,2,3,...的P = n ^ 2-2 + 41证明...在R中生成素数

来自分类Dev

我的SPOJ生成素数的C ++程序提供了预期的输出,但最终崩溃了。拜托,让我知道为什么会这样

来自分类Dev

随机生成素数

来自分类Dev

如何使用从 1 到 10 的列表理解生成素数列表?

来自分类Dev

生成素数列表

来自分类Dev

代码优化-生成素数

来自分类Dev

CUDA无法生成素数

来自分类Dev

EPI:生成素数的优化算法

来自分类Dev

在编译时生成素数

来自分类Dev

使用并行循环生成素数

来自分类Dev

在python中生成素数的错误

来自分类Dev

1到n之间以1结尾的素数个数

来自分类Dev

如何在具有1 TB磁盘空间的系统上从700 GB的txt文件中删除前3亿行?

来自分类Dev

使用LongStream和jOOλ生成素数会导致StackOverflowError

来自分类Dev

使用斐波那契生成素数可能吗?

来自分类Dev

在Python中高效生成素数并计算复杂度

来自分类Dev

在2个范围之间生成1亿条记录并插入

来自分类Dev

生成随机输出3n + 1 pblm

来自分类Dev

在Twitter Bootstrap 3中绑定到崩溃事件

来自分类Dev

在RocksDB上插入1亿条记录

来自分类Dev

apache2每天崩溃1-3次

来自分类Dev

apache2每天持续崩溃1-3次

来自分类Dev

Prolog代码以生成从1到N的质数

来自分类Dev

Prolog代码以生成从1到N的质数

来自分类Dev

我的素数生成器崩溃并被Windows 10关闭

来自分类Dev

ArrayList <Double>翻倍[],具有3亿个条目

来自分类Dev

Oracle截断表需要长达3亿行的表

来自分类Dev

编写算法以在给定范围内用Python生成素数

来自分类Dev

如何有效地实现Eratosphenes方法以生成素数?