/// <summary> /// check that algorithm computes either the topological order or finds a directed cycle /// </summary> /// <param name="g"></param> /// <param name="v"></param> private void Dfs(Digraph g, int v) { _onStack[v] = true; _marked[v] = true; foreach (int w in g.Adj(v)) { // short circuit if directed cycle found if (_cycle != null) { return; } //found new vertex, so recur if (!_marked[w]) { _edgeTo[w] = v; Dfs(g, w); } // trace back directed cycle else if (_onStack[w]) { _cycle = new Collections.Stack <Integer>(); for (var x = v; x != w; x = _edgeTo[x]) { _cycle.Push(x); } _cycle.Push(w); _cycle.Push(v); //assert check(); } } _onStack[v] = false; }
/// <summary> /// BFS from multiple sources /// </summary> /// <param name="g"></param> /// <param name="sources"></param> private void Bfs(Digraph g, IEnumerable <Integer> sources) { var q = new Collections.Queue <Integer>(); foreach (int s in sources) { _marked[s] = true; _distTo[s] = 0; q.Enqueue(s); } while (!q.IsEmpty()) { int v = q.Dequeue(); foreach (int w in g.Adj(v)) { if (!_marked[w]) { _edgeTo[w] = v; _distTo[w] = _distTo[v] + 1; _marked[w] = true; q.Enqueue(w); } } } }
private void Dfs(Digraph g, int v) { _marked[v] = true; _low[v] = _pre++; var min = _low[v]; _stack.Push(v); foreach (int j in g.Adj(v)) { if (!_marked[j]) { Dfs(g, j); } if (_low[j] < min) { min = _low[j]; } } if (min < _low[v]) { _low[v] = min; return; } int w; do { w = _stack.Pop(); _id[w] = _count; _low[w] = g.V; } while (w != v); _count++; }
private void Dfs(Digraph g, int v) { _marked[v] = true; _preorder[v] = _pre++; _stack1.Push(v); _stack2.Push(v); foreach (int w in g.Adj(v)) { if (!_marked[w]) { Dfs(g, w); } else if (_id[w] == -1) { while (_preorder[_stack2.Peek()] > _preorder[w]) { _stack2.Pop(); } } } // found strong component containing v if (_stack2.Peek() == v) { _stack2.Pop(); int w; do { w = _stack1.Pop(); _id[w] = _count; } while (w != v); _count++; } }
private void Dfs(Digraph g, int v) { _count++; _marked[v] = true; foreach (int w in g.Adj(v)) { if (!_marked[w]) Dfs(g, w); } }
private readonly Collections.Stack <Integer> _cycle; // Eulerian cycle; null if no such cylce /// <summary> /// Computes an Eulerian cycle in the specified digraph, if one exists. /// </summary> /// <param name="g">g the digraph</param> public DirectedEulerianCycle(Digraph g) { // must have at least one edge if (g.E == 0) { return; } // necessary condition: indegree(v) = outdegree(v) for each vertex v // (without this check, DFS might return a path instead of a cycle) for (var v = 0; v < g.V; v++) { if (g.Outdegree(v) != g.Indegree(v)) { return; } } // create local view of adjacency lists, to iterate one vertex at a time var adj = new IEnumerator <Integer> [g.V]; for (var v = 0; v < g.V; v++) { adj[v] = g.Adj(v).GetEnumerator(); } // initialize stack with any non-isolated vertex var s = NonIsolatedVertex(g); var stack = new Collections.Stack <Integer>(); stack.Push(s); // greedily add to putative cycle, depth-first search style _cycle = new Collections.Stack <Integer>(); while (!stack.IsEmpty()) { int v = stack.Pop(); while (adj[v].MoveNext()) { stack.Push(v); v = adj[v].Current; } // add vertex with no more leaving edges to cycle _cycle.Push(v); } // check if all edges have been used // (in case there are two or more vertex-disjoint Eulerian cycles) if (_cycle.Size() != g.E + 1) { _cycle = null; } //assert certifySolution(G); }
private readonly Collections.Stack<Integer> _path; // Eulerian path; null if no suh path #endregion Fields #region Constructors /// <summary> /// Computes an Eulerian path in the specified digraph, if one exists. /// </summary> /// <param name="g">g the digraph</param> public DirectedEulerianPath(Digraph g) { // find vertex from which to start potential Eulerian path: // a vertex v with outdegree(v) > indegree(v) if it exits; // otherwise a vertex with outdegree(v) > 0 var deficit = 0; var s = NonIsolatedVertex(g); for (var v = 0; v < g.V; v++) { if (g.Outdegree(v) > g.Indegree(v)) { deficit += (g.Outdegree(v) - g.Indegree(v)); s = v; } } // digraph can't have an Eulerian path // (this condition is needed) if (deficit > 1) return; // special case for digraph with zero edges (has a degenerate Eulerian path) if (s == -1) s = 0; // create local view of adjacency lists, to iterate one vertex at a time var adj = new IEnumerator<Integer>[g.V]; for (var v = 0; v < g.V; v++) adj[v] = g.Adj(v).GetEnumerator(); // greedily add to cycle, depth-first search style var stack = new Collections.Stack<Integer>(); stack.Push(s); _path = new Collections.Stack<Integer>(); while (!stack.IsEmpty()) { int v = stack.Pop(); while (adj[v].MoveNext()) { stack.Push(v); v = adj[v].Current; } // push vertex with no more available edges to path _path.Push(v); } // check if all edges have been used if (_path.Size() != g.E + 1) _path = null; //assert check(G); }
/// <summary> /// certify that digraph is acyclic /// </summary> /// <param name="g"></param> /// <returns></returns> public bool Check(Digraph g) { // digraph is acyclic if (HasOrder()) { // check that ranks are a permutation of 0 to V-1 var found = new bool[g.V]; for (var i = 0; i < g.V; i++) { found[Rank(i)] = true; } for (var i = 0; i < g.V; i++) { if (!found[i]) { Console.Error.WriteLine($"No vertex with rank {i}"); return(false); } } // check that ranks provide a valid topological order for (var v = 0; v < g.V; v++) { foreach (int w in g.Adj(v)) { if (Rank(v) > Rank(w)) { Console.WriteLine($"{v}-{w}: rank({v}) = {Rank(v)}, rank({w}) = {Rank(w)}{Environment.NewLine}"); return(false); } } } // check that order() is consistent with rank() var r = 0; foreach (int v in Order()) { if (Rank(v) != r) { Console.WriteLine("order() and rank() inconsistent"); return(false); } r++; } } return(true); }
private readonly int[] _rank; // rank[v] = order where vertex v appers in order /// <summary> /// Determines whether the digraph <tt>G</tt> has a topological order and, if so, /// finds such a topological order. /// </summary> /// <param name="g">g the digraph</param> public TopologicalX(Digraph g) { // indegrees of remaining vertices var indegree = new int[g.V]; for (var v = 0; v < g.V; v++) { indegree[v] = g.Indegree(v); } // initialize _rank = new int[g.V]; _order = new Collections.Queue <Integer>(); var count = 0; // initialize queue to contain all vertices with indegree = 0 var queue = new Collections.Queue <Integer>(); for (var v = 0; v < g.V; v++) { if (indegree[v] == 0) { queue.Enqueue(v); } } for (var j = 0; !queue.IsEmpty(); j++) { int v = queue.Dequeue(); _order.Enqueue(v); _rank[v] = count++; foreach (int w in g.Adj(v)) { indegree[w]--; if (indegree[w] == 0) { queue.Enqueue(w); } } } // there is a directed cycle in subgraph of vertices with indegree >= 1. if (count != g.V) { _order = null; } //assert check(G); }
/// <summary> /// run DFS in digraph G from vertex v and compute preorder/postorder /// </summary> /// <param name="g"></param> /// <param name="v"></param> private void Dfs(Digraph g, int v) { _marked[v] = true; _pre[v] = _preCounter++; _preorder.Enqueue(v); foreach (int w in g.Adj(v)) { if (!_marked[w]) { Dfs(g, w); } } _postorder.Enqueue(v); _post[v] = _postCounter++; }
/// <summary> /// Determines whether a digraph has an Eulerian path using necessary /// and sufficient conditions (without computing the path itself): /// - indegree(v) = outdegree(v) for every vertex, /// except one vertex v may have outdegree(v) = indegree(v) + 1 /// (and one vertex v may have indegree(v) = outdegree(v) + 1) /// - the graph is connected, when viewed as an undirected graph /// (ignoring isolated vertices) /// This method is solely for unit testing. /// </summary> /// <param name="g"></param> /// <returns></returns> private static bool HasEulerianPath(Digraph g) { if (g.E == 0) { return(true); } // Condition 1: indegree(v) == outdegree(v) for every vertex, // except one vertex may have outdegree(v) = indegree(v) + 1 var deficit = 0; for (var v = 0; v < g.V; v++) { if (g.Outdegree(v) > g.Indegree(v)) { deficit += (g.Outdegree(v) - g.Indegree(v)); } } if (deficit > 1) { return(false); } // Condition 2: graph is connected, ignoring isolated vertices var h = new Graph(g.V); for (var v = 0; v < g.V; v++) { foreach (int w in g.Adj(v)) { h.AddEdge(v, w); } } // check that all non-isolated vertices are connected var s = NonIsolatedVertex(g); var bfs = new BreadthFirstPaths(h, s); for (var v = 0; v < g.V; v++) { if (h.Degree(v) > 0 && !bfs.HasPathTo(v)) { return(false); } } return(true); }
/// <summary> /// Determines whether a digraph has an Eulerian cycle using necessary /// and sufficient conditions (without computing the cycle itself): /// - at least one edge /// - indegree(v) = outdegree(v) for every vertex /// - the graph is connected, when viewed as an undirected graph /// (ignoring isolated vertices) /// </summary> /// <param name="g"></param> /// <returns></returns> private static bool HasEulerianCycle(Digraph g) { // Condition 0: at least 1 edge if (g.E == 0) { return(false); } // Condition 1: indegree(v) == outdegree(v) for every vertex for (var v = 0; v < g.V; v++) { if (g.Outdegree(v) != g.Indegree(v)) { return(false); } } // Condition 2: graph is connected, ignoring isolated vertices var h = new Graph(g.V); for (var v = 0; v < g.V; v++) { foreach (int w in g.Adj(v)) { h.AddEdge(v, w); } } // check that all non-isolated vertices are conneted var s = NonIsolatedVertex(g); var bfs = new BreadthFirstPaths(h, s); for (var v = 0; v < g.V; v++) { if (h.Degree(v) > 0 && !bfs.HasPathTo(v)) { return(false); } } return(true); }
private readonly bool[] _marked; // marked[v] = is there an s->v path? /// <summary> /// Computes the vertices reachable from the source vertex <tt>s</tt> in the digraph <tt>G</tt>. /// </summary> /// <param name="g">g the digraph</param> /// <param name="s">s the source vertex</param> public NonrecursiveDirectedDFS(Digraph g, int s) { _marked = new bool[g.V]; // to be able to iterate over each adjacency list, keeping track of which // vertex in each adjacency list needs to be explored next var adj = new IEnumerator <Integer> [g.V]; for (var v = 0; v < g.V; v++) { adj[v] = g.Adj(v).GetEnumerator(); } // depth-first search using an explicit stack var stack = new Collections.Stack <Integer>(); _marked[s] = true; stack.Push(s); while (!stack.IsEmpty()) { int v = stack.Peek(); if (adj[v].MoveNext()) { int w = adj[v].Current; // StdOut.printf("check %d\n", w); if (!_marked[w]) { // discovered vertex w for the first time _marked[w] = true; // edgeTo[w] = v; stack.Push(w); // StdOut.printf("dfs(%d)\n", w); } } else { // StdOut.printf("%d done\n", v); stack.Pop(); } } }
private readonly int[] _rank; // rank[v] = order where vertex v appers in order #endregion Fields #region Constructors /// <summary> /// Determines whether the digraph <tt>G</tt> has a topological order and, if so, /// finds such a topological order. /// </summary> /// <param name="g">g the digraph</param> public TopologicalX(Digraph g) { // indegrees of remaining vertices var indegree = new int[g.V]; for (var v = 0; v < g.V; v++) { indegree[v] = g.Indegree(v); } // initialize _rank = new int[g.V]; _order = new Collections.Queue<Integer>(); var count = 0; // initialize queue to contain all vertices with indegree = 0 var queue = new Collections.Queue<Integer>(); for (var v = 0; v < g.V; v++) if (indegree[v] == 0) queue.Enqueue(v); for (var j = 0; !queue.IsEmpty(); j++) { int v = queue.Dequeue(); _order.Enqueue(v); _rank[v] = count++; foreach (int w in g.Adj(v)) { indegree[w]--; if (indegree[w] == 0) queue.Enqueue(w); } } // there is a directed cycle in subgraph of vertices with indegree >= 1. if (count != g.V) { _order = null; } //assert check(G); }
private readonly bool[] _marked; // marked[v] = is there an s->v path? #endregion Fields #region Constructors /// <summary> /// Computes the vertices reachable from the source vertex <tt>s</tt> in the digraph <tt>G</tt>. /// </summary> /// <param name="g">g the digraph</param> /// <param name="s">s the source vertex</param> public NonrecursiveDirectedDFS(Digraph g, int s) { _marked = new bool[g.V]; // to be able to iterate over each adjacency list, keeping track of which // vertex in each adjacency list needs to be explored next var adj = new IEnumerator<Integer>[g.V]; for (var v = 0; v < g.V; v++) adj[v] = g.Adj(v).GetEnumerator(); // depth-first search using an explicit stack var stack = new Collections.Stack<Integer>(); _marked[s] = true; stack.Push(s); while (!stack.IsEmpty()) { int v = stack.Peek(); if (adj[v].MoveNext()) { int w = adj[v].Current; // StdOut.printf("check %d\n", w); if (!_marked[w]) { // discovered vertex w for the first time _marked[w] = true; // edgeTo[w] = v; stack.Push(w); // StdOut.printf("dfs(%d)\n", w); } } else { // StdOut.printf("%d done\n", v); stack.Pop(); } } }
/// <summary> /// BFS from multiple sources /// </summary> /// <param name="g"></param> /// <param name="sources"></param> private void Bfs(Digraph g, IEnumerable<Integer> sources) { var q = new Collections.Queue<Integer>(); foreach (int s in sources) { _marked[s] = true; _distTo[s] = 0; q.Enqueue(s); } while (!q.IsEmpty()) { int v = q.Dequeue(); foreach (int w in g.Adj(v)) { if (!_marked[w]) { _edgeTo[w] = v; _distTo[w] = _distTo[v] + 1; _marked[w] = true; q.Enqueue(w); } } } }
/// <summary> /// Determines whether a digraph has an Eulerian path using necessary /// and sufficient conditions (without computing the path itself): /// - indegree(v) = outdegree(v) for every vertex, /// except one vertex v may have outdegree(v) = indegree(v) + 1 /// (and one vertex v may have indegree(v) = outdegree(v) + 1) /// - the graph is connected, when viewed as an undirected graph /// (ignoring isolated vertices) /// This method is solely for unit testing. /// </summary> /// <param name="g"></param> /// <returns></returns> private static bool HasEulerianPath(Digraph g) { if (g.E == 0) return true; // Condition 1: indegree(v) == outdegree(v) for every vertex, // except one vertex may have outdegree(v) = indegree(v) + 1 var deficit = 0; for (var v = 0; v < g.V; v++) if (g.Outdegree(v) > g.Indegree(v)) deficit += (g.Outdegree(v) - g.Indegree(v)); if (deficit > 1) return false; // Condition 2: graph is connected, ignoring isolated vertices var h = new Graph(g.V); for (var v = 0; v < g.V; v++) foreach (int w in g.Adj(v)) h.AddEdge(v, w); // check that all non-isolated vertices are connected var s = NonIsolatedVertex(g); var bfs = new BreadthFirstPaths(h, s); for (var v = 0; v < g.V; v++) if (h.Degree(v) > 0 && !bfs.HasPathTo(v)) return false; return true; }
private readonly Collections.Stack <Integer> _path; // Eulerian path; null if no suh path /// <summary> /// Computes an Eulerian path in the specified digraph, if one exists. /// </summary> /// <param name="g">g the digraph</param> public DirectedEulerianPath(Digraph g) { // find vertex from which to start potential Eulerian path: // a vertex v with outdegree(v) > indegree(v) if it exits; // otherwise a vertex with outdegree(v) > 0 var deficit = 0; var s = NonIsolatedVertex(g); for (var v = 0; v < g.V; v++) { if (g.Outdegree(v) > g.Indegree(v)) { deficit += (g.Outdegree(v) - g.Indegree(v)); s = v; } } // digraph can't have an Eulerian path // (this condition is needed) if (deficit > 1) { return; } // special case for digraph with zero edges (has a degenerate Eulerian path) if (s == -1) { s = 0; } // create local view of adjacency lists, to iterate one vertex at a time var adj = new IEnumerator <Integer> [g.V]; for (var v = 0; v < g.V; v++) { adj[v] = g.Adj(v).GetEnumerator(); } // greedily add to cycle, depth-first search style var stack = new Collections.Stack <Integer>(); stack.Push(s); _path = new Collections.Stack <Integer>(); while (!stack.IsEmpty()) { int v = stack.Pop(); while (adj[v].MoveNext()) { stack.Push(v); v = adj[v].Current; } // push vertex with no more available edges to path _path.Push(v); } // check if all edges have been used if (_path.Size() != g.E + 1) { _path = null; } //assert check(G); }
private void Dfs(Digraph g, int v) { _marked[v] = true; _preorder[v] = _pre++; _stack1.Push(v); _stack2.Push(v); foreach (int w in g.Adj(v)) { if (!_marked[w]) Dfs(g, w); else if (_id[w] == -1) { while (_preorder[_stack2.Peek()] > _preorder[w]) _stack2.Pop(); } } // found strong component containing v if (_stack2.Peek() == v) { _stack2.Pop(); int w; do { w = _stack1.Pop(); _id[w] = _count; } while (w != v); _count++; } }
/// <summary> /// check that algorithm computes either the topological order or finds a directed cycle /// </summary> /// <param name="g"></param> /// <param name="v"></param> private void Dfs(Digraph g, int v) { _onStack[v] = true; _marked[v] = true; foreach (int w in g.Adj(v)) { // short circuit if directed cycle found if (_cycle != null) return; //found new vertex, so recur if (!_marked[w]) { _edgeTo[w] = v; Dfs(g, w); } // trace back directed cycle else if (_onStack[w]) { _cycle = new Collections.Stack<Integer>(); for (var x = v; x != w; x = _edgeTo[x]) { _cycle.Push(x); } _cycle.Push(w); _cycle.Push(v); //assert check(); } } _onStack[v] = false; }
private readonly Collections.Stack<Integer> _cycle; // the directed cycle; null if digraph is acyclic #endregion Fields #region Constructors public DirectedCycleX(Digraph g) { // indegrees of remaining vertices var indegree = new int[g.V]; for (var v = 0; v < g.V; v++) { indegree[v] = g.Indegree(v); } // initialize queue to contain all vertices with indegree = 0 var queue = new Collections.Queue<Integer>(); for (var v = 0; v < g.V; v++) if (indegree[v] == 0) queue.Enqueue(v); for (var j = 0; !queue.IsEmpty(); j++) { int v = queue.Dequeue(); foreach (int w in g.Adj(v)) { indegree[w]--; if (indegree[w] == 0) queue.Enqueue(w); } } // there is a directed cycle in subgraph of vertices with indegree >= 1. var edgeTo = new int[g.V]; var root = -1; // any vertex with indegree >= -1 for (var v = 0; v < g.V; v++) { if (indegree[v] == 0) continue; root = v; foreach (int w in g.Adj(v)) { if (indegree[w] > 0) { edgeTo[w] = v; } } } if (root != -1) { // find any vertex on cycle var visited = new bool[g.V]; while (!visited[root]) { visited[root] = true; root = edgeTo[root]; } // extract cycle _cycle = new Collections.Stack<Integer>(); var v = root; do { _cycle.Push(v); v = edgeTo[v]; } while (v != root); _cycle.Push(root); } //assert check(); }
private void Dfs(Digraph g, int v) { _marked[v] = true; _low[v] = _pre++; var min = _low[v]; _stack.Push(v); foreach (int j in g.Adj(v)) { if (!_marked[j]) Dfs(g, j); if (_low[j] < min) min = _low[j]; } if (min < _low[v]) { _low[v] = min; return; } int w; do { w = _stack.Pop(); _id[w] = _count; _low[w] = g.V; } while (w != v); _count++; }
/// <summary> /// certify that digraph is acyclic /// </summary> /// <param name="g"></param> /// <returns></returns> public bool Check(Digraph g) { // digraph is acyclic if (HasOrder()) { // check that ranks are a permutation of 0 to V-1 var found = new bool[g.V]; for (var i = 0; i < g.V; i++) { found[Rank(i)] = true; } for (var i = 0; i < g.V; i++) { if (!found[i]) { Console.Error.WriteLine($"No vertex with rank {i}"); return false; } } // check that ranks provide a valid topological order for (var v = 0; v < g.V; v++) { foreach (int w in g.Adj(v)) { if (Rank(v) > Rank(w)) { Console.WriteLine($"{v}-{w}: rank({v}) = {Rank(v)}, rank({w}) = {Rank(w)}{Environment.NewLine}"); return false; } } } // check that order() is consistent with rank() var r = 0; foreach (int v in Order()) { if (Rank(v) != r) { Console.WriteLine("order() and rank() inconsistent"); return false; } r++; } } return true; }
private readonly Collections.Stack <Integer> _cycle; // the directed cycle; null if digraph is acyclic public DirectedCycleX(Digraph g) { // indegrees of remaining vertices var indegree = new int[g.V]; for (var v = 0; v < g.V; v++) { indegree[v] = g.Indegree(v); } // initialize queue to contain all vertices with indegree = 0 var queue = new Collections.Queue <Integer>(); for (var v = 0; v < g.V; v++) { if (indegree[v] == 0) { queue.Enqueue(v); } } for (var j = 0; !queue.IsEmpty(); j++) { int v = queue.Dequeue(); foreach (int w in g.Adj(v)) { indegree[w]--; if (indegree[w] == 0) { queue.Enqueue(w); } } } // there is a directed cycle in subgraph of vertices with indegree >= 1. var edgeTo = new int[g.V]; var root = -1; // any vertex with indegree >= -1 for (var v = 0; v < g.V; v++) { if (indegree[v] == 0) { continue; } root = v; foreach (int w in g.Adj(v)) { if (indegree[w] > 0) { edgeTo[w] = v; } } } if (root != -1) { // find any vertex on cycle var visited = new bool[g.V]; while (!visited[root]) { visited[root] = true; root = edgeTo[root]; } // extract cycle _cycle = new Collections.Stack <Integer>(); var v = root; do { _cycle.Push(v); v = edgeTo[v]; } while (v != root); _cycle.Push(root); } //assert check(); }