/// <summary> /// does this graph have two parallel edges? /// side effect: initialize cycle to be two parallel edges /// </summary> /// <param name="g"></param> /// <returns></returns> private bool HasParallelEdges(Graph g) { _marked = new bool[g.V]; for (var v = 0; v < g.V; v++) { // check for parallel edges incident to v foreach (int w in g.Adj(v)) { if (_marked[w]) { _cycle = new Collections.Stack <Integer>(); _cycle.Push(v); _cycle.Push(w); _cycle.Push(v); return(true); } _marked[w] = true; } // reset so marked[v] = false for all v foreach (int w in g.Adj(v)) { _marked[w] = false; } } return(false); }
/// <summary> /// breadth-first search from a single source /// </summary> /// <param name="g"></param> /// <param name="s"></param> private void Bfs(Graph g, int s) { var q = new Collections.Queue <Integer>(); for (var v = 0; v < g.V; v++) { _distTo[v] = INFINITY; } _distTo[s] = 0; _marked[s] = true; q.Enqueue(s); while (!q.IsEmpty()) { int v = q.Dequeue(); foreach (int w in g.Adj(v)) { if (_marked[w]) { continue; } _edgeTo[w] = v; _distTo[w] = _distTo[v] + 1; _marked[w] = true; q.Enqueue(w); } } }
private void Dfs(Graph g, int v) { _marked[v] = true; foreach (int w in g.Adj(v)) { // short circuit if odd-length cycle found if (_cycle != null) { return; } // found uncolored vertex, so recur if (!_marked[w]) { _edgeTo[w] = v; _color[w] = !_color[v]; Dfs(g, w); } // if v-w create an odd-length cycle, find it else if (_color[w] == _color[v]) { _isBipartite = false; _cycle = new Collections.Stack <Integer>(); _cycle.Push(w); // don't need this unless you want to include start vertex twice for (var x = v; x != w; x = _edgeTo[x]) { _cycle.Push(x); } _cycle.Push(w); } } }
private void Dfs(Graph g, int u, int v) { _marked[v] = true; foreach (int w in g.Adj(v)) { // short circuit if cycle already found if (_cycle != null) { return; } if (!_marked[w]) { _edgeTo[w] = v; Dfs(g, v, w); } // check for cycle (but disregard reverse of edge leading to v) else if (w != u) { _cycle = new Collections.Stack <Integer>(); for (var x = v; x != w; x = _edgeTo[x]) { _cycle.Push(x); } _cycle.Push(w); _cycle.Push(v); } } }
private void Dfs(Graph g, int u, int v) { _marked[v] = true; foreach (int w in g.Adj(v)) { // short circuit if cycle already found if (_cycle != null) return; if (!_marked[w]) { _edgeTo[w] = v; Dfs(g, v, w); } // check for cycle (but disregard reverse of edge leading to v) else if (w != u) { _cycle = new Collections.Stack<Integer>(); for (var x = v; x != w; x = _edgeTo[x]) { _cycle.Push(x); } _cycle.Push(w); _cycle.Push(v); } } }
/// <summary> /// breadth-first search from multiple sources /// </summary> /// <param name="g"></param> /// <param name="sources"></param> private void Bfs(Graph 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]) { continue; } _edgeTo[w] = v; _distTo[w] = _distTo[v] + 1; _marked[w] = true; q.Enqueue(w); } } }
/// <summary> /// depth first search from v /// </summary> /// <param name="g"></param> /// <param name="v"></param> private void Dfs(Graph g, int v) { _marked[v] = true; foreach (int w in g.Adj(v)) { if (_marked[w]) continue; _edgeTo[w] = v; Dfs(g, w); } }
/// <summary> /// check optimality conditions for single source /// </summary> /// <param name="g"></param> /// <param name="s"></param> /// <returns></returns> private bool Check(Graph g, int s) { // check that the distance of s = 0 if (_distTo[s] != 0) { Console.WriteLine("distance of source " + s + " to itself = " + _distTo[s]); return(false); } // check that for each edge v-w dist[w] <= dist[v] + 1 // provided v is reachable from s for (var v = 0; v < g.V; v++) { foreach (int w in g.Adj(v)) { if (HasPathTo(v) != HasPathTo(w)) { Console.WriteLine("edge " + v + "-" + w); Console.WriteLine("hasPathTo(" + v + ") = " + HasPathTo(v)); Console.WriteLine("hasPathTo(" + w + ") = " + HasPathTo(w)); return(false); } if (HasPathTo(v) && (_distTo[w] > _distTo[v] + 1)) { Console.WriteLine("edge " + v + "-" + w); Console.WriteLine("distTo[" + v + "] = " + _distTo[v]); Console.WriteLine("distTo[" + w + "] = " + _distTo[w]); return(false); } } } // check that v = edgeTo[w] satisfies distTo[w] + distTo[v] + 1 // provided v is reachable from s for (var w = 0; w < g.V; w++) { if (!HasPathTo(w) || w == s) { continue; } var v = _edgeTo[w]; if (_distTo[w] == _distTo[v] + 1) { continue; } Console.WriteLine("shortest path edge " + v + "-" + w); Console.WriteLine("distTo[" + v + "] = " + _distTo[v]); Console.WriteLine("distTo[" + w + "] = " + _distTo[w]); return(false); } return(true); }
/// <summary> /// depth first search from v /// </summary> /// <param name="g"></param> /// <param name="v"></param> private void Dfs(Graph g, int v) { _marked[v] = true; foreach (int w in g.Adj(v)) { if (_marked[w]) { continue; } _edgeTo[w] = v; Dfs(g, w); } }
private void Bfs(Graph g, int s) { var q = new Collections.Queue <Integer>(); _color[s] = WHITE; _marked[s] = true; q.Enqueue(s); while (!q.IsEmpty()) { int v = q.Dequeue(); foreach (int w in g.Adj(v)) { if (!_marked[w]) { _marked[w] = true; _edgeTo[w] = v; _color[w] = !_color[v]; q.Enqueue(w); } else if (_color[w] == _color[v]) { _isBipartite = false; // to form odd cycle, consider s-v path and s-w path // and let x be closest node to v and w common to two paths // then (w-x path) + (x-v path) + (edge v-w) is an odd-length cycle // Note: distTo[v] == distTo[w]; _cycle = new Collections.Queue <Integer>(); var stack = new Collections.Stack <Integer>(); int x = v, y = w; while (x != y) { stack.Push(x); _cycle.Enqueue(y); x = _edgeTo[x]; y = _edgeTo[y]; } stack.Push(x); while (!stack.IsEmpty()) { _cycle.Enqueue(stack.Pop()); } _cycle.Enqueue(w); return; } } } }
/// <summary> /// does this graph have a self loop? /// side effect: initialize cycle to be self loop /// </summary> /// <param name="g"></param> /// <returns></returns> private bool HasSelfLoop(Graph g) { for (var v = 0; v < g.V; v++) { foreach (int w in g.Adj(v)) { if (v != w) { continue; } _cycle = new Collections.Stack <Integer>(); _cycle.Push(v); _cycle.Push(v); return(true); } } return(false); }
private bool Check(Graph g) { // graph is bipartite if (_isBipartite) { for (var v = 0; v < g.V; v++) { foreach (int w in g.Adj(v)) { if (_color[v] != _color[w]) { continue; } Console.Error.WriteLine($"edge {v}-{w} with {v} and {w} in same side of bipartition\n"); return(false); } } } // graph has an odd-length cycle else { // verify cycle int first = -1, last = -1; foreach (int v in OddCycle()) { if (first == -1) { first = v; } last = v; } if (first == last) { return(true); } Console.Error.WriteLine($"cycle begins with {first} and ends with {last}{Environment.NewLine}"); return(false); } return(true); }
/// <summary> /// Computes the vertices connected to the source vertex <tt>s</tt> in the graph <tt>G</tt>. /// </summary> /// <param name="g">g the graph</param> /// <param name="s">s the source vertex</param> public NonrecursiveDFS(Graph 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> /// Computes the vertices connected to the source vertex <tt>s</tt> in the graph <tt>G</tt>. /// </summary> /// <param name="g">g the graph</param> /// <param name="s">s the source vertex</param> public NonrecursiveDFS(Graph 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> /// breadth-first search from a single source /// </summary> /// <param name="g"></param> /// <param name="s"></param> private void Bfs(Graph g, int s) { var q = new Collections.Queue<Integer>(); for (var v = 0; v < g.V; v++) _distTo[v] = INFINITY; _distTo[s] = 0; _marked[s] = true; q.Enqueue(s); while (!q.IsEmpty()) { int v = q.Dequeue(); foreach (int w in g.Adj(v)) { if (_marked[w]) continue; _edgeTo[w] = v; _distTo[w] = _distTo[v] + 1; _marked[w] = true; q.Enqueue(w); } } }
private readonly Collections.Stack <Integer> _path; // Eulerian path; null if no suh path /// <summary> /// Computes an Eulerian path in the specified graph, if one exists. /// </summary> /// <param name="g">g the graph</param> public EulerianPath(Graph g) { // find vertex from which to start potential Eulerian path: // a vertex v with odd degree(v) if it exits; // otherwise a vertex with degree(v) > 0 var oddDegreeVertices = 0; var s = NonIsolatedVertex(g); for (var v = 0; v < g.V; v++) { if (g.Degree(v) % 2 != 0) { oddDegreeVertices++; s = v; } } // graph can't have an Eulerian path // (this condition is needed for correctness) if (oddDegreeVertices > 2) { return; } // special case for graph 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 // the helper Edge data type is used to avoid exploring both copies of an edge v-w var adj = new Collections.Queue <EdgeW> [g.V]; for (var v = 0; v < g.V; v++) { adj[v] = new Collections.Queue <EdgeW>(); } for (var v = 0; v < g.V; v++) { var selfLoops = 0; foreach (int w in g.Adj(v)) { // careful with self loops if (v == w) { if (selfLoops % 2 == 0) { var e = new EdgeW(v, w, 0); adj[v].Enqueue(e); adj[w].Enqueue(e); } selfLoops++; } else if (v < w) { var e = new EdgeW(v, w, 0); adj[v].Enqueue(e); adj[w].Enqueue(e); } } } // initialize stack with any non-isolated vertex var stack = new Collections.Stack <Integer>(); stack.Push(s); // greedily search through edges in iterative DFS style _path = new Collections.Stack <Integer>(); while (!stack.IsEmpty()) { int v = stack.Pop(); while (!adj[v].IsEmpty()) { var edge = adj[v].Dequeue(); if (edge.IsUsed) { continue; } edge.IsUsed = true; stack.Push(v); v = edge.Other(v); } // push vertex with no more leaving edges to path _path.Push(v); } // check if all edges are used if (_path.Size() != g.E + 1) { _path = null; } //assert certifySolution(G); }
private readonly Collections.Stack<Integer> _cycle = new Collections.Stack<Integer>(); // Eulerian cycle; null if no such cycle #endregion Fields #region Constructors /// <summary> /// Computes an Eulerian cycle in the specified graph, if one exists. /// </summary> /// <param name="g">g the graph</param> public EulerianCycle(Graph g) { // must have at least one EdgeW if (g.E == 0) return; // necessary condition: all vertices have even degree // (this test is needed or it might find an Eulerian path instead of cycle) for (var v = 0; v < g.V; v++) if (g.Degree(v) % 2 != 0) return; // create local view of adjacency lists, to iterate one vertex at a time // the helper EdgeW data type is used to avoid exploring both copies of an EdgeW v-w var adj = new Collections.Queue<EdgeW>[g.V]; for (var v = 0; v < g.V; v++) adj[v] = new Collections.Queue<EdgeW>(); for (var v = 0; v < g.V; v++) { var selfLoops = 0; foreach (int w in g.Adj(v)) { // careful with self loops if (v == w) { if (selfLoops % 2 == 0) { var e = new EdgeW(v, w, 0); adj[v].Enqueue(e); adj[w].Enqueue(e); } selfLoops++; } else if (v < w) { var e = new EdgeW(v, w, 0); adj[v].Enqueue(e); adj[w].Enqueue(e); } } } // initialize Collections.Stack with any non-isolated vertex var s = NonIsolatedVertex(g); var stack = new Collections.Stack<Integer>(); stack.Push(s); // greedily search through EdgeWs in iterative DFS style _cycle = new Collections.Stack<Integer>(); while (!stack.IsEmpty()) { int v = stack.Pop(); while (!adj[v].IsEmpty()) { var edgeW = adj[v].Dequeue(); if (edgeW.IsUsed) continue; edgeW.IsUsed = true; stack.Push(v); v = edgeW.Other(v); } // push vertex with no more leaving EdgeWs to cycle _cycle.Push(v); } // check if all EdgeWs are used if (_cycle.Size() != g.E + 1) _cycle = null; //assert certifySolution(G); }
private void Dfs(Graph g, int v) { _marked[v] = true; foreach (int w in g.Adj(v)) { // short circuit if odd-length cycle found if (_cycle != null) return; // found uncolored vertex, so recur if (!_marked[w]) { _edgeTo[w] = v; _color[w] = !_color[v]; Dfs(g, w); } // if v-w create an odd-length cycle, find it else if (_color[w] == _color[v]) { _isBipartite = false; _cycle = new Collections.Stack<Integer>(); _cycle.Push(w); // don't need this unless you want to include start vertex twice for (var x = v; x != w; x = _edgeTo[x]) { _cycle.Push(x); } _cycle.Push(w); } } }
private bool Check(Graph g) { // graph is bipartite if (_isBipartite) { for (var v = 0; v < g.V; v++) { foreach (int w in g.Adj(v)) { if (_color[v] != _color[w]) continue; Console.Error.WriteLine($"edge {v}-{w} with {v} and {w} in same side of bipartition\n"); return false; } } } // graph has an odd-length cycle else { // verify cycle int first = -1, last = -1; foreach (int v in OddCycle()) { if (first == -1) first = v; last = v; } if (first == last) return true; Console.Error.WriteLine($"cycle begins with {first} and ends with {last}{Environment.NewLine}"); return false; } return true; }
/// <summary> /// breadth-first search from multiple sources /// </summary> /// <param name="g"></param> /// <param name="sources"></param> private void Bfs(Graph 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]) continue; _edgeTo[w] = v; _distTo[w] = _distTo[v] + 1; _marked[w] = true; q.Enqueue(w); } } }
private void Bfs(Graph g, int s) { var q = new Collections.Queue<Integer>(); _color[s] = WHITE; _marked[s] = true; q.Enqueue(s); while (!q.IsEmpty()) { int v = q.Dequeue(); foreach (int w in g.Adj(v)) { if (!_marked[w]) { _marked[w] = true; _edgeTo[w] = v; _color[w] = !_color[v]; q.Enqueue(w); } else if (_color[w] == _color[v]) { _isBipartite = false; // to form odd cycle, consider s-v path and s-w path // and let x be closest node to v and w common to two paths // then (w-x path) + (x-v path) + (edge v-w) is an odd-length cycle // Note: distTo[v] == distTo[w]; _cycle = new Collections.Queue<Integer>(); var stack = new Collections.Stack<Integer>(); int x = v, y = w; while (x != y) { stack.Push(x); _cycle.Enqueue(y); x = _edgeTo[x]; y = _edgeTo[y]; } stack.Push(x); while (!stack.IsEmpty()) _cycle.Enqueue(stack.Pop()); _cycle.Enqueue(w); return; } } } }
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 graph, if one exists. /// </summary> /// <param name="g">g the graph</param> public EulerianPath(Graph g) { // find vertex from which to start potential Eulerian path: // a vertex v with odd degree(v) if it exits; // otherwise a vertex with degree(v) > 0 var oddDegreeVertices = 0; var s = NonIsolatedVertex(g); for (var v = 0; v < g.V; v++) { if (g.Degree(v) % 2 != 0) { oddDegreeVertices++; s = v; } } // graph can't have an Eulerian path // (this condition is needed for correctness) if (oddDegreeVertices > 2) return; // special case for graph 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 // the helper Edge data type is used to avoid exploring both copies of an edge v-w var adj = new Collections.Queue<EdgeW>[g.V]; for (var v = 0; v < g.V; v++) adj[v] = new Collections.Queue<EdgeW>(); for (var v = 0; v < g.V; v++) { var selfLoops = 0; foreach (int w in g.Adj(v)) { // careful with self loops if (v == w) { if (selfLoops % 2 == 0) { var e = new EdgeW(v, w, 0); adj[v].Enqueue(e); adj[w].Enqueue(e); } selfLoops++; } else if (v < w) { var e = new EdgeW(v, w, 0); adj[v].Enqueue(e); adj[w].Enqueue(e); } } } // initialize stack with any non-isolated vertex var stack = new Collections.Stack<Integer>(); stack.Push(s); // greedily search through edges in iterative DFS style _path = new Collections.Stack<Integer>(); while (!stack.IsEmpty()) { int v = stack.Pop(); while (!adj[v].IsEmpty()) { var edge = adj[v].Dequeue(); if (edge.IsUsed) continue; edge.IsUsed = true; stack.Push(v); v = edge.Other(v); } // push vertex with no more leaving edges to path _path.Push(v); } // check if all edges are used if (_path.Size() != g.E + 1) _path = null; //assert certifySolution(G); }
/// <summary> /// does this graph have a self loop? /// side effect: initialize cycle to be self loop /// </summary> /// <param name="g"></param> /// <returns></returns> private bool HasSelfLoop(Graph g) { for (var v = 0; v < g.V; v++) { foreach (int w in g.Adj(v)) { if (v != w) continue; _cycle = new Collections.Stack<Integer>(); _cycle.Push(v); _cycle.Push(v); return true; } } return false; }
private readonly Collections.Stack <Integer> _cycle = new Collections.Stack <Integer>(); // Eulerian cycle; null if no such cycle /// <summary> /// Computes an Eulerian cycle in the specified graph, if one exists. /// </summary> /// <param name="g">g the graph</param> public EulerianCycle(Graph g) { // must have at least one EdgeW if (g.E == 0) { return; } // necessary condition: all vertices have even degree // (this test is needed or it might find an Eulerian path instead of cycle) for (var v = 0; v < g.V; v++) { if (g.Degree(v) % 2 != 0) { return; } } // create local view of adjacency lists, to iterate one vertex at a time // the helper EdgeW data type is used to avoid exploring both copies of an EdgeW v-w var adj = new Collections.Queue <EdgeW> [g.V]; for (var v = 0; v < g.V; v++) { adj[v] = new Collections.Queue <EdgeW>(); } for (var v = 0; v < g.V; v++) { var selfLoops = 0; foreach (int w in g.Adj(v)) { // careful with self loops if (v == w) { if (selfLoops % 2 == 0) { var e = new EdgeW(v, w, 0); adj[v].Enqueue(e); adj[w].Enqueue(e); } selfLoops++; } else if (v < w) { var e = new EdgeW(v, w, 0); adj[v].Enqueue(e); adj[w].Enqueue(e); } } } // initialize Collections.Stack with any non-isolated vertex var s = NonIsolatedVertex(g); var stack = new Collections.Stack <Integer>(); stack.Push(s); // greedily search through EdgeWs in iterative DFS style _cycle = new Collections.Stack <Integer>(); while (!stack.IsEmpty()) { int v = stack.Pop(); while (!adj[v].IsEmpty()) { var edgeW = adj[v].Dequeue(); if (edgeW.IsUsed) { continue; } edgeW.IsUsed = true; stack.Push(v); v = edgeW.Other(v); } // push vertex with no more leaving EdgeWs to cycle _cycle.Push(v); } // check if all EdgeWs are used if (_cycle.Size() != g.E + 1) { _cycle = null; } //assert certifySolution(G); }
/// <summary> /// check optimality conditions for single source /// </summary> /// <param name="g"></param> /// <param name="s"></param> /// <returns></returns> private bool Check(Graph g, int s) { // check that the distance of s = 0 if (_distTo[s] != 0) { Console.WriteLine("distance of source " + s + " to itself = " + _distTo[s]); return false; } // check that for each edge v-w dist[w] <= dist[v] + 1 // provided v is reachable from s for (var v = 0; v < g.V; v++) { foreach (int w in g.Adj(v)) { if (HasPathTo(v) != HasPathTo(w)) { Console.WriteLine("edge " + v + "-" + w); Console.WriteLine("hasPathTo(" + v + ") = " + HasPathTo(v)); Console.WriteLine("hasPathTo(" + w + ") = " + HasPathTo(w)); return false; } if (HasPathTo(v) && (_distTo[w] > _distTo[v] + 1)) { Console.WriteLine("edge " + v + "-" + w); Console.WriteLine("distTo[" + v + "] = " + _distTo[v]); Console.WriteLine("distTo[" + w + "] = " + _distTo[w]); return false; } } } // check that v = edgeTo[w] satisfies distTo[w] + distTo[v] + 1 // provided v is reachable from s for (var w = 0; w < g.V; w++) { if (!HasPathTo(w) || w == s) continue; var v = _edgeTo[w]; if (_distTo[w] == _distTo[v] + 1) continue; Console.WriteLine("shortest path edge " + v + "-" + w); Console.WriteLine("distTo[" + v + "] = " + _distTo[v]); Console.WriteLine("distTo[" + w + "] = " + _distTo[w]); return false; } return true; }
/// <summary> /// does this graph have two parallel edges? /// side effect: initialize cycle to be two parallel edges /// </summary> /// <param name="g"></param> /// <returns></returns> private bool HasParallelEdges(Graph g) { _marked = new bool[g.V]; for (var v = 0; v < g.V; v++) { // check for parallel edges incident to v foreach (int w in g.Adj(v)) { if (_marked[w]) { _cycle = new Collections.Stack<Integer>(); _cycle.Push(v); _cycle.Push(w); _cycle.Push(v); return true; } _marked[w] = true; } // reset so marked[v] = false for all v foreach (int w in g.Adj(v)) { _marked[w] = false; } } return false; }