예제 #1
1
        public List<FloorTile> getPath()
        {
            if (this.m_status.position != null)
            {
                startPoint = this.m_status.position.location.X + "_" + this.m_status.position.location.Y;
                m_parent.PostMessage("start: " + startPoint);
            }
            else
            {
                startPoint = "4_4";
            }
            if (this.m_status.endPoint != null)
            {
                targetPoint = this.m_status.endPoint.X + "_" + this.m_status.endPoint.Y;
                m_parent.PostMessage("end: " + targetPoint);
            }
            else
            {
                targetPoint = "4_6";
            }

            //startPoint = txtStartPoint.Text;
            //targetPoint = txtTargetPoint.Text;

            DijkstraShortestPathAlgorithm<string, Edge<string>> dijkstra = new DijkstraShortestPathAlgorithm<string, Edge<string>>(graph, AlgorithmExtensions.GetIndexer<Edge<string>, double>(edgeCost));

            // Attach a Vertex Predecessor Recorder Observer to give us the paths
            QuickGraph.Algorithms.Observers.VertexPredecessorRecorderObserver<string, Edge<string>> predecessorObserver = new QuickGraph.Algorithms.Observers.VertexPredecessorRecorderObserver<string, Edge<string>>();
            predecessorObserver.Attach(dijkstra);

            // attach a distance observer to give us the shortest path distances
            VertexDistanceRecorderObserver<string, Edge<string>> distObserver = new VertexDistanceRecorderObserver<string, Edge<string>>(AlgorithmExtensions.GetIndexer<Edge<string>, double>(edgeCost));
            distObserver.Attach(dijkstra);

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

            String outString = "";

            //outString += distObserver.Distances[targetPoint] + "\n";

            IEnumerable<Edge<string>> path;
            if (predecessorObserver.TryGetPath(targetPoint, out path))
                foreach (var u in path)
                    outString += u + ";";

            List<FloorTile> retval = new List<FloorTile>();

            string[] outEdges = Regex.Split(outString, ";");
            if (outEdges.Length > 0)
            {
                for (int i = 0; i < outEdges.Length; i++)
                {
                    if (outEdges[i].Length > 0)
                    {
                        m_parent.PostMessage(outEdges[i]);
                        string[] outPoint = Regex.Split(outEdges[i], "->");
                        //start points
                        retval.Add(getTileByIndex(fp, outPoint[0]));
                    }
                }
                //add target
                retval.Add(getTileByIndex(fp, targetPoint));
            }

            m_parent.PostMessage(retval.Count.ToString());
            m_parent.PostMessage(outString);

            if(retval.Count == 1 && retval[0].Equals(getTileByIndex(fp, targetPoint))){
                m_parent.PostMessage("Can't find path. Start or end point is not walkable or no available walkable tiles");
                return null;
            }

            return condenseList(retval);
        }
예제 #2
1
        public List<FloorTile> getPath()
        {
            List<FloorTile> retval = new List<FloorTile>();
            if (this.fp == null || this.fp.getStartTile() == null || this.fp.getTargetTile() == null)
                return retval;

            startPoint = this.fp.getStartTile().Position.X + "_" + this.fp.getStartTile().Position.Y;
            targetPoint = this.fp.getTargetTile().Position.X + "_" + this.fp.getTargetTile().Position.Y;

            this.messages += "- Start Get Path\n";
            //startPoint = txtStartPoint.Text;
            //targetPoint = txtTargetPoint.Text;

            DijkstraShortestPathAlgorithm<string, Edge<string>> dijkstra = new DijkstraShortestPathAlgorithm<string, Edge<string>>(graph, AlgorithmExtensions.GetIndexer<Edge<string>, double>(edgeCost));

            // Attach a Vertex Predecessor Recorder Observer to give us the paths
            QuickGraph.Algorithms.Observers.VertexPredecessorRecorderObserver<string, Edge<string>> predecessorObserver = new QuickGraph.Algorithms.Observers.VertexPredecessorRecorderObserver<string, Edge<string>>();
            predecessorObserver.Attach(dijkstra);

            // attach a distance observer to give us the shortest path distances
            VertexDistanceRecorderObserver<string, Edge<string>> distObserver = new VertexDistanceRecorderObserver<string, Edge<string>>(AlgorithmExtensions.GetIndexer<Edge<string>, double>(edgeCost));
            distObserver.Attach(dijkstra);

            // Run the algorithm with A set to be the source
            dijkstra.Compute(startPoint);
            this.messages += "    Start Point: " + startPoint + ".\n";
            this.messages += "    Target Point: " + targetPoint + ".\n";

            String outString = "";

            //outString += distObserver.Distances[targetPoint] + "\n";

            IEnumerable<Edge<string>> path;
            if (predecessorObserver.TryGetPath(targetPoint, out path))
                foreach (var u in path)
                    outString += u + ";";

            string[] outEdges = Regex.Split(outString, ";");
            if (outEdges.Length > 0)
            {
                for (int i = 0; i < outEdges.Length; i++)
                {
                    if (outEdges[i].Length > 0)
                    {
                        this.messages += outEdges[i] + "\n";
                        string[] outPoint = Regex.Split(outEdges[i], "->");
                        //start points
                        retval.Add(getTileByIndex(fp, outPoint[0]));
                    }
                }
                //add target
                retval.Add(getTileByIndex(fp, targetPoint));
            }

            this.messages += retval.Count.ToString()+ "\n";;

            if(retval.Count == 1 && retval[0].Equals(getTileByIndex(fp, targetPoint))){
                this.messages += "Can't find path. Start or end point is not walkable or no available walkable tiles" + "\n"; ;
                return null;
            }

            fp.setPath(retval);
            //return retval;

            return condenseList(retval);
        }
        private static void CompareSearches <TVertex, TEdge>(
            [NotNull] IBidirectionalGraph <TVertex, TEdge> graph,
            [NotNull] TVertex root,
            [NotNull] TVertex target)
            where TEdge : IEdge <TVertex>
        {
            double EdgeWeights(TEdge edge) => 1.0;

            IDistanceRelaxer distanceRelaxer = DistanceRelaxers.ShortestDistance;

            var search = new BestFirstFrontierSearchAlgorithm <TVertex, TEdge>(
                graph,
                EdgeWeights,
                distanceRelaxer);
            var recorder = new VertexDistanceRecorderObserver <TVertex, TEdge>(EdgeWeights);

            using (recorder.Attach(search))
                search.Compute(root, target);

            var dijkstra         = new DijkstraShortestPathAlgorithm <TVertex, TEdge>(graph, EdgeWeights, distanceRelaxer);
            var dijkstraRecorder = new VertexDistanceRecorderObserver <TVertex, TEdge>(EdgeWeights);

            using (dijkstraRecorder.Attach(dijkstra))
                dijkstra.Compute(root);

            IDictionary <TVertex, double> bffsVerticesDistances     = recorder.Distances;
            IDictionary <TVertex, double> dijkstraVerticesDistances = dijkstraRecorder.Distances;

            if (dijkstraVerticesDistances.TryGetValue(target, out double cost))
            {
                Assert.IsTrue(bffsVerticesDistances.ContainsKey(target), $"Target {target} not found, should be {cost}.");
                Assert.AreEqual(dijkstraVerticesDistances[target], bffsVerticesDistances[target]);
            }
        }
        public void CompareSearch <TVertex, TEdge>(
            [PexAssumeNotNull] IBidirectionalGraph <TVertex, TEdge> g,
            TVertex root, TVertex target)
            where TEdge : IEdge <TVertex>
        {
            Func <TEdge, double> edgeWeights = e => 1;
            var distanceRelaxer = DistanceRelaxers.ShortestDistance;

            var search = new BestFirstFrontierSearchAlgorithm <TVertex, TEdge>(
                null,
                g,
                edgeWeights,
                distanceRelaxer);
            var recorder = new VertexDistanceRecorderObserver <TVertex, TEdge>(edgeWeights);

            using (recorder.Attach(search))
                search.Compute(root, target);

            var dijkstra    = new DijkstraShortestPathAlgorithm <TVertex, TEdge>(g, edgeWeights, distanceRelaxer);
            var dijRecorder = new VertexDistanceRecorderObserver <TVertex, TEdge>(edgeWeights);

            using (dijRecorder.Attach(dijkstra))
                dijkstra.Compute(root);

            var    fvp = recorder.Distances;
            var    dvp = dijRecorder.Distances;
            double cost;

            if (dvp.TryGetValue(target, out cost))
            {
                Assert.IsTrue(fvp.ContainsKey(target), "target {0} not found, should be {1}", target, cost);
                Assert.AreEqual(dvp[target], fvp[target]);
            }
        }
        private void ComputeMinimumTree(
            TVertex goal,
            out IDictionary <TVertex, TEdge> successors,
            out IDictionary <TVertex, double> distances)
        {
            var reversedGraph =
                new ReversedBidirectionalGraph <TVertex, TEdge>(this.VisitedGraph);
            var successorsObserver =
                new VertexPredecessorRecorderObserver <TVertex, SReversedEdge <TVertex, TEdge> >();
            Func <SReversedEdge <TVertex, TEdge>, double> reversedEdgeWeight =
                e => this.edgeWeights(e.OriginalEdge);
            var distancesObserser =
                new VertexDistanceRecorderObserver <TVertex, SReversedEdge <TVertex, TEdge> >(reversedEdgeWeight);
            var shortestpath =
                new DijkstraShortestPathAlgorithm <TVertex, SReversedEdge <TVertex, TEdge> >(
                    this, reversedGraph, reversedEdgeWeight, this.DistanceRelaxer);

            using (successorsObserver.Attach(shortestpath))
                using (distancesObserser.Attach(shortestpath))
                    shortestpath.Compute(goal);

            successors = new Dictionary <TVertex, TEdge>();
            foreach (var kv in successorsObserver.VertexPredecessors)
            {
                successors.Add(kv.Key, kv.Value.OriginalEdge);
            }
            distances = distancesObserser.Distances;
        }
예제 #6
0
        public static IDictionary <int, double> Get(AdjacencyGraph <int, Edge <int> > g)
        {
            var dfs      = new DepthFirstSearchAlgorithm <int, Edge <int> >(g);
            var recorder = new VertexDistanceRecorderObserver <int, Edge <int> >(edgeWeights => 1.0);

            using (recorder.Attach(dfs))
            {
                dfs.Compute();
                return(recorder.Distances);
            }
        }
예제 #7
0
        public static IDictionary <string, double> Get(AdjacencyGraph <string, TaggedEdge <string, string> > g)
        {
            var dfs      = new DepthFirstSearchAlgorithm <string, TaggedEdge <string, string> >(g);
            var recorder = new VertexDistanceRecorderObserver <string, TaggedEdge <string, string> >(edgeWeights => double.Parse(edgeWeights.Tag));

            using (recorder.Attach(dfs))
            {
                dfs.Compute();
                return(recorder.Distances);
            }
        }
