-- (c) 2000-2005 by Martin Erwig [see file COPYRIGHT] -- | Graph Voronoi Diagram -- -- These functions can be used to create a /shortest path forest/ -- where the roots are specified. module Data.Graph.Inductive.Query.GVD ( Voronoi,LRTree, gvdIn,gvdOut, voronoiSet,nearestNode,nearestDist,nearestPath, -- vd,nn,ns, -- vdO,nnO,nsO ) where import Data.List (nub) import Data.Maybe (listToMaybe) import qualified Data.Graph.Inductive.Internal.Heap as H import Data.Graph.Inductive.Basic import Data.Graph.Inductive.Graph import Data.Graph.Inductive.Internal.RootPath import Data.Graph.Inductive.Query.SP (dijkstra) -- | Representation of a shortest path forest. type Voronoi a = LRTree a -- | Produce a shortest path forest (the roots of which are those -- nodes specified) from nodes in the graph /to/ one of the root -- nodes (if possible). gvdIn :: (DynGraph gr, Real b) => [Node] -> gr a b -> Voronoi b gvdIn vs g = gvdOut vs (grev g) -- | Produce a shortest path forest (the roots of which are those -- nodes specified) from nodes in the graph /from/ one of the root -- nodes (if possible). gvdOut :: (Graph gr, Real b) => [Node] -> gr a b -> Voronoi b gvdOut vs = dijkstra (H.build (zip (repeat 0) (map (\v->LP [(v,0)]) vs))) -- | Return the nodes reachable to/from (depending on how the -- 'Voronoi' was constructed) from the specified root node (if the -- specified node is not one of the root nodes of the shortest path -- forest, an empty list will be returned). voronoiSet :: Node -> Voronoi b -> [Node] voronoiSet v = nub . concat . filter (\p->last p==v) . map (map fst . unLPath) -- | Try to construct a path to/from a specified node to one of the -- root nodes of the shortest path forest. maybePath :: Node -> Voronoi b -> Maybe (LPath b) maybePath v = listToMaybe . filter ((v==) . fst . head . unLPath) -- | Try to determine the nearest root node to the one specified in the -- shortest path forest. nearestNode :: (Real b) => Node -> Voronoi b -> Maybe Node nearestNode v = fmap (fst . last . unLPath) . maybePath v -- | The distance to the 'nearestNode' (if there is one) in the -- shortest path forest. nearestDist :: Node -> Voronoi b -> Maybe b nearestDist v = fmap (snd . head . unLPath) . maybePath v -- | Try to construct a path to/from a specified node to one of the -- root nodes of the shortest path forest. nearestPath :: Node -> Voronoi b -> Maybe Path nearestPath v = fmap (map fst . unLPath) . maybePath v -- vd = gvdIn [4,5] vor -- vdO = gvdOut [4,5] vor -- nn = map (flip nearestNode vd) [1..8] -- nnO = map (flip nearestNode vdO) [1..8] -- ns = map (flip voronoiSet vd) [1..8] -- nsO = map (flip voronoiSet vdO) [1..8]