コード例 #1
0
        /// <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);
        }
コード例 #2
0
        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);
                }
            }
        }
コード例 #3
0
        /// <summary>
        /// check that algorithm computes either the topological order or finds a directed cycle
        /// </summary>
        /// <param name="g"></param>
        /// <param name="v"></param>
        private void Dfs(Digraph g, int v)
        {
            _onStack[v] = true;
            _marked[v]  = true;
            foreach (int w in g.Adj(v))
            {
                // short circuit if directed cycle found
                if (_cycle != null)
                {
                    return;
                }

                //found new vertex, so recur
                if (!_marked[w])
                {
                    _edgeTo[w] = v;
                    Dfs(g, w);
                }

                // trace back directed cycle
                else if (_onStack[w])
                {
                    _cycle = new Collections.Stack <Integer>();
                    for (var x = v; x != w; x = _edgeTo[x])
                    {
                        _cycle.Push(x);
                    }
                    _cycle.Push(w);
                    _cycle.Push(v);
                    //assert check();
                }
            }
            _onStack[v] = false;
        }
コード例 #4
0
        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);
                }
            }
        }
コード例 #5
0
        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);
                    }
                }
            }
        }
コード例 #6
0
 /// <summary>
 /// Returns a path between the source vertex <tt>s</tt> and vertex <tt>v</tt>, or
 /// <tt>null</tt> if no such path.
 /// </summary>
 /// <param name="v">v the vertex</param>
 /// <returns>the sequence of vertices on a path between the source vertex <tt>s</tt> and vertex <tt>v</tt>, as an Iterable</returns>
 public IEnumerable<Integer> PathTo(int v)
 {
     if (!HasPathTo(v)) return null;
     var path = new Collections.Stack<Integer>();
     for (var x = v; x != _s; x = _edgeTo[x])
         path.Push(x);
     path.Push(_s);
     return path;
 }
コード例 #7
0
 private void TraceBackDirectedCycle(DirectedEdge e, int w)
 {
     _cycle = new Collections.Stack <DirectedEdge>();
     while (e.From() != w)
     {
         _cycle.Push(e);
         e = _edgeTo[e.From()];
     }
     _cycle.Push(e);
 }
コード例 #8
0
        /// <summary>
        /// Returns the vertices in reverse postorder.
        /// </summary>
        /// <returns>the vertices in reverse postorder, as an iterable of vertices</returns>
        public IEnumerable <Integer> ReversePost()
        {
            var reverse = new Collections.Stack <Integer>();

            foreach (int v in _postorder)
            {
                reverse.Push(v);
            }
            return(reverse);
        }
コード例 #9
0
        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);
        }
コード例 #10
0
        /// <summary>
        /// Returns a shortest path from the source vertex <tt>s</tt> to vertex <tt>v</tt>.
        /// </summary>
        /// <param name="v">v the destination vertex</param>
        /// <returns>a shortest path from the source vertex <tt>s</tt> to vertex <tt>v</tt> as an iterable of edges, and <tt>null</tt> if no such path</returns>
        public IEnumerable <DirectedEdge> PathTo(int v)
        {
            if (!HasPathTo(v))
            {
                return(null);
            }
            var path = new Collections.Stack <DirectedEdge>();

            for (var e = _edgeTo[v]; e != null; e = _edgeTo[e.From()])
            {
                path.Push(e);
            }
            return(path);
        }
コード例 #11
0
        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;
                    }
                }
            }
        }
コード例 #12
0
        /// <summary>
        /// Returns a path between the source vertex <tt>s</tt> and vertex <tt>v</tt>, or
        /// <tt>null</tt> if no such path.
        /// </summary>
        /// <param name="v">v the vertex</param>
        /// <returns>the sequence of vertices on a path between the source vertex <tt>s</tt> and vertex <tt>v</tt>, as an Iterable</returns>
        public IEnumerable <Integer> PathTo(int v)
        {
            if (!HasPathTo(v))
            {
                return(null);
            }
            var path = new Collections.Stack <Integer>();

            for (var x = v; x != _s; x = _edgeTo[x])
            {
                path.Push(x);
            }
            path.Push(_s);
            return(path);
        }