예제 #8
0
        public void BuildGraphAndSearchShortestPathUsingGraphBuilder()
        {
            // Build algorithm
            GraphBuilder builder = new GraphBuilder();

            builder.Add(a);
            builder.Add(b, c);
            builder.Add(d);
            DijkstraShortestPathAlgorithm <IPoint, IEdge <IPoint> > algorithm = builder.PrepareAlgorithm();

            // Attach a distance observer to give us the shortest path distances
            VertexDistanceRecorderObserver <IPoint, IEdge <IPoint> > distObserver =
                new VertexDistanceRecorderObserver <IPoint, IEdge <IPoint> >();

            distObserver.Attach(algorithm);

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

            predecessorObserver.Attach(algorithm);

            // Run algorithm
            algorithm.Compute(start);

            // Check results
            int distance = distObserver.Distances[end];

            Assert.AreEqual(2, distance);
            IDictionary <IPoint, IEdge <IPoint> > predecessors = predecessorObserver.VertexPredecessors;

            for (int i = 0; i < distance; i++)
            {
                IEdge <IPoint> edge = predecessors[end];
                if (i == 0)
                {
                    Assert.AreEqual(d.GetPointN(d.NumPoints - 2), edge.Source);
                    Assert.AreEqual(d.EndPoint, edge.Target);
                }
                else if (i == 1)
                {
                    Assert.AreEqual(a.StartPoint, edge.Source);
                    Assert.AreEqual(d.GetPointN(d.NumPoints - 2), edge.Target);
                }
                end = edge.Source;
            }

            // Detach the observers
            distObserver.Detach(algorithm);
            predecessorObserver.Detach(algorithm);
        }
예제 #9
0
        public static string ShortestWayDijsktraAlgorithmDirected(GraphVertex vertexD, List <GraphEdge> listEdge, List <GraphVertex> listVertex)
        {
            string s = "";
            AdjacencyGraph <GraphVertex, Edge <GraphVertex> > graph = new AdjacencyGraph <GraphVertex, Edge <GraphVertex> >();

            foreach (var vert in listVertex)
            {
                graph.AddVertex(vert);
            }
            foreach (var edge in listEdge)
            {
                graph.AddEdge(new Edge <GraphVertex>(edge.StartVertex, edge.EndVertex));
            }
            Dictionary <Edge <GraphVertex>, double> edgeCost = new Dictionary <Edge <GraphVertex>, double>();
            int i = 0;

            foreach (var edge in graph.Edges)
            {
                double eCost = EdgeCostSearching(edge.Source, edge.Target, listEdge);
                edgeCost.Add(edge, eCost);
                i++;
            }
            Func <Edge <GraphVertex>, double> getW = edge => edgeCost[edge];
            DijkstraShortestPathAlgorithm <GraphVertex, Edge <GraphVertex> >  diijkstra = new DijkstraShortestPathAlgorithm <GraphVertex, Edge <GraphVertex> >(graph, getW);
            VertexDistanceRecorderObserver <GraphVertex, Edge <GraphVertex> > distObs   = new VertexDistanceRecorderObserver <GraphVertex, Edge <GraphVertex> >(getW);
            IEnumerable <Edge <GraphVertex> > pathh;

            using (distObs.Attach(diijkstra))
            {
                VertexPredecessorRecorderObserver <GraphVertex, Edge <GraphVertex> > predObs = new VertexPredecessorRecorderObserver <GraphVertex, Edge <GraphVertex> >();
                using (predObs.Attach(diijkstra))
                {
                    diijkstra.Compute(vertexD);
                    foreach (KeyValuePair <GraphVertex, double> kvp in distObs.Distances)
                    {
                        s += "From " + vertexD.Name + " to " + kvp.Key.Name + " is " + kvp.Value + "         by ";
                        if (predObs.TryGetPath(kvp.Key, out pathh))
                        {
                            foreach (var t in pathh)
                            {
                                s += "edge " + t.Source.Name + "<->" + t.Target.Name + " ";
                            }
                        }
                        s += System.Environment.NewLine;
                    }
                }
            }
            return(s);
        }
예제 #10
0
        public void Calculate()
        {
            Func <LabelledEdge <ExtendedWarp>, double> edgeCost = (x) => x.Cost;
            //TryFunc<ExtendedWarp, LabelledEdge<ExtendedWarp>> tryGetPaths = this
            var alg = new DijkstraShortestPathAlgorithm <ExtendedWarp, LabelledEdge <ExtendedWarp> >(this, edgeCost);

            var distObserver = new VertexDistanceRecorderObserver <ExtendedWarp, LabelledEdge <ExtendedWarp> >(edgeCost);

            distObserver.Attach(alg);
            var predecessorObserver = new VertexPredecessorRecorderObserver <ExtendedWarp, LabelledEdge <ExtendedWarp> >();

            predecessorObserver.Attach(alg);
            alg.Compute(this.Vertices.ElementAt(0));

            // Example: Get to town from farm hous
        }
예제 #11
0
        public void Populate()
        {
            foreach (GameLocation location in this.gameLocations)
            {
                var partialGraph = new PartialGraph(location);
                partialGraph.Populate();
                this.PartialGraphs.Add(partialGraph);
            }

            var farmBuildings = Game1.getFarm().buildings;

            foreach (Building building in farmBuildings)
            {
                var indoors = building.indoors.Value;
                if (indoors != null && indoors is AnimalHouse)
                {
                    var partialGraph = new PartialGraph((AnimalHouse)indoors);
                    partialGraph.Populate();
                    this.PartialGraphs.Add(partialGraph);
                }
            }

            foreach (PartialGraph pgSource in this.PartialGraphs)
            {
                foreach (PartialGraph pgTarget in this.PartialGraphs)
                {
                    if (pgSource != pgTarget)
                    {
                        this.ConnectPartialGraph(pgSource, pgTarget);
                    }
                }
            }

            foreach (PartialGraph partialGraph in this.PartialGraphs)
            {
                this.AddVertexRange(partialGraph.Vertices);
                this.AddEdgeRange(partialGraph.Edges);
            }

            Func <StardewEdge, double> edgeCost = (x) => x.Cost;

            this.dijkstra     = new DijkstraShortestPathAlgorithm <StardewVertex, StardewEdge>(this, edgeCost);
            this.distObserver = new VertexDistanceRecorderObserver <StardewVertex, StardewEdge>(edgeCost);
            this.distObserver.Attach(this.dijkstra);
            this.predecessorObserver = new VertexPredecessorRecorderObserver <StardewVertex, StardewEdge>();
            this.predecessorObserver.Attach(this.dijkstra);
        }
예제 #12
0
        public static IEnumerable <Edge <GraphVertex> > ShortestWayAstarAlgorithm(List <GraphVertex> listVertex, List <GraphEdge> listEdge, GraphVertex start, GraphVertex end)
        {
            AdjacencyGraph <GraphVertex, Edge <GraphVertex> > graph = new AdjacencyGraph <GraphVertex, Edge <GraphVertex> >();

            foreach (var vert in listVertex)
            {
                graph.AddVertex(vert);
            }
            foreach (var edge in listEdge)
            {
                graph.AddEdge(new Edge <GraphVertex>(edge.StartVertex, edge.EndVertex));
            }
            Dictionary <Edge <GraphVertex>, double> edgeCost = new Dictionary <Edge <GraphVertex>, double>();
            int i = 0;

            foreach (var edge in graph.Edges)
            {
                double eCost = EdgeCostSearching(edge.Source, edge.Target, listEdge);
                edgeCost.Add(edge, eCost);
                i++;
            }


            Func <Edge <GraphVertex>, double> getW = edge => edgeCost[edge];

            //---------------------------------
            IEnumerable <Edge <GraphVertex> > edgessAstar;
            AStarShortestPathAlgorithm <GraphVertex, Edge <GraphVertex> >     astar    = new AStarShortestPathAlgorithm <GraphVertex, Edge <GraphVertex> >(graph, getW, x => 0.0);
            VertexDistanceRecorderObserver <GraphVertex, Edge <GraphVertex> > distObsA = new VertexDistanceRecorderObserver <GraphVertex, Edge <GraphVertex> >(getW);

            using (distObsA.Attach(astar))
            {
                VertexPredecessorRecorderObserver <GraphVertex, Edge <GraphVertex> > predObs = new VertexPredecessorRecorderObserver <GraphVertex, Edge <GraphVertex> >();
                using (predObs.Attach(astar))
                {
                    astar.Compute(start);
                    if (predObs.TryGetPath(end, out edgessAstar))
                    {
                        return(edgessAstar);
                    }
                }
            }
            return(null);
        }
        public void Constructor()
        {
            Func <Edge <int>, double> edgeWeights = _ => 1.0;
            var recorder = new VertexDistanceRecorderObserver <int, Edge <int> >(edgeWeights);

            Assert.AreSame(edgeWeights, recorder.EdgeWeights);
            Assert.IsNotNull(recorder.DistanceRelaxer);
            Assert.IsNotNull(recorder.Distances);

            var distances = new Dictionary <int, double>();

            recorder = new VertexDistanceRecorderObserver <int, Edge <int> >(
                edgeWeights,
                DistanceRelaxers.ShortestDistance,
                distances);
            Assert.AreSame(edgeWeights, recorder.EdgeWeights);
            Assert.AreSame(DistanceRelaxers.ShortestDistance, recorder.DistanceRelaxer);
            Assert.AreSame(distances, recorder.Distances);
        }
        private void ComputeMinimumTree(
            [NotNull] TVertex target,
            out IDictionary <TVertex, TEdge> successors,
            out IDictionary <TVertex, double> distances)
        {
            Debug.Assert(target != null);

            var reversedGraph =
                new ReversedBidirectionalGraph <TVertex, TEdge>(VisitedGraph);
            var successorsObserver =
                new VertexPredecessorRecorderObserver <TVertex, SReversedEdge <TVertex, TEdge> >();
            var distancesObserver =
                new VertexDistanceRecorderObserver <TVertex, SReversedEdge <TVertex, TEdge> >(ReversedEdgeWeight);
            var shortestPath =
                new DijkstraShortestPathAlgorithm <TVertex, SReversedEdge <TVertex, TEdge> >(
                    this,
                    reversedGraph,
                    ReversedEdgeWeight,
                    DistanceRelaxer);

            using (successorsObserver.Attach(shortestPath))
                using (distancesObserver.Attach(shortestPath))
                    shortestPath.Compute(target);

            successors = new Dictionary <TVertex, TEdge>();
            foreach (KeyValuePair <TVertex, SReversedEdge <TVertex, TEdge> > pair in successorsObserver.VerticesPredecessors)
            {
                successors.Add(pair.Key, pair.Value.OriginalEdge);
            }

            distances = distancesObserver.Distances;

            #region Local function

            double ReversedEdgeWeight(SReversedEdge <TVertex, TEdge> edge)
            {
                return(_edgeWeights(edge.OriginalEdge));
            }

            #endregion
        }
