フィボナッチの6番目のフィボナッチ数を求める必要があります。 fib(6)はfib(4)とfib(5)を最初に呼び出すfib(5)と言う。 fib(5)はfib(4)とfib(3)を呼び出し、最後に基底caseとfib(2)、fib(3)fib(4)、そしてfib fib(5)計算されたfib(6)がfib(4)を呼び出します。今回は同じプロセスf(2)f(3)、最後にf(4)が計算されます。しかし、fiv(5)が呼び出されたときにfiv(4)の値を保存できれば、fiv(4)が呼び出されたときに再度計算する必要はありません。代わりに、fiv(5)が呼び出されたときにfiv(4)に保存された値を使用できます。どのように私は再帰関数をより速く実行する方法
答えて
は、あなたが探している用語であることを行うことができます "memoization。"これは非常に標準的な最適化であり、フィボナッチシーケンスは文字通りテキストブックの例です。
John Zwinckが指摘したように、用語はmemoizationです。つまり、すべてのステップで、計算される中間値を格納しています(再帰呼び出しが高価なため)。
コードは以下のように変更検討:このコードで
#include <iostream>
using namespace std;
int main()
{
int fibboA[10];
fibboA[0]=0; //1st Fibonacci number is always 0;
fibboA[1]=1; //2nd Fibonacci number is always 1;
cout<<fibboA[0]<<"\t"<<fibboA[1]<<"\t";
//3rd onwards, it is the sum of the previous 2;
for(int i=2;i<10;i++)
{
fibboA[i]=fibboA[i-1]+fibboA[i-2];
cout<<fibboA[i]<<"\t";
}
return 0;
}
、我々は配列fibboA[]
に前の値を保存していると計算しながら、以前に記憶された最新の二つの値(i-1
番目とi-2
番目)を用い現在のフィボナッチ数(i
)。
希望すると便利です。
一度に2つのフィボナッチ数を計算することで、単純で効率的な(線形時間)再帰的解を得ることができます。
void fib(int n, int& f1, int& f0)
{
if (n == 1)
{ f1= 1; f0= 0; }
else
{ fib(n - 1, f0, f1); f1+= f0; }
}
機能はFn
とFn-1
両方を返します。引数の入れ替えに注目してください。
#include <iostream>
using namespace std;
int ar[20];
int fib (int n)
{
if(n==0||n==1)
return n;
if(ar[n]!=-1)//check if ar[n] exists than just return values
return ar[n];
else
{
ar[n]= fib(n-1)+ fib(n-2);
return ar[n];
}
}
int main()
{
for(int i=0;i<20;i++)
ar[i]=-1;//initialise all to empty
cout<<fib(8);
}
このコードは、あなたが投稿した元のコードよりも確実に最適化されていますが、まだ完全には最適化されていません。 'main()'で 'fib(8)'を呼び出すとき、 'fib(7)'、 'fib(6)'はまだ評価されていないので 'ar []'要素は '-1'です。 'ar()'に値が存在するので、 'fib(8)'の後に 'main()'で 'fib(9)'をもう一度呼び出すと、このコードはうまく動作します。 *コールごとに*でなく*たくさんのコール*でコードを最適化しています。上記の私のコードは、コールごとに最適化されています*。 –
ここでは、再帰的な動的なプログラミングソリューションの1つの以上の例です:
#include <vector>
#include <iostream>
int fib(int n, std::vector<int>& data) {
if (n >= 2) {
int& num = data[n - 2];
if (num) {
return num;
}
return (num = fib(n - 1, data) + fib(n - 2, data));
}
return n;
}
int fib(int n) {
if (n >= 2) {
std::vector<int> data(n - 1, 0);
return fib(n, data);
}
return n;
}
int main(int argc, char *argv[]) {
std::cout << fib(23) << std::endl;
return 0;
}
- 1. この再帰関数をより速く実行するにはどうすればよいですか?
- 2. 再帰的に別の関数を実行する再帰関数を実装する
- 3. 再帰関数でデータベースクエリを実行する最も速い方法は何ですか?
- 4. ASP.net - C# - それをより速く実行する方法ajaxToolkit:ToolkitScriptManager
- 5. PRAGMA synchronous = OFFでSQLiteをより速く実行する方法
- 6. MSVCデバッグビルドをより速く実行する方法
- 7. 特定のマクロをより速く実行する方法
- 8. forを使用する再帰関数を行う方法
- 9. 再帰関数の実行時間がかかります
- 10. 再帰関数で行を1回実行する
- 11. 実行時に同じ関数を再実行する方法
- 12. F#再帰メンバ関数:「正しく定義する方法」
- 13. ビューの再帰関数を実行するには?
- 14. javascript再帰関数で何かを一度実行する
- 15. rack-livereloadをより速く実行する方法はありますか?
- 16. テール再帰(@tailrec)再帰関数対非再帰関数スカラースタックオーバーフローエラー?
- 17. 再帰関数の戻り
- 18. Arduino関数の実行速度を測定する方法は?
- 19. 再帰的テンプレート関数の最初の呼び出しで関数を実行する方法は?
- 20. PostDelayed関数がより速くて速くなる
- 21. 再帰関数
- 22. 再帰関数
- 23. 再帰関数
- 24. 再帰関数
- 25. 再帰関数。 、
- 26. 再帰関数?
- 27. プロローグ、再帰関数、および関数の引数による戻り値
- 28. ノードjs:再帰関数を順番に実行/制御フロー
- 29. javascript終了後に関数を再実行する方法
- 30. 再帰関数によるスタックオーバーフロー
たぶんループにそれを回すと、パフォーマンスが向上する可能性があります。 –
再帰関数でフィブス数を計算する必要はありません。 – SergeyA
@πάνταῥεtheは正しいアイデアを持っています...反復は通常、再帰よりも高速です。 :) – erip