public void Query <TC>(TC callback, AABB aabb) where TC : IQueryResultCollector <T> { var stack = new Collections.Stack <int>(256, Allocator.Temp); stack.Push(_root); while (stack.Count > 0) { var nodeId = stack.Pop(); if (nodeId == NullNode) { continue; } var node = _nodes + nodeId; if (TestOverlap(node->AABB, aabb)) { if (node->IsLeaf) { var proceed = callback.QueryCallback(node->UserData); if (proceed == false) { return; } } else { stack.Push(node->Child1); stack.Push(node->Child2); } } } }
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 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 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 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> /// Walks up in the hierarchy and ensures that all parent folder nodes of 'node' are included in the project. /// </summary> /// <param name="node">Start hierarchy node.</param> internal static void EnsureParentFolderIncluded(HierarchyNode node) { ErrorHelper.ThrowIsNull(node, "node"); // use stack to make sure all parent folders are included in the project. Collections.Stack <NemerleFolderNode> stack = new Collections.Stack <NemerleFolderNode>(); // Find out the parent folder nodes if any. NemerleFolderNode parentFolderNode = node.Parent as NemerleFolderNode; while (parentFolderNode != null && parentFolderNode.IsNonMemberItem) { stack.Push(parentFolderNode); parentFolderNode.CreateDirectory(); // ensure that the folder is there on file system parentFolderNode = parentFolderNode.Parent as NemerleFolderNode; } // include all parent folders in the project. while (stack.Count > 0) { NemerleFolderNode folderNode = stack.Pop(); ((IProjectSourceNode)folderNode).IncludeInProject(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); }
private void StrongConnect(uint v) { var nextStack = new Collections.Stack <uint>(); nextStack.Push(Constants.NO_VERTEX); nextStack.Push(v); while (nextStack.Count > 0) { v = nextStack.Pop(); var parent = nextStack.Pop(); if (_islands[v] != NO_ISLAND) { continue; } // 2 options: // OPTION 1: vertex was already processed, check if it's a root vertex. if (_index[v * 2 + 0] != NO_DATA) { // vertex was already processed, do wrap-up. if (parent != Constants.NO_VERTEX) { var vLowLink = _index[v * 2 + 1]; if (vLowLink < _index[parent * 2 + 1]) { _index[parent * 2 + 1] = vLowLink; } } if (_index[v * 2 + 0] == _index[v * 2 + 1]) { // this was a root node so this is an island! // pop from stack until root reached. var island = _nextIsland; _nextIsland++; uint size = 0; uint islandVertex = Constants.NO_VERTEX; do { islandVertex = _stack.Pop(); _onStack.Remove(islandVertex); size++; _islands[islandVertex] = island; } while (islandVertex != v); if (size == 1) { // only the root vertex, meaning this is a singleton. _islands[v] = SINGLETON_ISLAND; _nextIsland--; // reset island counter. } else { // keep island size. _islandSizes[island] = size; } } continue; } // OPTION 2: vertex wasn't already processed, process it and queue it's neigbours. // push again to trigger OPTION1. nextStack.Push(parent); nextStack.Push(v); var enumerator = _routerDb.Network.GeometricGraph.Graph.GetEdgeEnumerator(); enumerator.MoveTo(v); _index[v * 2 + 0] = _nextIndex; _index[v * 2 + 1] = _nextIndex; _nextIndex++; _stack.Push(v); _onStack.Add(v); if (enumerator.MoveTo(v)) { while (enumerator.MoveNext()) { float distance; ushort edgeProfile; EdgeDataSerializer.Deserialize(enumerator.Data0, out distance, out edgeProfile); var access = this.GetAccess(edgeProfile); if (enumerator.DataInverted) { if (access == Access.OnewayBackward) { access = Access.OnewayForward; } else if (access == Access.OnewayForward) { access = Access.OnewayBackward; } } if (access != Access.OnewayForward && access != Access.Bidirectional) { continue; } var n = enumerator.To; if (_islands[n] == RESTRICTED) { // check if this neighbour is restricted, if so ignore. continue; } var nIndex = _index[n * 2 + 0]; if (nIndex == NO_DATA) { // queue parent and neighbour. nextStack.Push(v); nextStack.Push(n); } else if (_onStack.Contains(n)) { if (nIndex < _index[v * 2 + 1]) { _index[v * 2 + 1] = nIndex; } } } } } }
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 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); }
public void RayCast <TC>(TC callback, RayCastInput input) where TC : IRayCastResultCollector <T> { var p1 = input.P1; var p2 = input.P2; var r = p2 - p1; Assert.IsTrue(math.any(r != 0.0f)); r = math.normalize(r); // v is perpendicular to the segment. var v = Cross(1.0f, r); var absV = math.abs(v); // Separating axis for segment (Gino, p80). // |dot(v, p1 - c)| > dot(|v|, h) var maxFraction = input.MaxFraction; // Build a bounding box for the segment. AABB segmentAABB; { var t = p1 + maxFraction * (p2 - p1); segmentAABB.LowerBound = math.min(p1, t); segmentAABB.UpperBound = math.max(p1, t); } var stack = new Collections.Stack <int>(256, Allocator.Temp); stack.Push(_root); while (stack.Count > 0) { var nodeId = stack.Pop(); if (nodeId == NullNode) { continue; } var node = _nodes + nodeId; if (TestOverlap(node->AABB, segmentAABB) == false) { continue; } // Separating axis for segment (Gino, p80). // |dot(v, p1 - c)| > dot(|v|, h) var c = node->AABB.GetCenter(); var h = node->AABB.GetExtents(); var separation = math.abs(math.dot(v, p1 - c)) - math.dot(absV, h); if (separation > 0.0f) { continue; } if (node->IsLeaf) { RayCastInput subInput; subInput.P1 = input.P1; subInput.P2 = input.P2; subInput.MaxFraction = maxFraction; var value = callback.RayCastCallback(subInput, node->UserData); if (value == 0.0f) { // The client has terminated the ray cast. return; } if (value > 0.0f) { // Update segment bounding box. maxFraction = value; var t = p1 + maxFraction * (p2 - p1); segmentAABB.LowerBound = math.min(p1, t); segmentAABB.UpperBound = math.max(p1, t); } } else { stack.Push(node->Child1); stack.Push(node->Child2); } } }