Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
vector
-based sparse graph implementation. Heavily inspired by cojna/iota
.
- TODO: move tree functions to the generic module
Synopsis
- data SparseGraph w = SparseGraph {}
- buildSG :: Int -> Vector (Vertex, Vertex) -> SparseGraph Int
- buildSG_ :: Int -> Vector (Vertex, Vertex) -> SparseGraph ()
- buildWSG :: Unbox w => Int -> Vector (Vertex, Vertex, w) -> SparseGraph w
- adj :: SparseGraph w -> Vertex -> Vector Vertex
- eAdj :: SparseGraph w -> Vertex -> Vector (EdgeId, Vertex)
- adjW :: Unbox w => SparseGraph w -> Vertex -> Vector (Vertex, w)
- componentsSG :: SparseGraph w -> Vector Vertex -> Vector Vertex
- groupSG :: SparseGraph w -> (Vector Int, [[Vertex]])
- dfsSG :: (Unbox w, Num w, Eq w) => SparseGraph w -> Vertex -> w -> Vector w
- dfsEveryPathLongestSG :: forall w. (Num w, Ord w, Unbox w) => SparseGraph w -> Vertex -> w
- bfsSG :: (Unbox w, Num w, Eq w) => SparseGraph w -> Vertex -> w -> Vector w
- bfs01SG :: SparseGraph Int -> Vector Vertex -> Vector Int
- djSG :: forall w. (Num w, Ord w, Unbox w) => SparseGraph w -> w -> Vector Vertex -> Vector w
- dfsTreeSG :: (Unbox w, Num w) => SparseGraph w -> Vertex -> w -> (Vector w, Vector Vertex)
- bfsTreeSG :: (Unbox w, Num w, Eq w) => SparseGraph w -> Vertex -> w -> (Vector w, Vector Vertex)
- djTreeSG :: forall w. (Num w, Ord w, Unbox w) => SparseGraph w -> w -> Vector Vertex -> (Vector w, Vector Vertex)
- data DigraphInfo = DigraphInfo {
- isAllDigraphDI :: !Bool
- vertColorDI :: !(Vector Int)
- vertComponentDI :: !(Vector Int)
- componentInfoDI :: !(Vector (Int, Int, Bool))
- digraphSG :: SparseGraph w -> DigraphInfo
- topSortSG :: SparseGraph w -> [Vertex]
- revSG :: Unbox w => SparseGraph w -> SparseGraph w
- downScc1SG :: forall w m. PrimMonad m => SparseGraph w -> MVector (PrimState m) Bool -> Vertex -> m [Vertex]
- downSccSG :: Unbox w => SparseGraph w -> [[Int]]
- topSccSG :: Unbox w => SparseGraph w -> [[Int]]
- collectMST :: (Ord w, Unbox w) => Int -> Vector (Vertex, Vertex, w) -> Vector (Vertex, Vertex, w)
- buildMST :: (Ord w, Unbox w) => Int -> Vector (Vertex, Vertex, w) -> SparseGraph w
- findCycleDirectedSG :: Unbox w => SparseGraph w -> Maybe (Vector (Vertex, Vertex, w))
- findCycleUndirectedSG :: Unbox w => SparseGraph w -> Maybe (Vector (Vertex, Vertex, w))
- findCycleComplexSG :: Unbox w => SparseGraph w -> Maybe (Vector (Vertex, Vertex, w))
- findCycleImplSG :: Unbox w => SparseGraph w -> Bool -> Maybe (Vector (Vertex, Vertex, w))
Documentation
data SparseGraph w #
CSR (compressed sparse row) representation of a graph, weightened or unweightened.
Instances
(Show w, Unbox w) => Show (SparseGraph w) # | |
Defined in Data.Graph.Sparse showsPrec :: Int -> SparseGraph w -> ShowS # show :: SparseGraph w -> String # showList :: [SparseGraph w] -> ShowS # |
buildSG :: Int -> Vector (Vertex, Vertex) -> SparseGraph Int #
\(O(N)\) Builds an non-weightned SparseGraph
.
buildSG_ :: Int -> Vector (Vertex, Vertex) -> SparseGraph () #
\(O(N)\) Builds an non-weightned SparseGraph
.
buildWSG :: Unbox w => Int -> Vector (Vertex, Vertex, w) -> SparseGraph w #
\(O(N)\) Builds a weightned SparseGraph
.
eAdj :: SparseGraph w -> Vertex -> Vector (EdgeId, Vertex) #
\(O(1)\) Returns (EdgeId, Vertex)
pairs. Hardly used.
adjW :: Unbox w => SparseGraph w -> Vertex -> Vector (Vertex, w) #
\(O(1)\) Retrieves adjacent vertices with weights.
Graph search (DFS, BFS, 01-BFS, Dijkstra)
componentsSG :: SparseGraph w -> Vector Vertex -> Vector Vertex #
\(O(V+E)\) Collects reachable vertices from source points.
groupSG :: SparseGraph w -> (Vector Int, [[Vertex]]) #
\(O(V+E)\) DFS that paints connnected components. Returns (vertexToComponentId, components)
.
Works on a non-directed graph only.
dfsSG :: (Unbox w, Num w, Eq w) => SparseGraph w -> Vertex -> w -> Vector w #
\(O(V+E)\) Depth-first search. Returns a vector of distances to each vertex. Unreachable vertices are given distance of `-1`.
dfsEveryPathLongestSG :: forall w. (Num w, Ord w, Unbox w) => SparseGraph w -> Vertex -> w #
\(O(N N!)\) Depth-first search that finds the longest path. Just a template!
Typical problems
bfsSG :: (Unbox w, Num w, Eq w) => SparseGraph w -> Vertex -> w -> Vector w #
\(O(V+E)\) Breadth-first search. Unreachable vertices are given distance of -1
.
bfs01SG :: SparseGraph Int -> Vector Vertex -> Vector Int #
\(O(V+E)\) 01-BFS. Unreachable vertices are given distance of -1
.
djSG :: forall w. (Num w, Ord w, Unbox w) => SparseGraph w -> w -> Vector Vertex -> Vector w #
\(O((E+V) \log {V})\) Dijkstra's algorithm.
>>>
let gr = buildWSG 4 (U.fromList [(0, 1, 1 :: Int), (1, 2, 1), (1, 3, 100), (2, 3, 1)])
>>>
djSG gr (-1 :: Int) (U.singleton 0)
[0,1,2,3]
Path restoration
dfsTreeSG :: (Unbox w, Num w) => SparseGraph w -> Vertex -> w -> (Vector w, Vector Vertex) #
\(O(V+E)\) depth-first search. Returns a vector of parents. The source vertex or unrechable vertices are given `-1` as their parent. Note that it doesn't return the shortest path.
bfsTreeSG :: (Unbox w, Num w, Eq w) => SparseGraph w -> Vertex -> w -> (Vector w, Vector Vertex) #
\(O(V+E)\) breadth-first search. Returns a vector of distances and parents. The source vertex or unrechable vertices are given `-1` as their parent.
>>>
bfsTreeSG (buildSG 4 (U.fromList [(0, 1), (1, 2), (1, 3), (2, 3)])) 0 (-1)
([0,1,2,2],[-1,0,1,1])
Retrieve a shortest path: >>> let (_, ps) = bfsTreeSG (buildSG 4 (U.fromList [(0, 1), (1, 2), (1, 3), (2, 3)])) 0 (-1) >>> restorePath ps 3 [0,1,3]
djTreeSG :: forall w. (Num w, Ord w, Unbox w) => SparseGraph w -> w -> Vector Vertex -> (Vector w, Vector Vertex) #
\(O((E+V) \log {V})\) Dijkstra's algorithm with path restoration information.
Digraph
data DigraphInfo #
Tries to paint the whole graph (possible not connected) as a digraph.
let DigraphInfo isFailure vertColors vertComps compInfos = paintDigraphSG gr
Typical problems
DigraphInfo | |
|
digraphSG :: SparseGraph w -> DigraphInfo #
\(O(V+E)\) Tries to paint the whole graph (possible not connected) as a digraph. Works on non-directed graphs only.
Topological sort and strongly connected components
topSortSG :: SparseGraph w -> [Vertex] #
\(O(V+E)\) Topological sort
Upstream (not referenced) vertices come first:
>>>
let !gr = buildSG 5 $ U.fromList ([(0, 1), (0, 2), (2, 3)] :: [(Int, Int)])
>>>
topSortSG gr
[4,0,2,3,1]
revSG :: Unbox w => SparseGraph w -> SparseGraph w #
\(O(V+E)\) Creates a reverse graph.
downScc1SG :: forall w m. PrimMonad m => SparseGraph w -> MVector (PrimState m) Bool -> Vertex -> m [Vertex] #
\(O(V+E)\) Partial running of topSccSG
over topologically sorted vertices, but for some connected components
only.
downSccSG :: Unbox w => SparseGraph w -> [[Int]] #
\(O(V+E)\) Collectes strongly connected components, reverse topologically sorted (referenced SCCs come first).
Downstream vertices come first, e.g., [v1 == v2 == v3] <- [v4 == v5] <- [v6]
.
- *TODO: Faster.**
topSccSG :: Unbox w => SparseGraph w -> [[Int]] #
\(O(V+E)\) Collectes strongly connected components, reverse topologically sorted (not referenced SCCs come first).
MST (Minimum Spanning Tree)
collectMST :: (Ord w, Unbox w) => Int -> Vector (Vertex, Vertex, w) -> Vector (Vertex, Vertex, w) #
\(O(E)\) Kruscal's algorithm. Returns edges for building a minimum spanning tree.
NOTE: User ia assumed to not duplicate the edges.
If you need to detect if the tree spans all the vertices, be sure to check the length of the edges
equals to the number of vertices minus one. Do not try to count the vertices directly, e.g.,
o-o o-o
contains four connected vertices, but only has two edges. It's apparently not a spanning
tree.
Typical problems
buildMST :: (Ord w, Unbox w) => Int -> Vector (Vertex, Vertex, w) -> SparseGraph w #
\(O(E)\) Kruscal's algorithm. Returns a minimum spanning tree.
NOTE: User ia assumed to not duplicate the edges.
Cycles
findCycleDirectedSG :: Unbox w => SparseGraph w -> Maybe (Vector (Vertex, Vertex, w)) #
\(O(V+E)\) Finds a cycle in a directed graph and collects their vertices. Embed edge information to the weight if necessary.
findCycleUndirectedSG :: Unbox w => SparseGraph w -> Maybe (Vector (Vertex, Vertex, w)) #
\(O(V+E)\) Finds a cycle in an undirected graph and collects their vertices. Embed edge information to the weight if necessary.
findCycleComplexSG :: Unbox w => SparseGraph w -> Maybe (Vector (Vertex, Vertex, w)) #
\(O(E)\) (Internal) Auxiliary function to `fincCycleUndirectedSG. Detects self-loop edges and multiple edges.
TODO: efficient implementation (findMap? and two of them in one loop?)
findCycleImplSG :: Unbox w => SparseGraph w -> Bool -> Maybe (Vector (Vertex, Vertex, w)) #
\(O(V+E)\) Finds a cycle in a directed or undirected graph and collects their vertices.
revEdgeIsCycle
: Reports reverse edge as a cycle onTrue. It's set to
False@ for undirected graphs where edges are duplicated.