private IEnumerable<DirectedEdge> _cycle; // negative cycle (or null if no such cycle) #endregion Fields #region Constructors /// <summary> /// Computes a shortest paths tree from <tt>s</tt> to every other vertex in /// the edge-weighted digraph <tt>G</tt>. /// </summary> /// <param name="g">g the acyclic digraph</param> /// <param name="s">s the source vertex</param> /// <exception cref="ArgumentException">unless 0 le; <tt>s</tt> le; <tt>V</tt> - 1</exception> public BellmanFordSP(EdgeWeightedDigraph g, int s) { _distTo = new double[g.V]; _edgeTo = new DirectedEdge[g.V]; _onQueue = new bool[g.V]; for (var v = 0; v < g.V; v++) _distTo[v] = double.PositiveInfinity; _distTo[s] = 0.0; // Bellman-Ford algorithm _queue = new Collections.Queue<Integer>(); _queue.Enqueue(s); _onQueue[s] = true; while (!_queue.IsEmpty() && !HasNegativeCycle()) { int v = _queue.Dequeue(); _onQueue[v] = false; Relax(g, v); } }
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); }
/// <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> /// 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 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> _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(); }