From b59ad621765a199867882eddc88a2852b5bd5020 Mon Sep 17 00:00:00 2001 From: Hamed Yousefi Date: Mon, 13 Mar 2023 12:32:11 +0330 Subject: [PATCH 1/2] add comment on kusaraju algorithm --- connectivity/kosaraju.go | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/connectivity/kosaraju.go b/connectivity/kosaraju.go index ab36e11..45391a6 100644 --- a/connectivity/kosaraju.go +++ b/connectivity/kosaraju.go @@ -2,16 +2,32 @@ package connectivity import "github.com/hmdsefi/gograph" -type kosarajuSCCS[T comparable] struct { +// Kosaraju's Algorithm: This algorithm is also based on depth-first search +// and is used to find strongly connected components in a graph. The algorithm +// has a time complexity of O(V+E) and is considered to be one of the most +// efficient algorithms for finding strongly connected components. +// +// Note that this implementation assumes that the graph is connected, and +// may not work correctly for disconnected graphs. It also does not handle +// cases where the graph contains self-loops or parallel edges. + +// kosarajuDFS exposes two different depth-first search methods. +type kosarajuDFS[T comparable] struct { visited map[T]bool } -func newKosarajuSCCS[T comparable]() *kosarajuSCCS[T] { - return &kosarajuSCCS[T]{ - visited: make(map[T]bool), - } +func newKosarajuSCCS[T comparable]() *kosarajuDFS[T] { + return &kosarajuDFS[T]{} } +// implements Kosaraju's Algorithm. It performs a depth-first search of +// the graph to create a stack of vertices, and then performs a second +// depth-first search on the transposed graph to identify the strongly +// connected components. +// +// The function returns a slice of slices, where each slice represents +// a strongly connected component and contains the vertices that belong +// to that component. func kosaraju[T comparable](g gograph.Graph[T]) [][]*gograph.Vertex[T] { vertices := g.GetAllVertices() @@ -42,7 +58,8 @@ func kosaraju[T comparable](g gograph.Graph[T]) [][]*gograph.Vertex[T] { return sccs } -func (k *kosarajuSCCS[T]) dfs1(v *gograph.Vertex[T], stack *[]T) { +// dfs1 creates the stack of vertices. +func (k *kosarajuDFS[T]) dfs1(v *gograph.Vertex[T], stack *[]T) { k.visited[v.Label()] = true neighbors := v.Neighbors() for _, neighbor := range neighbors { @@ -53,7 +70,8 @@ func (k *kosarajuSCCS[T]) dfs1(v *gograph.Vertex[T], stack *[]T) { *stack = append(*stack, v.Label()) } -func (k *kosarajuSCCS[T]) dfs2(v *gograph.Vertex[T], scc *[]*gograph.Vertex[T]) { +// dfs2 explores the strongly connected components. +func (k *kosarajuDFS[T]) dfs2(v *gograph.Vertex[T], scc *[]*gograph.Vertex[T]) { k.visited[v.Label()] = true *scc = append(*scc, v) neighbors := v.Neighbors() @@ -64,7 +82,7 @@ func (k *kosarajuSCCS[T]) dfs2(v *gograph.Vertex[T], scc *[]*gograph.Vertex[T]) } } -func (k *kosarajuSCCS[T]) reverse(g gograph.Graph[T]) gograph.Graph[T] { +func (k *kosarajuDFS[T]) reverse(g gograph.Graph[T]) gograph.Graph[T] { reversed := gograph.New[T](gograph.Directed()) vertices := g.GetAllVertices() From 7456c6f1b302b04756a728435b4fbe44ced162a7 Mon Sep 17 00:00:00 2001 From: Hamed Yousefi Date: Mon, 13 Mar 2023 12:33:49 +0330 Subject: [PATCH 2/2] fix kosaraju test --- connectivity/kosaraju.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/connectivity/kosaraju.go b/connectivity/kosaraju.go index 45391a6..0ee24e2 100644 --- a/connectivity/kosaraju.go +++ b/connectivity/kosaraju.go @@ -17,7 +17,9 @@ type kosarajuDFS[T comparable] struct { } func newKosarajuSCCS[T comparable]() *kosarajuDFS[T] { - return &kosarajuDFS[T]{} + return &kosarajuDFS[T]{ + visited: make(map[T]bool), + } } // implements Kosaraju's Algorithm. It performs a depth-first search of