フィボナッチ数、リュカ数、そしてそれらを一般化した数列の基本的な性質と、コンピューターにおける計算方法について記述します。
今回は、フィボナッチ数 (Fibonacci numbers) の基本的な性質と、コンピューターにおける計算方法について記述します。
漸化式
で定義される数列を、フィボナッチ数列 (Fibonacci sequence) と呼ぶ。
また、フィボナッチ数列に現れる数をフィボナッチ数 (Fibonacci number) と呼ぶ。
なお、添字
となるため、
また、リュカ数列およびリュカ数という用語との兼ね合いから、フィボナッチ数 (Fibonacci numbers; 複数形) がフィボナッチ数列を表すこともあるようです。
cf.
Lucas sequence - Wikipedia
フィボナッチ数列の一般項を求めます。
大学受験のときに求め方を習得した人も多いのではないでしょうか。
ただし、
ある実数
定義の漸化式において
そこで
このとき
さらに
したがって、
この
また、
となります。
比がほぼ
上記の一般項は理論上の解ですが、ここではフィボナッチ数をコンピューターで具体的に求める方法をいくつか挙げます。
以下、
一般項が判明していれば一般項から求める方法が自然に思えますが、コンピューターで計算するとなると事情が異なり、工夫が必要になることがあります。
フィボナッチ数列の一般項には
これを整数値に丸めることでフィボナッチ数を得る、という方法がまず考えられます。
しかし、プログラミング言語や
筆者の実行環境では、
もし実用化するのであれば、巨大な桁数を扱える数値型を、誤差を評価したうえで利用する必要があります。
なお、二項展開する方法もありそうですが、記述量や計算量でとくに利点がないため、それよりは次の漸化式を使う方法がよいです。
フィボナッチ数を整数のまま計算するには、定義の漸化式を用いて順に求めるのが簡単です。
時間計算量は
空間計算量は、途中の値をキャッシュする場合は
この方法は、プログラミングの練習でよく題材にされます。
C# では次のようなコードでフィボナッチ数列を作れます。
なお、
public static long[] CreateSeq(int nLast = 92)
{
var a = new long[nLast + 1];
a[1] = 1;
for (int i = 2; i <= nLast; i++)
a[i] = a[i - 1] + a[i - 2];
return a;
}
また、再帰関数として実装する練習も頻出ですが、
行列を利用すると、整数のままで、しかも高速に計算できます。
2 次正方行列
と表すことを考えると、定義の漸化式から
とすればよいです。したがって、
これで
値の桁が大きくなることを無視すれば (例えば、値を剰余群で考える場合)、
こちらのサイトで、
この範囲であれば、漸化式から求める方法でも 2 秒の実行時間制限に収まります:
次回: (2) リュカ数