1
- module Autotool.Solver.Hamilton (solve ) where
1
+ module Autotool.Solver.Hamilton (solve , isHamiltonCircle ) where
2
2
3
3
import Data.Set (delete , toList , member , size )
4
+ import qualified Data.Set as S
4
5
import Control.Monad (guard )
5
- import Autotool.Data.Graph (Graph )
6
+ import Autotool.Data.Graph (Graph , neighbours , containsEdge )
6
7
7
8
solve :: (Eq a , Ord a , Show a ) => Graph a -> [a ]
8
- solve g@ (vs,_ ) = take (size vs) $ go g [] where
9
+ solve g@ (vs,alles ) = take (size vs) $ go g [] where
9
10
go :: (Eq a , Ord a , Show a ) => Graph a -> [a ] -> [a ]
10
11
go g@ (vs, es) p
11
12
| null vs = p
13
+ | null p = let v0 = S. findMin vs in go (rm g v0) [v0]
12
14
| otherwise = do
13
- let vs' = toList vs
14
- v <- vs'
15
+ let pn = head p
16
+ v <- toList vs
15
17
guard $ v `notElem` p
16
- guard $
17
- null p ||
18
- (size vs == 1 && let x = last p in (v,x) `member` es || (x,v) `member` es) ||
19
- (size vs > 1 && let x = head p in (v,x) `member` es || (x,v) `member` es)
20
- let vs' = delete v vs
21
- let g' = (vs', es)
22
- let p' = v: p
23
- go g' p'
24
-
25
- -- hamilton :: (Eq a, Ord a, Show a) => Graph a -> [a]
26
- -- hamilton g@(vs, es) = let perms = permutations (toList vs) in head $ filter (isHamiltonCircle g) perms
18
+ guard $ containsEdge g (v, pn)
19
+ guard $ size vs > 1 || containsEdge g (v, last p)
20
+ go (rm g v) (v: p)
21
+ rm (vs,es) v = (S. delete v vs, es)
27
22
28
23
isHamiltonCircle :: (Ord a ) => Graph a -> [a ] -> Bool
29
- isHamiltonCircle (_, es) p = all f p' where
30
- p' = (head p, last p) : zip p (drop 1 p)
31
- f (a,b) = (a,b) `member` es || (b,a) `member` es
24
+ isHamiltonCircle g@ (_, es) p = all (containsEdge g) p' where
25
+ p' = (head p, last p) : zip p (drop 1 p)
0 commit comments