使用Memoization,以避免遞歸重復計算


使用Memoization,以避免遞歸重復計算

考慮Fibonacci(斐波那契)問題;

Fibonacci問題是可以通過簡單的遞歸方法來解決:

int fib ( n )
 { 
     if ( n ==  0 || n ==  1 ) { 
         return  1
    } 
     else { 
         return fib( n -  2 ) + fib ( n -  1 ); 
    } 
}

 注:在這里,我們考慮Fibonacci 系列從1開始,因此,該系列看起來:1,1,2,3,5,8,...

 

注意:從遞歸樹,我們計算fib(3)函數2次,fib(2)函數3次。這是相同函數的重復計算。如果n非常大,fib

這個簡單的技術叫做Memoization,可以被用在遞歸,加強計算速度。

fibonacci 函數Memoization的代碼,應該是下面的這個樣子:

int calc_fib (  int n )
 { 
     int val[ n ] , i;
     for ( i =  0; i <=n; i++ ) { 
        val[ i ] = - 1;       //  Value of the first n + 1 terms of the fibonacci terms set to -1 
    } 
    val[  0 ] =  1;    //  Value of fib ( 0 ) is set to 1 
    val[  1 ] =  1;     //  Value of fib ( 1 ) is set to 1 
     return fib( n , val ); 
}
  int fib(  int n ,  int* value ) 
{
      if ( value[ n ] != - 1 ) { 
         return value[ n ];               //  Using memoization 
    } 
     else { 
        value[ n ] = fib( n -  2 , value ) + fib ( n -  1 , value );           //  Computing the fibonacci term
     }
      return value[ n ];                 //  Returning the value 
}

上面代碼的紅色部分,不知道為什么可以那么聲明,在標准C和C++中數組都不可以那樣聲明吧,可能是使用編譯器進行了擴展。

下面是我用C++寫的:

#include <iostream>
#include <algorithm>
#include <iterator>
using  namespace std;

int fib( int n, int val[])
{
     if(val[n]!=- 1)
         return val[n];
     else
    {
        val[n]=fib(n- 1,val)+fib(n- 2,val);
         return val[n];
    }
}
void cal_fib( int n)
{
     int *val= new  int[n+ 1];
     for( int i= 0;i<=n;i++)
        val[i]=- 1;
    val[ 0]= 0;
    val[ 1]= 1;
    fib(n,val);
    copy(val,val+n+ 1,ostream_iterator< int>(cout, "   "));
    cout<<endl;
    delete[] val;

}
int main()
{
     for( int i= 3;i<= 15;i++)
        cal_fib(i);

}

 輸出的結果如下:

 

參考:http://blog.jobbole.com/1198/

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM