Esempio n. 1
0
        /// <summary>
        /// check that solution is correct
        /// </summary>
        /// <param name="g"></param>
        /// <returns></returns>
        public bool CertifySolution(Digraph g)
        {
            // internal consistency check
            if (HasEulerianCycle() == (Cycle() == null))
            {
                return(false);
            }

            // hashEulerianCycle() returns correct value
            if (HasEulerianCycle() != HasEulerianCycle(g))
            {
                return(false);
            }

            // nothing else to check if no Eulerian cycle
            if (_cycle == null)
            {
                return(true);
            }

            // check that cycle() uses correct number of edges
            if (_cycle.Size() != g.E + 1)
            {
                return(false);
            }

            // check that cycle() is a directed cycle of G
            // TODO

            return(true);
        }
Esempio n. 2
0
        public bool Check(Digraph g)
        {
            // internal consistency check
            if (HasEulerianPath() == (Path() == null))
            {
                return(false);
            }

            // hashEulerianPath() returns correct value
            if (HasEulerianPath() != HasEulerianPath(g))
            {
                return(false);
            }

            // nothing else to check if no Eulerian path
            if (_path == null)
            {
                return(true);
            }

            // check that path() uses correct number of edges
            if (_path.Size() != g.E + 1)
            {
                return(false);
            }

            // check that path() is a directed path in G
            // TODO

            return(true);
        }
Esempio n. 3
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);
        }
Esempio n. 4
0
        /// <summary>
        /// check that solution is correct
        /// </summary>
        /// <param name="g"></param>
        /// <returns></returns>
        public bool CertifySolution(Graph g)
        {
            // internal consistency check
            if (HasEulerianCycle() == (Cycle() == null))
            {
                return(false);
            }

            // hashEulerianCycle() returns correct value
            if (HasEulerianCycle() != HasEulerianCycle(g))
            {
                return(false);
            }

            // nothing else to check if no Eulerian cycle
            if (_cycle == null)
            {
                return(true);
            }

            // check that cycle() uses correct number of EdgeWs
            if (_cycle.Size() != g.E + 1)
            {
                return(false);
            }

            // check that cycle() is a cycle of G
            // TODO

            // check that first and last vertices in cycle() are the same
            int first = -1, last = -1;

            foreach (int v in Cycle())
            {
                if (first == -1)
                {
                    first = v;
                }
                last = v;
            }
            if (first != last)
            {
                return(false);
            }

            return(true);
        }
Esempio n. 5
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);
        }
Esempio n. 6
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);
        }
Esempio n. 7
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);
        }