と呼ばれていない再帰私はハノイの問題のタワーのハスケルでこの機能をプログラムします。この機能は、1つの代替スティックでソーススティックから複数のスティックへのステップ数を与えます。二つの全く仕上げ(ハノイの塔)
numStepsHanoi :: Integer -> Integer
numStepsHanoi 0 = 0
numStepsHanoi n = numStepsHanoi (n-1) + numStepsHanoi (n-1) + 1
この機能が正常に動作します... Nまで、ディスクの数が、高すぎます。 GHCiは終了しません。私はこの問題の複雑さを知っており、より速く走ることができないことを知っています。例えば
私はn = 64
とそれを呼び出す場合、私は20分待ってから(それが完了していない)何も出力を得ることはできません。 n = 20
でも約2秒かかります。
別の実装(下記)では、時間がかなり短縮されます。
numStepsHanoi :: Integer -> Integer
numStepsHanoi 0 = 0
numStepsHanoi n = 2 * numStepsHanoi (n-1) - 1
n = 64
となり、すぐに結果が得られます。明らかにこれには再帰呼び出しが1つしかありませんが、そのような大きな効果がありますか?
これはGHCi最適化の問題でしょうか?
GHCiでは最適化が行われず、それ以外にもGHCコンパイラは 'x + x'から' 2 * x'に最適化されません。後者が前者よりもずっと速い理由は、最初の解(指数関数)と2番目の(線形)の複雑さが間違っているからです。 – user2407038
@ user2407038私は指数関数的な複雑さを知っていましたが、GHCiはx * xを2 * xに変換すると考えました。どうもありがとう! –
[共通部分式除去](https://wiki.haskell.org/GHC_optimisations#Common_subexpression_elimination) – chepner