web-dev-qa-db-ja.com

アトキンのふるい-説明とJava例

ウィキペディアでアトキンのふるいについて読んだことがありますが、現時点ではウィキは限られています。アトキンのふるいの概要とJavaの例を探していました。

ありがとう。

31
Jash Sayani

素数、合成数、ふるいについてここで示した基本的な考え方のいくつかを知っているかもしれません(そしておそらく知っているかもしれません)が、アルゴリズムの性質を理解する上で他の読者に役立つかもしれません。この答えのいくつかは、StackOverflowと同等の数学に属することに危険なほど近づいていますが、アルゴリズムの機能とその方法を関連付ける必要があると感じています。

このふるいに関するウィキペディアの記事の3つのモジュラー算術および2次対は、このふるいのコアを定理(およびその証明)とともに公開したAtkinおよびBernsteinの論文の3つの対から派生しており、それらが集合的に素数のふるいを形成することを示しています。誰もが素数だけを生成しますが、すべての素数を生成するわけではありません。すべての素数を生成するには、3つすべてが必要です。

これがウィキペディアのアルゴリズムを実装するJavaプログラムです。ウィキペディアのJava)で直接実装されているだけで、実装の効率性については主張しません。記事のアルゴリズム。

// SieveOfAtkin.Java

import Java.util.Arrays;

public class SieveOfAtkin {
private static int limit = 1000;
private static boolean[] sieve = new boolean[limit + 1];
private static int limitSqrt = (int)Math.sqrt((double)limit);

public static void main(String[] args) {
    // there may be more efficient data structure
    // arrangements than this (there are!) but
    // this is the algorithm in Wikipedia
    // initialize results array
    Arrays.fill(sieve, false);
    // the sieve works only for integers > 3, so 
    // set these trivially to their proper values
    sieve[0] = false;
    sieve[1] = false;
    sieve[2] = true;
    sieve[3] = true;

    // loop through all possible integer values for x and y
    // up to the square root of the max prime for the sieve
    // we don't need any larger values for x or y since the
    // max value for x or y will be the square root of n
    // in the quadratics
    // the theorem showed that the quadratics will produce all
    // primes that also satisfy their wheel factorizations, so
    // we can produce the value of n from the quadratic first
    // and then filter n through the wheel quadratic 
    // there may be more efficient ways to do this, but this
    // is the design in the Wikipedia article
    // loop through all integers for x and y for calculating
    // the quadratics
    for (int x = 1; x <= limitSqrt; x++) {
        for (int y = 1; y <= limitSqrt; y++) {
            // first quadratic using m = 12 and r in R1 = {r : 1, 5}
            int n = (4 * x * x) + (y * y);
            if (n <= limit && (n % 12 == 1 || n % 12 == 5)) {
                sieve[n] = !sieve[n];
            }
            // second quadratic using m = 12 and r in R2 = {r : 7}
            n = (3 * x * x) + (y * y);
            if (n <= limit && (n % 12 == 7)) {
                sieve[n] = !sieve[n];
            }
            // third quadratic using m = 12 and r in R3 = {r : 11}
            n = (3 * x * x) - (y * y);
            if (x > y && n <= limit && (n % 12 == 11)) {
                sieve[n] = !sieve[n];
            } // end if
            // note that R1 union R2 union R3 is the set R
            // R = {r : 1, 5, 7, 11}
            // which is all values 0 < r < 12 where r is 
            // a relative prime of 12
            // Thus all primes become candidates
        } // end for
    } // end for
    // remove all perfect squares since the quadratic
    // wheel factorization filter removes only some of them
    for (int n = 5; n <= limitSqrt; n++) {
        if (sieve[n]) {
            int x = n * n;
            for (int i = x; i <= limit; i += x) {
                sieve[i] = false;
            } // end for
        } // end if
    } // end for
    // put the results to the System.out device
    // in 10x10 blocks
    for (int i = 0, j = 0; i <= limit; i++) {
        if (sieve[i]) {
            System.out.printf("%,8d", i);
            if (++j % 10 == 0) {
                System.out.println();
            } // end if
            if (j % 100 == 0) {
                System.out.println();
            } // end if
        } // end if
    } // end for
} // end main
} // end class SieveOfAtkin