예제 #15
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(Coordinate source, Coordinate 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
            var dijkstra =
                new DijkstraShortestPathAlgorithm <Coordinate, IEdge <Coordinate> >(graph, edge => consts[edge]);

            // Attach a Distance observer to give us the distances between edges
            var distanceObserver =
                new VertexDistanceRecorderObserver <Coordinate, IEdge <Coordinate> >(edge => consts[edge]);

            distanceObserver.Attach(dijkstra);

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

            predecessorObserver.Attach(dijkstra);

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

            // Get the path computed to the destination.
            IEnumerable <IEdge <Coordinate> > path;
            var result = predecessorObserver.TryGetPath(destination, out path);

            // Then we need to turn that into a geomery.
            return(result ? BuildString(new List <IEdge <Coordinate> >(path)) : null);

            // if the count is greater than one then a
            // path could not be found, so we return null
        }
예제 #16
0
        public void BuildGraphAndSearchShortestPathUsingGeometryUnion()
        {            
            IGeometry edges = a.Union(b).Union(c).Union(d).Union(e);
            Assert.IsNotNull(edges);            
            Assert.IsTrue(edges.GetType() == typeof(MultiLineString));
            Assert.Greater(edges.NumGeometries, 0);
            foreach (IGeometry edge in ((GeometryCollection) edges).Geometries)
            {
                Assert.IsNotNull(edge);
                Assert.IsTrue(edge.GetType() == typeof(LineString));
                Debug.WriteLine(edge);
            }

            // Build graph
            IDictionary<IEdge<IGeometry>, double> consts = new Dictionary<IEdge<IGeometry>, double>(edges.NumGeometries);
            AdjacencyGraph<IGeometry, IEdge<IGeometry>> graph = new AdjacencyGraph<IGeometry, IEdge<IGeometry>>(true);
            foreach (ILineString str in ((GeometryCollection) edges).Geometries)
            {               
                // Add vertex 1
                IGeometry vertex1 = str.StartPoint;
                Assert.IsNotNull(vertex1);
                if (!graph.ContainsVertex(vertex1))
                {
                    Debug.WriteLine(String.Format("Adding vertex {0} to the list", vertex1));
                    graph.AddVertex(vertex1);
                }
                else Debug.WriteLine(String.Format("Vertex {0} already present", vertex1));

                // Add vertex 2
                IGeometry vertex2 = str.EndPoint;
                Assert.IsNotNull(vertex2);
                if (!graph.ContainsVertex(vertex2))
                {
                    Debug.WriteLine(String.Format("Adding vertex {0} to the list", vertex2));
                    graph.AddVertex(vertex2);
                }
                else Debug.WriteLine(String.Format("Vertex {0} already present", vertex2));

                // Compute weight
                double weight = weightComputer(str);
                Assert.Greater(weight, 0.0);

                // Add edge for 1 => 2
                IEdge<IGeometry> edge1 = new Edge<IGeometry>(vertex1, vertex2);
                Assert.IsNotNull(edge1);
                graph.AddEdge(edge1);
                consts.Add(edge1, weight);

                // Add edge for 2 => 1
                IEdge<IGeometry> edge2 = new Edge<IGeometry>(vertex2, vertex1);
                Assert.IsNotNull(edge2);
                graph.AddEdge(edge2);
                consts.Add(edge2, weight);
            }

            // Perform DijkstraShortestPathAlgorithm
            DijkstraShortestPathAlgorithm<IGeometry, IEdge<IGeometry>> dijkstra =
                new DijkstraShortestPathAlgorithm<IGeometry, IEdge<IGeometry>>(graph, consts);

            // attach a distance observer to give us the shortest path distances
            VertexDistanceRecorderObserver<IGeometry, IEdge<IGeometry>> distObserver =
                new VertexDistanceRecorderObserver<IGeometry, IEdge<IGeometry>>();
            distObserver.Attach(dijkstra);

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

            // Run the algorithm             
            Debug.WriteLine(String.Format("Starting algorithm from root vertex {0}", start));
            dijkstra.Compute(start);

            foreach (KeyValuePair<IGeometry, int> kvp in distObserver.Distances)
                Debug.WriteLine(String.Format("Distance from root to node {0} is {1}", 
                    kvp.Key, kvp.Value));
            foreach (KeyValuePair<IGeometry, IEdge<IGeometry>> kvp in predecessorObserver.VertexPredecessors)
                Debug.WriteLine(String.Format(
                    "If you want to get to {0} you have to enter through the IN edge {1}", kvp.Key, kvp.Value));
            Check(graph, consts, predecessorObserver);

            // Detach the observers
            distObserver.Detach(dijkstra);
            predecessorObserver.Detach(dijkstra);
        }
예제 #17
0
파일: 01_example.cs 프로젝트: silgon/dev
        public static void Main(string[] args)
        {
            AdjacencyGraph <string, Edge <string> > graph = new AdjacencyGraph <string, Edge <string> >(true);

            // Add some vertices to the graph
            graph.AddVertex("A");
            graph.AddVertex("B");
            graph.AddVertex("C");
            graph.AddVertex("D");
            graph.AddVertex("E");
            graph.AddVertex("F");
            graph.AddVertex("G");
            graph.AddVertex("H");
            graph.AddVertex("I");
            graph.AddVertex("J");

            // Create the edges
            Edge <string> a_b = new Edge <string>("A", "B");
            Edge <string> a_d = new Edge <string>("A", "D");
            Edge <string> b_a = new Edge <string>("B", "A");
            Edge <string> b_c = new Edge <string>("B", "C");
            Edge <string> b_e = new Edge <string>("B", "E");
            Edge <string> c_b = new Edge <string>("C", "B");
            Edge <string> c_f = new Edge <string>("C", "F");
            Edge <string> c_j = new Edge <string>("C", "J");
            Edge <string> d_e = new Edge <string>("D", "E");
            Edge <string> d_g = new Edge <string>("D", "G");
            Edge <string> e_d = new Edge <string>("E", "D");
            Edge <string> e_f = new Edge <string>("E", "F");
            Edge <string> e_h = new Edge <string>("E", "H");
            Edge <string> f_i = new Edge <string>("F", "I");
            Edge <string> f_j = new Edge <string>("F", "J");
            Edge <string> g_d = new Edge <string>("G", "D");
            Edge <string> g_h = new Edge <string>("G", "H");
            Edge <string> h_g = new Edge <string>("H", "G");
            Edge <string> h_i = new Edge <string>("H", "I");
            Edge <string> i_f = new Edge <string>("I", "F");
            Edge <string> i_j = new Edge <string>("I", "J");
            Edge <string> i_h = new Edge <string>("I", "H");
            Edge <string> j_f = new Edge <string>("J", "F");

            // Add the edges
            graph.AddEdge(a_b);
            graph.AddEdge(a_d);
            graph.AddEdge(b_a);
            graph.AddEdge(b_c);
            graph.AddEdge(b_e);
            graph.AddEdge(c_b);
            graph.AddEdge(c_f);
            graph.AddEdge(c_j);
            graph.AddEdge(d_e);
            graph.AddEdge(d_g);
            graph.AddEdge(e_d);
            graph.AddEdge(e_f);
            graph.AddEdge(e_h);
            graph.AddEdge(f_i);
            graph.AddEdge(f_j);
            graph.AddEdge(g_d);
            graph.AddEdge(g_h);
            graph.AddEdge(h_g);
            graph.AddEdge(h_i);
            graph.AddEdge(i_f);
            graph.AddEdge(i_h);
            graph.AddEdge(i_j);
            graph.AddEdge(j_f);

            // Define some weights to the edges
            Dictionary <Edge <string>, double> edgeCost = new Dictionary <Edge <string>, double>(graph.EdgeCount)
            {
                { a_b, 4 },
                { a_d, 1 },
                { b_a, 74 },
                { b_c, 2 },
                { b_e, 12 },
                { c_b, 12 },
                { c_f, 74 },
                { c_j, 12 },
                { d_e, 32 },
                { d_g, 22 },
                { e_d, 66 },
                { e_f, 76 },
                { e_h, 33 },
                { f_i, 11 },
                { f_j, 21 },
                { g_d, 12 },
                { g_h, 10 },
                { h_g, 2 },
                { h_i, 72 },
                { i_f, 31 },
                { i_h, 18 },
                { i_j, 7 },
                { j_f, 8 }
            };

            Func <Edge <string>, double> getWeight = edge => edgeCost[edge];

            // We want to use Dijkstra on this graph
            DijkstraShortestPathAlgorithm <string, Edge <string> > dijkstra = new DijkstraShortestPathAlgorithm <string, Edge <string> >(graph, getWeight);

            //// attach a distance observer to give us the shortest path distances
            VertexDistanceRecorderObserver <string, Edge <string> > distObserver = new VertexDistanceRecorderObserver <string, Edge <string> >(getWeight);

            using (distObserver.Attach(dijkstra))
            {
                //// Attach a Vertex Predecessor Recorder Observer to give us the paths
                VertexPredecessorRecorderObserver <string, Edge <string> > predecessorObserver = new VertexPredecessorRecorderObserver <string, Edge <string> >();
                using (predecessorObserver.Attach(dijkstra))
                {
                    //// Run the algorithm with A set to be the source
                    dijkstra.Compute("A");

                    foreach (KeyValuePair <string, double> kvp in distObserver.Distances)
                    {
                        Console.WriteLine("Distance from root to node {0} is {1}", kvp.Key, kvp.Value);
                    }

                    foreach (KeyValuePair <string, Edge <string> > kvp in predecessorObserver.VertexPredecessors)
                    {
                        Console.WriteLine("If you want to get to {0} you have to enter through the in edge {1}", kvp.Key, kvp.Value);
                    }
                }
            }
        }
