public void CheckPredecessorLineGraph()
        {
            AdjacencyGraph <int, Edge <int> > g = new AdjacencyGraph <int, Edge <int> >(true);

            g.AddVertex(1);
            g.AddVertex(2);
            g.AddVertex(3);

            Edge <int> e12 = new Edge <int>(1, 2); g.AddEdge(e12);
            Edge <int> e23 = new Edge <int>(2, 3); g.AddEdge(e23);

            Dictionary <Edge <int>, double> weights =
                DijkstraShortestPathAlgorithm <int, Edge <int> > .UnaryWeightsFromEdgeList(g);

            DijkstraShortestPathAlgorithm <int, Edge <int> >     dij = new DijkstraShortestPathAlgorithm <int, Edge <int> >(g, weights);
            VertexPredecessorRecorderObserver <int, Edge <int> > vis = new VertexPredecessorRecorderObserver <int, Edge <int> >();

            vis.Attach(dij);
            dij.Compute(1);

            IList <Edge <int> > col = vis.Path(2);

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

            col = vis.Path(3);
            Assert.AreEqual(2, col.Count);
            Assert.AreEqual(e12, col[0]);
            Assert.AreEqual(e23, col[1]);
        }
        public void CheckPredecessorLineGraph()
        {
            AdjacencyGraph<int, Edge<int>> g = new AdjacencyGraph<int, Edge<int>>(true);
            g.AddVertex(1);
            g.AddVertex(2);
            g.AddVertex(3);

            Edge<int> e12 = new Edge<int>(1, 2); g.AddEdge(e12);
            Edge<int> e23 = new Edge<int>(2, 3); g.AddEdge(e23);

            Dictionary<Edge<int>, double> weights =
                DijkstraShortestPathAlgorithm<int, Edge<int>>.UnaryWeightsFromEdgeList(g);
            DijkstraShortestPathAlgorithm<int, Edge<int>> dij = new DijkstraShortestPathAlgorithm<int, Edge<int>>(g, weights);
            VertexPredecessorRecorderObserver<int, Edge<int>> vis = new VertexPredecessorRecorderObserver<int, Edge<int>>();
            vis.Attach(dij);
            dij.Compute(1);

            IList<Edge<int>> col = vis.Path(2);
            Assert.AreEqual(1, col.Count);
            Assert.AreEqual(e12, col[0]);

            col = vis.Path(3);
            Assert.AreEqual(2, col.Count);
            Assert.AreEqual(e12, col[0]);
            Assert.AreEqual(e23, col[1]);
        }
        /// <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 ICollection <ICollection <TEdge> > Trails(TVertex 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)
            {
                TEdge e = this.Circuit[i];
                if (this.temporaryEdges.Contains(e))
                {
                    continue;
                }
                if (e.Source.Equals(s))
                {
                    break;
                }
            }
            if (i == this.Circuit.Count)
            {
                throw new Exception("Did not find vertex in eulerian trail?");
            }

            // create collections
            List <ICollection <TEdge> > trails = new List <ICollection <TEdge> >();
            List <TEdge> trail = new List <TEdge>();
            BreadthFirstSearchAlgorithm <TVertex, TEdge> bfs =
                new BreadthFirstSearchAlgorithm <TVertex, TEdge>(VisitedGraph);
            VertexPredecessorRecorderObserver <TVertex, TEdge> vis =
                new VertexPredecessorRecorderObserver <TVertex, TEdge>();

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

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

            for (; i < this.Circuit.Count; ++i)
            {
                TEdge e = this.Circuit[i];
                if (this.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)
            {
                TEdge e = this.Circuit[i];
                if (this.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);
        }
Пример #4
0
        /// <summary>
        /// Carries out the shortest path between the two nodes
        /// ids passed as variables and returns an <see cref="ILineString" /> 
        /// giveing the shortest path.
        /// </summary>
        /// <param name="source">The source node</param>
        /// <param name="destination">The destination node</param>
        /// <returns>A line string geometric shape of the path</returns>
        public ILineString Perform(ICoordinate source, ICoordinate destination)
        {
            if (!graph.ContainsVertex(source))
                throw new ArgumentException("key not found in the graph", "source");
            if (!graph.ContainsVertex(destination))
                throw new ArgumentException("key not found in the graph", "destination");

            // Build algorithm
            DijkstraShortestPathAlgorithm<ICoordinate, IEdge<ICoordinate>> dijkstra =
                new DijkstraShortestPathAlgorithm<ICoordinate, IEdge<ICoordinate>>(graph, consts);

            // Attach a Distance observer to give us the distances between edges
            VertexDistanceRecorderObserver<ICoordinate, IEdge<ICoordinate>> distanceObserver =
                new VertexDistanceRecorderObserver<ICoordinate, IEdge<ICoordinate>>();
            distanceObserver.Attach(dijkstra);

            // Attach a Vertex Predecessor Recorder Observer to give us the paths
            VertexPredecessorRecorderObserver<ICoordinate, IEdge<ICoordinate>> predecessorObserver =
                new VertexPredecessorRecorderObserver<ICoordinate, IEdge<ICoordinate>>();
            predecessorObserver.Attach(dijkstra);

            // Run the algorithm with A set to be the source
            dijkstra.Compute(source);

            // Get the path computed to the destination.
            IList<IEdge<ICoordinate>> path = predecessorObserver.Path(destination);

            // Then we need to turn that into a geomery.
            if (path.Count > 1)
                return buildString(path);

            // if the count is greater than one then a 
            // path could not be found, so we return null 
            return null;
        }