私は、ふるいが構成されている定理を説明しているAtkin(Bernsteinとの共著)のオリジナルの論文のコピーを持っています。その論文はここから入手できます: http://www.ams.org/mcom/2004-73-246/S0025-5718-03-01501-1/S0025-5718-03-01501-1.pdf 。それは非数学者のための密な読書であり、アメリカ数学会の論文に典型的なすべての簡潔さを持っています。

ここに続くのは、アルゴリズムがAtkinとBernsteinの説明と論文からどのように導き出されるかについてのより深い説明です。

AtkinとBernsteinは(当然のことながら)、読者が素数ふるい、モジュラー演算、およびモジュラー演算を使用したホイール因数分解を完全に理解していることを前提としています。残念ながら、ウィキペディアの記事の説明とアルゴリズムは、程度はわずかですが、同様のことを前提としています。 AtkinとBernsteinは、3組のホイール因数分解と既約二次方程式だけが使用できると主張せず、他のペアの合格例を示していますが、その方法についてはこれ以上のコメントはありません。したがって、AtkinとBernsteinが定理と証明を与える3つは、彼らの仕事に基づくアルゴリズムで使用される3つです。アトキンとバーンスタインはまた、彼らの3つのペアが最適なものであるとは主張していません。どうやら便利なものです。

この種の議論に簡潔に役立つファンキーな数学記号は、ここでは利用できません。この回答の目的のために、私は使用します

{1つを定義するいくつかの列挙されたセットまたはプロパティ}

セットを表す

Nat0

ゼロを含む自然数のセットを表す、つまり、Nat0 = {0、1、2、...}、

ナット

ゼロを含まない自然数のセットを表すには、つまり、Nat = {1、2、3、...}と、セットを定義するための次の構成と、その要素の記号:

{セットの要素のシンボル:シンボルの観点からセットを定義する基準}

セットのカーディナリティ、つまりセット内の要素の数を表す

^

べき乗を表す、つまりx ^ 2として記述されたxの2乗

説明、定理、およびアルゴリズムのホイール因数分解で使用されるモジュラー演算は、2つの同等の形式で表示されます。

n =(k * m)+ r for k in Nat0 and r in R = {r:r in Nat0 and r <m}

n mod m = rここで、r in R = {r:r in Nat0 and r <m}

以下は、彼らの論文の定理で与えられた定義と、モジュラー算術形式に関するいくつかの注記です。

  1. nは常に素数であり、#{(x、y):n =(4 * x ^ 2)+(y ^ 2)、n in {n:(Nat0 * 4)+ 1}、ここでxおよびy> = 1 nには完全な平方係数がありません}は奇数です。つまり、2次n =(4 * x ^ 2)+(y ^ 2)を解く奇数の(x、y)ペアがある場合に限ります。ここで、xおよびy整数> = 1、n mod 4 = 1で、nに完全な二次因子がない場合、nは素数です。ここで、rがRにあるn mod m = rの形式はm = 4およびR = {r:1}であることに注意してください。

  2. nは常に素数であり、#{(x、y):n =(3 * x ^ 2)+(y ^ 2)、n in {n:(Nat0 * 6)+ 1}、ここでxおよびy> = 1 nには完全な平方係数がありません}は奇数です。つまり、2次n =(3 * x ^ 2)+(y ^ 2)を解く奇数の(x、y)ペアがある場合に限ります。ここで、xおよびy整数> = 1、n mod 6 = 1で、nに完全な二次因子がない場合、nは素数です。ここで、rが集合Rにあるn mod m = rの形式はm = 6およびR = {r:1}であることに注意してください。

  3. nは常に素数であり、#{(x、y):n =(3 * x ^ 2)-(y ^ 2)、{n:(Nat0 * 12)+ 11}、x> y> = 1であり、nは完全な二乗因子はありません}は奇妙です。つまり、2次n =(3 * x ^ 2)-(y ^ 2)を解く奇数の(x、y)ペアがある場合に限り、x、y整数、x> y> = 1 、n mod 12 = 11であり、nに完全な二次因子がない場合、nは素数です。ここで、rが集合Rにあるn mod m = rの形式は、m = 12およびR = {r:11}であることに注意してください。

