素数の一覧表を作るときに、一個一個の数を素数かどうか判定していくのもよいですが、もう少し効率的に行う方法があります。
その方法の一つが エラトステネスの篩(ふるい) です。
エラトステネスの篩は、情報系の大学生であればプログラミングの演習等で一度は実装したことがあるかと思いますが、実に「アルゴリズム的」なものです。説明の際は「手順」を説明されることが多く、私はこれを数式で表そうと考えたことがありませんでした。
ところが、Wikipediaを見ると、エラトステネスの篩はこんな数式で表せると書いてあります。
:
以下の素数の個数
:
以下のすべての素数を掛け合わせて得られる数
:メビウス関数
:ガウス記号(
を超えない最大の整数)
:
は
を割り切る
こんな風に表せるのか!と驚いた一方で、これはいったいどういうことなんだろうとも思いました。
実際、式 の意味するところは何なのか、初見ではあまりよくわかりません。そこでこの記事では、式
の意味を理解し、どのようにして導かれるのかを理解するために順を追って解説したいと思います。
エラトステネスの篩(復習)
まずはエラトステネスの篩を復習しましょう。エラトステネスの篩は、数の一覧表の中から素数の倍数の数を下から順に篩い落としていき、最終的に残った数を素数と確定する手法です。
ここでは例として100以下の素数を列挙することを考えます。
①まず、1から100までの数を並べます。

この表の数は現在「未確定」の状態になっていますが、以降の手順で「素数である○」「素数ではない×」のいずれかに確定させます。
②表から1を篩い落とします。(つまり1を「素数ではない」として確定させます。)

③表の先頭の数(この場合は2)を「素数である」と確定して、2以外の2の倍数をすべて表から篩い落とします。(つまりこれらの数を「素数ではない」として確定させます。)

④続いて、まだ未確定の数の中から先頭の数(この場合は3)を「素数である」と確定して、3以外の3の倍数をすべて表から篩い落とします。(つまりこれらの数を「素数ではない」として確定させます。)

⑤まだ未確定の数の中から先頭の数(この場合は5)を「素数である」と確定して、5以外の5の倍数をすべて表から篩い落とします。(つまりこれらの数を「素数ではない」として確定させます。)

⑥まだ未確定の数の中から先頭の数(この場合は7)を「素数である」と確定して、7以外の7の倍数をすべて表から篩い落とします。(つまりこれらの数を「素数ではない」として確定させます。)

⑦まだ未確定の数の中から先頭の数(この場合は11)が、 を超えたので、未確定の数をすべて「素数である」と確定させます。
これにて、100以下の素数がすべて列挙できました!

集合の要素数で言い換える
エラトステネスの篩の手続きをまとめると、1から までの
個の数に対して、そこから
以外の
の倍数
を篩い落としていくという手法でした。
この手続きは、集合を使って表すと分かりやすいです。
1から までの自然数の集合を
としましょう。ここで
です。(
は集合の要素数を表す記号です。)
自然数 に対して、
の中で
の倍数全体を
と表すことにします。たとえば、
の中の
の倍数全体は
と表されます。
の中で「
の倍数ではないもの」は、
から
の元を除いた差集合
で表すことができます。これがまさに上のエラトステネスの篩の手順③に相当しますね。
(ただし、この場合は 2 を余分に除き過ぎているので、あとで考慮します。)

また、ここからさらに3の倍数を除くと
となります。
同様に、 から
の倍数全体を除いたものは
となりますね。
のときは、エラトステネスの篩の手続きはここでストップします。

よって 以下の素数の個数は、この集合に素数
(4個)を加えて、
(1個)を除いたものを考えれば良いことになります。したがって
となります。
ここで、 以下の素数の個数を定義しておくと便利ですね。より一般に、実数
に対して、
以下の素数の個数を
と定義することにしましょう。
すると
となります。
右辺の は
以下の素数
の個数ですので
と表しておくとよいでしょう。
移項すると
となります。これはだいぶ式 の形に近づいてきましたね!
ここで
ですので、 を計算できれば良いことになります。
ここで使えるのが 包除原理 です。
包除原理
一般に集合 と
があったときに、
は
と求められます。これが包除原理です。
これはベン図で表すとよく分かります。

の要素数と
の要素数を足すと、
にも
にも含まれる要素を重複してカウントしていることになりますので、
を引けば良いというわけですね。
集合が の3つの場合は
となります。
これもベン図を考えるとよく分かります。

