微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

python – 为什么我天真的阿特金斯筛选实施排除5?

我写了一个非常天真的Atna Sieve实现,基于 Wikipedia’s inefficient but clear pseudocode.我最初在MATLAB中编写了算法,它省略了5作为素数.我也用Python编写了算法,结果相同.

从技术上讲,我知道为什么要排除5;在n = 4 * x ^ 2 y ^ 2的步骤中,当x == 1且y == 1时n == 5.这仅发生一次,因此5从素数转换为非素数并且从不翻转.

为什么我的算法与维基百科上的算法不匹配?虽然我做了一些表面调整(例如,在每次迭代中只计算一次x ^ 2,在第一个等式中使用时存储mod(n,12)的值等),但它们不应该改变逻辑.算法.

我在several discussions related阅读了Atkin的Sieve,但我不知道在我的实现中产生问题的区别是什么.

Python代码

def atkin1(limit):
    res = [0] * (limit + 1)
    res[2] = 1
    res[3] = 1
    res[5] = 1

    limitSqrt = int(math.sqrt(limit))
    for x in range(1,limitSqrt+1):
        for y in range(1,limitSqrt+1):
            x2 = x**2
            y2 = y**2
            n = 4*x2 + y2
            if n == 5:
                print('debug1')
            nMod12 = n % 12
            if n <= limit and (nMod12 == 1 or nMod12 == 5):
                res[n] ^= 1

            n = 3*x2 + y2
            if n == 5:
                print('debug2')
            if n <= limit and (n % 12 == 7):
                res[n] ^= 1

            if x > y:
                n = 3*x2 - y2
                if n == 5:
                    print('debug3')
                if n <= limit and (n % 12 == 11):
                    res[n] ^= 1

    ndx = 5
    while ndx <= limitSqrt:
        m = 1
        if res[ndx]:
            ndx2 = ndx**2
            ndx2Mult =m * ndx2
            while ndx2Mult < limit:
                res[ndx2Mult] = 0
                m += 1
                ndx2Mult = m * ndx2
        ndx += 1

    return res

MATLAB代码

function p = atkin1(limit)

% 1. Create a results list,filled with 2,3,and 5
res = [0,1,1];

% 2. Create a sieve list with an entry for each positive integer; all entries of
% this list should initially be marked nonprime (composite).
res = [res,zeros(1,limit-5)];

% 3. For each entry number n in the sieve list,with modulo-sixty remainder r:

limitSqrt = floor(sqrt(limit));
for x=1:limitSqrt
    for y=1:limitSqrt
        x2 = x^2;       y2 = y^2;

        % If r is 1,13,17,29,37,41,49,or 53,flip the entry for each
        % possible solution to 4x^2 + y^2 = n.
        n = 4*x2 + y2;
        nMod12 = mod(n,12); 
        if n <= limit && (nMod12 == 1 || nMod12 == 5)
            res(1,n) = ~res(1,n);
        end

        % If r is 7,19,31,or 43,flip the entry for each possible solution
        % to 3x^2 + y^2 = n.
        n = 3*x2 + y2;
        if n <= limit && mod(n,12) == 7
            res(1,n);
        end

        % If r is 11,23,47,or 59,flip the entry for each possible solution
        % to 3x^2 - y^2 = n when x > y.
        if x > y
            n = 3*x2 - y2;
            if n <= limit && mod(n,12) == 11
                res(1,n);
            end
        end

        % If r is something else,ignore it completely.
    end
end

   % 4. Start with the lowest number in the sieve list.
ndx = 5;
while ndx < limitSqrt
    m = 1;
    if res(ndx)
        % 5. Take the next number in the sieve list still marked prime.
        % 6. Include the number in the results list.
        % 7. Square the number and mark all multiples of that square as nonprime.
        ndx2 = ndx^2;
        ndx2Mult = m * ndx2;
        while ndx2Mult < limit
            res(ndx2Mult) = 0;
            m = m + 1;
            ndx2Mult = m * ndx2;
        end
    end

    % 8. Repeat steps five through eight.
    ndx = ndx + 1;
end

p = find(res); % Find the indexes of nonzerogo
end

Wikipedia pseudocode

// arbitrary search limit
limit ← 1000000         

