我使用Haskell实现了Knight游览的递归解决方案。我的算法基本上是基于Warnsdorff的规则。
示例:
基于这个例子的基本思想:
(1)计算从当前点(3,3)的允许移动
=> (1,2),(1,4),(2,1),(2,5),(4,1),(4,5),(5,2),(5,4)
(2)对于这些点中的每一点,计算到达该点时可以执行的移动次数(“入口”的数量)
=> ((1,2),2),((1,4),2),((2,1),2),((2,5),2),((4,1),2), ((4,5),2),((5,2),2),((5,4),2)
(3)如果所有点的入口数相同,则找到最小入口点或第一个入口点 => (1,2)
(4)用确定的点(开始递归)调用相同的函数
这样我就能确定解决问题的方法。但现在我需要为起始位置确定所有其他可能的解决方案(在示例(3,3)中)。 不幸的是,我真的没有达到如何实现这一目标。
非常感谢您的想法。
这是我当前的Haskell代码(为指定的起始位置提供一种解决方案):
> kt :: Int -> (Int,Int) -> [(Int,Int)]
> kt dimension startPos = kt' (delete startPos allFields) [startPos] startPos
> where allFields = [(h,v) | h <- [1..dimension], v <- [1..dimension]]
> kt' :: [(Int,Int)] -> [(Int,Int)] -> (Int,Int) -> [(Int,Int)]
> kt' [] moves _ = moves
> kt' freeFields moves currentPos
> | nextField /= (0,0) = kt' (delete nextField freeFields) (moves ++ [nextField]) nextField
> | otherwise = error "Oops ... dead end!"
> where h = fst currentPos
> v = snd currentPos
> nextField = if nextFieldEnv /= [] then fst (head (sortBy sortGT nextFieldEnv)) else (0,0)
> nextFieldEnv = fieldEnv' currentPos freeFields
> sortGT ((a1,a2),a3) ((b1,b2),b3)
> | a3 > b3 = GT
> | a3 < b3 = LT
> | a3 == b3 = EQ
> fieldEnv :: (Int,Int) -> [(Int,Int)] -> [(Int,Int)]
> fieldEnv field freeFields = [nField | nField <- [(hor-2,ver-1),(hor-2,ver+1),(hor-1,ver-2),(hor-1,ver+2),(hor+1,ver-2),(hor+1,ver+2),(hor+2,ver-1),(hor+2,ver+1)], nField `elem` freeFields]
> where hor = fst field
> ver = snd field
> fieldEnv' :: (Int,Int) -> [(Int,Int)] -> [((Int,Int),Int)]
> fieldEnv' field freeFields = [(nField,length (fieldEnv nField freeFields)) | nField <- (fieldEnv field freeFields)]
> where hor = fst field
> ver = snd field
答案 0 :(得分:1)
社区维基回答最终的解决方案:
“我担心如果你想要所有的游览,无论如何你都会有一个慢的算法,从一个起点开始的游览数量对于不太小的游戏来说是巨大的”