を計算すると、
と
、
と
、
と
の共通部分がそれぞれ重複してカウントされます。そこで、
を引く必要があります。すると、今度は
の全部の共通部分が引かれ過ぎてしまっているので、
を足せばよいというわけです。
そんなわけで、3つの場合の包除原理が証明されます。
集合が3つのケースは
と思うことができます。
これと同じことが つ以上の場合でも一般に成り立ちます。
したがって、元々の についても
と表せるわけです。
すなわち
というわけです。
ここで は「2の倍数かつ3の倍数(なる1以上100以下の整数)」なので
です。同様に考えると
が得られます。
あとは、 を計算すればよいわけですが、これは100以下の
の倍数の個数なので
で表せます。ここで はガウス記号(つまり、
の整数部分)です。
要するに、 個の数を下から
個ずつとっていくと、最大何セット取り除けるかということですね。
したがって
が成り立ちます。
式 で計算したのは「2の倍数 or 3の倍数 or 5の倍数 or 7の倍数」の個数なので、実際に計算すべきなのは
から上の個数を引いたものになります。
を使うと
が得られます。あとは、これを計算すれば100以下の素数の個数が得られるわけですね。
さて、もうこの式の形は、だいぶ冒頭の式 に近いものになっています。あとはこの符号をどうにかすればよいですね。
ここで
を導入しましょう。
すると、式 の各項は
という形の数になっています。この
は、次の2条件を満たす数になっています:
の約数
は平方因子を持たない(素因数の指数はすべて1以下)
また、2行目の符号が 、3行目の符号が
、・・・と符号が交互に入れ替わっています。
これは の素因数の個数の偶奇によって決まっています。 すなわち、偶数であれば
、奇数であれば
ということです。
この状況を見事に表す関数があります。それが メビウス関数 です。
は自然数
に対して次のように定義されます:
ここで は
の素因子の個数です。
これによって、 が偶数であれば
、
が奇数であれば
となり整合するわけです。
これを用いると、式 は次のように書き直せます。
Σ記号を使ってまとめると
となります。ここで は「
が
の約数」の意味です。これは平方因子を持たないものも含まれますが、
が平方因子を持つ場合は
になり、その項が消えるのでうまくいくわけですね。
よって
が成り立ちます。
ここまでは として具体的に計算してきましたが、一般の
でも同じ議論ができて、
をすべて
に置き換えた
が得られると言うわけです。これでようやく式 が得られました。
お疲れ様です!!
一橋大学の入試
一橋大学で次のような入試問題が出たことがありました。
この問題は大変話題になったと思いますが、tsujimotterも過去に解いたことがあります。
tsujimotter.hatenablog.com
この解法は「合成数を力技で750個列挙する」という「ウケ狙い」の解法でした。
本来想定される解法は、今回の記事のように 包除原理 を使うものです。同じ考え方で解けるのでやってみましょう。
まず、 を「1以上1000以下の整数全体の集合」とします。
を先ほどと同様に「
の中で
の倍数全体」を表すものとします。
これまでの議論と同様に考えると、 なので
以下の素数の倍数を
から取り除けば良いことになります。
したがって
を計算すれば良いことになります。
しかしながら、これを包除原理でそのまま計算するのは大変です。
そこで素数 すべてに対して
を取り除くのではなく、その中の一部の素数だけを考えます。具体的には、
に対して、
を取り除くことを考えましょう。すると、取り除く倍数の個数が小さい分、残る数の個数は多くなります。
したがって、次のような不等式が成り立ちます:
あとは右辺を包除原理で計算すればよいでしょう。
より
であるので、 が示されました。
発展:篩法
エラトステネスの篩、思いのほか深くて面白いですね!
今回、エラトステネスの篩を勉強したきっかけは、実は 篩法(ふるいほう) の理解のためでした。
せっかく丁寧に説明しましたので、そのエッセンスを少しだけお話しします。
エラトステネスの篩では、 として、そこから素数
の倍数全体
を除いて行ったときに残った数の個数を求めるものでした。これは
と表せますね。
より一般に、 を正の整数の部分集合とします。また、素数の部分集合
を考えて、実数
に対して
以下の
の元全体を
とします。
の元全体の積を
とします。
このとき、 内の素数
について、
内の
の倍数全体
を除いていきます。その残りの個数を
とおきます。
これは
と表せますね。
この を計算するさまざまな手法を一般に篩法というそうです。
ところで、包除原理で得られたすべての項を計算することで を直接計算できるわけですが、計算すべき項の数が爆発的に大きくなってしまいます。具体的には
の個数
に対して
個の項が現れることになります。これでは大変ですね。
そこで、 をうまく計算する方法が色々提案されていて、ブルンの篩とか、セルバーグの篩といったものが提案されています。
ブルンの篩は、双子素数に関するブルンの定理を証明するのに実際に使われています。
たとえば
とします。
の元
が
なる素数
で割り切れるのであれば
か
は合成数です。逆に、
なる任意の素数
で割り切れないのであれば
も
も素数となり、
は双子素数となります。
したがって、 として
を計算することで、双子素数の個数
が評価できるというわけです。厳密には
となるみたいです。
ここから をブルンの篩と呼ばれる方法で計算することで、双子素数の個数
を上から評価できるというのがブルンの定理です。面白いですね!!
この辺については大変面白いので、また別の記事で紹介したいと思っています。
(今回は力尽きました。)
それでは、今日はまたこの辺で!