プログラムへの変更fibonacci
は、実際に合計を計算するために機能します。ただし、再帰を使用した方法は非効率的です。これに対処する 1 つの方法は、2 回目の再帰呼び出しで再利用できるように、計算された値がキャッシュされる「動的プログラミング」アプローチを使用することです。ただし、n 番目のフィボナッチ数は基数から順方向に計算できます。これを再帰的に実装すると、次のようになります。
public static int fib_r (int a, int b, int n) {
if (n == 1) return a;
if (n == 2) return b;
return fib_r(b, a+b, n-1);
}
public static int fib (int n) {
return fib_r(0, 1, (n > 0) ? n : 1);
}
合計に対応するコードは次のようになります。
public static int sumfib_r (int a, int b, int n) {
if (n == 1) return a;
if (n == 2) return b;
return sumfib_r(b, a+b+1, n-1);
}
public static int sumfib (int n) {
return sumfib_r(0, 1, (n > 0) ? n : 1);
}
末尾再帰は、コンパイラ/インタプリタによって末尾呼び出し削除の一部として単純なループに変更されることがよくあります。
あなたは尋ねました:
1を追加すると、シリーズの合計がどのように機能するかまだわかりません。誰か説明してもらえますか??
この質問は、実際にはアルゴリズムを理解することに関するものであり、SO で話題になっていると思います。ただし、アルゴリズムが機能する理由を説明するには数学が必要です。ですから、これは本当に数学の問題です。フィボナッチ数の和に関するよく知られた定理があります。F[i]
が i 番目のフィボナッチ数でありS[n]
、 が最初のフィボナッチ数の合計である場合n
、上記の定理は次のように述べています。
S[n] = F[n+2] - 1
したがって、 の定義から考えるとS[n+2]
、
S[n+2] = S[n+1] + F[n+2]
S[n] + 1
次に、次のように置き換えF[n+2]
ます。
S[n+2] = S[n+1] + S[n] + 1
認識する必要があるのは、「add 1 modified」fibonacci
関数です。
以下は、元の回答で提供した合計をプログラムが計算することの帰納法による証明です。F
あなたのfibonacci
関数をS
表し、あなたの「変更された1つの追加」関数を表しましょうfibonacci
。
F[1] = 0
F[2] = 1
F[i] = F[i-1] + F[i-2] for i > 1
S[1] = 0
S[2] = 1
S[i] = S[i-1] + S[i-2] + 1 for i > 1
次に、次の証明が必要ですk > 0
。
k
.---
S[k] = > F[i]
`---
i = 1
上記の合計は、次の場合にのみ真となることに注意してください。
S[1] = F[1]
S[k] = F[k] + S[k-1] for k > 1
証明はかなり簡単です。基本的なケースは自明です。
S[1] = F[1] = 0
S[2] = F[2] + F[1] = 1
S[3] = S[2] + S[1] + 1 = F[3] + F[2] + F[1] = 2
誘導ステップは次k > 2
のとおりS[j+1] = F[j+1] + S[j]
です。0 < j < k+1
j = k+1
S[k+2] = F[k+2] + S[k+1]
S[k+2] = S[k+1] + S[k] + 1
=> S[k+2] = (F[k+1] + S[k]) + (F[k] + S[k-1]) + 1
=> S[k+2] = (F[k+1] + F[k]) + (S[k] + S[k-1] + 1)
=> S[k+2] = F[k+2] + S[k+1]
これで証明が完了する.