예제 #18
0
        public List <FloorTile> getPath()
        {
            List <FloorTile> retval = new List <FloorTile>();

            if (this.fp == null || this.fp.getStartTile() == null || this.fp.getTargetTile() == null)
            {
                return(retval);
            }

            startPoint  = this.fp.getStartTile().Position.X + "_" + this.fp.getStartTile().Position.Y;
            targetPoint = this.fp.getTargetTile().Position.X + "_" + this.fp.getTargetTile().Position.Y;



            this.messages += "- Start Get Path\n";
            //startPoint = txtStartPoint.Text;
            //targetPoint = txtTargetPoint.Text;

            DijkstraShortestPathAlgorithm <string, Edge <string> > dijkstra = new DijkstraShortestPathAlgorithm <string, Edge <string> >(graph, AlgorithmExtensions.GetIndexer <Edge <string>, double>(edgeCost));

            // Attach a Vertex Predecessor Recorder Observer to give us the paths
            QuickGraph.Algorithms.Observers.VertexPredecessorRecorderObserver <string, Edge <string> > predecessorObserver = new QuickGraph.Algorithms.Observers.VertexPredecessorRecorderObserver <string, Edge <string> >();
            predecessorObserver.Attach(dijkstra);

            // attach a distance observer to give us the shortest path distances
            VertexDistanceRecorderObserver <string, Edge <string> > distObserver = new VertexDistanceRecorderObserver <string, Edge <string> >(AlgorithmExtensions.GetIndexer <Edge <string>, double>(edgeCost));

            distObserver.Attach(dijkstra);

            // Run the algorithm with A set to be the source
            dijkstra.Compute(startPoint);
            this.messages += "    Start Point: " + startPoint + ".\n";
            this.messages += "    Target Point: " + targetPoint + ".\n";

            String outString = "";

            //outString += distObserver.Distances[targetPoint] + "\n";

            IEnumerable <Edge <string> > path;

            if (predecessorObserver.TryGetPath(targetPoint, out path))
            {
                foreach (var u in path)
                {
                    outString += u + ";";
                }
            }



            string[] outEdges = Regex.Split(outString, ";");
            if (outEdges.Length > 0)
            {
                for (int i = 0; i < outEdges.Length; i++)
                {
                    if (outEdges[i].Length > 0)
                    {
                        this.messages += outEdges[i] + "\n";
                        string[] outPoint = Regex.Split(outEdges[i], "->");
                        //start points
                        retval.Add(getTileByIndex(fp, outPoint[0]));
                    }
                }
                //add target
                retval.Add(getTileByIndex(fp, targetPoint));
            }

            this.messages += retval.Count.ToString() + "\n";;

            if (retval.Count == 1 && retval[0].Equals(getTileByIndex(fp, targetPoint)))
            {
                this.messages += "Can't find path. Start or end point is not walkable or no available walkable tiles" + "\n";;
                return(null);
            }

            fp.setPath(retval);
            //return retval;

            return(condenseList(retval));
        }
        public void Attach()
        {
            // DFS is used for tests but result may change if using another search algorithm
            // or another starting point
            {
                var recorder = new VertexDistanceRecorderObserver <int, Edge <int> >(_ => 1.0);

                var graph = new AdjacencyGraph <int, Edge <int> >();

                var dfs = new DepthFirstSearchAlgorithm <int, Edge <int> >(graph);
                using (recorder.Attach(dfs))
                {
                    dfs.Compute();

                    CollectionAssert.IsEmpty(recorder.Distances);
                }
            }

            {
                var recorder = new VertexDistanceRecorderObserver <int, Edge <int> >(_ => 1.0);

                var graph = new AdjacencyGraph <int, Edge <int> >();
                graph.AddVertexRange(new[] { 1, 2 });

                var dfs = new DepthFirstSearchAlgorithm <int, Edge <int> >(graph);
                using (recorder.Attach(dfs))
                {
                    dfs.Compute();

                    CollectionAssert.IsEmpty(recorder.Distances);
                }
            }

            {
                var recorder = new VertexDistanceRecorderObserver <int, Edge <int> >(_ => 1.0);

                // Graph without cycle
                var edge12 = new Edge <int>(1, 2);
                var edge13 = new Edge <int>(1, 3);
                var edge14 = new Edge <int>(1, 4);
                var edge24 = new Edge <int>(2, 4);
                var edge31 = new Edge <int>(3, 1);
                var edge33 = new Edge <int>(3, 3);
                var edge34 = new Edge <int>(3, 4);
                var graph  = new AdjacencyGraph <int, Edge <int> >();
                graph.AddVerticesAndEdgeRange(new[]
                {
                    edge12, edge13, edge14, edge24, edge31, edge33, edge34
                });

                var dfs = new DepthFirstSearchAlgorithm <int, Edge <int> >(graph);
                using (recorder.Attach(dfs))
                {
                    dfs.Compute();

                    CollectionAssert.AreEqual(
                        new Dictionary <int, double>
                    {
                        [1] = 0,
                        [2] = 1,
                        [3] = 1,
                        [4] = 2
                    },
                        recorder.Distances);
                }
            }

            {
                var recorder = new VertexDistanceRecorderObserver <int, Edge <int> >(_ => 1.0);

                // Graph with cycle
                var edge12 = new Edge <int>(1, 2);
                var edge13 = new Edge <int>(1, 3);
                var edge14 = new Edge <int>(1, 4);
                var edge24 = new Edge <int>(2, 4);
                var edge31 = new Edge <int>(3, 1);
                var edge33 = new Edge <int>(3, 3);
                var edge34 = new Edge <int>(3, 4);
                var edge41 = new Edge <int>(4, 1);
                var graph  = new AdjacencyGraph <int, Edge <int> >();
                graph.AddVerticesAndEdgeRange(new[]
                {
                    edge12, edge13, edge14, edge24, edge31, edge33, edge34, edge41
                });

                var dfs = new DepthFirstSearchAlgorithm <int, Edge <int> >(graph);
                using (recorder.Attach(dfs))
                {
                    dfs.Compute();

                    CollectionAssert.AreEqual(
                        new Dictionary <int, double>
                    {
                        [1] = 0,
                        [2] = 1,
                        [3] = 1,
                        [4] = 2
                    },
                        recorder.Distances);
                }
            }
        }
예제 #20
0
        static void PrepareGitHubExample()
        {
            AdjacencyGraph<string, Edge<string>> graph = new AdjacencyGraph<string, Edge<string>>(true);

            // Add some vertices to the graph
            graph.AddVertex("A");
            graph.AddVertex("B");
            graph.AddVertex("C");
            graph.AddVertex("D");
            graph.AddVertex("E");
            graph.AddVertex("F");
            graph.AddVertex("G");
            graph.AddVertex("H");
            graph.AddVertex("I");
            graph.AddVertex("J");

            // Create the edges
            Edge<string> a_b = new Edge<string>("A", "B");
            Edge<string> a_d = new Edge<string>("A", "D");
            Edge<string> b_a = new Edge<string>("B", "A");
            Edge<string> b_c = new Edge<string>("B", "C");
            Edge<string> b_e = new Edge<string>("B", "E");
            Edge<string> c_b = new Edge<string>("C", "B");
            Edge<string> c_f = new Edge<string>("C", "F");
            Edge<string> c_j = new Edge<string>("C", "J");
            Edge<string> d_e = new Edge<string>("D", "E");
            Edge<string> d_g = new Edge<string>("D", "G");
            Edge<string> e_d = new Edge<string>("E", "D");
            Edge<string> e_f = new Edge<string>("E", "F");
            Edge<string> e_h = new Edge<string>("E", "H");
            Edge<string> f_i = new Edge<string>("F", "I");
            Edge<string> f_j = new Edge<string>("F", "J");
            Edge<string> g_d = new Edge<string>("G", "D");
            Edge<string> g_h = new Edge<string>("G", "H");
            Edge<string> h_g = new Edge<string>("H", "G");
            Edge<string> h_i = new Edge<string>("H", "I");
            Edge<string> i_f = new Edge<string>("I", "F");
            Edge<string> i_j = new Edge<string>("I", "J");
            Edge<string> i_h = new Edge<string>("I", "H");
            Edge<string> j_f = new Edge<string>("J", "F");

            // Add the edges
            graph.AddEdge(a_b);
            graph.AddEdge(a_d);
            graph.AddEdge(b_a);
            graph.AddEdge(b_c);
            graph.AddEdge(b_e);
            graph.AddEdge(c_b);
            graph.AddEdge(c_f);
            graph.AddEdge(c_j);
            graph.AddEdge(d_e);
            graph.AddEdge(d_g);
            graph.AddEdge(e_d);
            graph.AddEdge(e_f);
            graph.AddEdge(e_h);
            graph.AddEdge(f_i);
            graph.AddEdge(f_j);
            graph.AddEdge(g_d);
            graph.AddEdge(g_h);
            graph.AddEdge(h_g);
            graph.AddEdge(h_i);
            graph.AddEdge(i_f);
            graph.AddEdge(i_h);
            graph.AddEdge(i_j);
            graph.AddEdge(j_f);

            // Define some weights to the edges
            Dictionary<Edge<string>, double> edgeCost = new Dictionary<Edge<string>, double>(graph.EdgeCount);
            edgeCost.Add(a_b, 4);
            edgeCost.Add(a_d, 1);
            edgeCost.Add(b_a, 74);
            edgeCost.Add(b_c, 2);
            edgeCost.Add(b_e, 12);
            edgeCost.Add(c_b, 12);
            edgeCost.Add(c_f, 74);
            edgeCost.Add(c_j, 12);
            edgeCost.Add(d_e, 32);
            edgeCost.Add(d_g, 22);
            edgeCost.Add(e_d, 66);
            edgeCost.Add(e_f, 76);
            edgeCost.Add(e_h, 33);
            edgeCost.Add(f_i, 11);
            edgeCost.Add(f_j, 21);
            edgeCost.Add(g_d, 12);
            edgeCost.Add(g_h, 10);
            edgeCost.Add(h_g, 2);
            edgeCost.Add(h_i, 72);
            edgeCost.Add(i_f, 31);
            edgeCost.Add(i_h, 18);
            edgeCost.Add(i_j, 7);
            edgeCost.Add(j_f, 8);

            Func<Edge<string>, double> edgeCostFunction = e => edgeCost[e]; // constant cost

            Func<Edge<string>, double> distObserverFunction = e => 1;

            // We want to use Dijkstra on this graph
            DijkstraShortestPathAlgorithm<string, Edge<string>> dijkstra = new DijkstraShortestPathAlgorithm<string, Edge<string>>(graph, edgeCostFunction);

            // attach a distance observer to give us the shortest path distances
            VertexDistanceRecorderObserver<string, Edge<string>> distObserver = new VertexDistanceRecorderObserver<string, Edge<string>>(distObserverFunction);
            distObserver.Attach(dijkstra);

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

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

            foreach (KeyValuePair<string, double> kvp in distObserver.Distances)
                Console.WriteLine("Distance from root to node {0} is {1}", kvp.Key, kvp.Value);

            foreach (KeyValuePair<string, Edge<string>> kvp in predecessorObserver.VertexPredecessors)
                Console.WriteLine("If you want to get to {0} you have to enter through the in edge {1}", kvp.Key, kvp.Value);

            // Remember to detach the observers
            // distObserver.Detach(dijkstra);
            // predecessorObserver.Detach(dijkstra);

            // Visualize the Graph
            var graphviz = new GraphvizAlgorithm<string, Edge<string>>(graph);
            graphviz.ImageType = GraphvizImageType.Jpeg;

            // render
            string outputString = graphviz.Generate();
            string output = graphviz.Generate(new FileDotEngine(), "MyGraph");
        }