// initialize the sieve
is_prime(i) ← false,∀ i ∈ [5,limit] 

// put in candidate primes: 
// integers which have an odd number of
// representations by certain quadratic forms
for (x,y) in [1,√limit] × [1,√limit]:
    n ← 4x²+y²
    if (n ≤ limit) and (n mod 12 = 1 or n mod 12 = 5):
        is_prime(n) ← ¬is_prime(n)
    n ← 3x²+y²
    if (n ≤ limit) and (n mod 12 = 7):
        is_prime(n) ← ¬is_prime(n)
    n ← 3x²-y²
    if (x > y) and (n ≤ limit) and (n mod 12 = 11):
        is_prime(n) ← ¬is_prime(n)

// eliminate composites by sieving
for n in [5,√limit]:
    if is_prime(n):
        // n is prime,omit multiples of its square; this is
        // sufficient because composites which managed to get
        // on the list cannot be square-free
        is_prime(k) ← false,k ∈ {n²,2n²,3n²,...,limit} 

print 2,3
for n in [5,limit]:
    if is_prime(n): print n

解决方法

在维基百科的算法文本描述中,“结果列表”和“筛选列表”是两个不同的东西.您的Matlab代码只有一个向量用于两者.但是筛选清单中5的初始值应该是“非素数”.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


我最近重新拾起了计算机视觉,借助Python的opencv还有face_recognition库写了个简单的图像识别demo,额外定制了一些内容,原本想打包成exe然后发给朋友,不过在这当中遇到了许多小问题,都解决了,记录一下踩过的坑。 1、Pyinstaller打包过程当中出现warning,跟d
说到Pooling,相信学习过CNN的朋友们都不会感到陌生。Pooling在中文当中的意思是“池化”,在神经网络当中非常常见,通常用的比较多的一种是Max Pooling,具体操作如下图: 结合图像理解,相信你也会大概明白其中的本意。不过Pooling并不是只可以选取2x2的窗口大小,即便是3x3,
记得大一学Python的时候,有一个题目是判断一个数是否是复数。当时觉得比较复杂不好写,就琢磨了一个偷懒的好办法,用异常处理的手段便可以大大程度帮助你简短代码(偷懒)。以下是判断整数和复数的两段小代码: 相信看到这里,你也有所顿悟,能拓展出更多有意思的方法~
文章目录 3 直方图Histogramplot1. 基本直方图的绘制 Basic histogram2. 数据分布与密度信息显示 Control rug and density on seaborn histogram3. 带箱形图的直方图 Histogram with a boxplot on t
文章目录 5 小提琴图Violinplot1. 基础小提琴图绘制 Basic violinplot2. 小提琴图样式自定义 Custom seaborn violinplot3. 小提琴图颜色自定义 Control color of seaborn violinplot4. 分组小提琴图 Group
文章目录 4 核密度图Densityplot1. 基础核密度图绘制 Basic density plot2. 核密度图的区间控制 Control bandwidth of density plot3. 多个变量的核密度图绘制 Density plot of several variables4. 边
首先 import tensorflow as tf tf.argmax(tenso,n)函数会返回tensor中参数指定的维度中的最大值的索引或者向量。当tensor为矩阵返回向量,tensor为向量返回索引号。其中n表示具体参数的维度。 以实际例子为说明: import tensorflow a
seaborn学习笔记章节 seaborn是一个基于matplotlib的Python数据可视化库。seaborn是matplotlib的高级封装,可以绘制有吸引力且信息丰富的统计图形。相对于matplotlib,seaborn语法更简洁,两者关系类似于numpy和pandas之间的关系,seabo
Python ConfigParser教程显示了如何使用ConfigParser在Python中使用配置文件。 文章目录 1 介绍1.1 Python ConfigParser读取文件1.2 Python ConfigParser中的节1.3 Python ConfigParser从字符串中读取数据
1. 处理Excel 电子表格笔记(第12章)(代码下载) 本文主要介绍openpyxl 的2.5.12版处理excel电子表格,原书是2.1.4 版,OpenPyXL 团队会经常发布新版本。不过不用担心,新版本应该在相当长的时间内向后兼容。如果你有新版本,想看看它提供了什么新功能,可以查看Open