查找素数的快速算法?

时间:2010-09-27 21:48:13

标签: algorithm performance primes sieve-of-eratosthenes

首先 - 我在这个论坛上查了很多,但我还没找到足够快的东西。 我尝试创建一个函数,返回指定范围内的素数。 例如,我使用Eratosthenes的筛子完成了这个功能(在C#中)。我也尝试了阿特金的筛子,但是Eratosthenes的速度更快(在我的实施中):

public static void SetPrimesSieve(int Range)
    {
        Primes = new List<uint>();
        Primes.Add(2);
        int Half = (Range - 1) >> 1;
        BitArray Nums = new BitArray(Half, false);
        int Sqrt = (int)Math.Sqrt(Range);
        for (int i = 3, j; i <= Sqrt; )
        {
            for (j = ((i * i) >> 1) - 1; j < Half; j += i)
                Nums[j] = true;
            do
                i += 2;
            while (i <= Sqrt && Nums[(i >> 1) - 1]);
        }
        for (int i = 0; i < Half; ++i)
           if (!Nums[i])
                Primes.Add((uint)(i << 1) + 3);
    }

它的运行速度比代码快两倍。我找到的算法...... 应该有更快的方法来找到素数,你能帮助我吗?

5 个答案:

答案 0 :(得分:9)

在搜索关于此主题的算法时(对于项目Euler)我不记得找到更快的东西。如果速度确实是关注的问题,您是否考虑过只存储素数而只需要查找它?

编辑:快速谷歌搜索找到this,确认最快的方法只是分页结果并根据需要查找。

再一次编辑 - 您可能会发现更多信息here,基本上是此主题的副本。那里的最高职位是atkin的筛子比现在更快,直到在飞行中生成。

答案 1 :(得分:2)

到目前为止,根据我的经验,最快的算法是使用车轮分解为2,3和5的Erathostenes筛,其中剩余数字中的素数表示为字节数组中的位。在我3岁笔记本电脑的一个核心上的Java中,需要23秒才能计算出高达10亿的素数。

通过车轮分解,Atkin的Sieve大约慢了两倍,而普通的BitSet大约快了30%。

另见this answer

答案 2 :(得分:1)

我做了一个算法,可以在I 350M笔记本上找到2-90 000 000范围内的素数,持续0.65秒,用C语言编写....你必须使用按位运算并且有“代码”来重新计算索引你的数组索引你想要的具体位。例如,如果你想要数字2的折叠,具体位将是例如.... 10101000 ...所以如果你从左边读...你得到索引4,6,8 ......就是这样

答案 3 :(得分:0)

几条评论。

  1. 对于速度,预计算然后从磁​​盘加载。它超级快。我很久以前就用Java做过了。

  2. 不要存储为数组,存储为奇数的位序列。更有效的记忆方式

  3. 如果您的速度问题是您希望此特定计算快速运行(您需要证明为什么您无法预先计算并从磁盘加载它),则需要编写更好的Atkin筛选器。它更快。但只是轻微的。

  4. 您尚未指出这些素数的最终用途。我们可能完全错过了一些东西,因为你没有告诉我们申请。告诉我们应用程序的草图,答案将更好地针对您的背景。

  5. 为什么你认为存在更快的东西?你没有证明你的预感是正当的。这是一个非常难的问题。 (那就是找到更快的东西)

答案 4 :(得分:0)

使用Sieve of Atkin可以做得更好,但正确地快速实现非常棘手。维基百科伪代码的简单翻译可能不够好。

相关问题