Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么我对Atkins筛选的天真实现排除了5?_Python_Matlab_Sieve Of Atkin - Fatal编程技术网

Python 为什么我对Atkins筛选的天真实现排除了5?

Python 为什么我对Atkins筛选的天真实现排除了5?,python,matlab,sieve-of-atkin,Python,Matlab,Sieve Of Atkin,我写了一个非常幼稚的Atkin筛实现,基于。我最初在MATLAB中编写了算法,它省略了5作为素数。我还用Python编写了算法,得到了相同的结果 从技术上讲,我知道为什么5被排除在外;在n=4*x^2+y^2的步骤中,当x==1和y==1时,n==5。这种情况只发生一次,所以5从素数转换为非素数,并且永远不会返回 为什么我的算法与维基百科上的算法不匹配?虽然我做了一些表面上的调整(例如,每次迭代只计算x^2一次,在第一个等式中使用mod(n,12)时存储mod的值,等等),但它们不应该改变算法的

我写了一个非常幼稚的Atkin筛实现,基于。我最初在MATLAB中编写了算法,它省略了5作为素数。我还用Python编写了算法,得到了相同的结果

从技术上讲,我知道为什么5被排除在外;在
n=4*x^2+y^2
的步骤中,当x==1和y==1时,n==5。这种情况只发生一次,所以5从素数转换为非素数,并且永远不会返回

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

我仔细阅读了Atkin的文章,但我不知道是什么差异在我的实现中造成了问题

Python代码:
不看代码,我在您的描述中读到了以下内容:

so 5 is flipped from prime to nonprime and never flipped back

我想这就是问题所在,它应该被初始化为false(因此是非prime),因为它只有在保持prime时才会被切换。

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

我想对于matlab,你应该从:
res=false(5,1)
开始,就像维基上描述的那样。@DennisJaheruddin或
res=[0,1,1,0,0]
因为我们知道2和3是素数。捕捉得好。这是一个简单的错误,但我花了半个小时在我的算法的“内脏”中挖掘,我没有在代码的顶部看到它。
function p = atkin1(limit)

% 1. Create a results list, filled with 2, 3, and 5
res = [0, 1, 1, 0, 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) = ~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) = ~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
// 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
so 5 is flipped from prime to nonprime and never flipped back