フィボナッチ素数とは、フィボナッチ数列に現れる数のうち、素数であるものです。

小さい順に並べると、2、3、5、13、89、233、1597……と続きます。例えば13はフィボナッチ数列に含まれ、1と13以外の正の約数を持たないため、フィボナッチ素数です。

ただし、フィボナッチ数がすべて素数になるわけではありません。また、「素数番目のフィボナッチ数なら必ず素数」というわけでもありません。

この記事では、具体例で違いを確認し、最後にPythonでフィボナッチ素数を探します。

目次

フィボナッチ数列と素数の基本

フィボナッチ数列は、直前の2つの数を足して次の数を作る数列です。

この記事では、番号を0から始め、次のように定義します。

  • F₀=0
  • F₁=1
  • Fₙ=Fₙ₋₁+Fₙ₋₂(n≧2)

実際に並べると、次のようになります。

番号nフィボナッチ数Fₙ計算
00最初に決める値
11最初に決める値
210+1
321+1
431+2
552+3
683+5
7135+8
8218+13

一方、素数は、正の約数が1と自分自身の2つだけである、2以上の整数です。

2、3、5、7、11、13などが該当します。1は正の約数が1つしかないため、素数に含めません。

フィボナッチ素数は、この2つの条件を両方満たす数です。

フィボナッチ素数の具体例

フィボナッチ数列の中から、素数になるものと、ならないものを確認してみましょう。

番号nフィボナッチ数Fₙ判定
32素数
43素数
55素数
68合成数:2×2×2
713素数
821合成数:3×7
934合成数:2×17
1055合成数:5×11
1189素数
13233素数
171,597素数
194,181合成数:37×113

※合成数は、2以上の整数のうち、素数ではない数です。

ここで、番号nと、その位置にある数Fₙは別のものだと意識してください。

例えば、F₇=13では「7」が番号、「13」がフィボナッチ数です。素数かどうかを調べたいのは、まず値である13の方です。

フィボナッチ数が素数になるための条件

フィボナッチ素数には、次の性質があります。

Fₙが素数なら、nは素数または4です。

これは「そうなることが多い」という傾向ではなく、成り立つ性質です。例外となる番号4では、F₄=3が素数になります。

なぜ番号にも条件があるのか

背景には、正の整数aがbを割り切るとき、FₐもFᵦを割り切るという性質があります。

例えば、4は8を割り切ります。それに対応して、F₄=3もF₈=21を割り切ります。

番号nが4以外の合成数なら、3以上でnより小さい約数aを選べます。このときFₐは、1より大きくFₙより小さい約数になるため、Fₙは素数になりません。

n=4では、1以外の適切な約数は2ですが、F₂=1です。そのため、この場合だけはF₄が合成数だとはいえず、実際にF₄=3は素数になります。

番号が素数でも、値が素数になるとは限らない

注意したいのは、先ほどの性質を逆向きには使えないことです。

19は素数ですが、

F19=4,181=37×113F₁₉=4,181=37×113

となり、フィボナッチ数の方は合成数です。

つまり、「番号が素数か4であること」は候補を絞るための条件であり、その値が素数だと保証する条件ではありません。

Pythonでフィボナッチ素数を探す

実際にプログラムを動かして確認してみましょう。

以下のコードは、F₀からF₃₀までを作り、その中から素数だけを取り出します。Python 3.8以降で動作し、追加ライブラリは不要です。

from math import isqrt


def is_prime(number):
"""2以上の整数が素数かどうかを判定する。"""
if number < 2:
return False

for divisor in range(2, isqrt(number) + 1):
if number % divisor == 0:
return False

return True


def fibonacci_primes(max_index):
"""F_0からF_max_indexまでのフィボナッチ素数を返す。"""
a, b = 0, 1
results = []

for n in range(max_index + 1):
if is_prime(a):
results.append((n, a))

a, b = b, a + b

return results


for n, value in fibonacci_primes(30):
print(f"F_{n} = {value}")

実行方法

  1. コードをfibonacci_primes.pyという名前で保存します。
  2. 保存先のフォルダでターミナルを開きます。
  3. python fibonacci_primes.pyを実行します。

環境によっては、pythonの代わりにpython3を使います。

実行結果は次のとおりです。

F3=2F4=3F5=5F7=13F11=89F13=233F17=1597F23=28657F29=514229\begin{aligned} F_3 &=& 2 \\ F_4 &=& 3 \\ F_5 &=& 5 \\ F_7 &=& 13 \\ F_{11} &=& 89 \\ F_{13} &=& 233 \\ F_{17} &=& 1597 \\ F_{23} &=& 28657 \\ F_{29} &=& 514229 \end{aligned}

この範囲では、9個のフィボナッチ素数が見つかります。値と番号は、整数列データベースOEISの掲載内容とも一致します。

コードの仕組みを理解する

平方根まで割って調べればよい理由

is_primeでは、2から調べる数の平方根まで、割り切れる整数があるかを確認しています。

合成数を2つの整数の積で表すと、少なくとも一方は平方根以下になります。両方が平方根より大きければ、積が元の数より大きくなってしまうからです。

例えば91なら、平方根は約9.54です。2~9を調べる途中で7で割り切れることが分かり、合成数だと判定できます。

isqrtは、平方根の整数部分を正確に求めるPython標準の関数です。浮動小数点の平方根を整数へ変換する方法と違い、整数計算で求められます。

2つの変数で数列を作る

aとbには、隣り合うフィボナッチ数を入れています。

繰り返しの最初では、aがFₙ、bがFₙ₊₁です。aを素数判定した後に、

a,b=b,a+ba,b = b,a + b

で、次の組へ進みます。

Pythonでは右側を先に評価するため、更新前のaとbを使って次の値を計算できます。

また、fibonacci_primes(30)の30は、調べる番号の上限です。「素数を30個見つける」という意味ではありません。

大きな番号では処理が重くなる

このコードは、仕組みを学ぶための試し割りによる実装です。

フィボナッチ数は番号が進むと急速に大きくなるため、調べる番号を大幅に増やすと、素数判定に時間がかかります。まずは30程度の範囲で、数列の生成と判定の流れを確認してください。

よくある質問

フィボナッチ素数は無限にありますか?

無限に存在すると予想されていますが、まだ証明されていません。

プログラムで多くの例を見つけることと、無限に存在すると数学的に証明することは別です。

すべての素数はフィボナッチ数列に現れますか?

現れません。

例えば7は素数ですが、フィボナッチ数列は5の次が8なので、7を含みません。フィボナッチ素数は、素数全体の一部です。

フィボナッチ数列の1は素数ですか?

素数ではありません。

数列に含まれるかどうかに関係なく、素数は2以上の整数です。今回のプログラムでも、2未満の数は素数ではないと判定しています。

数学の条件を、プログラムで確かめる

フィボナッチ素数を調べると、数列の規則、素数判定、必要条件と十分条件の違いを一緒に学べます。

特に重要なのは、番号が素数でも、その位置のフィボナッチ数が素数とは限らないという点です。

まずは表で予想し、プログラムで確かめ、なぜその結果になるのかを考えてみてください。短いコードでも、数学の性質とアルゴリズムの関係を具体的に体験できます。

Learning Tools

記事を検索したい方はここから!

辞書から探す

本文中で気になった概念やキーワードを、辞書ページで一覧から確認できます。

辞書を見る