コード例 #13
0
        /// <summary>
        /// Returns a shortest path between the source vertex <tt>s</tt> (or sources)
        /// and <tt>v</tt>, or <tt>null</tt> if no such path.
        /// </summary>
        /// <param name="v">v the vertex</param>
        /// <returns>the sequence of vertices on a shortest path, as an Iterable</returns>
        public IEnumerable <Integer> PathTo(int v)
        {
            if (!HasPathTo(v))
            {
                return(null);
            }
            var path = new Collections.Stack <Integer>();
            int x;

            for (x = v; _distTo[x] != 0; x = _edgeTo[x])
            {
                path.Push(x);
            }
            path.Push(x);
            return(path);
        }
コード例 #14
0
        /// <summary>
        /// Returns a shortest path between the source vertex <tt>s</tt> and vertex <tt>v</tt>.
        /// </summary>
        /// <param name="v">v the destination vertex</param>
        /// <returns>a shortest path between the source vertex <tt>s</tt> and vertex <tt>v</tt>; <tt>null</tt> if no such path</returns>
        public IEnumerable <EdgeW> PathTo(int v)
        {
            if (!HasPathTo(v))
            {
                return(null);
            }
            var path = new Collections.Stack <EdgeW>();
            var x    = v;

            for (var e = _edgeTo[v]; e != null; e = _edgeTo[x])
            {
                path.Push(e);
                x = e.Other(x);
            }
            return(path);
        }
コード例 #15
0
 /// <summary>
 /// Initializes a new edge-weighted graph that is a deep copy of <tt>G</tt>.
 /// </summary>
 /// <param name="g">g the edge-weighted graph to copy</param>
 public EdgeWeightedGraph(EdgeWeightedGraph g) : this(g.V)
 {
     E = g.E;
     for (var v = 0; v < g.V; v++)
     {
         // reverse so that adjacency list is in same order as original
         var reverse = new Collections.Stack <EdgeW>();
         foreach (var e in g._adj[v])
         {
             reverse.Push(e);
         }
         foreach (var e in reverse)
         {
             _adj[v].Add(e);
         }
     }
 }
コード例 #16
0
 /// <summary>
 /// Initializes a new graph that is a deep copy of <tt>G</tt>.
 /// </summary>
 /// <param name="g">g the graph to copy</param>
 public Graph(Graph g) : this(g.V)
 {
     E = g.E;
     for (var v = 0; v < g.V; v++)
     {
         // reverse so that adjacency list is in same order as original
         var reverse = new Collections.Stack <Integer>();
         foreach (int w in g._adj[v])
         {
             reverse.Push(w);
         }
         foreach (int w in reverse)
         {
             _adj[v].Add(w);
         }
     }
 }
コード例 #17
0
        /// <summary>
        /// Returns a shortest path from vertex <tt>s</tt> to vertex <tt>t</tt>.
        /// </summary>
        /// <param name="s">s the source vertex</param>
        /// <param name="t">t the destination vertex</param>
        /// <returns>a shortest path from vertex <tt>s</tt> to vertex <tt>t</tt> as an iterable of edges, and <tt>null</tt> if no such path</returns>
        /// <exception cref="NotSupportedException">if there is a negative cost cycle</exception>
        public IEnumerable <DirectedEdge> Path(int s, int t)
        {
            if (HasNegativeCycle)
            {
                throw new NotSupportedException("Negative cost cycle exists");
            }
            if (!HasPath(s, t))
            {
                return(null);
            }
            var path = new Collections.Stack <DirectedEdge>();

            for (var e = _edgeTo[s][t]; e != null; e = _edgeTo[s][e.From()])
            {
                path.Push(e);
            }
            return(path);
        }
コード例 #18
0
 /// <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);
 }
コード例 #19
0
        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();
                }
            }
        }
コード例 #20
0
        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();
                }
            }
        }
