コード例 #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
        /// <summary>
        /// breadth-first search from a single source
        /// </summary>
        /// <param name="g"></param>
        /// <param name="s"></param>
        private void Bfs(Graph g, int s)
        {
            var q = new Collections.Queue <Integer>();

            for (var v = 0; v < g.V; v++)
            {
                _distTo[v] = INFINITY;
            }
            _distTo[s] = 0;
            _marked[s] = true;
            q.Enqueue(s);

            while (!q.IsEmpty())
            {
                int v = q.Dequeue();
                foreach (int w in g.Adj(v))
                {
                    if (_marked[w])
                    {
                        continue;
                    }
                    _edgeTo[w] = v;
                    _distTo[w] = _distTo[v] + 1;
                    _marked[w] = true;
                    q.Enqueue(w);
                }
            }
        }
コード例 #3
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);
                }
            }
        }
コード例 #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
ファイル: 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);
                }
            }
        }
コード例 #6
0
        /// <summary>
        /// breadth-first search from multiple sources
        /// </summary>
        /// <param name="g"></param>
        /// <param name="sources"></param>
        private void Bfs(Graph g, IEnumerable <Integer> sources)
        {
            var q = new Collections.Queue <Integer>();

            foreach (int s in sources)
            {
                _marked[s] = true;
                _distTo[s] = 0;
                q.Enqueue(s);
            }
            while (!q.IsEmpty())
            {
                int v = q.Dequeue();
                foreach (int w in g.Adj(v))
                {
                    if (_marked[w])
                    {
                        continue;
                    }
                    _edgeTo[w] = v;
                    _distTo[w] = _distTo[v] + 1;
                    _marked[w] = true;
                    q.Enqueue(w);
                }
            }
        }
コード例 #7
0
 /// <summary>
 /// depth first search from v
 /// </summary>
 /// <param name="g"></param>
 /// <param name="v"></param>
 private void Dfs(Graph g, int v)
 {
     _marked[v] = true;
     foreach (int w in g.Adj(v))
     {
         if (_marked[w]) continue;
         _edgeTo[w] = v;
         Dfs(g, w);
     }
 }
コード例 #8
0
        /// <summary>
        /// check optimality conditions for single source
        /// </summary>
        /// <param name="g"></param>
        /// <param name="s"></param>
        /// <returns></returns>
        private bool Check(Graph g, int s)
        {
            // check that the distance of s = 0
            if (_distTo[s] != 0)
            {
                Console.WriteLine("distance of source " + s + " to itself = " + _distTo[s]);
                return(false);
            }

            // check that for each edge v-w dist[w] <= dist[v] + 1
            // provided v is reachable from s
            for (var v = 0; v < g.V; v++)
            {
                foreach (int w in g.Adj(v))
                {
                    if (HasPathTo(v) != HasPathTo(w))
                    {
                        Console.WriteLine("edge " + v + "-" + w);
                        Console.WriteLine("hasPathTo(" + v + ") = " + HasPathTo(v));
                        Console.WriteLine("hasPathTo(" + w + ") = " + HasPathTo(w));
                        return(false);
                    }
                    if (HasPathTo(v) && (_distTo[w] > _distTo[v] + 1))
                    {
                        Console.WriteLine("edge " + v + "-" + w);
                        Console.WriteLine("distTo[" + v + "] = " + _distTo[v]);
                        Console.WriteLine("distTo[" + w + "] = " + _distTo[w]);
                        return(false);
                    }
                }
            }

            // check that v = edgeTo[w] satisfies distTo[w] + distTo[v] + 1
            // provided v is reachable from s
            for (var w = 0; w < g.V; w++)
            {
                if (!HasPathTo(w) || w == s)
                {
                    continue;
                }
                var v = _edgeTo[w];
                if (_distTo[w] == _distTo[v] + 1)
                {
                    continue;
                }
                Console.WriteLine("shortest path edge " + v + "-" + w);
                Console.WriteLine("distTo[" + v + "] = " + _distTo[v]);
                Console.WriteLine("distTo[" + w + "] = " + _distTo[w]);
                return(false);
            }

            return(true);
        }
コード例 #9
0
 /// <summary>
 /// depth first search from v
 /// </summary>
 /// <param name="g"></param>
 /// <param name="v"></param>
 private void Dfs(Graph g, int v)
 {
     _marked[v] = true;
     foreach (int w in g.Adj(v))
     {
         if (_marked[w])
         {
             continue;
         }
         _edgeTo[w] = v;
         Dfs(g, w);
     }
 }
コード例 #10
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;
                    }
                }
            }
        }
コード例 #11
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);
 }
コード例 #12
0
        private bool Check(Graph g)
        {
            // graph is bipartite
            if (_isBipartite)
            {
                for (var v = 0; v < g.V; v++)
                {
                    foreach (int w in g.Adj(v))
                    {
                        if (_color[v] != _color[w])
                        {
                            continue;
                        }
                        Console.Error.WriteLine($"edge {v}-{w} with {v} and {w} in same side of bipartition\n");
                        return(false);
                    }
                }
            }

            // graph has an odd-length cycle
            else
            {
                // verify cycle
                int first = -1, last = -1;
                foreach (int v in OddCycle())
                {
                    if (first == -1)
                    {
                        first = v;
                    }
                    last = v;
                }
                if (first == last)
                {
                    return(true);
                }
                Console.Error.WriteLine($"cycle begins with {first} and ends with {last}{Environment.NewLine}");
                return(false);
            }

            return(true);
        }