論文とウィキペディアの記事が読者がよく知っていると想定しているホイール因数分解の特性は、モジュラー演算を使用して、特定の素因数を持たない整数のみを選択的に選択できることです。フォームで

n mod m = r、r in R = {r:Nat0、r <m}、

mに対して互いに素であるRの要素のみを選択した場合、式を満たすすべての整数nは素数になるか、mに対して互いに素になります。

mがnに対して互いに素であるということは、共通の整数除数が1より大きいことを意味します。互いに素な数の例は次のとおりです。2は互いに素で3、4は互いに素で9、9は互いに素で14。モジュラー算術で使用される互いに素(残差)と、説明やアルゴリズムのさまざまなバージョンでそれらがどのように同等であるか。

以下では、定理、アルゴリズム、および説明がすべてどのように関連しているかを説明します。

最初の2次式の場合、n =(4 * x ^ 2)+(y ^ 2):

定理は次の形式を使用します。

n =(k * 4)+ rここで、R1のr = {r:1}およびNat0のk

これは書くのと同じです

n mod 4 = rここで、R1のr = {r:1}

Nは、1から始まるNat0の1つおきの奇数、つまり{1、5、9、13、...}である必要があると定義されていることに注意してください。

アルゴリズムの場合、mに対してさまざまな選択を行うことができ、正しいセットRを使用すると、定理によって示されるプロパティが保持されます。論文とウィキペディアの記事の著者は、読者がすでにこれらすべてを知っており、すぐにそれを認識すると想定しています。論文とウィキペディアの記事で使用されているmの他の値については、同等のものは次のとおりです。

n mod 12 = rここで、R1aのr = {r:1、5、9}

n mod 60 = rここで、R1bのr = {r:1、5、9、13、17、21、25、29、33、37、41、45、49、53、57}

セットR1aおよびR1bの特定の要素は、後で説明する2つの理由で削除される可能性があり、定理は引き続き適用されます。

2次二次方程式の場合、n =(3 * x ^ 2)+(y ^ 2):

定理は次の形式を使用します。

n =(k * 6)+ rここで、R2のr = {r:1}およびNat0のk

繰り返しますが、これはと同じです

n mod 6 = rここで、R2のr = {r:1}

ここで、これは1から始まるNat0の3つおきの奇数、つまり{1、7、13、19、...}であることに注意してください。

論文と記事の同等物は次のとおりです。

n mod 12 = rここで、R2aのr = {r:1、7}

n mod 60 = rここで、R2bのr = {r:1、7、13、19、25、31、37、43、49、55}

繰り返しますが、セットR2aとR2bの値は、後で説明する2つの理由で削除される可能性があり、定理は引き続き適用されます。

3次2次式の場合、(3 * x ^ 2)-(y ^ 2):

定理は次の形式を使用します。

n = k * 12 + rここで、Nat0のkとR3aのr = {r:11}

繰り返しますが、これは次と同じです。

n mod 12 = rここで、R3aのr = {r:11}

ここで、これは11から始まるNat0の6番目ごとの奇数、つまり{11、23、35、47、...}であることに注意してください。

論文と記事の同等物は次のとおりです。

n mod 60 = rここで、R3bのr = {r:11、23、35、47、59}

この場合も、後で説明する理由でセットR3bの値を削除しても、定理は引き続き適用されます。

