バイナリーオプション教材

フィボナッチ数列の計算量について

フィボナッチ数列の計算量について
この場合、5行目と6行目のリスト(長さは約半分の $n/2$) left_list と right_list のために必要なメモリが発生するため $M_(n)$ は次のようになる。 \[ M_(n) = c + d n + 2M_(n/2) \]

整数の公式でフィボナッチ数列を求める

よって、もし \(m = \left(\begin 1 & 1 \\ 1 & 0 \end \right)フィボナッチ数列の計算量について ^n\) なら、 \(bn = m\\) になります(Pythonと違って、行列の添え字は通常1が基準になることに注意してください)。 NumPy行列のべき乗が繰り返し二乗法のような振る舞いをすると想定すると、計算量は \(O(\mathrm\ n)\) になります。 さらに、漸化式を解くために、閉じた式を見つける方法もあります。 これにより、次の実数値の公式が導かれます: \(\phi = (1 フィボナッチ数列の計算量について + \sqrt) / 2\) 、 \(\psi = (1 フィボナッチ数列の計算量について - \sqrt) / 2\) とすると、 \(\mathrm(n) = (\phi^ - \psi^) / \sqrt)\) 。 この手法には、任意精度の実数計算を要するという実用上の欠点がありますが、 \(n\) の値が小さければ問題はありません。

任意の数列 \(an\) の母関数は、 \(\Sigman anx^n\) の無限和です。フィボナッチ数列の場合は \(\Sigman \mathrm(n)x^n\) になります。つまり、これは無限に続くべき級数であり、 \(x^n\) の係数は \(n\) 番目のフィボナッチ数に相当します。

この式に \(フィボナッチ数列の計算量について x^\) をかけて \(フィボナッチ数列の計算量について n\) 全体で和をとると、以下の式が得られます。

\(F(x)\) を \(\mathrm\) の母関数として、それを \(\Sigma_n\mathrm(n)x^n\) と定義すると、上の式は次のように簡略化できます。

\[F(x) - x フィボナッチ数列の計算量について - 1 = x(F(x) - 1) + x^2F(x)\]

\[F(x) = xF(x) + フィボナッチ数列の計算量について x^2F(x) + 1\]

これを \(F\) について解くと以下の式が得られます。

整数の公式

まずは、この公式を直感的にとらえるため、 \(10^\) で母関数 \(F\) を評価してみましょう。

興味深いことに、小数展開した部分に \(1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89\) と、フィボナッチ数列が現れています。魔法のような結果に驚いてしまいますが、その理由は次の式から分かります。

\(F(10^) = \mathrm(0) + \mathrm(1)/10^3 + \mathrm(2)/10^6 + \mathrm(3)/10^9 + \ldots\)フィボナッチ数列の計算量について フィボナッチ数列の計算量について

この例では、フィボナッチ数列が次々と \(1/1000\) 倍されて並んでいきます。つまり、その値が一旦1000を超えると、隣り合う数に影響を及ぼし始めるということです。この現象は、上記の \(F(10^)\) の計算で988から確認できます。正しいフィボナッチ数は987ですが、数列の次の数から1だけオーバーフローが発生しています。その結果Off-by-oneエラーが発生し、以降はパターンが崩れてしまうのです。

しかし、いかなる \(n\) の値に対しても、10の負の指数を十分大きく取れば、たとえオーバーフローが発生したとしても、 \(n\) 番目のフィボナッチ数に悪影響が出ることはありません。ここでは、ある \(k\) という値について \(10^\) が妥当な値になると仮定しましょう。この値は後ほど選定します。

さらに整数で計算をしたいので(その方がコーディングしやすいので)、全体を \(10^\) 倍して \(n\) 番目のフィボナッチ数が整数の範囲にくるようにして、式を整理します。

この結果を \(10^k\) を法として見ると、 \(n\) 番目のフィボナッチ数が得られます(先ほども書きましたが、 \(k\) には十分大きな値を選んだものと想定しています)。

あとは \(\mathrm(n+1)\) \(2^k\) になるように、 \(k\) を十分大きく取るだけです。フィボナッチ数列は \(\phi^n\) のように増大して、 \(\phi\) < \(2\) なので、 \(k = n+1\) とすれば安全です。

非反復型で閉じた解が得られたのは興味深いですが、これは全く実用的な手法ではありません。ここではサイズが \( O(n^2) \) ビットの整数を用いて、整数演算を実行しています。でも実際には、最終的にビット単位で論理積を取る前に、最初の \( n \) 個のフィボナッチ数が全て連結した整数値を取得しているのです。

関連記事

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

目次
閉じる