Pascal の三角形、メモ化版
>
>素人くさいSICP読書会、第4回
>には行けなかったわけですが、折角なんで、問題を問いてました。それで練習問題 1.12、 Pascal の三角形の問題について
>こないだ
>書いていた版に言及したのですが、ついでにメモ化することを思いつきました。
>
>Scheme は慣れていないので Haskell で書くと、
>
>import Control.Monad.State
import Data.Map
import Prelude hiding (lookup)
*Main> ptm 1000 500
(長いので略)
(17.18 secs, 622941608 bytes)
*Main> pti 1000 500
(長いので略)
(0.58 secs, 51275988 bytes) > >というわけでメモ化した方がだいぶ遅いです。 Data.Map は log n な速度ですし、 AVL 木なので回転に計算コストがかかっているのかも。それとも State モナドが単に遅い? というわけで気になったので Data.Array.IO を使って IO 操作でメモ化する方針のもちょっと書いてみましたが、やっぱりむしろ遅くなりました。どこかアルゴリズム間違えている? > >実のところ pti も Haskell 処理系自身のメモ化による高速化がされたものなので、そちらの方が速いのは当然なのかもしれませんが……。 >
import Data.Map
import Prelude hiding (lookup)
ptm l n = evalState (main l n) empty
where main 0 _ = modify (insert (0, 0) 1) >> return 1
main l 0 = modify (insert (l, 0) 1) >> return 1
main l x
| l == x = modify (insert (l, x) 1) >> return 1
| otherwise = do v1' <- gets $ lookup (l-1, x)
v1 <- maybe (main (l-1) x) return v1'
v2' <- gets $ lookup (l-1, x-1)
v2 <- maybe (main (l-1) (x-1)) return v2'
modify (insert (l, x) (v1+v2))
return (v1+v2)
>
*Main> ptm 1000 500
(長いので略)
(17.18 secs, 622941608 bytes)
*Main> pti 1000 500
(長いので略)
(0.58 secs, 51275988 bytes) > >というわけでメモ化した方がだいぶ遅いです。 Data.Map は log n な速度ですし、 AVL 木なので回転に計算コストがかかっているのかも。それとも State モナドが単に遅い? というわけで気になったので Data.Array.IO を使って IO 操作でメモ化する方針のもちょっと書いてみましたが、やっぱりむしろ遅くなりました。どこかアルゴリズム間違えている? > >実のところ pti も Haskell 処理系自身のメモ化による高速化がされたものなので、そちらの方が速いのは当然なのかもしれませんが……。 >