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); }
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; }
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); } }
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); } }
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); }
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); }
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 }
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); }
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 }
/// <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 }
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); }
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); } } } }
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); } } }
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"); }
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; }
/// <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; }
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); }
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); }
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)); }
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(); }
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); }
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); }
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); }
/// <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; }
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); }
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); }
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)); }