さまざまなアルゴリズムと説明では、m = 12とm = 60の値の場合、セットRの要素は、定理またはアルゴリズムの有効性に影響を与えることなく削除されます。セットRの一部の値が破棄される理由は2つあります。

最初の理由は、ペアになっているmに対して互いに素ではない集合R内のrの値は、1つ以上の素因数がmである複合整数であるnの値を含めるためだけに役立つためです。素数になります。モジュラー演算のこの機能は、ホイール因数分解を使用して、素数であるかどうかについて、通常はより複雑で効率の低い、さらなるテストから大量の非素数を除外する理由です。このふるいでは、より複雑なテストは、特定の既約二次方程式の解の数が奇数であるかどうかです。つまり、このアルゴリズムのセットR内の、そのセットRで使用されているmの値に比較的プライムされていないすべての値をすぐに破棄できます。

2番目の理由は、この論文では、ホイールの因数分解により、重なり合う素数を含む、重なり合う整数のセットが作成されることです。それらは便利であり、重複は定理にとって重要ではありませんでしたが、アルゴリズムでは、簡単に回避できれば無駄です。この場合、それは簡単に回避されます。また、ホイール因数分解からの整数のセットが重複する場合、1つの2次の奇数の解と別の2次の奇数の解は、累積偶数の解になります(奇数と奇数は常に偶数)。ウィキペディアの実装を含む多くの実装では、ウィキペディアのような実装はすべての二次方程式の累積解から素数性を決定し、各二次方程式から解を分離しないため、これは素数が素数ではないことを識別します。そのような場合、ホイール因数分解からの整数が整数の排他的サブセットであることが不可欠です。

実装では、必要がない場合、複数の2次式で同じ数をテストする必要はありません。同じmが使用されていると仮定して、3つの2次方程式で使用される集合Rのrの値は、そのうちの1つだけに含める必要があります。それが複数ある場合、nの同じ値が複数回表示され、複数の2次式でテストされます。使用中のmの値が同じである場合、Rの同じ要素が複数の2次方程式でRに表示されないようにすると、重なりがなくなります。ウィキペディアの記事の場合、ホイール因数分解によって防止される重なりは、単一の二次方程式では奇数であるが、2つの二次方程式では偶数に累積する累積二次解で発生する誤った結果を防止します。

別のアルゴリズムは、二次方程式を計算する前にオーバーラップを回避する場合があります。二次方程式とホイール因数分解の経験的テストでは、m = 12のホイール因数分解では、二次方程式を解くよりもnの値が大幅に少なくなります。 m = 60の場合にホイール因数分解を使用すると、差が大幅に増加します。 nの特定の値に対する二次解アルゴリズムが非常に効率的である場合、二次方程式をテストするためにホイール因数分解から得られた値のみを使用することにより、大幅な改善が見込めます。

互いに素ではない要素を削除した後のホイールの因数分解は次のとおりです。最初の2次式の場合:

n mod 12 = rここで、R1aのr = {1:1、5}(9には12と共通の除数3があります)

n mod 60 = rここで、R1bのr = {r:1、13、17、29、37、41、49、53}(5、25、および45には60と共通の除数5があります; 9、21、33、45および57は60と共通の除数3を持っています)そしてこれはAtkinとBernsteinの論文のアルゴリズムの形式です。

2次の場合:

n mod 12 = rここで、R2aのr = {1、7}(Rの要素には12と共通の約数がありません}

n mod 60 = rここで、R2b = {r:1、7、13、19、31、37、43、49}(25と55は60と共通の除数5を持ちます)のrであり、これはのアルゴリズムの形式です。アトキンとバーンスタインの論文。

3次2次式の場合:

n mod 12 = rここで、R3aのr = {r:11}(Rの要素には12と共通の約数がありません}

n mod 60 = 4ここで、R3bのr = {r:11、23、47、59}(35には60と共通の除数5があります)。これは、Atkin andBernsteinの論文のアルゴリズムの形式です。