예제 #21
0
        internal ILineString PerformShortestPathAnalysis(IPoint source, IPoint destination,bool usesCondensedGraph)
        {
            // We keep  a copy so we can terminate the search early.
            _theDestination = destination;

            // This is an instrance of the shortest path algortihm.
            _dijkstra = new DijkstraShortestPathAlgorithm<Coordinate, Edge<Coordinate>>(_graph, AlgorithmExtensions.GetIndexer(_edgeCost));
            
            // Quick Graph uses 'observers'  to record the distance traveled and the path travelled througth, 
            var distObserver = new VertexDistanceRecorderObserver<Coordinate, Edge<Coordinate>>(AlgorithmExtensions.GetIndexer(_edgeCost));
            var predecessorObserver = new VertexPredecessorRecorderObserver<Coordinate, Edge<Coordinate>>();
            distObserver.Attach(_dijkstra);
            predecessorObserver.Attach(_dijkstra);

            // Having this present means that when we finally reach the target node 
            // the dijkstra algortihm can quit without scanning other nodes in the graph, leading to
            // performance increases.
            _dijkstra.FinishVertex += dijkstra_FinishVertex;


            // This is where the shortest path is calculated. 
            var sw = new System.Diagnostics.Stopwatch();
            sw.Start();
            _dijkstra.Compute(source.Coordinate);
            sw.Stop();
            System.Diagnostics.Debug.WriteLine("Dijsktra Took: " + sw.ElapsedMilliseconds);

            // get the cost of the path. If one is found then d (=distance) should be greater than zero so we get the edges making up
            // the path.
            double d = AlgorithmExtensions.ComputePredecessorCost(predecessorObserver.VertexPredecessors, _edgeCost, destination.Coordinate);
            System.Diagnostics.Debug.WriteLine(d);

            if (d > 0)
            {
                IEnumerable<Edge<Coordinate>> edgesInShortestPath;
                if (predecessorObserver.TryGetPath(destination.Coordinate, out edgesInShortestPath))
                {
                    var theCompleteShortestPath = new List<Coordinate>();

                    // We need to use a different approach when using the condensed graph.
                    if (usesCondensedGraph)
                    {
                        foreach (var edgeInShortPath in edgesInShortestPath)
                        {
                            var ls = GetLineStringInformation(edgeInShortPath);

                            if (ls != null)
                            {
                                // We need to get each of the nodes that makes up the lines.
                                // we need to add each of them on one list. 
                                var count = ls.Coordinates.Length;

                                for (var i = 0; i < count; i++)
                                    theCompleteShortestPath.Add(ls.Coordinates[i]);
                            } // End Of If
                        } // Loop Around Each Edge In The Shortest Path
                    } // End of If
                    else
                    {
                        foreach (var edgeInShortPath in edgesInShortestPath)
                        {
                            theCompleteShortestPath.Add(edgeInShortPath.Source);
                            theCompleteShortestPath.Add(edgeInShortPath.Target);
                        }
                    } // End Of Else

                    var theShortestPath = _geomFactory.CreateLineString(theCompleteShortestPath.ToArray());
                    return theShortestPath;

                } // There Was A Shortest Path

                // Return null. 
                // ToDo: Need to improve this bit so it at least indicates if the SP didnt get a path/
                return null; 
            }

            return null;

        }
예제 #22
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;
        }
예제 #23
0
        public void BuildGraphFromMinimalGraphShapefile()
        {
            string path = "minimalgraph.shp";
            int count = 15;
            Assert.IsTrue(File.Exists(path));
            ShapefileReader reader = new ShapefileReader(path);
            IGeometryCollection edges = reader.ReadAll();
            Assert.IsNotNull(edges);
            Assert.IsInstanceOfType(typeof(GeometryCollection), edges);
            Assert.AreEqual(count, edges.NumGeometries);

            ILineString startls = null;
            // Build graph
            Dictionary<IEdge<IGeometry>, double> consts = new Dictionary<IEdge<IGeometry>, double>(edges.NumGeometries);
            AdjacencyGraph<IGeometry, IEdge<IGeometry>> graph = new AdjacencyGraph<IGeometry, IEdge<IGeometry>>(true);
            foreach (IMultiLineString mlstr in edges.Geometries)
            {
                Assert.AreEqual(1, mlstr.NumGeometries);
                ILineString str = (ILineString) mlstr.GetGeometryN(0);
                if (startls == null)
                    startls = str;

                // Add vertex 1
                IGeometry vertex1 = str.StartPoint;
                Assert.IsNotNull(vertex1);
                if (!graph.ContainsVertex(vertex1))
                {
                    Debug.WriteLine(String.Format("Adding vertex {0} to the list", vertex1));
                    graph.AddVertex(vertex1);
                }
                else Debug.WriteLine(String.Format("Vertex {0} already present", vertex1));

                // Add vertex 2
                IGeometry vertex2 = str.EndPoint;
                Assert.IsNotNull(vertex2);
                if (!graph.ContainsVertex(vertex2))
                {
                    Debug.WriteLine(String.Format("Adding vertex {0} to the list", vertex2));
                    graph.AddVertex(vertex2);
                }
                else Debug.WriteLine(String.Format("Vertex {0} already present", vertex2));

                // Compute weight
                double weight = weightComputer(str);
                Assert.Greater(weight, 0.0);

                // Add edge 1 => 2
                IEdge<IGeometry> edge1 = new Edge<IGeometry>(vertex1, vertex2);
                Assert.IsNotNull(edge1);                
                graph.AddEdge(edge1);
                consts.Add(edge1, weight);

                // Add edge 2 => 1
                IEdge<IGeometry> edge2 = new Edge<IGeometry>(vertex2, vertex1);
                Assert.IsNotNull(edge2);
                graph.AddEdge(edge2);
                consts.Add(edge2, weight);
            }

            // Perform DijkstraShortestPathAlgorithm
            DijkstraShortestPathAlgorithm<IGeometry, IEdge<IGeometry>> dijkstra =
                new DijkstraShortestPathAlgorithm<IGeometry, IEdge<IGeometry>>(graph, consts);

            // attach a distance observer to give us the shortest path distances
            VertexDistanceRecorderObserver<IGeometry, IEdge<IGeometry>> distObserver =
                new VertexDistanceRecorderObserver<IGeometry, IEdge<IGeometry>>();
            distObserver.Attach(dijkstra);

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

            // Run the algorithm   
            Assert.IsNotNull(startls);
            IGeometry startPoint = startls.StartPoint;
            Debug.WriteLine(String.Format("Starting algorithm from root vertex {0}", startPoint));
            dijkstra.Compute(startPoint);

            foreach (KeyValuePair<IGeometry, int> kvp in distObserver.Distances)
                Debug.WriteLine(String.Format("Distance from root to node {0} is {1}",
                    kvp.Key, kvp.Value));
            foreach (KeyValuePair<IGeometry, IEdge<IGeometry>> kvp in predecessorObserver.VertexPredecessors)
                Debug.WriteLine(String.Format(
                    "If you want to get to {0} you have to enter through the IN edge {1}", kvp.Key, kvp.Value));
            Check(graph, consts, predecessorObserver);

            // Detach the observers
            distObserver.Detach(dijkstra);
            predecessorObserver.Detach(dijkstra);
        }
예제 #24
0
        internal ILineString PerformShortestPathAnalysis(IPoint source, IPoint destination, bool usesCondensedGraph)
        {
            // We keep  a copy so we can terminate the search early.
            _theDestination = destination;

            // This is an instrance of the shortest path algortihm.
            _dijkstra = new DijkstraShortestPathAlgorithm <Coordinate, Edge <Coordinate> >(_graph, AlgorithmExtensions.GetIndexer(_edgeCost));

            // Quick Graph uses 'observers'  to record the distance traveled and the path travelled througth,
            var distObserver        = new VertexDistanceRecorderObserver <Coordinate, Edge <Coordinate> >(AlgorithmExtensions.GetIndexer(_edgeCost));
            var predecessorObserver = new VertexPredecessorRecorderObserver <Coordinate, Edge <Coordinate> >();

            distObserver.Attach(_dijkstra);
            predecessorObserver.Attach(_dijkstra);

            // Having this present means that when we finally reach the target node
            // the dijkstra algortihm can quit without scanning other nodes in the graph, leading to
            // performance increases.
            _dijkstra.FinishVertex += dijkstra_FinishVertex;


            // This is where the shortest path is calculated.
            var sw = new System.Diagnostics.Stopwatch();

            sw.Start();
            _dijkstra.Compute(source.Coordinate);
            sw.Stop();
            System.Diagnostics.Debug.WriteLine("Dijsktra Took: " + sw.ElapsedMilliseconds);

            // get the cost of the path. If one is found then d (=distance) should be greater than zero so we get the edges making up
            // the path.
            double d = AlgorithmExtensions.ComputePredecessorCost(predecessorObserver.VertexPredecessors, _edgeCost, destination.Coordinate);

            System.Diagnostics.Debug.WriteLine(d);

            if (d > 0)
            {
                IEnumerable <Edge <Coordinate> > edgesInShortestPath;
                if (predecessorObserver.TryGetPath(destination.Coordinate, out edgesInShortestPath))
                {
                    var theCompleteShortestPath = new List <Coordinate>();

                    // We need to use a different approach when using the condensed graph.
                    if (usesCondensedGraph)
                    {
                        foreach (var edgeInShortPath in edgesInShortestPath)
                        {
                            var ls = GetLineStringInformation(edgeInShortPath);

                            if (ls != null)
                            {
                                // We need to get each of the nodes that makes up the lines.
                                // we need to add each of them on one list.
                                var count = ls.Coordinates.Length;

                                for (var i = 0; i < count; i++)
                                {
                                    theCompleteShortestPath.Add(ls.Coordinates[i]);
                                }
                            } // End Of If
                        }     // Loop Around Each Edge In The Shortest Path
                    }         // End of If
                    else
                    {
                        foreach (var edgeInShortPath in edgesInShortestPath)
                        {
                            theCompleteShortestPath.Add(edgeInShortPath.Source);
                            theCompleteShortestPath.Add(edgeInShortPath.Target);
                        }
                    } // End Of Else

                    var theShortestPath = _geomFactory.CreateLineString(theCompleteShortestPath.ToArray());
                    return(theShortestPath);
                } // There Was A Shortest Path

                // Return null.
                // ToDo: Need to improve this bit so it at least indicates if the SP didnt get a path/
                return(null);
            }

            return(null);
        }
