【问题标题】:Prime numbers using Sieve of Atkin with BigInteger使用带有 BigInteger 的阿特金筛法的素数
【发布时间】:2015-04-15 17:17:19
【问题描述】:

有没有人碰巧知道使用 BigInteger 的 C# Sieve of Atkin 算法?据我了解,这是目前存在的最著名的素数分解算法。

我目前有这个功能:

/// <summary>
        /// Finds prime numbers using the Sieve of Atkins algorithm.
        /// </summary>
        /// <param name="max">The limit of the prime list.</param>
        /// <returns>The list of prime numbers.</returns>
        public List<int> FindPrimes(int max)
        {
            var isPrime = new bool[max + 1];
            var sqrt = (int) Math.Sqrt(max);

            Parallel.For(1, sqrt, x =>
            {
                var xx = x * x;
                for (int y = 1; y <= sqrt; y++)
                {
                    var yy = y * y;
                    var n = 4 * xx + yy;
                    if (n <= max && (n % 12 == 1 || n % 12 == 5))
                        isPrime[n] ^= true;

                    n = 3 * xx + yy;
                    if (n <= max && n % 12 == 7)
                        isPrime[n] ^= true;

                    n = 3 * xx - yy;
                    if (x > y && n <= max && n % 12 == 11)
                        isPrime[n] ^= true;
                }
            });

            var primes = new List<int>() { 2, 3 };
            for (int n = 5; n <= sqrt; n++)
            {
                if (isPrime[n])
                {
                    primes.Add(n);
                    int nn = n * n;
                    for (int k = nn; k <= max; k += nn)
                        isPrime[k] = false;
                }
            }

            for (int n = sqrt + 1; n <= max; n++)
                if (isPrime[n])
                    primes.Add(n);

            return primes;

        }

但是我想要一个看起来更像下面的函数签名,这样它就可以接受一个数字来测试并在数字是素数时输出 true。

public bool IsPrime(BigInteger number) { ... }

【问题讨论】:

  • 这个问题专门询问BigInteger。另外,该问题的答案是使用简单的试除法。
  • 我同意。我已经对你的问题摸不着头脑了:)
  • 由于算法的性质,看起来我可能需要切换到阿特金斯以外的其他东西,因为它依赖于以前的因素。接收任意大数并有效地将其处理为素数的能力是我们的目标,而 int 迅速突破了任意属性。

标签: c# math primes prime-factoring


【解决方案1】:

我认为,根据算法的性质,没有直接的方法来检查 N 是否为素数。

要检查 N 是否为素数,首先,您可以使用简单的除数(2、5、7 等),然后您可以生成 N 下的所有阿特金素数,然后尝试将 N 除以每个阿特金素数。如果它是可分的,那么你返回 false。如果没有,那么恐怕你将不得不测试 N.... 下的所有数字。

也许您可以使用一些概率方法,这可以更有效地检查单个数字。尝试Miller–RabinSolovay–Strassen primality test(用于RSA)等方法。

我想你会很高兴:here's 是 Solovay 的实现,here's 是一个关于所有素性测试算法的非常有趣的页面。

【讨论】:

    【解决方案2】:

    您应该以不同的方式解决几个相关的问题:

    • 查找给定合数的所有质因数:根据大小,您应该使用 Pollard rho、椭圆曲线法、二次筛或数域筛。一般来说,因式分解数字需要很长时间。
    • 测试给定数是否为素数:您应该使用 Miller-Rabin 进行此操作。它的速度非常快,并且通过使用除“那些没有非平凡因子的素数”之外的素数特征来规避“因数分解很慢”的问题。
    • 查找范围内的所有素数:对于接近零的范围使用 Eratosthenes 筛,对于远离零的范围使用 Atkin 筛。

    您正在询问如何应用阿特金筛法来测试素数或将数字分解为素数。这是解决这两个问题的错误方法。

    【讨论】:

      猜你喜欢
      • 2010-11-04
      • 2014-05-23
      • 2015-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多