func Sort(g *graph.DirGraph) *stack.Stack { var visit func(v graph.VertexId) sorted := stack.New() visited := make(map[graph.VertexId]bool) marked := make(map[graph.VertexId]bool) visit = func(v graph.VertexId) { if marked[v] { panic("Not a Directed Acyclic Graph (DAG)") } marked[v] = true successors := g.GetSuccessors(v).VerticesIter() for successor := range successors { if !marked[successor] && !visited[successor] { visit(successor) } } visited[v] = true marked[v] = false sorted.Push(v) } vertices := g.VerticesIter() for vertex := range vertices { if !visited[vertex] { visit(vertex) } } return sorted }
func DirectedDfs(g *graph.DirGraph, v graph.VertexId, fn func(graph.VertexId)) { s := stack.New() s.Push(v) visited := make(map[graph.VertexId]bool) for s.Len() > 0 { v = s.Pop().(graph.VertexId) if _, ok := visited[v]; !ok { visited[v] = true fn(v) neighbours := g.GetSuccessors(v).VerticesIter() for neighbour := range neighbours { s.Push(neighbour) } } } }
func ShortestPath(g *graph.DirGraph, start graph.VertexId) (dist map[graph.VertexId]int) { dist = make(map[graph.VertexId]int) visited := make(map[graph.VertexId]bool) getDist := func(v graph.VertexId) { neighbours := g.GetNeighbours(v).VerticesIter() visited[v] = true for neighbour := range neighbours { ok, _ := visited[neighbour] if !ok { dist[neighbour] = dist[v] + 1 } } } bfs.Bfs(g, start, getDist) return }
func Bfs(g *graph.DirGraph, start graph.VertexId, fn func(graph.VertexId)) { queue := []graph.VertexId{start} visited := make(map[graph.VertexId]bool) var next []graph.VertexId for len(queue) > 0 { next = []graph.VertexId{} for _, vertex := range queue { visited[vertex] = true neighbours := g.GetNeighbours(vertex).VerticesIter() fn(vertex) for neighbour := range neighbours { _, ok := visited[neighbour] if !ok { next = append(next, neighbour) } } } queue = next } }
func Scc(g *graph.DirGraph) []stack.Stack { s := stack.New() n := g.Order() SCCs := make([]stack.Stack, 0) visited := make(map[graph.VertexId]bool) vertices := g.VerticesIter() for s.Len() != n { vertex := <-vertices dfs.DirectedDfs(g, vertex, func(v graph.VertexId) { if visited[v] == false { fmt.Println(vertex, v) s.Push(v) visited[v] = true } }) } fmt.Println(s) r := g.Reverse() visited = make(map[graph.VertexId]bool) for s.Len() > 0 { vertex := s.Pop().(graph.VertexId) scc := stack.New() if visited[vertex] == false { dfs.DirectedDfs(r, vertex, func(v graph.VertexId) { fmt.Println(vertex, v) if visited[graph.VertexId(v)] == false { visited[graph.VertexId(v)] = true fmt.Println(vertex, v) scc.Push(v) } }) } if scc.Len() > 1 { SCCs = append(SCCs, *scc) } } return SCCs }