toy-lib-0.1.0.0
Safe HaskellSafe-Inferred
LanguageHaskell2010

Data.Graph.Sparse

Description

vector-based sparse graph implementation. Heavily inspired by cojna/iota.

  • TODO: move tree functions to the generic module
Synopsis

Documentation

data SparseGraph w #

CSR (compressed sparse row) representation of a graph, weightened or unweightened.

Constructors

SparseGraph 

Fields

Instances

Instances details
(Show w, Unbox w) => Show (SparseGraph w) # 
Instance details

Defined in Data.Graph.Sparse

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.

adj :: SparseGraph w -> Vertex -> Vector Vertex #

\(O(1)\) Retrieves adjacent vertices.

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

Constructors

DigraphInfo 

Fields

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 on True. It's set to False@ for undirected graphs where edges are duplicated.

<https://drken1215.hatenablog.com/entry/2023/05/20/200517z.