让我们考虑使用动态编程实现Fibonacci系列。
// Fibonacci Series using Dynamic Programming
class fibonacci
{
static int fib(int n)
{
/* Declare an array to store Fibonacci numbers. */
int f[] = new int[n+1];
int i;
/* 0th and 1st number of the series are 0 and 1*/
f[0] = 0;
f[1] = 1;
for (i = 2; i <= n; i++)
{
/* Add the previous 2 numbers in the series
and store it */
f[i] = f[i-1] + f[i-2];
}
return f[n];
}
public static void main (String args[])
{
int n = 9;
System.out.println(fib(n));
}
}
我们使用动态编程,以便不会发生递归工作的重复。但是在每次调用该函数时,都会生成一个新数组。那么这个算法如何被称为更优化呢?
答案 0 :(得分:1)
一次优化只会保存最后2个值而不是所有结果。您无需存储所有结果。
你也可以在O(n)中递归写出斐波纳契数列:
int fib(int n1, int n2, int counter)
{
if(counter == 0)
{
return n2;
}
else
{
return fib(n2,n2 + n1,counter-1);
}
}
//to start:
int result = fib(0,1,100); //gives you the 100 fibonacci value
此代码以递归方式运行,易于阅读。您不必初始化数组或其他内容。
或者您可以使用非递归选项:
int fib(int number)
{
int n1 = 0;
int n2 = 1;
int temp;
for(int i = 0; i< number;i++)
{
temp = n1 + n2;
n1 = n2;
n2 = temp;
}
return n2;
}
如果要存储结果,则必须在fib函数之外初始化数组:
// Fibonacci Series using Dynamic Programming
class fibonacci
{
/* Declare an array to store Fibonacci numbers. */
int f[];
static void init(int n)
{ /* 0th and 1st number of the series are 0 and 1*/
f = new int[n+1];
f[0] = 0;
f[1] = 1;
}
static int fib(int n)
{
int i;
for (i = 2; i <= n; i++)
{
/* Add the previous 2 numbers in the series
and store it */
f[i] = f[i-1] + f[i-2];
}
return f[n];
}
public static void main (String args[])
{
int n = 9;
init(n);
System.out.println(fib(n));
}
}
答案 1 :(得分:1)
我们使用记事来防止动态编程的进一步递归。记忆化是存储已经计算出的值的方法-例如,索引m的fib(m)被计算并存储在记忆表中。进一步在即将到来的递归中,如果再次发生fib(m)进行计算,那么我们从记忆表中获取它,而不是再次执行fib(m-1)+ fib(m-2),即避免不必要的递归...注意-这将保持复杂度线性,即O(n)。
我们可以通过多种方式来实现此备忘录,以加快搜索速度。但是在这里,对于斐波那契,我们可以将备忘录实现为数组。 是的,记忆表将只初始化一次。下面的代码是上面解释的说明-
注意-我们采用了一个变量“ complexity”,当我们在备忘录表中找不到值时,即每次进行递归时,它都会增加。
package com.company.dynamicProgramming;
import java.math.BigInteger;
public class FibonacciByBigDecimal {
static int complexity = 0;
public static void main(String ...args) {
int n = 200;
BigInteger[] memoization = new BigInteger[n + 1];
System.out.println("fibonacci of "+ n + " is : " + fibByDivCon(n, memoization));
System.out.println("Complexity is "+complexity);
}
static BigInteger fibByDivCon(int n, BigInteger[] memoization){
if(memoization[n]!=null){
return memoization[n];
}
complexity++;
if (n == 1 || n== 2){
memoization[n] = BigInteger.ONE;
return BigInteger.ONE;
}
// creates 2 further entries in stack
BigInteger fibOfn = fibByDivCon(n-1, memoization).add( fibByDivCon(n-2, memoization)) ;
memoization[n] = fibOfn;
return fibOfn;
}
}
上面我正在计算索引为200的斐波那契数。当我在上面的代码中运行时,结果是:-
fibonacci of 200 is : 280571172992510140037611932413038677189525
Complexity is 200
Process finished with exit code 0