예제 #25
0
        static void Main(string[] args)
        {
            var graph    = new AdjacencyGraph <string, Edge <string> >(false);
            var edgeCost = new Dictionary <Edge <string>, double>();

            //Add all vertices
            for (int eastWest = 0; eastWest < numEastWest; eastWest++)
            {
                for (int northSouth = 0; northSouth < numNorthSouth; northSouth++)
                {
                    string cornerName = ToCornerName(eastWest, northSouth);
                    Trace.WriteLine("Adding vertex: " + cornerName);

                    graph.AddVertex(cornerName);
                }
            }

            // Create the edges
            for (int eastWest = 0; eastWest < numEastWest; eastWest++)
            {
                for (int northSouth = 0; northSouth < numNorthSouth; northSouth++)
                {
                    var cornerName = ToCornerName(eastWest, northSouth);

                    AddEdge(graph, edgeCost, cornerName, ToCornerName(eastWest, northSouth - 1));
                    AddEdge(graph, edgeCost, cornerName, ToCornerName(eastWest, northSouth + 1));
                    AddEdge(graph, edgeCost, cornerName, ToCornerName(eastWest - 1, northSouth));
                    AddEdge(graph, edgeCost, cornerName, ToCornerName(eastWest + 1, northSouth));
                }
            }

            Func <Edge <string>, double> getWeight = edge => edgeCost[edge];

            // We want to use Dijkstra on this graph
            var dijkstra = new DijkstraShortestPathAlgorithm <string, Edge <string> >(graph, getWeight);

            // attach a distance observer to give us the shortest path distances
            var distObserver = new VertexDistanceRecorderObserver <string, Edge <string> >(getWeight);

            distObserver.Attach(dijkstra);

            // Attach a Vertex Predecessor Recorder Observer to give us the paths
            VertexPredecessorRecorderObserver <string, Edge <string> > predecessorObserver = new VertexPredecessorRecorderObserver <string, Edge <string> >();

            predecessorObserver.Attach(dijkstra);

            // Run the algorithm from the starting point
            dijkstra.Compute(startVertex);

            foreach (KeyValuePair <string, double> kvp in distObserver.Distances)
            {
                Log(string.Format("Distance from {0} to node {1} is {2}", startVertex, kvp.Key, kvp.Value));
            }

            foreach (KeyValuePair <string, Edge <string> > kvp in predecessorObserver.VertexPredecessors)
            {
                Log(string.Format("If you want to get to {0} you have to enter through the in edge {1}", kvp.Key, kvp.Value));
            }

            //Get those paths that travel at least once in the ultra path.
            var ultraEdgePaths = new List <Edge <string> >();

            foreach (var edge in predecessorObserver.VertexPredecessors.Values)
            {
                if (edge.Source.Contains("U") && edge.Target.Contains("U"))
                {
                    ultraEdgePaths.Add(edge);
                }
            }

            var destinationsTravellingUltra = GetUltraPaths(predecessorObserver);

            Bitmap bitmap = GenerateBitmap(destinationsTravellingUltra, distObserver);

            var filename = "C:/temp/riddle.png";

            bitmap.Save(filename, ImageFormat.Png);

            Process.Start(@"firefox.exe", "file://" + filename);

            destinationsTravellingUltra.Sort();
            foreach (var dest in destinationsTravellingUltra)
            {
                Log("Destination travelling ultra: " + dest);
            }

            var ultraProjection = from s in destinationsTravellingUltra
                                  select new Tuple <int, string>(int.Parse(s.Substring(0, s.Length - 1)), s);

            var northCorners = from t in ultraProjection
                               where t.Item1 < 20
                               group t by t.Item2.Substring(t.Item2.Length - 1) into g
                               orderby g.Key
                               select g.Max().Item2;

            var southCorners = from t in ultraProjection
                               where t.Item1 > 20
                               group t by t.Item2.Substring(t.Item2.Length - 1) into g
                               orderby g.Key descending
                               select g.Min().Item2;

            Log("All blocks north of and to the east of (including): " + string.Join(",", northCorners));
            Log("All blocks south of and to the east of (including): " + string.Join(",", southCorners));
        }
예제 #26
0
        static void Test2(InputMode pIM)
        {
            string filePath = null;

            System.IO.StreamReader sR = null;
            Console.WriteLine();
            if (pIM == InputMode.CLI)
            {
                Console.WriteLine("Please enter your query in the form of:");
                Console.WriteLine("\t>: number n of cities in the graph (beginning at 0)");
                Console.WriteLine("\t>: number m of unidirectinal prexisting roads");
                Console.WriteLine("\t>: NEXT M LINES: <city1>:<city2>:<road length>");
                Console.WriteLine("\t>: number k of optional unidirectional roads");
                Console.WriteLine("\t>: NEXT K LINES: <city1>:<city2>:<road length>");
                Console.WriteLine("\t>: s (source city)");
                Console.WriteLine("\t>: t (target city)");
            }
            else
            {
                Console.WriteLine("Please enter the path of the file to pull input from.");
                filePath = Console.ReadLine();
                while (!File.Exists(filePath))
                {
                    Console.WriteLine("That file appears to not exist. Try again.");
                    filePath = Console.ReadLine();
                }
                while (IsFileinUse(filePath))
                {
                    Console.WriteLine("File is currently in use. Please close it and press enter.");
                    Console.ReadLine();
                }
                sR = new System.IO.StreamReader(filePath);
            }

            AdjacencyGraph<string, Edge<string>> graph = new AdjacencyGraph<string, Edge<string>>(true);
            // Transpose graph
            AdjacencyGraph<string, Edge<string>> tGraph = new AdjacencyGraph<string, Edge<string>>(true);
            Dictionary<Edge<string>, double> edgeCost = new Dictionary<Edge<string>, double>();
            Dictionary<Edge<string>, double> tEdgeCost = new Dictionary<Edge<string>, double>();

            int n = Convert.ToInt32((pIM == InputMode.CLI) ? Console.ReadLine() : sR.ReadLine());
            for (int i = 0; i < n; i++)
            {
                AddNodeToBoth(graph, tGraph, ""+i);
            }
            int m = Convert.ToInt32((pIM == InputMode.CLI) ? Console.ReadLine() : sR.ReadLine());
            char[] splitChars = {':'};
            string[] theParts;
            for (int i = 0; i < m; i++)
            {
                theParts = ((pIM == InputMode.CLI) ? Console.ReadLine() : sR.ReadLine()).Replace(" ", "").Replace("\t", "").Split(splitChars);
                AddEdgeToBoth(graph, tGraph, edgeCost, tEdgeCost, theParts[0], theParts[1], Convert.ToInt32(theParts[2]));
            }
            int k = Convert.ToInt32(((pIM == InputMode.CLI) ? Console.ReadLine() : sR.ReadLine()));
            Stack<string[]> optionalEdgeStack = new Stack<string[]>();
            for (int i = 0; i < k; i++)
            {
                optionalEdgeStack.Push(((pIM == InputMode.CLI) ? Console.ReadLine() : sR.ReadLine()).Replace(" ", "").Replace("\t", "").Split(splitChars));
            }
            string source = ((pIM == InputMode.CLI) ? Console.ReadLine() : sR.ReadLine());
            string target = ((pIM == InputMode.CLI) ? Console.ReadLine() : sR.ReadLine());

            System.Func<Edge<String>, double> EdgeCostFunct = (QuickGraph.Edge<string> input) => { return (edgeCost.ContainsKey(input)) ? edgeCost[input] : 1000.0; };
            System.Func<Edge<String>, double> EdgeCostFunct2 = (QuickGraph.Edge<string> input) => { return (tEdgeCost.ContainsKey(input)) ? tEdgeCost[input] : 1000.0; };

            //FORWARD SEARCH

            // We want to use Dijkstra on this graph
            DijkstraShortestPathAlgorithm<string, Edge<string>> dijkstra = new DijkstraShortestPathAlgorithm<string, Edge<string>>(graph, EdgeCostFunct);

            // attach a distance observer to give us the shortest path distances

            VertexDistanceRecorderObserver<string, Edge<string>> distObserver = new VertexDistanceRecorderObserver<string, Edge<string>>(EdgeCostFunct);
            distObserver.Attach(dijkstra);

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

            //BACKWARD SEARCH

            // We want to use Dijkstra on this graph
            DijkstraShortestPathAlgorithm<string, Edge<string>> dijkstra2 = new DijkstraShortestPathAlgorithm<string, Edge<string>>(tGraph, EdgeCostFunct2);

            // attach a distance observer to give us the shortest path distances

            VertexDistanceRecorderObserver<string, Edge<string>> distObserver2 = new VertexDistanceRecorderObserver<string, Edge<string>>(EdgeCostFunct2);
            distObserver2.Attach(dijkstra2);

            // Attach a Vertex Predecessor Recorder Observer to give us the paths
            VertexPredecessorRecorderObserver<string, Edge<string>> predecessorObserver2 = new VertexPredecessorRecorderObserver<string, Edge<string>>();
            predecessorObserver2.Attach(dijkstra2);

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

            if (distObserver.Distances.ContainsKey(target) == false)
            {
                Console.WriteLine(target + " is unreachable");
            }
            else
            {
                dijkstra2.Compute(target);

                double initialPathLength = distObserver.Distances[target];
                Stack<string> viablePathAdditions = new Stack<string>();
                string currentMinEdgeAddition = "";
                double currentMinEdgeWeight = -1.0;
                while (optionalEdgeStack.Count > 0)
                {
                    string[] triple = optionalEdgeStack.Pop();
                    if (distObserver.Distances.ContainsKey(triple[0]) && distObserver2.Distances.ContainsKey(triple[1]))
                    {
                        double total = distObserver.Distances[triple[0]] + distObserver2.Distances[triple[1]] + (double)Int32.Parse(triple[2]);
                        if (total < initialPathLength)
                        {
                            viablePathAdditions.Push(triple[0] + ':' + triple[1]);
                            if (currentMinEdgeWeight < 0 || total < currentMinEdgeWeight)
                            {
                                currentMinEdgeWeight = total;
                                currentMinEdgeAddition = triple[0] + ':' + triple[1];
                            }
                        }
                    }
                }
                if (viablePathAdditions.Count > 0)
                {
                    Console.WriteLine("Additions that would lower path length.");
                    while (viablePathAdditions.Count > 0)
                    {
                        Console.WriteLine(viablePathAdditions.Pop());
                    }
                    Console.WriteLine("The cost-minimizing addition is:");
                    Console.WriteLine(currentMinEdgeAddition);
                }
                else
                {
                    Console.WriteLine("There are no additions that would minimize path length.");
                }
            }
            Console.WriteLine("");
            Console.WriteLine("Press enter to return to the main menu.");
            Console.ReadLine();
            if (sR != null) sR.Close();
        }
