我試圖使用memoization技術來優化斐波那契的計算。我的代碼是:ocaml memoization失敗時應用於斐波那契數列
let memo f =
let vtable = ref [] in
let rec match_function x vt=
match vt with
|(x',y)::_ when x=x' -> y
|_::l ->
match_function x l
|[] ->
let y = (f x) in
vtable := (x,y):: !vtable;
y
in
(fun x -> (match_function x !vtable));;
let rec ggfib = function
0|1 as i -> i
|x -> ggfib(x-1) + ggfib(x-2);;
let memoggfib = memo ggfib;;
let running_time f x =
let start_time = Sys.time() in
let y = f x in
let finish_time = Sys.time() in
Printf.printf "Time lapse:%f\n" (finish_time -. start_time);
y;;
running_time ggfib 30;;
running_time memoggfib 30;;
輸出是:
Time lapse:0.357187
Time lapse:0.353663
不同的是沒有那麼多。爲什麼?而更糟的是,當我嘗試使用
running_time ggfib 40;;
running_time memoggfib 40;;
程序在40計算斐波那契似乎碰上了死循環,並停止輸出。
這裏有什麼問題?我沒有照顧什麼問題?
我改變了上面的代碼,爲memoization引入了一個'靜態'vtable。
let rec ggfib = function
0|1 as i -> i
|x -> ggfib(x-1) + ggfib(x-2);;
let running_time x0 =
let vtable = ref [] in
let start_time = Sys.time() in
let x = ref 1 in
let rec match_function ff x vt=
match vt with
|(x',y)::_ when x=x' -> y
|_::l ->
match_function ff x l
|[] ->
let y = (ff x) in
vtable := (x,y):: !vtable;
y
in
let y=ref 1 in
while !x<x0 do
y:= match_function ggfib !x !vtable;
x:=!x+1;
done;
let finish_time = Sys.time() in
Printf.printf "Time lapse:%f\n" (finish_time -. start_time);
y;;
let running_time2 x0=
let start_time = Sys.time() in
let x = ref 1 in
while !x<x0 do
ggfib !x;
x:=!x+1;
done;
let finish_time = Sys.time() in
Printf.printf "Time lapse:%f\n" (finish_time -. start_time);;
running_time 40;;
running_time2 30;;
它仍然作爲基本相同。我沒有看到明顯的改善......
Time lapse:0.581918
Time lapse:0.577813
非常感謝!請允許我想一想你的帖子。很多咀嚼新學習者。 – lkahtz 2012-03-25 18:53:57