(1)循环执行
FIB-LOOP(N) {
F0=0; F1=1;
if(N=0)return F0;
if (N=1) return F1;
for (i=2; i<=N;i++) {
F=F1+F0;
F0=F1;
F1=F;
//支付选项付加费的用户改进升级版(1-Premium)加上 save(i,F);
}
return F
} //end FIB-LOOP
(2) 迭代执行
FIB(N) {
If lookup(N,F) returns F ; //if Fib N has been computed and saved already, return the saved value.
if (N=0) return 0;
if(N=1) return 1;
F=FIB(N-1)+FIB(N-2);
save (N,F); //save to a file or database that can be looked up quickly.
return F;
}
看起来(1)循环执行是快,如果没记忆的话,一次用。 但如果有记忆 FIB(N-1,N-2, 。。2,1,0)的值的话,有其是反复用,迭代也可很快,因为迭代1,2步就可以回转了。 尤其是计算 F(0),F(1),F(2),。。。F(N)巨长的序列。
例如要计算 Fib 数系列 从f0,f1,f2 ...到f10000000 百万,用迭代算法(2):
For (n=0; n<=1000000; n++)
f(n)=FIB(n);
这个程序是很快的,每个数只需要2 function call, 2 lookups call, 1 addition, 1 save , 时间是一样的。整个时间和n是线性关系, n x (5 functions call+1 addition)
而间单循环算法(1)就很慢了:
For (n=0;n<=1000000;n++)
F(n)=FIB-LOOP(n);
每个数要循环n次,整个时间是1+2+3+。。。+n (=1000000),是n 平方的量级。但也不是指数量级的。
当然可以说这是狡辩,其实循环算法(1)只要叫一次就可以把这一百万个数都算出来。的确可以的,不过要修改一下,在每个循环时加个 save 就好了,升级为算法(1-Premium)。然后就 call FIB-LOOP(1000000) 就好了,0到一百万的Fib数都有了,如果用户支付选相附加费的话。算法(1),(2)是免费开源的。