예제 #27
0
        public static void foo()
        {
            AdjacencyGraph <string, Edge <string> > graph = new AdjacencyGraph <string, Edge <string> >(true);

            // Add some vertices to the graph
            graph.AddVertex("A");
            graph.AddVertex("B");
            graph.AddVertex("C");
            graph.AddVertex("D");
            graph.AddVertex("E");
            graph.AddVertex("F");
            graph.AddVertex("G");
            graph.AddVertex("H");
            graph.AddVertex("I");
            graph.AddVertex("J");

            var e = graph.Edges;
            // Create the edges
            Edge <string> a_b = new Edge <string>("A", "B");
            Edge <string> a_d = new Edge <string>("A", "D");
            Edge <string> b_a = new Edge <string>("B", "A");
            Edge <string> b_c = new Edge <string>("B", "C");
            Edge <string> b_e = new Edge <string>("B", "E");
            Edge <string> c_b = new Edge <string>("C", "B");
            Edge <string> c_f = new Edge <string>("C", "F");
            Edge <string> c_j = new Edge <string>("C", "J");
            Edge <string> d_e = new Edge <string>("D", "E");
            Edge <string> d_g = new Edge <string>("D", "G");
            Edge <string> e_d = new Edge <string>("E", "D");
            Edge <string> e_f = new Edge <string>("E", "F");
            Edge <string> e_h = new Edge <string>("E", "H");
            Edge <string> f_i = new Edge <string>("F", "I");
            Edge <string> f_j = new Edge <string>("F", "J");
            Edge <string> g_d = new Edge <string>("G", "D");
            Edge <string> g_h = new Edge <string>("G", "H");
            Edge <string> h_g = new Edge <string>("H", "G");
            Edge <string> h_i = new Edge <string>("H", "I");
            Edge <string> i_f = new Edge <string>("I", "F");
            Edge <string> i_j = new Edge <string>("I", "J");
            Edge <string> i_h = new Edge <string>("I", "H");
            Edge <string> j_f = new Edge <string>("J", "F");

            // Add the edges
            graph.AddEdge(a_b);
            graph.AddEdge(a_d);
            graph.AddEdge(b_a);
            graph.AddEdge(b_c);
            graph.AddEdge(b_e);
            graph.AddEdge(c_b);
            graph.AddEdge(c_f);
            graph.AddEdge(c_j);
            graph.AddEdge(d_e);
            graph.AddEdge(d_g);
            graph.AddEdge(e_d);
            graph.AddEdge(e_f);
            graph.AddEdge(e_h);
            graph.AddEdge(f_i);
            graph.AddEdge(f_j);
            graph.AddEdge(g_d);
            graph.AddEdge(g_h);
            graph.AddEdge(h_g);
            graph.AddEdge(h_i);
            graph.AddEdge(i_f);
            graph.AddEdge(i_h);
            graph.AddEdge(i_j);
            graph.AddEdge(j_f);

            // Define some weights to the edges
            Dictionary <Edge <string>, double> edgeCost = new Dictionary <Edge <string>, double>(graph.EdgeCount);

            edgeCost.Add(a_b, 4);
            edgeCost.Add(a_d, 1);
            edgeCost.Add(b_a, 74);
            edgeCost.Add(b_c, 2);
            edgeCost.Add(b_e, 12);
            edgeCost.Add(c_b, 12);
            edgeCost.Add(c_f, 74);
            edgeCost.Add(c_j, 12);
            edgeCost.Add(d_e, 32);
            edgeCost.Add(d_g, 22);
            edgeCost.Add(e_d, 66);
            edgeCost.Add(e_f, 76);
            edgeCost.Add(e_h, 33);
            edgeCost.Add(f_i, 11);
            edgeCost.Add(f_j, 21);
            edgeCost.Add(g_d, 12);
            edgeCost.Add(g_h, 10);
            edgeCost.Add(h_g, 2);
            edgeCost.Add(h_i, 72);
            edgeCost.Add(i_f, 31);
            edgeCost.Add(i_h, 18);
            edgeCost.Add(i_j, 7);
            edgeCost.Add(j_f, 8);

            Func <Edge <string>, double>       edgeCost2 = e1 => 1; // constant cost
            Dictionary <Edge <string>, double> edgeCost3 = new Dictionary <Edge <string>, double>(graph.EdgeCount);

            // We want to use Dijkstra on this graph
            DijkstraShortestPathAlgorithm <string, Edge <string> > dijkstra = new DijkstraShortestPathAlgorithm <string, Edge <string> >(graph, edgeCost2);

            // attach a distance observer to give us the shortest path distances
            VertexDistanceRecorderObserver <string, Edge <string> > distObserver = new VertexDistanceRecorderObserver <string, Edge <string> >(edgeCost2);

            distObserver.Attach(dijkstra);

            // Attach a Vertex Predecessor Recorder Observer to give us the paths
            VertexPredecessorRecorderObserver <string, Edge <string> > predecessorObserver = new VertexPredecessorRecorderObserver <string, Edge <string> >();

            predecessorObserver.Attach(dijkstra);

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

            foreach (KeyValuePair <string, double> kvp in distObserver.Distances)
            {
                Console.WriteLine("Distance from root to node {0} is {1}", kvp.Key, kvp.Value);
            }

            foreach (KeyValuePair <string, Edge <string> > kvp in predecessorObserver.VertexPredecessors)
            {
                Console.WriteLine("If you want to get to {0} you have to enter through the edge {1}", kvp.Key, kvp.Value);
            }

            // Remember to detach the observers
            // distObserver.Detach(dijkstra);
            // predecessorObserver.Detach(dijkstra);
        }
예제 #28
0
        public void BuildGraphAndSearchShortestPathUsingGraphBuilder()
        {
            // Build algorithm
            GraphBuilder builder = new GraphBuilder();
            builder.Add(a);
            builder.Add(b, c);
            builder.Add(d);
            DijkstraShortestPathAlgorithm<IPoint, IEdge<IPoint>> algorithm = builder.PrepareAlgorithm();

            // Attach a distance observer to give us the shortest path distances
            VertexDistanceRecorderObserver<IPoint, IEdge<IPoint>> distObserver =
                new VertexDistanceRecorderObserver<IPoint, IEdge<IPoint>>();
            distObserver.Attach(algorithm);

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

            // Run algorithm
            algorithm.Compute(start);

            // Check results
            int distance = distObserver.Distances[end];
            Assert.AreEqual(2, distance);
            IDictionary<IPoint, IEdge<IPoint>> predecessors = predecessorObserver.VertexPredecessors;
            for (int i = 0; i < distance; i++)
            {
                IEdge<IPoint> edge = predecessors[end];
                if (i == 0)
                {
                    Assert.AreEqual(d.GetPointN(d.NumPoints - 2), edge.Source);
                    Assert.AreEqual(d.EndPoint, edge.Target);
                }
                else if (i == 1)
                {
                    Assert.AreEqual(a.StartPoint, edge.Source);
                    Assert.AreEqual(d.GetPointN(d.NumPoints - 2), edge.Target);
                }
                end = edge.Source;
            }

            // Detach the observers
            distObserver.Detach(algorithm);
            predecessorObserver.Detach(algorithm);
        }        
예제 #29
0
        public void BuildGraphFromMinimalGraphShapefile()
        {
            string path  = "minimalgraph.shp";
            int    count = 15;

            Assert.IsTrue(File.Exists(path));
            ShapefileReader     reader = new ShapefileReader(path);
            IGeometryCollection edges  = reader.ReadAll();

            Assert.IsNotNull(edges);
            Assert.IsInstanceOfType(typeof(GeometryCollection), edges);
            Assert.AreEqual(count, edges.NumGeometries);

            ILineString startls = null;
            // Build graph
            Dictionary <IEdge <IGeometry>, double>         consts = new Dictionary <IEdge <IGeometry>, double>(edges.NumGeometries);
            AdjacencyGraph <IGeometry, IEdge <IGeometry> > graph  = new AdjacencyGraph <IGeometry, IEdge <IGeometry> >(true);

            foreach (IMultiLineString mlstr in edges.Geometries)
            {
                Assert.AreEqual(1, mlstr.NumGeometries);
                ILineString str = (ILineString)mlstr.GetGeometryN(0);
                if (startls == null)
                {
                    startls = str;
                }

                // Add vertex 1
                IGeometry vertex1 = str.StartPoint;
                Assert.IsNotNull(vertex1);
                if (!graph.ContainsVertex(vertex1))
                {
                    Debug.WriteLine(String.Format("Adding vertex {0} to the list", vertex1));
                    graph.AddVertex(vertex1);
                }
                else
                {
                    Debug.WriteLine(String.Format("Vertex {0} already present", vertex1));
                }

                // Add vertex 2
                IGeometry vertex2 = str.EndPoint;
                Assert.IsNotNull(vertex2);
                if (!graph.ContainsVertex(vertex2))
                {
                    Debug.WriteLine(String.Format("Adding vertex {0} to the list", vertex2));
                    graph.AddVertex(vertex2);
                }
                else
                {
                    Debug.WriteLine(String.Format("Vertex {0} already present", vertex2));
                }

                // Compute weight
                double weight = weightComputer(str);
                Assert.Greater(weight, 0.0);

                // Add edge 1 => 2
                IEdge <IGeometry> edge1 = new Edge <IGeometry>(vertex1, vertex2);
                Assert.IsNotNull(edge1);
                graph.AddEdge(edge1);
                consts.Add(edge1, weight);

                // Add edge 2 => 1
                IEdge <IGeometry> edge2 = new Edge <IGeometry>(vertex2, vertex1);
                Assert.IsNotNull(edge2);
                graph.AddEdge(edge2);
                consts.Add(edge2, weight);
            }

            // Perform DijkstraShortestPathAlgorithm
            DijkstraShortestPathAlgorithm <IGeometry, IEdge <IGeometry> > dijkstra =
                new DijkstraShortestPathAlgorithm <IGeometry, IEdge <IGeometry> >(graph, consts);

            // attach a distance observer to give us the shortest path distances
            VertexDistanceRecorderObserver <IGeometry, IEdge <IGeometry> > distObserver =
                new VertexDistanceRecorderObserver <IGeometry, IEdge <IGeometry> >();

            distObserver.Attach(dijkstra);

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

            predecessorObserver.Attach(dijkstra);

            // Run the algorithm
            Assert.IsNotNull(startls);
            IGeometry startPoint = startls.StartPoint;

            Debug.WriteLine(String.Format("Starting algorithm from root vertex {0}", startPoint));
            dijkstra.Compute(startPoint);

            foreach (KeyValuePair <IGeometry, int> kvp in distObserver.Distances)
            {
                Debug.WriteLine(String.Format("Distance from root to node {0} is {1}",
                                              kvp.Key, kvp.Value));
            }
            foreach (KeyValuePair <IGeometry, IEdge <IGeometry> > kvp in predecessorObserver.VertexPredecessors)
            {
                Debug.WriteLine(String.Format(
                                    "If you want to get to {0} you have to enter through the IN edge {1}", kvp.Key, kvp.Value));
            }
            Check(graph, consts, predecessorObserver);

            // Detach the observers
            distObserver.Detach(dijkstra);
            predecessorObserver.Detach(dijkstra);
        }
