Path existence checking between graph nodes
This commit is contained in:
parent
644670b494
commit
7d8596c52b
2 changed files with 69 additions and 0 deletions
68
src/Data/Graph/Inductive/Query/Path.hs
Normal file
68
src/Data/Graph/Inductive/Query/Path.hs
Normal file
|
@ -0,0 +1,68 @@
|
|||
{- This file is part of Vervis.
|
||||
-
|
||||
- Written in 2016 by fr33domlover <fr33domlover@riseup.net>.
|
||||
-
|
||||
- ♡ Copying is an act of love. Please copy, reuse and share.
|
||||
-
|
||||
- The author(s) have dedicated all copyright and related and neighboring
|
||||
- rights to this software to the public domain worldwide. This software is
|
||||
- distributed without any warranty.
|
||||
-
|
||||
- You should have received a copy of the CC0 Public Domain Dedication along
|
||||
- with this software. If not, see
|
||||
- <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
-}
|
||||
|
||||
-- | Detecting existence of paths in graphs, and finding the paths.
|
||||
--
|
||||
-- Some path related functions already exist in @fgl@ in the Query modules on
|
||||
-- the algorithms they're based on. In this module I'm putting additional path
|
||||
-- related utilities I need.
|
||||
module Data.Graph.Inductive.Query.Path
|
||||
( -- * Existence of a path between given nodes
|
||||
connects
|
||||
, uconnects
|
||||
, rconnects
|
||||
)
|
||||
where
|
||||
|
||||
import Prelude
|
||||
|
||||
import Data.Graph.Inductive.Graph
|
||||
import Data.Graph.Inductive.Internal.Queue
|
||||
|
||||
-- | Since FGL's BFS module doesn't allow to specify the traversal direction,
|
||||
-- I'm writing a modified version here. I could use DFS as long as I only check
|
||||
-- for existence, but it will be easier to reuse code if the algorithm used for
|
||||
-- checking is also used for getting the paths themselves.
|
||||
xbfsnWith'
|
||||
:: Graph g
|
||||
=> (Context a b -> [Node])
|
||||
-> (Context a b -> c)
|
||||
-> Queue Node
|
||||
-> g a b
|
||||
-> [c]
|
||||
xbfsnWith' follow result = go
|
||||
where
|
||||
go q g =
|
||||
if queueEmpty q || isEmpty g
|
||||
then []
|
||||
else
|
||||
let (n, q') = queueGet q
|
||||
in case match n g of
|
||||
(Just c, g') ->
|
||||
let q'' = queuePutList (follow c) q'
|
||||
in result c : go q'' g'
|
||||
(Nothing, g') -> go q' g'
|
||||
|
||||
xbfs :: Graph g => (Context a b -> [Node]) -> Node -> g a b -> [Node]
|
||||
xbfs follow node = xbfsnWith' follow node' (queuePut node mkQueue)
|
||||
|
||||
connects :: Graph g => Node -> Node -> g a b -> Bool
|
||||
connects u v = elem v . xbfs suc' u
|
||||
|
||||
uconnects :: Graph g => Node -> Node -> g a b -> Bool
|
||||
uconnects u v = elem v . xbfs neighbors' u
|
||||
|
||||
rconnects :: Graph g => Node -> Node -> g a b -> Bool
|
||||
rconnects u v = elem v . xbfs pre' u
|
|
@ -55,6 +55,7 @@ library
|
|||
Data.Git.Local
|
||||
Data.Graph.Inductive.Query.Cycle
|
||||
Data.Graph.Inductive.Query.Layer
|
||||
Data.Graph.Inductive.Query.Path
|
||||
Data.HashMap.Lazy.Local
|
||||
Data.Hourglass.Local
|
||||
Data.List.Local
|
||||
|
|
Loading…
Reference in a new issue