0
大学数学基礎解説
文献あり

フィボナッチ数の性質と計算方法 (2) リュカ数

208
0

この連載について

フィボナッチ数、リュカ数、そしてそれらを一般化した数列の基本的な性質と、コンピューターにおける計算方法について記述します。

  1. フィボナッチ数
  2. リュカ数 (本稿)
  3. 定数係数 3 項間漸化式
  4. ほとんど整数 (おまけ)

本文

今回は、フィボナッチ数と対で語られることの多いリュカ数 (Lucas numbers) を扱います。
さらに、初項a0,a1や添字nの拡張について考察します。

定義

リュカ数

漸化式
  a0=2,a1=1,  an+2an+1an=0  (n0)
で定義される数列に現れる数をリュカ数 (Lucas number) と呼ぶ。

リュカ数の定義は、フィボナッチ数の初項a0のみを変更したものです。

なお、添字nを負数まで拡張すると、この数列は
,18,11,7,4,3,1,2,1,3,4,7,11,18,
となります。

また、リュカ数列が別の意味を持つ用語として定義されていることから、リュカ数 (Lucas numbers; 複数形) が上記の数列を表すようです。
cf. Lucas sequence - Wikipedia

一般項

リュカ数の一般項を求めます。
証明方法はフィボナッチ数とほぼ同じのため省略します。

リュカ数の一般項

  an=αn+βn=αn+(α)n
ただし、α=1+52,β=152.

n番目のフィボナッチ数およびリュカ数をそれぞれFn,Lnとすると、
  limnLnFn=5
となります。
比がほぼ5になる整数の組を、規則的にいくらでも見つけられるというのは面白い現象です。

次に、初項を一般化してみます。

数列anを漸化式
  an+2an+1an=0  (n0)
で定義する。a0,a1は任意の実数とする。

この数列の一般項は、
  an=αn(a1βa0)βn(a1αa0)αβ=αn(2a1a0+a05)βn(2a1a0a05)25
ただし、α=1+52,β=152.

フィボナッチ数のときの解法と同様にして、
{an+1αan=βn(a1αa0)an+1βan=αn(a1βa0)
となることから得られる。

次に、添字nを負数まで拡張します。

公式 2 は、任意の整数nに対して成り立つ。

  an+an+1an+2=0  (n<0)
とし、a1,a2,a3,と順に値が定まっていくと考え、n0のときと同様の解法を用いる。

2 次方程式 x2+x1=0 の 2 解はx=α,βだから、n1に対し、
  an=(α)1n(a0+βa1)(β)1n(a0+αa1)(αβ)       =(α)n(a1αa0)(β)n(a1βa0)(αβ)       =αn(a1βa0)βn(a1αa0)αβ
ここで、αβ=1を使った。

ところで、フィボナッチ数やリュカ数では、an=±anが成り立っていました。
このような性質を持つ数列はどれだけあるのでしょうか。

任意の整数nに対して、数列anを漸化式
  an+2an+1an=0
で定義する。a0,a1は任意の実数とする。

このとき、任意の整数nに対して an=(1)n+1an を満たすanは、フィボナッチ数の定数倍に限られる。
また、任意の整数nに対して an=(1)nan を満たすanは、リュカ数の定数倍に限られる。

α+β=1, αβ=1 を用いる。

an=(1)n+1an を式変形していくと、
  αn(a1βa0)βn(a1αa0)=(1)n+1(αn(a1βa0)βn(a1αa0))  αn(a1βa0)βn(a1αa0)=βn(a1βa0)+αn(a1αa0)  αn(αβ)a0+βn(αβ)a0=0  (αn+βn)(αβ)a0=0
したがって a0=0 となり、これはフィボナッチ数の定数倍を意味する。

また、an=(1)nan を式変形していくと、
  αn(a1βa0)βn(a1αa0)=(1)n(αn(a1βa0)βn(a1αa0))  αn(a1βa0)βn(a1αa0)=βn(a1βa0)αn(a1αa0)  αn(2a1(α+β)a0)βn(2a1(α+β)a0)=0  (αnβn)(2a1a0)=0
したがって a0=2a1 となり、これはリュカ数の定数倍を意味する。

リュカ数の計算

リュカ数をコンピューターで具体的に求める方法をいくつか挙げます。
内容は前回の フィボナッチ数 とほぼ同様で、とくに新しい説明はありません。一般項から求める方法は省略します。
以下、a0,a1は整数とし、n0 とします。

漸化式から求める

リュカ数を整数のまま計算するには、定義の漸化式を用いて順に求めるのが簡単です。
時間計算量は O(n) です。
空間計算量は、途中の値をキャッシュする場合は O(n)、キャッシュしない場合は O(1) でできます。
任意のa0,a1に対しても同様です。

C# では次のようなコードでリュカ数を作れます。
なお、anの値を符号付き 64 ビット整数で表せる範囲は n90 しかありません。

          public static long[] CreateSeq(int nLast = 90)
    {
        var a = new long[nLast + 1];
        a[0] = 2;
        a[1] = 1;
        for (int i = 2; i <= nLast; i++)
            a[i] = a[i - 1] + a[i - 2];
        return a;
    }
    

また、再帰関数として実装する方法もありますが、nが大きくなるとスタックオーバーフローの原因になるため注意が必要です。

行列の漸化式から求める

行列を利用すると、整数のままで、しかも高速に計算できます。

2 次正方行列Aを用いて
(an+2an+1)=A(an+1an)
と表すことを考えると、定義の漸化式から
A=(1110)
とすればよいです。したがって、
(an+1an)=An(a1a0)=An(12)

これでAnを計算するとanを求めることができ、繰り返し二乗法により、時間計算量は O(logn) です。
任意のa0,a1に対しても同様です。
値の桁が大きくなることを無視すれば (例えば、値を剰余群で考える場合)、nが 64 ビット整数の最大値であったとしても一瞬で計算できます。

作成したサンプル コード

前回: (1) フィボナッチ数
次回: (3) 定数係数 3 項間漸化式

参考文献

投稿日:2021616
OptHub AI Competition

この記事を高評価した人

高評価したユーザはいません

この記事に送られたバッジ

バッジはありません。
バッチを贈って投稿者を応援しよう

バッチを贈ると投稿者に現金やAmazonのギフトカードが還元されます。

投稿者

Researcher and Developer for Algorithms, using C# (.NET). 数検1級金賞 (2002).

コメント

他の人のコメント

コメントはありません。
読み込み中...
読み込み中
  1. この連載について
  2. 本文
  3. 定義
  4. 一般項
  5. リュカ数の計算
  6. 参考文献