예제 #30
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>
        /// A <see cref="ILineString"/> or a <see cref="IMultiLineString"/>
        /// with all the elements of the graph that composes the shortest path,
        /// sequenced using a <see cref="LineSequencer"/>.
        /// </returns>
        public IGeometry Find(Coordinate source, Coordinate 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
            var dijkstra =
                new DijkstraShortestPathAlgorithm<Coordinate, IEdge<Coordinate>>(graph, edge => consts[edge]);

            // Attach a Distance observer to give us the distances between edges
            var distanceObserver =
                new VertexDistanceRecorderObserver<Coordinate, IEdge<Coordinate>>(edge => consts[edge]);
            distanceObserver.Attach(dijkstra);

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

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

            // Get the path computed to the destination.
            IEnumerable<IEdge<Coordinate>> path;
            var result = predecessorObserver.TryGetPath(destination, out path);

            // Then we need to turn that into a geomery.
            return result ? BuildString(new List<IEdge<Coordinate>>(path)) : null;
        }
예제 #31
0
        private static Bitmap GenerateBitmap(List <string> destinationsTravellingUltra, VertexDistanceRecorderObserver <string, Edge <string> > distObserver)
        {
            int bitmapSize = 2000;
            var bitmap     = new Bitmap(bitmapSize, bitmapSize);
            var graphics   = Graphics.FromImage(bitmap);

            graphics.FillRectangle(new SolidBrush(Color.White), 0, 0, bitmapSize, bitmapSize);

            var blackPen = new Pen(Color.Black);
            var greenPen = new Pen(Color.Green);
            var bluePen  = new Pen(Color.Blue);

            var font       = new Font("Arial", 8);
            var greenBrush = new SolidBrush(Color.Green);
            var blackBrush = new SolidBrush(Color.Black);
            var blueBrush  = new SolidBrush(Color.Blue);

            int border = 50;

            for (int eastWest = 0; eastWest < numEastWest; eastWest++)
            {
                int hX1 = border;
                int hY1 = border + (((bitmapSize - (2 * border)) / (numEastWest - 1)) * eastWest);
                int hX2 = bitmapSize - border;
                int hY2 = hY1;

                graphics.DrawLine(blackPen, hX1, hY1, hX2, hY2);

                for (int northSouth = 0; northSouth < numNorthSouth; northSouth++)
                {
                    int vX1 = border + (((bitmapSize - (2 * border)) / (numNorthSouth - 1)) * northSouth);
                    int vY1 = border;
                    int vX2 = vX1;
                    int vY2 = bitmapSize - border;

                    Pen pen;
                    if (northSouth == ('U' - 'A'))
                    {
                        pen = greenPen;
                    }
                    else
                    {
                        pen = blackPen;
                    }

                    graphics.DrawLine(pen, vX1, vY1, vX2, vY2);

                    var cornerName = ToCornerName(eastWest, northSouth);
                    var distance   = Math.Abs(eastWest - 19) + Math.Abs(northSouth - 5);
                    var cost       = distObserver.Distances[cornerName];

                    SolidBrush brush;
                    if (destinationsTravellingUltra.Contains(cornerName))
                    {
                        brush = greenBrush;
                    }
                    else if (cornerName == startVertex)
                    {
                        brush = blueBrush;

                        graphics.DrawEllipse(bluePen, vX1 - 20, hY1 - 20, 40, 40);
                    }
                    else
                    {
                        brush = blackBrush;
                    }

                    graphics.DrawString(cornerName, font, brush, vX1, hY1);
                    graphics.DrawString(string.Format("{0}:{1}", distance * 18, cost), font, brush, vX1, hY1 + 10);

                    //straight cost vs ultra cost
                }
            }

            return(bitmap);
        }
예제 #32
0
        public void BuildGraphAndSearchShortestPathUsingGeometryUnion()
        {
            IGeometry edges = a.Union(b).Union(c).Union(d).Union(e);

            Assert.IsNotNull(edges);
            Assert.IsTrue(edges.GetType() == typeof(MultiLineString));
            Assert.Greater(edges.NumGeometries, 0);
            foreach (IGeometry edge in ((GeometryCollection)edges).Geometries)
            {
                Assert.IsNotNull(edge);
                Assert.IsTrue(edge.GetType() == typeof(LineString));
                Debug.WriteLine(edge);
            }

            // Build graph
            IDictionary <IEdge <IGeometry>, double>        consts = new Dictionary <IEdge <IGeometry>, double>(edges.NumGeometries);
            AdjacencyGraph <IGeometry, IEdge <IGeometry> > graph  = new AdjacencyGraph <IGeometry, IEdge <IGeometry> >(true);

            foreach (ILineString str in ((GeometryCollection)edges).Geometries)
            {
                // Add vertex 1
                IGeometry vertex1 = str.StartPoint;
                Assert.IsNotNull(vertex1);
                if (!graph.ContainsVertex(vertex1))
                {
                    Debug.WriteLine(String.Format("Adding vertex {0} to the list", vertex1));
                    graph.AddVertex(vertex1);
                }
                else
                {
                    Debug.WriteLine(String.Format("Vertex {0} already present", vertex1));
                }

                // Add vertex 2
                IGeometry vertex2 = str.EndPoint;
                Assert.IsNotNull(vertex2);
                if (!graph.ContainsVertex(vertex2))
                {
                    Debug.WriteLine(String.Format("Adding vertex {0} to the list", vertex2));
                    graph.AddVertex(vertex2);
                }
                else
                {
                    Debug.WriteLine(String.Format("Vertex {0} already present", vertex2));
                }

                // Compute weight
                double weight = weightComputer(str);
                Assert.Greater(weight, 0.0);

                // Add edge for 1 => 2
                IEdge <IGeometry> edge1 = new Edge <IGeometry>(vertex1, vertex2);
                Assert.IsNotNull(edge1);
                graph.AddEdge(edge1);
                consts.Add(edge1, weight);

                // Add edge for 2 => 1
                IEdge <IGeometry> edge2 = new Edge <IGeometry>(vertex2, vertex1);
                Assert.IsNotNull(edge2);
                graph.AddEdge(edge2);
                consts.Add(edge2, weight);
            }

            // Perform DijkstraShortestPathAlgorithm
            DijkstraShortestPathAlgorithm <IGeometry, IEdge <IGeometry> > dijkstra =
                new DijkstraShortestPathAlgorithm <IGeometry, IEdge <IGeometry> >(graph, consts);

            // attach a distance observer to give us the shortest path distances
            VertexDistanceRecorderObserver <IGeometry, IEdge <IGeometry> > distObserver =
                new VertexDistanceRecorderObserver <IGeometry, IEdge <IGeometry> >();

            distObserver.Attach(dijkstra);

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

            predecessorObserver.Attach(dijkstra);

            // Run the algorithm
            Debug.WriteLine(String.Format("Starting algorithm from root vertex {0}", start));
            dijkstra.Compute(start);

            foreach (KeyValuePair <IGeometry, int> kvp in distObserver.Distances)
            {
                Debug.WriteLine(String.Format("Distance from root to node {0} is {1}",
                                              kvp.Key, kvp.Value));
            }
            foreach (KeyValuePair <IGeometry, IEdge <IGeometry> > kvp in predecessorObserver.VertexPredecessors)
            {
                Debug.WriteLine(String.Format(
                                    "If you want to get to {0} you have to enter through the IN edge {1}", kvp.Key, kvp.Value));
            }
            Check(graph, consts, predecessorObserver);

            // Detach the observers
            distObserver.Detach(dijkstra);
            predecessorObserver.Detach(dijkstra);
        }
예제 #33
0
        public List <FloorTile> getPath()
        {
            if (this.m_status.position != null)
            {
                startPoint = this.m_status.position.location.X + "_" + this.m_status.position.location.Y;
                m_parent.PostMessage("start: " + startPoint);
            }
            else
            {
                startPoint = "4_4";
            }
            if (this.m_status.endPoint != null)
            {
                targetPoint = this.m_status.endPoint.X + "_" + this.m_status.endPoint.Y;
                m_parent.PostMessage("end: " + targetPoint);
            }
            else
            {
                targetPoint = "4_6";
            }



            //startPoint = txtStartPoint.Text;
            //targetPoint = txtTargetPoint.Text;

            DijkstraShortestPathAlgorithm <string, Edge <string> > dijkstra = new DijkstraShortestPathAlgorithm <string, Edge <string> >(graph, AlgorithmExtensions.GetIndexer <Edge <string>, double>(edgeCost));

            // Attach a Vertex Predecessor Recorder Observer to give us the paths
            QuickGraph.Algorithms.Observers.VertexPredecessorRecorderObserver <string, Edge <string> > predecessorObserver = new QuickGraph.Algorithms.Observers.VertexPredecessorRecorderObserver <string, Edge <string> >();
            predecessorObserver.Attach(dijkstra);

            // attach a distance observer to give us the shortest path distances
            VertexDistanceRecorderObserver <string, Edge <string> > distObserver = new VertexDistanceRecorderObserver <string, Edge <string> >(AlgorithmExtensions.GetIndexer <Edge <string>, double>(edgeCost));

            distObserver.Attach(dijkstra);

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

            String outString = "";

            //outString += distObserver.Distances[targetPoint] + "\n";

            IEnumerable <Edge <string> > path;

            if (predecessorObserver.TryGetPath(targetPoint, out path))
            {
                foreach (var u in path)
                {
                    outString += u + ";";
                }
            }

            List <FloorTile> retval = new List <FloorTile>();

            string[] outEdges = Regex.Split(outString, ";");
            if (outEdges.Length > 0)
            {
                for (int i = 0; i < outEdges.Length; i++)
                {
                    if (outEdges[i].Length > 0)
                    {
                        m_parent.PostMessage(outEdges[i]);
                        string[] outPoint = Regex.Split(outEdges[i], "->");
                        //start points
                        retval.Add(getTileByIndex(fp, outPoint[0]));
                    }
                }
                //add target
                retval.Add(getTileByIndex(fp, targetPoint));
            }

            m_parent.PostMessage(retval.Count.ToString());
            m_parent.PostMessage(outString);

            if (retval.Count == 1 && retval[0].Equals(getTileByIndex(fp, targetPoint)))
            {
                m_parent.PostMessage("Can't find path. Start or end point is not walkable or no available walkable tiles");
                return(null);
            }



            return(condenseList(retval));
        }