public void CheckPredecessorLineGraph() { AdjacencyGraph<int, Edge<int>> g = new AdjacencyGraph<int, Edge<int>>(true); g.AddVertex(1); g.AddVertex(2); g.AddVertex(3); Edge<int> e12 = new Edge<int>(1, 2); g.AddEdge(e12); Edge<int> e23 = new Edge<int>(2, 3); g.AddEdge(e23); var dij = new DijkstraShortestPathAlgorithm<int, Edge<int>>(g, e => 1); var vis = new VertexPredecessorRecorderObserver<int, Edge<int>>(); using(vis.Attach(dij)) dij.Compute(1); IEnumerable<Edge<int>> path; Assert.IsTrue(vis.TryGetPath(2, out path)); var col = path.ToList(); Assert.AreEqual(1, col.Count); Assert.AreEqual(e12, col[0]); Assert.IsTrue(vis.TryGetPath(3, out path)); col = path.ToList(); Assert.AreEqual(2, col.Count); Assert.AreEqual(e12, col[0]); Assert.AreEqual(e23, col[1]); }
public void CheckPredecessorDoubleLineGraph() { AdjacencyGraph <int, Edge <int> > g = new AdjacencyGraph <int, Edge <int> >(true); g.AddVertex(1); g.AddVertex(2); g.AddVertex(3); Edge <int> e12 = new Edge <int>(1, 2); g.AddEdge(e12); Edge <int> e23 = new Edge <int>(2, 3); g.AddEdge(e23); Edge <int> e13 = new Edge <int>(1, 3); g.AddEdge(e13); var dij = new DijkstraShortestPathAlgorithm <int, Edge <int> >(g, e => 1); var vis = new VertexPredecessorRecorderObserver <int, Edge <int> >(); using (vis.Attach(dij)) dij.Compute(1); IEnumerable <Edge <int> > path; Assert.IsTrue(vis.TryGetPath(2, out path)); var col = path.ToList(); Assert.AreEqual(1, col.Count); Assert.AreEqual(e12, col[0]); Assert.IsTrue(vis.TryGetPath(3, out path)); col = path.ToList(); Assert.AreEqual(1, col.Count); Assert.AreEqual(e13, col[0]); }
public void PredecessorsDoubleLineGraph() { var graph = new AdjacencyGraph <int, Edge <int> >(true); graph.AddVertex(1); graph.AddVertex(2); graph.AddVertex(3); var e12 = new Edge <int>(1, 2); graph.AddEdge(e12); var e23 = new Edge <int>(2, 3); graph.AddEdge(e23); var e13 = new Edge <int>(1, 3); graph.AddEdge(e13); var algorithm = new DijkstraShortestPathAlgorithm <int, Edge <int> >(graph, e => 1); var vis = new VertexPredecessorRecorderObserver <int, Edge <int> >(); using (vis.Attach(algorithm)) algorithm.Compute(1); Assert.IsTrue(vis.TryGetPath(2, out IEnumerable <Edge <int> > path)); Edge <int>[] pathArray = path.ToArray(); Assert.AreEqual(1, pathArray.Length); Assert.AreEqual(e12, pathArray[0]); Assert.IsTrue(vis.TryGetPath(3, out path)); pathArray = path.ToArray(); Assert.AreEqual(1, pathArray.Length); Assert.AreEqual(e13, pathArray[0]); }
private static void RunSearch <TVertex, TEdge>( [NotNull] IBidirectionalGraph <TVertex, TEdge> graph) where TEdge : IEdge <TVertex> { if (graph.VertexCount == 0) { return; } IDistanceRelaxer distanceRelaxer = DistanceRelaxers.ShortestDistance; var search = new BestFirstFrontierSearchAlgorithm <TVertex, TEdge>( graph, e => 1, distanceRelaxer); TVertex root = graph.Vertices.First(); TVertex target = graph.Vertices.Last(); var recorder = new VertexPredecessorRecorderObserver <TVertex, TEdge>(); using (recorder.Attach(search)) search.Compute(root, target); if (recorder.VertexPredecessors.ContainsKey(target)) { Assert.IsTrue(recorder.TryGetPath(target, out _)); } }
public Stack <Edge <POI> > GetShortestPath(POI Source, POI Target) { QuickGraph.Algorithms.ShortestPath.DijkstraShortestPathAlgorithm <POI, Edge <POI> > algo = new QuickGraph.Algorithms.ShortestPath.DijkstraShortestPathAlgorithm <POI, Edge <POI> >(POIsGraph, (Edge <POI> arg) => arg.Distance); // creating the observer & attach it var vis = new VertexPredecessorRecorderObserver <POI, Edge <POI> >(); vis.Attach(algo); // compute and record shortest paths algo.Compute(Target); // vis can create all the shortest path in the graph IEnumerable <Edge <POI> > path = null; vis.TryGetPath(Source, out path); Stack <Edge <POI> > pathStack = new Stack <Edge <POI> >(); if (path == null) { return(null); } foreach (Edge <POI> e in path) { pathStack.Push(e); } return(pathStack); }
public void RunSearch <TVertex, TEdge>( [PexAssumeNotNull] IBidirectionalGraph <TVertex, TEdge> g) where TEdge : IEdge <TVertex> { if (g.VertexCount == 0) { return; } Func <TEdge, double> edgeWeights = e => 1; var distanceRelaxer = DistanceRelaxers.ShortestDistance; var search = new BestFirstFrontierSearchAlgorithm <TVertex, TEdge>( null, g, edgeWeights, distanceRelaxer); var root = Enumerable.First(g.Vertices); var target = Enumerable.Last(g.Vertices); var recorder = new VertexPredecessorRecorderObserver <TVertex, TEdge>(); using (recorder.Attach(search)) search.Compute(root, target); if (recorder.VertexPredecessors.ContainsKey(target)) { TestConsole.WriteLine("cost: {0}", recorder.VertexPredecessors[target]); IEnumerable <TEdge> path; Assert.IsTrue(recorder.TryGetPath(target, out path)); } #if DEBUG TestConsole.WriteLine("operator max count: {0}", search.OperatorMaxCount); #endif }
internal static Dictionary <string, double> Ancestor(Graph weightedDirectedGraph) { var tempGraph = new Graph(); var resultDictionary = new Dictionary <string, double>(); //Create negative weighted directed graph tempGraph.AddVertexRange(weightedDirectedGraph.Vertices); tempGraph.AddEdgeRange(weightedDirectedGraph.Edges.Select(x => new Edge(x.Name, x.Source, x.Target, -x.Weight))); //Solve shortest path of Top -> vertex var algorithm = new BellmanFordShortestPathAlgorithm <string, Edge>(tempGraph, e => e.Weight); var pred = new VertexPredecessorRecorderObserver <string, Edge>(); pred.Attach(algorithm); foreach (var vertex in tempGraph.Vertices) { algorithm.Compute("Top"); IEnumerable <Edge> path; pred.TryGetPath(vertex, out path); if (path != null) { resultDictionary[vertex] = -path.Sum(a => a.Weight); } } return(resultDictionary); }
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); }
private SortedPath?GetShortestPathInGraph( [NotNull] AdjacencyGraph <TVertex, TaggedEquatableEdge <TVertex, double> > graph) { // Compute distances between the start vertex and other var algorithm = new DijkstraShortestPathAlgorithm <TVertex, TaggedEquatableEdge <TVertex, double> >(graph, _weights); var recorder = new VertexPredecessorRecorderObserver <TVertex, TaggedEquatableEdge <TVertex, double> >(); using (recorder.Attach(algorithm)) algorithm.Compute(_sourceVertex); // Get shortest path from start (source) vertex to target return(recorder.TryGetPath(_targetVertex, out IEnumerable <TaggedEquatableEdge <TVertex, double> > path) ? new SortedPath(path) : (SortedPath?)null); }
private IEnumerable <TaggedEquatableEdge <TVertex, double> > GetShortestPathInGraph( AdjacencyGraph <TVertex, TaggedEquatableEdge <TVertex, double> > graph) { // calc distances beetween the start vertex and other var dij = new DijkstraShortestPathAlgorithm <TVertex, TaggedEquatableEdge <TVertex, double> >(graph, e => e.Tag); var vis = new VertexPredecessorRecorderObserver <TVertex, TaggedEquatableEdge <TVertex, double> >(); using (vis.Attach(dij)) dij.Compute(sourceVertix); // get shortest path from start (source) vertex to target IEnumerable <TaggedEquatableEdge <TVertex, double> > path; return(vis.TryGetPath(targetVertix, out path) ? path : null); }
private IEnumerable <DataEdge> GetShortestPathInGraph( BidirectionalGraph <DataVertex, DataEdge> graph) { Func <DataEdge, double> edgeWeights = E => E.Weight; // calc distances beetween the start vertex and other var dijkstra = new DijkstraShortestPathAlgorithm <DataVertex, DataEdge>(graph, edgeWeights); var vis = new VertexPredecessorRecorderObserver <DataVertex, DataEdge>(); using (vis.Attach(dijkstra)) dijkstra.Compute(sourceVertex); // get shortest path from start (source) vertex to target IEnumerable <DataEdge> path; return(vis.TryGetPath(targetVertex, out path) ? path : null); }
public RiskResult CalculateMinimalRisk(IVertexAndEdgeListGraph<Station, StationPath> graph, Station from, Station to) { Func<StationPath, double> calcWeight = visiting => visiting.Risk; Func<Station, double> calcHeuristic = visiting => visiting.CalculateRisk(to); var algorithm = new AStarShortestPathAlgorithm<Station, StationPath>(graph, calcWeight, calcHeuristic); var pathRecorder = new VertexPredecessorRecorderObserver<Station, StationPath>(); using (pathRecorder.Attach(algorithm)) { algorithm.Compute(from); IEnumerable<StationPath> path; pathRecorder.TryGetPath(to, out path); return new RiskResult(path, from.RadianLocation.Radius); } }
public List <KancolleActionEdge> Navigate(KancolleSceneTypes from, KancolleSceneTypes to) { if (from == to) { return(new List <KancolleActionEdge>()); } VertexPredecessorRecorderObserver <KancolleSceneTypes, KancolleActionEdge> predecessorObserver = new VertexPredecessorRecorderObserver <KancolleSceneTypes, KancolleActionEdge>(); predecessorObserver.Attach(shortestPathAlg); shortestPathAlg.Compute(from); IEnumerable <KancolleActionEdge> edges; if (predecessorObserver.TryGetPath(to, out edges)) { return(edges.ToList()); } return(null); }
public IEnumerable <ReferenceEdge> GetShortestPathToRoot(long addr) { if (cachedAddr == addr && cachedResult != null) { return(cachedResult); } if (Roots.ContainsKey(addr)) { cachedResult = new List <ReferenceEdge>(); cachedAddr = addr; return(cachedResult); } if (!referencesFromBuilt) { referencesFromBuilt = true; var sw = Stopwatch.StartNew(); BuildReferencesFrom(); sw.Stop(); } var bfsa = new BreadthFirstSearchAlgorithm <long, ReferenceEdge>(this); var vis = new VertexPredecessorRecorderObserver <long, ReferenceEdge>(); vis.Attach(bfsa); long foundRoot = 0; //possible optimisation to find only shortest path, worthiness is questionable bfsa.ExamineVertex += (vertex) => { if (Roots.ContainsKey(vertex)) { bfsa.Services.CancelManager.Cancel(); foundRoot = vertex; } }; bfsa.Compute(addr); if (!vis.TryGetPath(foundRoot, out var path)) { path = new List <ReferenceEdge>(); } //Find shortest path cachedResult = path; cachedAddr = addr; return(cachedResult); }
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); }
private static void RunAndCheckSearch <TVertex, TEdge>( [NotNull] IBidirectionalGraph <TVertex, TEdge> graph) where TEdge : IEdge <TVertex> { if (graph.VertexCount == 0) { return; } IDistanceRelaxer distanceRelaxer = DistanceRelaxers.ShortestDistance; var search = new BestFirstFrontierSearchAlgorithm <TVertex, TEdge>( graph, _ => 1.0, distanceRelaxer); bool targetReached = false; search.TargetReached += (_, _) => targetReached = true; TVertex root = graph.Vertices.First(); TVertex target = graph.Vertices.Last(); var recorder = new VertexPredecessorRecorderObserver <TVertex, TEdge>(); using (recorder.Attach(search)) search.Compute(root, target); if (recorder.VerticesPredecessors.ContainsKey(target)) { Assert.IsTrue(recorder.TryGetPath(target, out IEnumerable <TEdge> path)); if (Equals(root, path.First().Source)) { Assert.IsTrue(targetReached); } else { Assert.IsFalse(targetReached); } } }
public List <IEnumerable <ReferenceEdge> > GetTop5PathsToRoots(long addr) { if (cachedAddr == addr && cachedResult != null) { return(cachedResult); } cachedResult = new List <IEnumerable <ReferenceEdge> > (); cachedAddr = addr; if (Roots.ContainsKey(addr)) { return(cachedResult); } BuildReferencesFrom(); var result = new List <List <ReferenceEdge> > (); var bfsa = new BreadthFirstSearchAlgorithm <long, ReferenceEdge> (this); var vis = new VertexPredecessorRecorderObserver <long, ReferenceEdge> (); vis.Attach(bfsa); var visitedRoots = new HashSet <long> (); bfsa.ExamineVertex += (vertex) => { if (Roots.ContainsKey(vertex)) { visitedRoots.Add(vertex); if (visitedRoots.Count == 5) { bfsa.Services.CancelManager.Cancel(); } } }; bfsa.Compute(addr); foreach (var root in visitedRoots) { if (vis.TryGetPath(root, out var path)) { cachedResult.Add(path); } } return(cachedResult); }
bool findBestPath(SetupStore ss) { Dictionary <RoutingGraph.Link, double> edgeCost = new Dictionary <RoutingGraph.Link, double>(ss.ownTopology.EdgeCount); int index = 0; int max = ss.ownTopology.EdgeCount; while (index < max) { //free capisity < requierd if (ss.ownTopology.Edges.ElementAt(index).Capacity < ss.requieredCapacity) { ss.ownTopology.RemoveEdge(ss.ownTopology.Edges.ElementAt(index)); max = ss.ownTopology.EdgeCount; } else { index++; } } foreach (var e in ss.ownTopology.Edges) { edgeCost.Add(e, e.Capacity); } var dijkstra = new DijkstraShortestPathAlgorithm <RoutingGraph.Node, RoutingGraph.Link>(ss.ownTopology, e => edgeCost[e]); var predecessor = new VertexPredecessorRecorderObserver <RoutingGraph.Node, RoutingGraph.Link>(); predecessor.Attach(dijkstra); dijkstra.Compute(this.IDtoNode(ss.source, ss.ownTopology)); IEnumerable <RoutingGraph.Link> path; if (predecessor.TryGetPath(this.IDtoNode(ss.target, ss.ownTopology), out path)) { ss.path.AddRange(path); return(true); } else { return(false); } }
private SortedPath?GetShortestPathInGraph( IVertexListGraph <TVertex, EquatableTaggedEdge <TVertex, double> > graph, TVertex source, TVertex target) { Debug.Assert(graph != null); Debug.Assert(source != null); Debug.Assert(target != null); // Compute distances between the start vertex and other var algorithm = new DijkstraShortestPathAlgorithm <TVertex, EquatableTaggedEdge <TVertex, double> >(graph, _weights); var recorder = new VertexPredecessorRecorderObserver <TVertex, EquatableTaggedEdge <TVertex, double> >(); using (recorder.Attach(algorithm)) algorithm.Compute(source); // Get shortest path from start (source) vertex to target return(recorder.TryGetPath(target, out IEnumerable <EquatableTaggedEdge <TVertex, double> > path) ? new SortedPath(path) : (SortedPath?)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(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 }
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); }
private IEnumerable <ICollection <TEdge> > TrailsInternal(TVertex startingVertex) { int index = FindFirstEdgeInCircuit(startingVertex); // Create trail var trail = new List <TEdge>(); var bfs = new BreadthFirstSearchAlgorithm <TVertex, TEdge>(VisitedGraph); var vis = new VertexPredecessorRecorderObserver <TVertex, TEdge>(); using (vis.Attach(bfs)) { bfs.Compute(startingVertex); // Go through the edges and build the predecessor table int start = index; for (; index < _circuit.Count; ++index) { TEdge edge = _circuit[index]; if (_temporaryEdges.Contains(edge)) { // Store previous trail and start new one if (trail.Count != 0) { yield return(trail); } // Start new trail // Take the shortest path from the start vertex to the target vertex if (!vis.TryGetPath(edge.Target, out IEnumerable <TEdge> path)) { throw new InvalidOperationException(); } trail = new List <TEdge>(path); } else { trail.Add(edge); } } // Starting again on the circuit for (index = 0; index < start; ++index) { TEdge edge = _circuit[index]; if (_temporaryEdges.Contains(edge)) { // Store previous trail and start new one if (trail.Count != 0) { yield return(trail); } // Start new trail // Take the shortest path from the start vertex to the target vertex if (!vis.TryGetPath(edge.Target, out IEnumerable <TEdge> path)) { throw new InvalidOperationException(); } trail = new List <TEdge>(path); } else { trail.Add(edge); } } } // Adding the last element if (trail.Count != 0) { yield return(trail); } }
/// <summary> /// Computes a set of eulerian trail, starting at <paramref name="s"/> /// that spans the entire graph. /// </summary> /// <remarks> /// <para> /// This method computes a set of eulerian trail starting at <paramref name="s"/> /// that spans the entire graph.The algorithm outline is as follows: /// </para> /// <para> /// The algorithms iterates throught the Eulerian circuit of the augmented /// graph (the augmented graph is the graph with additional edges to make /// the number of odd vertices even). /// </para> /// <para> /// If the current edge is not temporary, it is added to the current trail. /// </para> /// <para> /// If the current edge is temporary, the current trail is finished and /// added to the trail collection. The shortest path between the /// start vertex <paramref name="s"/> and the target vertex of the /// temporary edge is then used to start the new trail. This shortest /// path is computed using the BreadthFirstSearchAlgorithm. /// </para> /// </remarks> /// <param name="s">start vertex</param> /// <returns>eulerian trail set, all starting at s</returns> /// <exception cref="ArgumentNullException">s is a null reference.</exception> /// <exception cref="Exception">Eulerian trail not computed yet.</exception> public ICollection <ICollection <TEdge> > Trails(TVertex s) { Contract.Requires(s != null); if (this.Circuit.Count == 0) { throw new InvalidOperationException("Circuit is empty"); } // find the first edge in the circuit. int i = 0; for (i = 0; i < this.Circuit.Count; ++i) { TEdge e = this.Circuit[i]; if (this.temporaryEdges.Contains(e)) { continue; } if (e.Source.Equals(s)) { break; } } if (i == this.Circuit.Count) { throw new Exception("Did not find vertex in eulerian trail?"); } // create collections List <ICollection <TEdge> > trails = new List <ICollection <TEdge> >(); List <TEdge> trail = new List <TEdge>(); BreadthFirstSearchAlgorithm <TVertex, TEdge> bfs = new BreadthFirstSearchAlgorithm <TVertex, TEdge>(VisitedGraph); VertexPredecessorRecorderObserver <TVertex, TEdge> vis = new VertexPredecessorRecorderObserver <TVertex, TEdge>(); vis.Attach(bfs); bfs.Compute(s); // go throught the edges and build the predecessor table. int start = i; for (; i < this.Circuit.Count; ++i) { TEdge e = this.Circuit[i]; if (this.temporaryEdges.Contains(e)) { // store previous trail and start new one. if (trail.Count != 0) { trails.Add(trail); } // start new trail // take the shortest path from the start vertex to // the target vertex IEnumerable <TEdge> path; if (!vis.TryGetPath(e.Target, out path)) { throw new InvalidOperationException(); } trail = new List <TEdge>(path); } else { trail.Add(e); } } // starting again on the circuit for (i = 0; i < start; ++i) { TEdge e = this.Circuit[i]; if (this.temporaryEdges.Contains(e)) { // store previous trail and start new one. if (trail.Count != 0) { trails.Add(trail); } // start new trail // take the shortest path from the start vertex to // the target vertex IEnumerable <TEdge> path; if (!vis.TryGetPath(e.Target, out path)) { throw new InvalidOperationException(); } trail = new List <TEdge>(path); } else { trail.Add(e); } } // adding the last element if (trail.Count != 0) { trails.Add(trail); } return(trails); }
public void RunBFSAndCheck <TVertex, TEdge>( [NotNull] IVertexAndEdgeListGraph <TVertex, TEdge> graph, [NotNull] TVertex sourceVertex) where TEdge : IEdge <TVertex> { var parents = new Dictionary <TVertex, TVertex>(); var distances = new Dictionary <TVertex, int>(); TVertex currentVertex = default; int currentDistance = 0; var algorithm = new BreadthFirstSearchAlgorithm <TVertex, TEdge>(graph); algorithm.InitializeVertex += vertex => { Assert.AreEqual(GraphColor.White, algorithm.VerticesColors[vertex]); }; algorithm.StartVertex += vertex => { Assert.AreEqual(GraphColor.White, algorithm.VerticesColors[vertex]); }; algorithm.DiscoverVertex += vertex => { Assert.AreEqual(GraphColor.Gray, algorithm.VerticesColors[vertex]); if (vertex.Equals(sourceVertex)) { currentVertex = sourceVertex; } else { Assert.IsNotNull(currentVertex); Assert.AreEqual(parents[vertex], currentVertex); // ReSharper disable once AccessToModifiedClosure Assert.AreEqual(distances[vertex], currentDistance + 1); Assert.AreEqual(distances[vertex], distances[parents[vertex]] + 1); } }; algorithm.ExamineEdge += edge => { Assert.AreEqual(edge.Source, currentVertex); }; algorithm.ExamineVertex += vertex => { TVertex u = vertex; currentVertex = u; // Ensure that the distances monotonically increase. // ReSharper disable AccessToModifiedClosure Assert.IsTrue(distances[u] == currentDistance || distances[u] == currentDistance + 1); if (distances[u] == currentDistance + 1) // New level { ++currentDistance; } // ReSharper restore AccessToModifiedClosure }; algorithm.TreeEdge += edge => { TVertex u = edge.Source; TVertex v = edge.Target; Assert.AreEqual(GraphColor.White, algorithm.VerticesColors[v]); Assert.AreEqual(distances[u], currentDistance); parents[v] = u; distances[v] = distances[u] + 1; }; algorithm.NonTreeEdge += edge => { TVertex u = edge.Source; TVertex v = edge.Target; Assert.IsFalse(algorithm.VerticesColors[v] == GraphColor.White); if (algorithm.VisitedGraph.IsDirected) { // Cross or back edge Assert.IsTrue(distances[v] <= distances[u] + 1); } else { // Cross edge (or going backwards on a tree edge) Assert.IsTrue( distances[v] == distances[u] || distances[v] == distances[u] + 1 || distances[v] == distances[u] - 1); } }; algorithm.GrayTarget += edge => { Assert.AreEqual(GraphColor.Gray, algorithm.VerticesColors[edge.Target]); }; algorithm.BlackTarget += edge => { Assert.AreEqual(GraphColor.Black, algorithm.VerticesColors[edge.Target]); foreach (TEdge outEdge in algorithm.VisitedGraph.OutEdges(edge.Target)) { Assert.IsFalse(algorithm.VerticesColors[outEdge.Target] == GraphColor.White); } }; algorithm.FinishVertex += vertex => { Assert.AreEqual(GraphColor.Black, algorithm.VerticesColors[vertex]); }; parents.Clear(); distances.Clear(); currentDistance = 0; foreach (TVertex vertex in graph.Vertices) { distances[vertex] = int.MaxValue; parents[vertex] = vertex; } distances[sourceVertex] = 0; var recorder = new VertexPredecessorRecorderObserver <TVertex, TEdge>(); using (recorder.Attach(algorithm)) { algorithm.Compute(sourceVertex); } // All white vertices should be unreachable from the source. foreach (TVertex vertex in graph.Vertices) { if (algorithm.VerticesColors[vertex] == GraphColor.White) { // Check !IsReachable(sourceVertex, vertex, graph); if (recorder.TryGetPath(vertex, out IEnumerable <TEdge> path)) { foreach (TEdge edge in path) { Assert.AreNotEqual(sourceVertex, edge.Source); Assert.AreNotEqual(sourceVertex, edge.Target); } } } } // The shortest path to a child should be one longer than // shortest path to the parent. foreach (TVertex vertex in graph.Vertices) { if (!parents[vertex].Equals(vertex)) // Not the root of the BFS tree { Assert.AreEqual(distances[vertex], distances[parents[vertex]] + 1); } } }
bool findBestPath(SetupStore ss) { Dictionary<RoutingGraph.Link, double> edgeCost = new Dictionary<RoutingGraph.Link, double>(ss.ownTopology.EdgeCount); int index = 0; int max = ss.ownTopology.EdgeCount; while (index < max) { //free capisity < requierd if (ss.ownTopology.Edges.ElementAt(index).Capacity < ss.requieredCapacity) { ss.ownTopology.RemoveEdge(ss.ownTopology.Edges.ElementAt(index)); max = ss.ownTopology.EdgeCount; } else index++; } foreach (var e in ss.ownTopology.Edges) { edgeCost.Add(e, e.Capacity); } var dijkstra = new DijkstraShortestPathAlgorithm<RoutingGraph.Node, RoutingGraph.Link>(ss.ownTopology, e => edgeCost[e]); var predecessor = new VertexPredecessorRecorderObserver<RoutingGraph.Node, RoutingGraph.Link>(); predecessor.Attach(dijkstra); dijkstra.Compute(this.IDtoNode(ss.source, ss.ownTopology)); IEnumerable<RoutingGraph.Link> path; if (predecessor.TryGetPath(this.IDtoNode(ss.target, ss.ownTopology), out path)) { ss.path.AddRange(path); return true; } else return false; }
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; }
public void TryGetPath() { { var recorder = new VertexPredecessorRecorderObserver <int, Edge <int> >(); var graph = new AdjacencyGraph <int, Edge <int> >(); var dfs = new DepthFirstSearchAlgorithm <int, Edge <int> >(graph); using (recorder.Attach(dfs)) { dfs.Compute(); // Vertex not in the graph Assert.IsFalse(recorder.TryGetPath(2, out _)); } } { var recorder = new VertexPredecessorRecorderObserver <int, Edge <int> >(); 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(); Assert.IsFalse(recorder.TryGetPath(2, out _)); } } { var recorder = new VertexPredecessorRecorderObserver <int, Edge <int> >(); // 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(); Assert.IsTrue(recorder.TryGetPath(4, out IEnumerable <Edge <int> > path)); CollectionAssert.AreEqual(new[] { edge12, edge24 }, path); } } { var recorder = new VertexPredecessorRecorderObserver <int, Edge <int> >(); // 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(); Assert.IsTrue(recorder.TryGetPath(4, out IEnumerable <Edge <int> > path)); CollectionAssert.AreEqual(new[] { edge12, edge24 }, path); } } }
/// <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 IEnumerable<Edge<Node>> FindShortestPath(Node source, Node target) { Func<Edge<Node>, double> edgeCost = e => e.Source.GetDistance(e.Target); var dijkstra = new DijkstraShortestPathAlgorithm<Node, Edge<Node>>(_graph, edgeCost); var predecessors = new VertexPredecessorRecorderObserver<Node, Edge<Node>>(); using (predecessors.Attach(dijkstra)) { dijkstra.Compute(source); } IEnumerable<Edge<Node>> path; predecessors.TryGetPath(target, out path); return path; }