Exemplo n.º 1
0
        public void CheckPredecessorLineGraph()
        {
            AdjacencyGraph g  = new AdjacencyGraph(true);
            IVertex        v1 = g.AddVertex();
            IVertex        v2 = g.AddVertex();
            IVertex        v3 = g.AddVertex();

            IEdge e12 = g.AddEdge(v1, v2);
            IEdge e23 = g.AddEdge(v2, v3);

            EdgeDoubleDictionary          weights = DijkstraShortestPathAlgorithm.UnaryWeightsFromEdgeList(g);
            DijkstraShortestPathAlgorithm dij     = new DijkstraShortestPathAlgorithm(g, weights);
            PredecessorRecorderVisitor    vis     = new PredecessorRecorderVisitor();

            dij.RegisterPredecessorRecorderHandlers(vis);

            dij.Compute(v1);

            EdgeCollection col = vis.Path(v2);

            Assert.AreEqual(1, col.Count);
            Assert.AreEqual(e12, col[0]);

            col = vis.Path(v3);
            Assert.AreEqual(2, col.Count);
            Assert.AreEqual(e12, col[0]);
            Assert.AreEqual(e23, col[1]);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Computes a set of eulerian trail, starting at <paramref name="s"/>
        /// that spans the entire graph.
        /// </summary>
        /// <remarks>
        /// <para>
        /// This method computes a set of eulerian trail starting at <paramref name="s"/>
        /// that spans the entire graph.The algorithm outline is as follows:
        /// </para>
        /// <para>
        /// The algorithms iterates throught the Eulerian circuit of the augmented
        /// graph (the augmented graph is the graph with additional edges to make
        /// the number of odd vertices even).
        /// </para>
        /// <para>
        /// If the current edge is not temporary, it is added to the current trail.
        /// </para>
        /// <para>
        /// If the current edge is temporary, the current trail is finished and
        /// added to the trail collection. The shortest path between the
        /// start vertex <paramref name="s"/> and the target vertex of the
        /// temporary edge is then used to start the new trail. This shortest
        /// path is computed using the <see cref="BreadthFirstSearchAlgorithm"/>.
        /// </para>
        /// </remarks>
        /// <param name="s">start vertex</param>
        /// <returns>eulerian trail set, all starting at s</returns>
        /// <exception cref="ArgumentNullException">s is a null reference.</exception>
        /// <exception cref="Exception">Eulerian trail not computed yet.</exception>
        public EdgeCollectionCollection Trails(IVertex s)
        {
            if (s == null)
            {
                throw new ArgumentNullException("s");
            }
            if (this.Circuit.Count == 0)
            {
                throw new Exception("Circuit is empty");
            }

            // find the first edge in the circuit.
            int i = 0;

            for (i = 0; i < this.Circuit.Count; ++i)
            {
                IEdge e = this.Circuit[i];
                if (TemporaryEdges.Contains(e))
                {
                    continue;
                }
                if (e.Source == s)
                {
                    break;
                }
            }
            if (i == this.Circuit.Count)
            {
                throw new Exception("Did not find vertex in eulerian trail?");
            }

            // create collections
            EdgeCollectionCollection    trails = new EdgeCollectionCollection();
            EdgeCollection              trail  = new EdgeCollection();
            BreadthFirstSearchAlgorithm bfs    =
                new BreadthFirstSearchAlgorithm(VisitedGraph);
            PredecessorRecorderVisitor vis = new PredecessorRecorderVisitor();

            bfs.RegisterPredecessorRecorderHandlers(vis);
            bfs.Compute(s);

            // go throught the edges and build the predecessor table.
            int start = i;

            for (; i < this.Circuit.Count; ++i)
            {
                IEdge e = this.Circuit[i];
                if (TemporaryEdges.Contains(e))
                {
                    // store previous trail and start new one.
                    if (trail.Count != 0)
                    {
                        trails.Add(trail);
                    }
                    // start new trail
                    // take the shortest path from the start vertex to
                    // the target vertex
                    trail = vis.Path(e.Target);
                }
                else
                {
                    trail.Add(e);
                }
            }

            // starting again on the circuit
            for (i = 0; i < start; ++i)
            {
                IEdge e = this.Circuit[i];
                if (TemporaryEdges.Contains(e))
                {
                    // store previous trail and start new one.
                    if (trail.Count != 0)
                    {
                        trails.Add(trail);
                    }
                    // start new trail
                    // take the shortest path from the start vertex to
                    // the target vertex
                    trail = vis.Path(e.Target);
                }
                else
                {
                    trail.Add(e);
                }
            }

            // adding the last element
            if (trail.Count != 0)
            {
                trails.Add(trail);
            }

            return(trails);
        }