// breadth-first search from multiple sources private void bfs(Graph G, IEnumerable <int> sources) { LinkedQueue <int> q = new LinkedQueue <int>(); 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); } } } }
// is there an augmenting path? // if so, upon termination edgeTo[] will contain a parent-link representation of such a path // this implementation finds a shortest augmenting path (fewest number of edges), // which performs well both in theory and in practice private bool hasAugmentingPath(FlowNetwork G, int s, int t) { edgeTo = new FlowEdge[G.V]; marked = new bool[G.V]; // breadth-first search LinkedQueue <int> queue = new LinkedQueue <int>(); queue.Enqueue(s); marked[s] = true; while (!queue.IsEmpty && !marked[t]) { int v = queue.Dequeue(); foreach (FlowEdge e in G.Adj(v)) { int w = e.Other(v); // if residual capacity from v to w if (e.ResidualCapacityTo(w) > 0) { if (!marked[w]) { edgeTo[w] = e; marked[w] = true; queue.Enqueue(w); } } } } // is there an augmenting path? return(marked[t]); }
/// <summary> /// Returns all keys in this symbol table in the given range, /// as an <c>IEnumerable</c>.</summary> /// <returns>all keys in this symbol table between <c>lo</c> /// (inclusive) and <c>hi</c> (exclusive)</returns> /// <param name="lo">lower bound key</param> /// <param name="hi">upper bound key</param> /// <exception cref="ArgumentNullException">if either <c>lo</c> or <c>hi</c> /// is <c>null</c></exception> /// public IEnumerable <Key> Keys(Key lo, Key hi) { if (lo == null) { throw new ArgumentNullException("first argument to Count is null"); } if (hi == null) { throw new ArgumentNullException("second argument to Count is null"); } LinkedQueue <Key> queue = new LinkedQueue <Key>(); if (lo == null) { throw new ArgumentNullException("lo is null in keys()"); } if (hi == null) { throw new ArgumentNullException("hi is null in keys()"); } if (lo.CompareTo(hi) > 0) { return(queue); } for (int i = Rank(lo); i < Rank(hi); i++) { queue.Enqueue(keys[i]); } if (Contains(hi)) { queue.Enqueue(keys[Rank(hi)]); } return(queue); }
// breadth-first search from a single source private void bfs(Graph G, int s) { LinkedQueue <int> q = new LinkedQueue <int>(); for (int 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]) { edgeTo[w] = v; distTo[w] = distTo[v] + 1; marked[w] = true; q.Enqueue(w); } } } }
// is there an augmenting path? // an alternating path is a path whose edges belong alternately to the matching and not to the matchign // an augmenting path is an alternating path that starts and ends at unmatched vertices // // if so, upon termination adj[] contains the level graph; // if not, upon termination marked[] specifies those vertices reachable via an alternating path // from one side of the bipartition private bool hasAugmentingPath(Graph G) { // shortest path distances marked = new bool[V]; distTo = new int[V]; for (int v = 0; v < V; v++) { distTo[v] = int.MaxValue; } // breadth-first search (starting from all unmatched vertices on one side of bipartition) LinkedQueue <int> queue = new LinkedQueue <int>(); for (int v = 0; v < V; v++) { if (bipartition.Color(v) && !IsMatched(v)) { queue.Enqueue(v); marked[v] = true; distTo[v] = 0; } } // run BFS until an augmenting path is found // (and keep going until all vertices at that distance are explored) bool hasAugmentingPath = false; while (!queue.IsEmpty) { int v = queue.Dequeue(); foreach (int w in G.Adj(v)) { // forward edge not in matching or backwards edge in matching if (isResidualGraphEdge(v, w)) { if (!marked[w]) { distTo[w] = distTo[v] + 1; marked[w] = true; if (!IsMatched(w)) { hasAugmentingPath = true; } // stop enqueuing vertices once an alternating path has been discovered // (no vertex on same side will be marked if its shortest path distance longer) if (!hasAugmentingPath) { queue.Enqueue(w); } } } } } return(hasAugmentingPath); }
private void bfs(Graph G, int s) { LinkedQueue <int> q = new LinkedQueue <int>(); 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 LinkedQueue <int>(); LinkedStack <int> stack = new LinkedStack <int>(); 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> /// Determines whether the edge-weighted digraph <c>G</c> has a /// topological order and, if so, finds such a topological order.</summary> /// <param name="G">the digraph</param> /// public TopologicalX(EdgeWeightedDigraph G) { // indegrees of remaining vertices int[] indegree = new int[G.V]; for (int v = 0; v < G.V; v++) { indegree[v] = G.Indegree(v); } // initialize rank = new int[G.V]; order = new LinkedQueue <int>(); int count = 0; // initialize queue to contain all vertices with indegree = 0 LinkedQueue <int> queue = new LinkedQueue <int>(); for (int v = 0; v < G.V; v++) { if (indegree[v] == 0) { queue.Enqueue(v); } } for (int j = 0; !queue.IsEmpty; j++) { int v = queue.Dequeue(); order.Enqueue(v); rank[v] = count++; foreach (DirectedEdge e in G.Adj(v)) { int w = e.To; 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; } Debug.Assert(check(G)); }
// run DFS in digraph G from vertex v and compute preorder/postorder 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++; }
private void collect(Node x, StringBuilder prefix, string pattern, LinkedQueue <string> results) { if (x == null) { return; } int d = prefix.Length; if (d == pattern.Length && x.Value != null) { results.Enqueue(prefix.ToString()); } if (d == pattern.Length) { return; } char c = pattern[d]; if (c == '.') { for (int i = 0; i < R; i++) { prefix.Append(alphabet.ToChar(i)); collect(x[i], prefix, pattern, results); prefix.Remove(prefix.Length - 1, 1); } } else { prefix.Append(c); collect(x[alphabet.ToIndex(c)], prefix, pattern, results); prefix.Remove(prefix.Length - 1, 1); } }
// relax vertex v and put other endpoints on queue if changed private void relax(EdgeWeightedDigraph G, int v) { foreach (DirectedEdge e in G.Adj(v)) { int w = e.To; if (distTo[w] > distTo[v] + e.Weight) { distTo[w] = distTo[v] + e.Weight; edgeTo[w] = e; if (!onQueue[w]) { queue.Enqueue(w); onQueue[w] = true; } } if (cost++ % G.V == 0) { findNegativeCycle(); if (HasNegativeCycle) { return; // found a negative cycle } } } }
private LinkedQueue <Edge> mst = new LinkedQueue <Edge>(); // edges in MST /// <summary> /// Compute a minimum spanning tree (or forest) of an edge-weighted graph.</summary> /// <param name="G">the edge-weighted graph</param> /// public KruskalMST(EdgeWeightedGraph G) { // more efficient to build heap by passing array of edges MinPQ <Edge> pq = new MinPQ <Edge>(); foreach (Edge e in G.Edges()) { pq.Insert(e); } // run greedy algorithm UF uf = new UF(G.V); while (!pq.IsEmpty && mst.Count < G.V - 1) { Edge e = pq.DelMin(); int v = e.Either; int w = e.Other(v); if (!uf.Connected(v, w)) { // v-w does not create a cycle uf.Union(v, w); // merge v and w components mst.Enqueue(e); // add edge e to mst weight += e.Weight; } } // check optimality conditions Debug.Assert(check(G)); }
private void collect(Node x, StringBuilder prefix, int i, string pattern, LinkedQueue <string> queue) { if (x == null) { return; } char c = pattern[i]; if (c == '.' || c < x.c) { collect(x.left, prefix, i, pattern, queue); } if (c == '.' || c == x.c) { if (i == pattern.Length - 1 && x.val != null) { queue.Enqueue(prefix.ToString() + x.c); } if (i < pattern.Length - 1) { collect(x.mid, prefix.Append(x.c), i + 1, pattern, queue); prefix.Remove(prefix.Length - 1, 1); } } if (c == '.' || c > x.c) { collect(x.right, prefix, i, pattern, queue); } }
// is there an augmenting path? // an alternating path is a path whose edges belong alternately to the matching and not to the matching // an augmenting path is an alternating path that starts and ends at unmatched vertices // // if so, upon termination edgeTo[] contains a parent-link representation of such a path // if not, upon terminatation marked[] specifies the subset of vertices reachable via an alternating // path from one side of the bipartition // // this implementation finds a shortest augmenting path (fewest number of edges), though there // is no particular advantage to do so here private bool hasAugmentingPath(Graph G) { marked = new bool[numVertices]; edgeTo = new int[numVertices]; for (int v = 0; v < numVertices; v++) { edgeTo[v] = -1; } // breadth-first search (starting from all unmatched vertices on one side of bipartition) LinkedQueue <int> queue = new LinkedQueue <int>(); for (int v = 0; v < numVertices; v++) { if (bipartition.Color(v) && !IsMatched(v)) { queue.Enqueue(v); marked[v] = true; } } // run BFS, stopping as soon as an alternating path is found while (!queue.IsEmpty) { int v = queue.Dequeue(); foreach (int w in G.Adj(v)) { // either (1) forward edge not in matching or (2) backward edge in matching if (isResidualGraphEdge(v, w)) { if (!marked[w]) { edgeTo[w] = v; marked[w] = true; if (!IsMatched(w)) { return(true); } queue.Enqueue(w); } } } } return(false); }
/// <summary> /// Returns all keys in the symbol table as an <c>Iterable</c>. /// To iterate over all of the keys in the symbol table named <c>st</c>, /// use the foreach notation: <c>foreach (Key key in st.Keys())</c>.</summary> /// <returns>all keys in the sybol table</returns> /// public IEnumerable <Key> Keys() { LinkedQueue <Key> queue = new LinkedQueue <Key>(); for (Node x = first; x != null; x = x.next) { queue.Enqueue(x.key); } return(queue); }
/// <summary> /// Returns the keys in the BST in level order (for debugging).</summary> /// <returns>the keys in the BST in level order traversal</returns> /// public IEnumerable <Key> LevelOrder() { LinkedQueue <Key> keys = new LinkedQueue <Key>(); LinkedQueue <Node> queue = new LinkedQueue <Node>(); queue.Enqueue(root); while (!queue.IsEmpty) { Node x = queue.Dequeue(); if (x == null) { continue; } keys.Enqueue(x.key); queue.Enqueue(x.left); queue.Enqueue(x.right); } return(keys); }
/// <summary> /// Returns all keys in this symbol table as an <c>Iterable</c>. /// To iterate over all of the keys in the symbol table named <c>st</c>, /// use the foreach notation: <c>foreach (Key key in st.Keys())</c>.</summary> /// <returns>all keys in this sybol table</returns> /// public IEnumerable <Key> Keys() { LinkedQueue <Key> queue = new LinkedQueue <Key>(); for (int i = 0; i < M; i++) { if (keys[i] != null) { queue.Enqueue((Key)keys[i]); } } return(queue); }
/// <summary> /// Returns all keys in the symbol table as an <c>IEnumerable</c>. /// To iterate over all of the keys in the symbol table named <c>st</c>, /// use the foreach notation: <c>foreach (Key key in st.Keys())</c>.</summary> /// <returns>all keys in the sybol table as an <c>IEnumerable</c></returns> /// public IEnumerable <Key> Keys() { LinkedQueue <Key> queue = new LinkedQueue <Key>(); for (int i = 0; i < M; i++) { foreach (Key key in st[i].Keys()) { queue.Enqueue(key); } } return(queue); }
/// <summary> /// Returns the edges in a minimum spanning tree (or forest).</summary> /// <returns>the edges in a minimum spanning tree (or forest) as /// an iterable of edges</returns> /// public IEnumerable <Edge> Edges() { LinkedQueue <Edge> mst = new LinkedQueue <Edge>(); for (int v = 0; v < edgeTo.Length; v++) { Edge e = edgeTo[v]; if (e != null) { mst.Enqueue(e); } } return(mst); }
// all keys in subtrie rooted at x with given prefix private void collect(Node x, StringBuilder prefix, LinkedQueue <string> queue) { if (x == null) { return; } collect(x.left, prefix, queue); if (x.val != null) { queue.Enqueue(prefix.ToString() + x.c); } collect(x.mid, prefix.Append(x.c), queue); prefix.Remove(prefix.Length - 1, 1); collect(x.right, prefix, queue); }
/// <summary> /// Returns all of the keys in the set that start with <c>prefix</c>.</summary> /// <param name="prefix">the prefix</param> /// <returns>all of the keys in the set that start with <c>prefix</c> /// as an iterable</returns> /// public IEnumerable <string> KeysWithPrefix(string prefix) { LinkedQueue <string> queue = new LinkedQueue <string>(); Node x = get(root, prefix, 0); if (x == null) { return(queue); } if (x.val != null) { queue.Enqueue(prefix); } collect(x.mid, new StringBuilder(prefix), queue); return(queue); }
private void collect(Node x, StringBuilder prefix, LinkedQueue <string> results) { if (x == null) { return; } if (x.Value != null) { results.Enqueue(prefix.ToString()); } for (int i = 0; i < R; i++) { prefix.Append(alphabet.ToChar(i)); collect(x[i], prefix, results); prefix.Remove(prefix.Length - 1, 1); } }
public static void MainTest(string[] args) { LinkedQueue <string> q = new LinkedQueue <string>(); TextInput StdIn = new TextInput(); while (!StdIn.IsEmpty) { string item = StdIn.ReadString(); if (!item.Equals("-")) { q.Enqueue(item); } else if (!q.IsEmpty) { Console.Write(q.Dequeue() + " "); } } Console.WriteLine("(" + q.Count + " left on queue)"); }
// add the keys between lo and hi in the subtree rooted at x // to the queue private void keys(Node x, LinkedQueue <Key> queue, Key lo, Key hi) { if (x == null) { return; } int cmplo = lo.CompareTo(x.key); int cmphi = hi.CompareTo(x.key); if (cmplo < 0) { keys(x.left, queue, lo, hi); } if (cmplo <= 0 && cmphi >= 0) { queue.Enqueue(x.key); } if (cmphi > 0) { keys(x.right, queue, lo, hi); } }
private IEnumerable <DirectedEdge> cycle; // negative cycle (or null if no such cycle) /// <summary>Computes a shortest paths tree from <c>s</c> to every other vertex in /// the edge-weighted digraph <c>G</c>.</summary> /// <param name="G">the acyclic digraph</param> /// <param name="s">the source vertex</param> /// <exception cref="ArgumentException">unless 0 <= <c>s</c> <= <c>V</c> - 1</exception> /// public BellmanFordSP(EdgeWeightedDigraph G, int s) { distTo = new double[G.V]; edgeTo = new DirectedEdge[G.V]; onQueue = new bool[G.V]; for (int v = 0; v < G.V; v++) { distTo[v] = double.PositiveInfinity; } distTo[s] = 0.0; // Bellman-Ford algorithm queue = new LinkedQueue <int>(); queue.Enqueue(s); onQueue[s] = true; while (!queue.IsEmpty && !HasNegativeCycle) { int v = queue.Dequeue(); onQueue[v] = false; relax(G, v); } Debug.Assert(check(G, s)); }
// run Prim's algorithm private void prim(EdgeWeightedGraph G, int s) { scan(G, s); while (!pq.IsEmpty) { // better to stop when mst has V-1 edges Edge e = pq.DelMin(); // smallest edge on pq int v = e.Either, w = e.Other(v); // two endpoints Debug.Assert(marked[v] || marked[w]); if (marked[v] && marked[w]) { continue; // lazy, both v and w already scanned } mst.Enqueue(e); // add e to MST weight += e.Weight; if (!marked[v]) { scan(G, v); // v becomes part of tree } if (!marked[w]) { scan(G, w); // w becomes part of tree } } }
private LinkedStack <int> cycle; // the directed cycle; null if digraph is acyclic /// <summary> /// Determines whether the digraph <c>G</c> has a directed cycle and, if so, /// finds such a cycle.</summary> /// <param name="G">the digraph</param> /// public DirectedCycleX(Digraph G) { // indegrees of remaining vertices int[] indegree = new int[G.V]; for (int v = 0; v < G.V; v++) { indegree[v] = G.Indegree(v); } // initialize queue to contain all vertices with indegree = 0 LinkedQueue <int> queue = new LinkedQueue <int>(); for (int v = 0; v < G.V; v++) { if (indegree[v] == 0) { queue.Enqueue(v); } } for (int 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. int[] edgeTo = new int[G.V]; int root = -1; // any vertex with indegree >= -1 for (int v = 0; v < G.V; v++) { if (indegree[v] == 0) { continue; } else { root = v; } foreach (int w in G.Adj(v)) { if (indegree[w] > 0) { edgeTo[w] = v; } } } if (root != -1) { // find any vertex on cycle bool[] visited = new bool[G.V]; while (!visited[root]) { visited[root] = true; root = edgeTo[root]; } // extract cycle cycle = new LinkedStack <int>(); int v = root; do { cycle.Push(v); v = edgeTo[v]; } while (v != root); cycle.Push(root); } Debug.Assert(check()); }