コード例 #13
0
        /// <summary>
        /// Computes the vertices connected to the source vertex <tt>s</tt> in the graph <tt>G</tt>.
        /// </summary>
        /// <param name="g">g the graph</param>
        /// <param name="s">s the source vertex</param>
        public NonrecursiveDFS(Graph 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();
                }
            }
        }
コード例 #14
0
        /// <summary>
        /// Computes the vertices connected to the source vertex <tt>s</tt> in the graph <tt>G</tt>.
        /// </summary>
        /// <param name="g">g the graph</param>
        /// <param name="s">s the source vertex</param>
        public NonrecursiveDFS(Graph 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();
                }
            }
        }
コード例 #15
0
        /// <summary>
        /// breadth-first search from a single source
        /// </summary>
        /// <param name="g"></param>
        /// <param name="s"></param>
        private void Bfs(Graph g, int s)
        {
            var q = new Collections.Queue<Integer>();
            for (var v = 0; v < g.V; v++)
                _distTo[v] = INFINITY;
            _distTo[s] = 0;
            _marked[s] = true;
            q.Enqueue(s);

            while (!q.IsEmpty())
            {
                int v = q.Dequeue();
                foreach (int w in g.Adj(v))
                {
                    if (_marked[w]) continue;
                    _edgeTo[w] = v;
                    _distTo[w] = _distTo[v] + 1;
                    _marked[w] = true;
                    q.Enqueue(w);
                }
            }
        }
コード例 #16
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);
        }
コード例 #17
0
        private readonly Collections.Stack<Integer> _cycle = new Collections.Stack<Integer>(); // Eulerian cycle; null if no such cycle

        #endregion Fields

        #region Constructors

        /// <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);
        }
コード例 #18
0
ファイル: Bipartite.cs プロジェクト: vladdnc/Algorithms-NET
        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);
                }
            }
        }
コード例 #19
0
ファイル: Bipartite.cs プロジェクト: vladdnc/Algorithms-NET
        private bool Check(Graph g)
        {
            // graph is bipartite
            if (_isBipartite)
            {
                for (var v = 0; v < g.V; v++)
                {
                    foreach (int w in g.Adj(v))
                    {
                        if (_color[v] != _color[w]) continue;
                        Console.Error.WriteLine($"edge {v}-{w} with {v} and {w} in same side of bipartition\n");
                        return false;
                    }
                }
            }

            // graph has an odd-length cycle
            else
            {
                // verify cycle
                int first = -1, last = -1;
                foreach (int v in OddCycle())
                {
                    if (first == -1) first = v;
                    last = v;
                }
                if (first == last) return true;
                Console.Error.WriteLine($"cycle begins with {first} and ends with {last}{Environment.NewLine}");
                return false;
            }

            return true;
        }
コード例 #20
0
 /// <summary>
 /// breadth-first search from multiple sources
 /// </summary>
 /// <param name="g"></param>
 /// <param name="sources"></param>
 private void Bfs(Graph g, IEnumerable<Integer> sources)
 {
     var q = new Collections.Queue<Integer>();
     foreach (int s in sources)
     {
         _marked[s] = true;
         _distTo[s] = 0;
         q.Enqueue(s);
     }
     while (!q.IsEmpty())
     {
         int v = q.Dequeue();
         foreach (int w in g.Adj(v))
         {
             if (_marked[w]) continue;
             _edgeTo[w] = v;
             _distTo[w] = _distTo[v] + 1;
             _marked[w] = true;
             q.Enqueue(w);
         }
     }
 }
コード例 #21
0
ファイル: BipartiteX.cs プロジェクト: vladdnc/Algorithms-NET
        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;
                    }
                }
            }
        }
コード例 #22
0
        private readonly Collections.Stack<Integer> _path; // Eulerian path; null if no suh path

        #endregion Fields

        #region Constructors

        /// <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);
        }
コード例 #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
        /// <summary>
        /// check optimality conditions for single source
        /// </summary>
        /// <param name="g"></param>
        /// <param name="s"></param>
        /// <returns></returns>
        private bool Check(Graph g, int s)
        {
            // check that the distance of s = 0
            if (_distTo[s] != 0)
            {
                Console.WriteLine("distance of source " + s + " to itself = " + _distTo[s]);
                return false;
            }

            // check that for each edge v-w dist[w] <= dist[v] + 1
            // provided v is reachable from s
            for (var v = 0; v < g.V; v++)
            {
                foreach (int w in g.Adj(v))
                {
                    if (HasPathTo(v) != HasPathTo(w))
                    {
                        Console.WriteLine("edge " + v + "-" + w);
                        Console.WriteLine("hasPathTo(" + v + ") = " + HasPathTo(v));
                        Console.WriteLine("hasPathTo(" + w + ") = " + HasPathTo(w));
                        return false;
                    }
                    if (HasPathTo(v) && (_distTo[w] > _distTo[v] + 1))
                    {
                        Console.WriteLine("edge " + v + "-" + w);
                        Console.WriteLine("distTo[" + v + "] = " + _distTo[v]);
                        Console.WriteLine("distTo[" + w + "] = " + _distTo[w]);
                        return false;
                    }
                }
            }

            // check that v = edgeTo[w] satisfies distTo[w] + distTo[v] + 1
            // provided v is reachable from s
            for (var w = 0; w < g.V; w++)
            {
                if (!HasPathTo(w) || w == s) continue;
                var v = _edgeTo[w];
                if (_distTo[w] == _distTo[v] + 1) continue;
                Console.WriteLine("shortest path edge " + v + "-" + w);
                Console.WriteLine("distTo[" + v + "] = " + _distTo[v]);
                Console.WriteLine("distTo[" + w + "] = " + _distTo[w]);
                return false;
            }

            return true;
        }
コード例 #26
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;
        }