同じ要素のいくつかが、第1および第2の二次方程式のセットR1aおよびR2aに表示されることに注意してください。セットR1bとR2bについても同じことが言えます。 mが12の場合、共通要素のセットは{1}です。 mが60の場合、共通要素のセットは{1、13、37、49}です。 Rの要素が1つの二次方程式にのみ含まれるようにすると、次のフォームが作成されます。これは、ウィキペディアの記事から認識できるはずです。

最初の2次式の場合:

n mod 12 = rここで、R1aのr = {r:1、5}(重複は削除されません)(これはウィキペディアのアルゴリズムに示されている形式です)

n mod 60 = rここで、R1bのr = {r:1、13、17、29、37、41、49、53}(重複は削除されません)(これはウィキペディアの説明に示されている形式です)

2次の場合:

n mod 12 = rここで、R2aのr = {r:7}(要素1はすでにR1aにあるため削除されています)(これはウィキペディアのアルゴリズムに示されている形式です)

n mod 60 = rここで、R2bのr = {r:7、19、31、43}(要素1、13、37、および49はすでにR1bにあるため削除されています)(これはウィキペディアの説明に示されている形式です)

3次2次式の場合:

n mod 12 = rここで、R3aのr = {r:11}(重複なし)

n mod 60 = rここで、R3bのr = {r:11、23、47、59}(重複なし)

Mの値が4、6、12、60を超える理由について、残りの1つの質問があります。これは、を使用して素数であるためのより複雑なテストから除外する複合(つまり非素数)数の数と関係があります。二次方程式と使用されるホイール因数分解の複雑さ。

使用されるmの値は、素数を削除せずにすぐに削除できるコンポジットを決定できます。 m = 4およびR1 = {r:1}の場合、最初の2次の定理のように、1はすべての数に対して互いに素であり、4は2の素因数を持つため、素因数が2のすべての数は削除されます。 3はこのセットRに含まれていないため、m = 4とセットR1を使用した素因数分解でも、多数の素数、おそらくそれらの半分が除外されることに注意してください。

2番目の2次の定理のようにm = 6およびR2 = {r:1}の場合、1はすべての数に対して互いに素であり、6は2と3の素因数を持つため、2または3の素因数を持つすべての合成数は削除されます。繰り返しますが、m = 6で、5を含まないR2を設定すると、多数の素数、おそらくそれらの半分が除外されます。

3番目の2次方程式の定理のようにm = 12およびR3 = {r:11}の場合、11は12に対して互いに素であり、12は2および3の素因数を持つため、素因数が2または3のすべての複合マンバーは削除されます。繰り返しますが、m = 12で、1、5、または7を含まないR3を設定すると、多数の素数、おそらくそれらの半分以上が除外されます。

AtkinとBernsteinが彼らの論文で非公式に示していることの1つは、定理のホイール因数分解はそれぞれの二次方程式から素数を個別に除外しますが、3つのホイール因数分解はすべての素数を許可し、ホイール因数分解の場合は1番目と2番目の二次方程式は、有意なオーバーラップを許可します。 m = 60のアルゴリズムでは重複を削除しませんが、ウィキペディアの記事では、記事のアルゴリズムでm = 12、記事の説明でm = 60を設定しています。

彼らの定理で使用されている二次方程式の場合、それらに伴うホイール因数分解を弱めると、それらが定理に従って動作することが無効になります。ただし、より多くのコンポジットのみを削除し、まったく同じ素数を維持する方法でそれらを強化することができます。 m = 4(4 = 2 * 2)の形式の場合、すべての偶数の整数がフィルター処理されます。 m = 12(12 = 2 * 2 * 3)の形式の場合、素因数が2または3のすべての整数がフィルター処理されます。 m = 60(60 = 2 * 2 * 3 * 5)の形式の場合、素因数が2、3、または5のすべての整数がフィルター処理されます。 m = 12と同じ効果にはm = 6、m = 60と同じ効果にはm = 30のフィルターを使用できる可能性がありますが、作成するものがで使用されるものと同等であることに注意する必要があります。定理。

