私はSelect
モナドの仕組みを理解しようとしています。明らかに、それはCont
のいとこで、バックトラック検索に使用できます。私が代わりにSelect
を使用するには、このソリューションを適応させるのに苦労してい選択モナドを使ってn-queensを解く方法は?
-- All the ways of extracting an element from a list.
oneOf :: [Int] -> [(Int,[Int])]
oneOf [] = []
oneOf (x:xs) = (x,xs) : map (\(y,ys) -> (y,x:ys)) (oneOf xs)
-- Adding a new queen at col x, is it threathened diagonally by any of the
-- existing queens?
safeDiag :: Int -> [Int] -> Bool
safeDiag x xs = all (\(y,i) -> abs (x-y) /= i) (zip xs [1..])
nqueens :: Int -> [[Int]]
nqueens queenCount = go [] [1..queenCount]
where
-- cps = columsn of already positioned queens.
-- fps = columns that are still available
go :: [Int] -> [Int] -> [[Int]]
go cps [] = [cps]
go cps fps = [ps | (p,nfps) <- oneOf fps, ps <- go (p:cps) nfps, safeDiag p cps]
:
私はN-クイーン問題のこのリストベースのソリューションを持っています。
Select
は、回答を比較するために使用される「評価関数」を抽象化できるようです。その関数はrunSelect
に渡されます。私のソリューションではsafeDiag
のようなものが評価関数として機能するかもしれないと感じていますが、計算自体をSelect
のように構成する方法はありますか?
また、Select
のモナドだけで十分ですか、またはリストの上にトランスフォーマーバージョンを使用する必要がありますか?
'選択 'モナドが本当にありますか?私の「選択」の理解は、可能な解決策の存在を証明しようとすることです(目撃証拠として)。 「選択」の典型的な例は、SATソルバーである。あなたはおそらくリストモナド上で 'SelectT'を使って何かを強制することができますが、実際には選択されたモナドを本当に使っていると確信しています。 – Alec
@Alec「選択」はバックトラック検索に適しており、n-queensはそのタイプの典型的な問題であると読んだので、モナドの良いユースケースであると仮定しました。 – danidiaz
ソリューションを見つけるまで、バックトラッキングとバックトラックの区別があります。それでは、もう一度、以前は「選択」で遊んだだけなので、真剣に何も言わないでください。 – Alec