コード例 #21
0
ファイル: HierarchyHelpers.cs プロジェクト: ugurak/nemerle
        /// <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);
            }
        }
コード例 #22
0
        private readonly Collections.Stack <Integer> _cycle;     // the directed cycle; null if digraph is acyclic

        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();
        }
コード例 #23
0
ファイル: Cycle.cs プロジェクト: vladdnc/Algorithms-NET
 /// <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;
 }
コード例 #24
0
        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);
        }
コード例 #25
0
        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);
        }
コード例 #26
0
        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);
                }
            }
        }
コード例 #27
0
 /// <summary>
 /// Returns a shortest path from <tt>s</tt> (or sources) to <tt>v</tt>, or
 /// <tt>null</tt> if no such path.
 /// </summary>
 /// <param name="v">v the vertex</param>
 /// <returns>the sequence of vertices on a shortest path, as an Iterable</returns>
 public IEnumerable<Integer> PathTo(int v)
 {
     if (!HasPathTo(v)) return null;
     var path = new Collections.Stack<Integer>();
     int x;
     for (x = v; _distTo[x] != 0; x = _edgeTo[x])
         path.Push(x);
     path.Push(x);
     return path;
 }
コード例 #28
0
ファイル: Cycle.cs プロジェクト: vladdnc/Algorithms-NET
        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);
                }
            }
        }
コード例 #29
0
ファイル: Cycle.cs プロジェクト: vladdnc/Algorithms-NET
        /// <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;
        }
コード例 #30
0
        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;
                            }
                        }
                    }
                }
            }
        }
コード例 #31
0
        /// <summary>
        /// Runs the island detection.
        /// </summary>
        protected override void DoRun(CancellationToken cancellationToken)
        {
            _onStack = new SparseLongIndex();
            var vertexCount = _routerDb.Network.GeometricGraph.Graph.VertexCount;

            // initialize all islands to NO_ISLAND.
            for (uint i = 0; i < _islands.Length; i++)
            {
                _islands[i] = NO_ISLAND;

                if (_restrictionCollection != null)
                {
                    _restrictionCollection.Update(i);

                    for (var r = 0; r < _restrictionCollection.Count; r++)
                    {
                        var restriction = _restrictionCollection[r];

                        if (restriction.Vertex2 == Constants.NO_VERTEX &&
                            restriction.Vertex3 == Constants.NO_VERTEX)
                        {
                            _islands[i] = RESTRICTED;
                            break;
                        }
                        else
                        {
                            // TODO: support other restrictions.
                        }
                    }
                }
            }

            // build index data structure and stack.
            _index = Context.ArrayFactory.CreateMemoryBackedArray <uint>(vertexCount * 2);
            for (var i = 0; i < _index.Length; i++)
            {
                _index[i] = NO_DATA;
            }
            _stack = new Collections.Stack <uint>();

            // https://en.wikipedia.org/wiki/Tarjan's_strongly_connected_components_algorithm
            for (uint v = 0; v < vertexCount; v++)
            {
                var vIndex = _index[v * 2];
                if (vIndex != NO_DATA)
                {
                    continue;
                }

                StrongConnect(v);
            }

            // sort islands.
            var sortedIslands = new List <KeyValuePair <ushort, uint> >(_islandSizes);

            sortedIslands.Sort((x, y) => - x.Value.CompareTo(y.Value));
            var newIds = new Dictionary <ushort, ushort>();

            for (ushort i = 0; i < sortedIslands.Count; i++)
            {
                newIds[sortedIslands[i].Key] = i;
            }
            for (var v = 0; v < _islands.Length; v++)
            {
                ushort newId;
                if (newIds.TryGetValue(_islands[v], out newId))
                {
                    _islands[v] = newId;
                }
            }
            _islandSizes.Clear();
            foreach (var sortedIsland in sortedIslands)
            {
                ushort newId;
                if (newIds.TryGetValue(sortedIsland.Key, out newId))
                {
                    _islandSizes[newId] = sortedIsland.Value;
                }
            }
        }
コード例 #32
0
        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);
        }