ホイールの因数分解に関するいくつかの有用な統計があります。 Nat0の整数の50%は偶数であり、2以外は素数ではありません。 Nat0の整数の33%は、素因数として3を持ち、素因数ではありません。 Nat0の整数の20%は、素因数として5を持ち、素因数ではありません。まとめると、Nat0の整数の67%は、素因数が2または3であり、素因数ではありません。まとめると、Nat0の整数の約75%は、2、3、または5の素因数を持ち、素因数ではありません。素数であるためのより複雑なテストからNat0の整数の1/2、2/3、または3/4を削除する簡単な方法は非常に魅力的であり、素数ふるいの予備フィルターとしてホイール因数分解を使用する動機です。また、大量の複合材料を表す素因数ですべての複合材料をフィルタリングできる、付随するセットRとともにmの値を使用する動機もあります。

絶対的な最小値として、素因数が2のコンポジット(つまり、すべての偶数)を削除し、最後に2を追加し直したいと思うでしょう。少なくとも素因数が2または3のコンポジットを削除したいのですが、素因数が2、3、または5のコンポジットを削除したいのが望ましいです。それを過ぎると、統計は収穫逓減を示します。 R1でm = 4は、最低限を達成します。 m = 12で、R1a、R2a、およびR3aは、必要な最小値を達成します。 m = 60、R1b、R2b、R3bは非常に望ましい結果を達成します。

Mと集合Rの値を操作する際に考慮すべきことがいくつかあります。2つの形式は最初の2次式では同等ではないことに注意してください。

n mod 12 = rここで、R1aのr = {r:1、5}

そして

n mod 6 = rここで、r in R = {r:1、5}

m = 6の形式はと同等ではないため

n mod 4 = rここで、R1のr = {r:1}

ご了承ください:

n mod 6 = rここで、r in R = {r:1}

と同等です

n mod 12 = rここで、r in R = {r:1、7}

m = 6の形式は、2次2次式で使用できます。実際、これは定理の2次2次方程式で使用される形式です。すでに検討した例の代わりにそれを使用する場合、m = 12のときに、最初の2次方程式の集合Rから要素1を削除して、重複を削除できます。

アルゴリズムを調整する際には、定理が必要とする条件を維持するためにデューデリジェンスを使用する必要があります。 mの値とRのセットを選択するときは、定理のホイール因数分解によって生成されなかったnの新しい値を2次方程式に導入しない形式と同等であることを確認する必要があります。

実装の場合、データ構造、算術演算、プロセッサ機能(特に乗算と除算に関して)、使用可能なプロセッサキャッシュ、メモリ、およびデータ構造のサイズに関連する複雑さと効率に基づいて選択が行われます。 mの値と、チェックする必要のあるセットRの剰余(剰余)の数の間にはトレードオフがあります。これらのいくつかは、説明でm = 60、アルゴリズムでm = 12と表示される理由である可能性があります。これらは、AtkinとBernsteinが論文のアルゴリズムでm = 60のフォームを使用した理由です。

AtkinとBernsteinの論文では、格子を使用してnの特定の値の2次方程式の解を見つけるためのアルゴリズムも提供しています。これらの追加のアルゴリズムにより、AtkinとBernsteinは、二次方程式とホイール因数分解で同時にフィルタリングするふるいアルゴリズムを作成できました。ウィキペディアの記事のアルゴリズムでは、ホイール因数分解を使用した二次方程式の格子導出解のアルゴリズムはどれも考慮されていませんでした。ウィキペディアの記事では、徹底的なx、y値の手法が二次方程式で使用され、二次方程式がnの値を返した後にホイール因数分解が適用されます。繰り返しますが、これは効率の問題であり、実装者が決定する必要があります。

129
Jim