Advertisement
Guest User

Untitled

a guest
Feb 9th, 2016
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.24 KB | None | 0 0
  1. {-# LANGUAGE BangPatterns #-}
  2. {-# LANGUAGE DeriveFunctor #-}
  3. {-# LANGUAGE ViewPatterns #-}
  4. {-# LANGUAGE FlexibleContexts #-}
  5. import qualified Data.IntMap.Strict as IntMap
  6. import qualified Data.IntSet as IntSet
  7. import qualified Data.Sequence as Seq
  8. import qualified Data.Foldable as F
  9. import Data.IntMap.Strict(IntMap)
  10. import Data.IntSet(IntSet)
  11. import Data.Sequence(Seq)
  12. import Control.Monad.State
  13. import Data.Monoid
  14. import Data.Maybe
  15.  
  16. type Node = Int
  17. type LNode a = (Node, a)
  18. type Edge = (Int, Int)
  19. type LEdge a = (Edge, a)
  20.  
  21. newtype Graph a = Graph {
  22. unGraph :: IntMap (Seq (LNode a))
  23. }
  24.  
  25. instance (Show a) => Show (Graph a) where
  26. show = show . unGraph
  27.  
  28. empty = Graph IntMap.empty
  29.  
  30. addUEdge s t w = Graph . IntMap.insertWith (\old new -> old <> new) t (Seq.singleton (s, w)) . IntMap.insertWith (\old new -> old <> new) s (Seq.singleton (t, w)) . unGraph
  31. addEdge s t w = Graph . IntMap.insertWith (\old new -> old <> new) s (Seq.singleton (t, w)) . unGraph
  32.  
  33. mkGraph :: [LEdge a] -> Graph a
  34. mkGraph = foldl acc empty
  35. where acc g (!(!s, !t), !w) = addEdge s t w g
  36.  
  37. mkUGraph :: [LEdge a] -> Graph a
  38. mkUGraph = foldl acc empty
  39. where acc g (!(!s, !t), !w) = addUEdge s t w g
  40.  
  41. data Policy = BFS | DFS
  42.  
  43. enqueue BFS s q = q <> s
  44. enqueue DFS s q = s <> q
  45.  
  46. fsg :: (MonadState IntSet m, Monoid n, Num a) => (Node -> Node -> Int -> a -> n) -> Graph a -> n -> Policy -> Seq (Node, (Node, Int, a)) -> m n
  47. fsg f g m p (Seq.viewl -> Seq.EmptyL) = return m
  48. fsg f g m p (Seq.viewl -> ((!t, (!s, !l, !z))) Seq.:< q) = do
  49. visited <- get
  50. if t `IntSet.member` visited then fsg f g m p q else do
  51. put (IntSet.insert t visited)
  52. let adjs = maybe Seq.empty id (IntMap.lookup t (unGraph g))
  53. notVisited = fmap (\(x, y) -> (x, (t, l + 1, y + z))) . Seq.filter (\(x, y) -> x `IntSet.notMember` visited) $ adjs
  54. fsg f g (f t s l z <> m) p (enqueue p notVisited q)
  55.  
  56. start z = Seq.singleton (z, (z, 1, 0) )
  57. nodes s p l w = Seq.singleton s
  58.  
  59. bfsWith f z g = evalState (fsg f g mempty BFS s) IntSet.empty
  60. where s = start z
  61. dfsWith f z g = evalState (fsg f g mempty BFS s) IntSet.empty
  62. where s = start z
  63.  
  64. bfs z g = F.toList . evalState (fsg nodes g mempty BFS s) $ IntSet.empty
  65. where s = start z
  66.  
  67. dfs z g = F.toList . evalState (fsg nodes g mempty DFS s) $ IntSet.empty
  68. where s = start z
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement