private int M; // number of characters in regular expression /// <summary>Initializes the NFA from the specified regular expression.</summary> /// <param name="regexp">the regular expression</param> /// <exception cref="ArgumentException">if the regular expression is invalid</exception> /// public NFA(string regexp) { this.regexp = regexp; M = regexp.Length; LinkedStack <int> ops = new LinkedStack <int>(); G = new Digraph(M + 1); for (int i = 0; i < M; i++) { int lp = i; if (regexp[i] == '(' || regexp[i] == '|') { ops.Push(i); } else if (regexp[i] == ')') { int or = ops.Pop(); // 2-way or operator if (regexp[or] == '|') { lp = ops.Pop(); G.AddEdge(lp, or + 1); G.AddEdge(or, i); } else if (regexp[or] == '(') { lp = or; } else { Debug.Assert(false); } } // closure operator (uses 1-character lookahead) if (i < M - 1 && regexp[i + 1] == '*') { G.AddEdge(lp, i + 1); G.AddEdge(i + 1, lp); } if (regexp[i] == '(' || regexp[i] == '*' || regexp[i] == ')') { G.AddEdge(i, i + 1); } } if (ops.Count != 0) { throw new ArgumentException("Invalid regular expression"); } }
private void dfs(Digraph G, int v) { marked[v] = true; low[v] = pre++; int min = low[v]; stack.Push(v); foreach (int w in G.Adj(v)) { if (!marked[w]) { dfs(G, w); } if (low[w] < min) { min = low[w]; } } if (min < low[v]) { low[v] = min; return; } int u; do { u = stack.Pop(); id[u] = count; low[u] = G.V; } while (u != 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 LinkedStack <int> cycle = null; // Eulerian cycle; null if no such cylce /// <summary> /// Computes an Eulerian cycle in the specified digraph, if one exists. /// </summary> /// <param name="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 (int 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 IEnumerator <int>[] adj = new IEnumerator <int> [G.V]; for (int v = 0; v < G.V; v++) { adj[v] = G.Adj(v).GetEnumerator(); } // initialize stack with any non-isolated vertex int s = nonIsolatedVertex(G); LinkedStack <int> stack = new LinkedStack <int>(); stack.Push(s); // greedily add to putative cycle, depth-first search style cycle = new LinkedStack <int>(); 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.Count != G.E + 1) { cycle = null; } Debug.Assert(certifySolution(G)); }
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; } } } }
private readonly int s; // source vertex /// <summary> /// Computes the vertices connected to the source vertex <c>s</c> in the graph <c>G</c>.</summary> /// <param name="G">the graph</param> /// <param name="s">the source vertex</param> /// public NonrecursiveDFS(Graph G, int s) { this.s = s; marked = new bool[G.V]; edgeTo = new int[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 IEnumerator <int>[] adj = new IEnumerator <int> [G.V]; for (int v = 0; v < G.V; v++) { adj[v] = G.Adj(v).GetEnumerator(); } // depth-first search using an explicit stack LinkedStack <int> stack = new LinkedStack <int>(); marked[s] = true; stack.Push(s); //Console.Write("Visiting ({0})\n", s); while (!stack.IsEmpty) { int v = stack.Peek(); if (adj[v].MoveNext()) { int w = adj[v].Current; //Console.Write("Approaching {0}\n", w); if (!marked[w]) { // discovered vertex w for the first time marked[w] = true; edgeTo[w] = v; stack.Push(w); //Console.Write("Visiting ({0})\n", w); } //else // Console.Write("Visited {0}\n", w); } else { //Console.Write("Returning from {0}\n", stack.Peek()); stack.Pop(); } } }
public static void MainTest(string[] args) { LinkedStack <string> s = new LinkedStack <string>(); TextInput StdIn = new TextInput(); while (!StdIn.IsEmpty) { string item = StdIn.ReadString(); if (!item.Equals("-")) { s.Push(item); } else if (!s.IsEmpty) { Console.Write(s.Pop() + " "); } } Console.WriteLine("(" + s.Count + " left on stack)"); }
private bool[] marked; // marked[v] = is there an s->v path? /// <summary> /// Computes the vertices reachable from the source vertex <c>s</c> in the /// digraph <c>G</c>.</summary> /// <param name="G">the digraph</param> /// <param name="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 IEnumerator <int>[] adj = new IEnumerator <int> [G.V]; for (int v = 0; v < G.V; v++) { adj[v] = G.Adj(v).GetEnumerator(); } // depth-first search using an explicit stack LinkedStack <int> stack = new LinkedStack <int>(); marked[s] = true; stack.Push(s); while (!stack.IsEmpty) { int v = stack.Peek(); if (adj[v].MoveNext()) { int w = adj[v].Current; // Console.Write("check {0}\n", w); if (!marked[w]) { // discovered vertex w for the first time marked[w] = true; // edgeTo[w] = v; stack.Push(w); // Console.Write("dfs({0})\n", w); } } else { // Console.Write("{0} done\n", v); stack.Pop(); } } }
/// <summary> /// Computes the convex hull of the specified array of points. /// </summary> /// <param name="pts">the array of points</param> /// <exception cref="NullReferenceException">if <c>points</c> is <c>null</c> or if any /// entry in <c>points[]</c> is <c>null</c></exception> /// public GrahamScan(Point2D[] pts) { // defensive copy int N = pts.Length; Point2D[] points = new Point2D[N]; for (int i = 0; i < N; i++) { points[i] = pts[i]; } // preprocess so that points[0] has lowest y-coordinate; break ties by x-coordinate // points[0] is an extreme point of the convex hull // (alternatively, could do easily in linear time) Array.Sort(points); // sort by polar angle with respect to base point points[0], // breaking ties by distance to points[0] Array.Sort(points, 1, N - 1, points[0].GetPolarOrder()); hull.Push(points[0]); // p[0] is first extreme point // find index k1 of first point not equal to points[0] int k1; for (k1 = 1; k1 < N; k1++) { if (!points[0].Equals(points[k1])) { break; } } if (k1 == N) { return; // all points equal } // find index k2 of first point not collinear with points[0] and points[k1] int k2; for (k2 = k1 + 1; k2 < N; k2++) { if (Point2D.Ccw(points[0], points[k1], points[k2]) != 0) { break; } } hull.Push(points[k2 - 1]); // points[k2-1] is second extreme point // Graham scan; note that points[N-1] is extreme point different from points[0] for (int i = k2; i < N; i++) { Point2D top = hull.Pop(); while (Point2D.Ccw(hull.Peek(), top, points[i]) <= 0) { top = hull.Pop(); } hull.Push(top); hull.Push(points[i]); } Debug.Assert(isConvex()); }
/// <summary> /// Computes an Eulerian cycle in the specified graph, if one exists.</summary> /// <param name="G">the graph</param> /// public EulerianCycle(Graph G) { // must have at least one edge 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 (int 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 Edge data type is used to avoid exploring both copies of an edge v-w LinkedQueue <Edge>[] adj = new LinkedQueue <Edge> [G.V]; for (int v = 0; v < G.V; v++) { adj[v] = new LinkedQueue <Edge>(); } for (int v = 0; v < G.V; v++) { int selfLoops = 0; foreach (int w in G.Adj(v)) { // careful with self loops if (v == w) { if (selfLoops % 2 == 0) { Edge e = new Edge(v, w); adj[v].Enqueue(e); adj[w].Enqueue(e); } selfLoops++; } else if (v < w) { Edge e = new Edge(v, w); adj[v].Enqueue(e); adj[w].Enqueue(e); } } } // initialize stack with any non-isolated vertex int s = nonIsolatedVertex(G); LinkedStack <int> stack = new LinkedStack <int>(); stack.Push(s); // greedily search through edges in iterative DFS style cycle = new LinkedStack <int>(); while (!stack.IsEmpty) { int v = stack.Pop(); while (!adj[v].IsEmpty) { Edge 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 cycle cycle.Push(v); } // check if all edges are used if (cycle.Count != G.E + 1) { cycle = null; } Debug.Assert(certifySolution(G)); }
/// <summary> /// Computes an Eulerian path in the specified graph, if one exists.</summary> /// <param name="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 int oddDegreeVertices = 0; int s = nonIsolatedVertex(G); for (int 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 LinkedQueue <Edge>[] adj = new LinkedQueue <Edge> [G.V]; for (int v = 0; v < G.V; v++) { adj[v] = new LinkedQueue <Edge>(); } for (int v = 0; v < G.V; v++) { int selfLoops = 0; foreach (int w in G.Adj(v)) { // careful with self loops if (v == w) { if (selfLoops % 2 == 0) { Edge e = new Edge(v, w); adj[v].Enqueue(e); adj[w].Enqueue(e); } selfLoops++; } else if (v < w) { Edge e = new Edge(v, w); adj[v].Enqueue(e); adj[w].Enqueue(e); } } } // initialize stack with any non-isolated vertex LinkedStack <int> stack = new LinkedStack <int>(); stack.Push(s); // greedily search through edges in iterative DFS style path = new LinkedStack <int>(); while (!stack.IsEmpty) { int v = stack.Pop(); while (!adj[v].IsEmpty) { Edge 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.Count != G.E + 1) { path = null; } Debug.Assert(certifySolution(G)); }
private int[] distTo; // distTo[v] = number of edges on shortest path to v /// <summary> /// Determines a maximum matching (and a minimum vertex cover) /// in a bipartite graph.</summary> /// <param name="G">the bipartite graph</param> /// <exception cref="ArgumentException">if <c>G</c> is not bipartite</exception> /// public HopcroftKarp(Graph G) { bipartition = new BipartiteX(G); if (!bipartition.IsBipartite) { throw new ArgumentException("graph is not bipartite"); } // initialize empty matching this.V = G.V; mate = new int[V]; for (int v = 0; v < V; v++) { mate[v] = UNMATCHED; } // the call to hasAugmentingPath() provides enough info to reconstruct level graph while (hasAugmentingPath(G)) { // to be able to iterate over each adjacency list, keeping track of which // vertex in each adjacency list needs to be explored next IEnumerator <int>[] adj = new IEnumerator <int> [G.V]; for (int v = 0; v < G.V; v++) { adj[v] = G.Adj(v).GetEnumerator(); } // for each unmatched vertex s on one side of bipartition for (int s = 0; s < V; s++) { if (IsMatched(s) || !bipartition.Color(s)) { continue; // or use distTo[s] == 0 } // find augmenting path from s using nonrecursive DFS LinkedStack <int> path = new LinkedStack <int>(); path.Push(s); while (!path.IsEmpty) { int v = path.Peek(); // retreat, no more edges in level graph leaving v if (!adj[v].MoveNext()) { path.Pop(); } // advance else { // process edge v-w only if it is an edge in level graph int w = adj[v].Current; if (!isLevelGraphEdge(v, w)) { continue; } // add w to augmenting path path.Push(w); // augmenting path found: update the matching if (!IsMatched(w)) { // Console.WriteLine("augmenting path: " + toString(path)); while (!path.IsEmpty) { int x = path.Pop(); int y = path.Pop(); mate[x] = y; mate[y] = x; } cardinality++; } } } } } // also find a min vertex cover inMinVertexCover = new bool[V]; for (int v = 0; v < V; v++) { if (bipartition.Color(v) && !marked[v]) { inMinVertexCover[v] = true; } if (!bipartition.Color(v) && marked[v]) { inMinVertexCover[v] = true; } } Debug.Assert(certifySolution(G)); }
private LinkedStack <int> path = null; // Eulerian path; null if no suh path /// <summary> /// Computes an Eulerian path in the specified digraph, if one exists.</summary> /// <param name="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 int deficit = 0; int s = nonIsolatedVertex(G); for (int 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 IEnumerator <int>[] adj = new IEnumerator <int> [G.V]; for (int v = 0; v < G.V; v++) { adj[v] = G.Adj(v).GetEnumerator(); } // greedily add to cycle, depth-first search style LinkedStack <int> stack = new LinkedStack <int>(); stack.Push(s); path = new LinkedStack <int>(); 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.Count != G.E + 1) { path = null; } Debug.Assert(check(G)); }