-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Common graph search algorithms -- -- Library containing common graph search algorithms, including -- depth-first and breadth-first searches, Dijkstra's algorithm, and A* @package search-algorithms @version 0.3.2 -- | This module contains a collection of generalized graph search -- algorithms, for when you don't want to explicitly represent your data -- as a graph. The general idea is to provide these algorithms with a way -- of generating "next" states, a way of generating associated -- information, a way of determining when you have found a solution, and -- an initial state. module Algorithm.Search -- | bfs next found initial performs a breadth-first search over a -- set of states, starting with initial, and generating -- neighboring states with next. It returns a path to a state -- for which found returns True. Returns Nothing -- if no path is possible. -- --
-- >>> :{
-- countChange target = bfs (add_one_coin `pruning` (> target)) (== target) 0
-- where
-- add_one_coin amt = map (+ amt) coins
-- coins = [25, 10, 5, 1]
-- :}
--
--
-- -- >>> countChange 67 -- Just [25,50,60,65,66,67] --bfs :: (Foldable f, Ord state) => (state -> f state) -> (state -> Bool) -> state -> Maybe [state] -- | dfs next found initial performs a depth-first search over a -- set of states, starting with initial and generating -- neighboring states with next. It returns a depth-first path -- to a state for which found returns True. Returns -- Nothing if no path is possible. -- --
-- >>> import qualified Data.Map as Map ---- --
-- >>> graph = Map.fromList [(1, [2, 3]), (2, [4]), (3, [4]), (4, [])] ---- --
-- >>> dfs (graph Map.!) (== 4) 1 -- Just [3,4] --dfs :: (Foldable f, Ord state) => (state -> f state) -> (state -> Bool) -> state -> Maybe [state] -- | dijkstra next cost found initial performs a shortest-path -- search over a set of states using Dijkstra's algorithm, starting with -- initial, generating neighboring states with next, -- and their incremental costs with costs. This will find the -- least-costly path from an initial state to a state for which -- found returns True. Returns Nothing if no path -- to a solved state is possible. -- --
-- >>> :{
-- -- Twist: dimes have a face value of 10 cents, but are actually rare
-- -- misprints which are worth 10 dollars
-- countChange target =
-- dijkstra (add_coin `pruning` (> target)) true_cost (== target) 0
-- where
-- coin_values = [(25, 25), (10, 1000), (5, 5), (1, 1)]
-- add_coin amt = map ((+ amt) . snd) coin_values
-- true_cost low high =
-- case lookup (high - low) coin_values of
-- Just val -> val
-- Nothing -> error $ "invalid costs: " ++ show high ++ ", " ++ show low
-- :}
--
--
-- -- >>> countChange 67 -- Just (67,[1,2,7,12,17,42,67]) --dijkstra :: (Foldable f, Num cost, Ord cost, Ord state) => (state -> f state) -> (state -> state -> cost) -> (state -> Bool) -> state -> Maybe (cost, [state]) -- | dijkstraAssoc next found initial performs a shortest-path -- search over a set of states using Dijkstra's algorithm, starting with -- initial, generating neighboring states with associated -- incremenal costs with next. This will find the least-costly -- path from an initial state to a state for which found returns -- True. Returns Nothing if no path to a solved state is -- possible. dijkstraAssoc :: (Num cost, Ord cost, Ord state) => (state -> [(state, cost)]) -> (state -> Bool) -> state -> Maybe (cost, [state]) -- | aStar next cost remaining found initial performs a best-first -- search using the A* search algorithm, starting with the state -- initial, generating neighboring states with next, -- their cost with cost, and an estimate of the remaining cost -- with remaining. This returns a path to a state for which -- found returns True. If remaining is strictly -- a lower bound on the remaining cost to reach a solved state, then the -- returned path is the shortest path. Returns Nothing if no path -- to a solved state is possible. -- --
-- >>> :{
-- neighbors (x, y) = [(x, y + 1), (x - 1, y), (x + 1, y), (x, y - 1)]
-- dist (x1, y1) (x2, y2) = abs (y2 - y1) + abs (x2 - x1)
-- start = (0, 0)
-- end = (0, 2)
-- isWall = (== (0, 1))
-- :}
--
--
-- -- >>> aStar (neighbors `pruning` isWall) dist (dist end) (== end) start -- Just (4,[(1,0),(1,1),(1,2),(0,2)]) --aStar :: (Foldable f, Num cost, Ord cost, Ord state) => (state -> f state) -> (state -> state -> cost) -> (state -> cost) -> (state -> Bool) -> state -> Maybe (cost, [state]) -- | aStarAssoc next remaining found initial performs a best-first -- search using the A* search algorithm, starting with the state -- initial, generating neighboring states and their associated -- costs with next, and an estimate of the remaining cost with -- remaining. This returns a path to a state for which -- found returns True. If remaining is strictly -- a lower bound on the remaining cost to reach a solved state, then the -- returned path is the shortest path. Returns Nothing if no path -- to a solved state is possible. aStarAssoc :: (Num cost, Ord cost, Ord state) => (state -> [(state, cost)]) -> (state -> cost) -> (state -> Bool) -> state -> Maybe (cost, [state]) -- | bfsM is a monadic version of bfs: it has support for -- monadic next and found parameters. bfsM :: (Monad m, Foldable f, Ord state) => (state -> m (f state)) -> (state -> m Bool) -> state -> m (Maybe [state]) -- | dfsM is a monadic version of dfs: it has support for -- monadic next and found parameters. dfsM :: (Monad m, Foldable f, Ord state) => (state -> m (f state)) -> (state -> m Bool) -> state -> m (Maybe [state]) -- | dijkstraM is a monadic version of dijkstra: it has -- support for monadic next, cost, and found -- parameters. dijkstraM :: (Monad m, Foldable f, Num cost, Ord cost, Ord state) => (state -> m (f state)) -> (state -> state -> m cost) -> (state -> m Bool) -> state -> m (Maybe (cost, [state])) -- | aStarM is a monadic version of aStar: it has support -- for monadic next, cost, remaining, and -- found parameters. aStarM :: (Monad m, Foldable f, Num cost, Ord cost, Ord state) => (state -> m (f state)) -> (state -> state -> m cost) -> (state -> m cost) -> (state -> m Bool) -> state -> m (Maybe (cost, [state])) -- | incrementalCosts cost_fn states gives a list of the -- incremental costs going from state to state along the path given in -- states, using the cost function given by cost_fn. -- Note that the paths returned by the searches in this module do not -- include the initial state, so if you want the incremental costs along -- a path returned by one of these searches, you want to use -- incrementalCosts cost_fn (initial : path). -- --
-- >>> import Data.Maybe (fromJust) ---- --
-- >>> :{
-- cyclicWeightedGraph :: Map.Map Char [(Char, Int)]
-- cyclicWeightedGraph = Map.fromList [
-- ('a', [('b', 1), ('c', 2)]),
-- ('b', [('a', 1), ('c', 2), ('d', 5)]),
-- ('c', [('a', 1), ('d', 2)]),
-- ('d', [])
-- ]
-- start = (0, 0)
-- end = (0, 2)
-- cost a b = fromJust . lookup b $ cyclicWeightedGraph Map.! a
-- :}
--
--
-- -- >>> incrementalCosts cost ['a', 'b', 'd'] -- [1,5] --incrementalCosts :: (state -> state -> cost) -> [state] -> [cost] -- | incrementalCostsM is a monadic version of -- incrementalCosts: it has support for a monadic -- const_fn parameter. incrementalCostsM :: Monad m => (state -> state -> m cost) -> [state] -> m [cost] -- | next `pruning` predicate streams the elements generate by -- next into a list, removing elements which satisfy -- predicate. This is useful for the common case when you want -- to logically separate your search's next function from some -- way of determining when you've reached a dead end. -- --
-- >>> import qualified Data.Set as Set ---- --
-- >>> ((\x -> Set.fromList [0..x]) `pruning` even) 10 -- [1,3,5,7,9] ---- --
-- >>> import qualified Data.Map as Map ---- --
-- >>> :{
-- graph = Map.fromList [
-- ('a', ['b', 'c', 'd']),
-- ('b', [undefined]),
-- ('c', ['e']),
-- ('d', [undefined]),
-- ('e', [])
-- ]
-- :}
--
--
-- -- >>> dfs ((graph Map.!) `pruning` (`elem` "bd")) (== 'e') 'a' -- Just "ce" --pruning :: Foldable f => (a -> f a) -> (a -> Bool) -> a -> [a] -- | pruningM is a monadic version of pruning: it has -- support for monadic next and predicate parameters pruningM :: (Monad m, Foldable f) => (a -> m (f a)) -> (a -> m Bool) -> a -> m [a] instance Algorithm.Search.SearchContainer (Data.Sequence.Internal.Seq a) instance Algorithm.Search.SearchContainer [a] instance GHC.Classes.Ord k => Algorithm.Search.SearchContainer (Algorithm.Search.LIFOHeap k a)