1

I implemented a recursive solution for the Knight's tour using Haskell. My algorithm is basically based on Warnsdorff's Rule.

Example:

  • Size of chessboard: 5x5
  • Starting position: (3,3)

The basic idea based on this example:

(1) Calculate allowed moves from current point (3,3)
=> (1,2),(1,4),(2,1),(2,5),(4,1),(4,5),(5,2),(5,4)

(2) For each of these points, calculate the number of moves which can be performed to reach that point (number of "entrances")
=> ((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) Find the point with the minimum entrances or the first one if all points have the same number of entrances
=> (1,2)

(4) Call same function with the determined point (start recursion)

That way I'm able to determine a way to solve the problem. But now I need to determine all other possible solutions for a starting position (in the example (3,3)). Unfortunately I don't really get how to achieve that.

Ideas are very appreciated.

This is my current Haskell code (providing one solution for a specified starting position):

> 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
false
  • 10,264
  • 13
  • 101
  • 209
Patrick
  • 3,091
  • 4
  • 26
  • 29
  • Can you solve the problem *without* the special selection rule? Do you know how to solve other similar backtracking problems (N queens, etc) ? – hugomg Dec 23 '12 at 18:32
  • Could you describe what you mean with "special selection rule"? I didn't try to solve the N Queens Problem or similar problems, but in terms of computing time my implementation is quite efficient, I think. Much more efficient than a "simple" backtracking approach which I tried first (and, of course, was much, much slower). – Patrick Dec 23 '12 at 18:57
  • 1
    I'm afraid if you want all tours, you will have a slow algorithm no matter what, the number of open tours from a starting point is huge for not too small boards. – Daniel Fischer Dec 23 '12 at 19:37
  • All right. Thanks four your answers! – Patrick Dec 24 '12 at 11:28

1 Answers1

1

Community-wiki answer with the eventual approximation to a solution:

"I'm afraid if you want all tours, you will have a slow algorithm no matter what, the number of open tours from a starting point is huge for not too small boards"

sclv
  • 38,665
  • 7
  • 99
  • 204