私はnqueens問題の2つのバージョンを書きました、そしてそれらは同様の効率を持つべきだと思いますが、そうではありません。Haskellの遅延評価動作によるものだと思います。次の例でどのように機能するかを誰かに説明してもらえますか?
nqueens1 n 1 = [[i] | i <- [1..n]]
nqueens1 n k = [ i:q | i <- [1..n], q <- (nqueens1 n (k - 1)), isSafe i q k]
isSafe i q n = isSafeHelper i (zip q [(n-1),(n-2)..1])
where isSafeHelper i [] = True
isSafeHelper i (x:xs) = (i /= fst x) && abs(i - (fst x)) /= abs(n - (snd x)) &&
isSafeHelper i xs
nqueens2 n 1 = [[i] | i <- [1..n]]
nqueens2 n k = [ i:q | i <- [1..n], q <- boards, isSafe i q k]
where boards = nqueens2 n (k-1)
nqueens1 88またはnqueens288を呼び出して、サイズ8のボードを評価することで、それらを評価できます。
nqueens2は非常に効率的に機能しますが、nqueens1にはパフォーマンスの問題があります。再帰呼び出し(nqueens n(k-1))が複数回評価されているためだと思います。Haskellsの遅延評価についての私の理解から、これは当てはまらないはずです。
この振る舞いを理解するのを手伝ってください。
前もって感謝します。