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 CheckPredecessorLineGraph() { AdjacencyGraph <int, Edge <int> > g = new AdjacencyGraph <int, Edge <int> >(true); g.AddVertex(1); g.AddVertex(2); g.AddVertex(3); Edge <int> e12 = new Edge <int>(1, 2); g.AddEdge(e12); Edge <int> e23 = new Edge <int>(2, 3); g.AddEdge(e23); Dictionary <Edge <int>, double> weights = DijkstraShortestPathAlgorithm <int, Edge <int> > .UnaryWeightsFromEdgeList(g); DijkstraShortestPathAlgorithm <int, Edge <int> > dij = new DijkstraShortestPathAlgorithm <int, Edge <int> >(g, weights); VertexPredecessorRecorderObserver <int, Edge <int> > vis = new VertexPredecessorRecorderObserver <int, Edge <int> >(); vis.Attach(dij); dij.Compute(1); IList <Edge <int> > col = vis.Path(2); Assert.AreEqual(1, col.Count); Assert.AreEqual(e12, col[0]); col = vis.Path(3); Assert.AreEqual(2, col.Count); Assert.AreEqual(e12, col[0]); Assert.AreEqual(e23, col[1]); }
public void 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 Compute(IUndirectedGraph <string, Edge <string> > g) { Dictionary <Edge <string>, double> distances = new Dictionary <Edge <string>, double>(); foreach (Edge <string> edge in g.Edges) { distances.Add(edge, 1); } PrimMinimumSpanningTreeAlgorithm <string, Edge <string> > prim = new PrimMinimumSpanningTreeAlgorithm <string, Edge <string> >(g, distances); VertexPredecessorRecorderObserver <string, Edge <string> > predecessors = new VertexPredecessorRecorderObserver <string, Edge <string> >(); predecessors.Attach(prim); prim.Compute(); foreach (string v in g.Vertices) { Edge <string> edge; if (predecessors.VertexPredecessors.TryGetValue(v, out edge)) { Console.WriteLine("{0}: {1}", v, edge); } else { Console.WriteLine("{0}", v); } } }
public static TryFunc <TVertex, IEnumerable <TEdge> > TreeCyclePoppingRandom <TVertex, TEdge>( #if !NET20 this #endif IVertexListGraph <TVertex, TEdge> visitedGraph, TVertex root, IMarkovEdgeChain <TVertex, TEdge> edgeChain) where TEdge : IEdge <TVertex> { Contract.Requires(visitedGraph != null); Contract.Requires(root != null); Contract.Requires(visitedGraph.ContainsVertex(root)); Contract.Ensures(Contract.Result <TryFunc <TVertex, IEnumerable <TEdge> > >() != null); var algo = new CyclePoppingRandomTreeAlgorithm <TVertex, TEdge>(visitedGraph, edgeChain); var predecessorRecorder = new VertexPredecessorRecorderObserver <TVertex, TEdge>(); using (predecessorRecorder.Attach(algo)) algo.Compute(root); var predecessors = predecessorRecorder.VertexPredecessors; return(delegate(TVertex v, out IEnumerable <TEdge> edges) { return EdgeExtensions.TryGetPath(predecessors, v, out edges); }); }
public void Compute() { var g = new AdjacencyGraph <char, Edge <char> >(); var distances = new Dictionary <Edge <char>, double>(); g.AddVertexRange("ABCDE"); AddEdge(g, distances, 'A', 'C', 1); AddEdge(g, distances, 'B', 'B', 2); AddEdge(g, distances, 'B', 'D', 1); AddEdge(g, distances, 'B', 'E', 2); AddEdge(g, distances, 'C', 'B', 7); AddEdge(g, distances, 'C', 'D', 3); AddEdge(g, distances, 'D', 'E', 1); AddEdge(g, distances, 'E', 'A', 1); AddEdge(g, distances, 'E', 'B', 1); var dijkstra = new DijkstraShortestPathAlgorithm <char, Edge <char> >(g, AlgorithmExtensions.GetIndexer(distances)); var predecessors = new VertexPredecessorRecorderObserver <char, Edge <char> >(); using (predecessors.Attach(dijkstra)) dijkstra.Compute('A'); Assert.AreEqual(0, dijkstra.Distances['A']); Assert.AreEqual(6, dijkstra.Distances['B']); Assert.AreEqual(1, dijkstra.Distances['C']); Assert.AreEqual(4, dijkstra.Distances['D']); Assert.AreEqual(5, dijkstra.Distances['E']); }
private PathResult CalculatePath(PathNode start, PathNode stop) { var result = new PathResult(); var astar = new AStarShortestPathAlgorithm <PathNode, PathEdge>( _graph, edge => edge.Weight, node => node.Coords.DistanceTo(stop.Coords) ); astar.SetRootVertex(start); astar.FinishVertex += vertex => { if (Equals(vertex, stop)) { astar.Abort(); } }; var recorderObserver = new VertexPredecessorRecorderObserver <PathNode, PathEdge>(); recorderObserver.Attach(astar); astar.Compute(); var predecessors = recorderObserver.VertexPredecessors; if (predecessors.TryGetPath(stop, out var edges)) { result.Status = PathStatus.Success; result.Path = new List <PathEdge>(edges as PathEdge[] ?? edges.ToArray()); return(result); } result.Status = PathStatus.NotFound; result.Message = $"No path found between {start.Id} and {stop.Id}"; return(result); }
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 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]); }
void SearchGraph( BidirectionalGraph <Vertex, SEdge <Vertex> > graph, VertexPredecessorRecorderObserver <Vertex, SEdge <Vertex> > observer = null ) { BreadthFirstSearchAlgorithm <Vertex, SEdge <Vertex> > bfs = new BreadthFirstSearchAlgorithm <Vertex, SEdge <Vertex> > (graph); if (observer == null) { bfs.Compute(); } else { using (observer.Attach(bfs)) { bfs.Compute(); foreach ( KeyValuePair <Vertex, SEdge <Vertex> > pair in observer.VerticesPredecessors ) { Debug.Log( pair.Value.Source.Point + " -> " + pair.Value.Target.Point ); } } } }
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 _)); } }
private void TarjanOfflineLeastCommonAncestorAlgorithm <TVertex, TEdge>( IVertexListGraph <TVertex, TEdge> g, TVertex root, SEquatableEdge <TVertex>[] pairs ) where TEdge : IEdge <TVertex> { var lca = g.OfflineLeastCommonAncestorTarjan(root, pairs); var predecessors = new VertexPredecessorRecorderObserver <TVertex, TEdge>(); var dfs = new DepthFirstSearchAlgorithm <TVertex, TEdge>(g); using (predecessors.Attach(dfs)) dfs.Compute(root); TVertex ancestor; foreach (var pair in pairs) { if (lca(pair, out ancestor)) { Assert.True(EdgeExtensions.IsPredecessor(predecessors.VertexPredecessors, root, pair.Source)); Assert.True(EdgeExtensions.IsPredecessor(predecessors.VertexPredecessors, root, pair.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 TryFunc <TVertex, IEnumerable <TEdge> > ShortestPathsDag <TVertex, TEdge>( #if !NET20 this #endif IVertexAndEdgeListGraph <TVertex, TEdge> visitedGraph, Func <TEdge, double> edgeWeights, TVertex source ) where TEdge : IEdge <TVertex> { Contract.Requires(visitedGraph != null); Contract.Requires(edgeWeights != null); Contract.Requires(source != null); var algorithm = new DagShortestPathAlgorithm <TVertex, TEdge>(visitedGraph, edgeWeights); var predecessorRecorder = new VertexPredecessorRecorderObserver <TVertex, TEdge>(); using (predecessorRecorder.Attach(algorithm)) algorithm.Compute(source); var predecessors = predecessorRecorder.VertexPredecessors; return(delegate(TVertex v, out IEnumerable <TEdge> edges) { return EdgeExtensions.TryGetPath(predecessors, v, out edges); }); }
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 TryFunc <TVertex, IEnumerable <TEdge> > TreeBreadthFirstSearch <TVertex, TEdge>( #if !NET20 this #endif IVertexListGraph <TVertex, TEdge> visitedGraph, TVertex root) where TEdge : IEdge <TVertex> { //Contract.Requires(visitedGraph != null); //Contract.Requires(root != null); //Contract.Requires(visitedGraph.ContainsVertex(root)); //Contract.Ensures(//Contract.Result<TryFunc<TVertex, IEnumerable<TEdge>>>() != null); var algo = new BreadthFirstSearchAlgorithm <TVertex, TEdge>(visitedGraph); var predecessorRecorder = new VertexPredecessorRecorderObserver <TVertex, TEdge>(); using (predecessorRecorder.Attach(algo)) algo.Compute(root); var predecessors = predecessorRecorder.VertexPredecessors; return(delegate(TVertex v, out IEnumerable <TEdge> edges) { return EdgeExtensions.TryGetPath(predecessors, v, out edges); }); }
static void DijkstraExample(Dictionary <string, User> users) { var graph = MakeGraph(users); var dijkstra = new DijkstraShortestPathAlgorithm <string, Edge <string> >(graph, e => 1); // Attach a Vertex Predecessor Recorder Observer to give us the paths var predecessorObserver = new VertexPredecessorRecorderObserver <string, Edge <string> >(); using (predecessorObserver.Attach(dijkstra)) { // Run the algorithm with A set to be the source dijkstra.Compute("abagael"); } //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); foreach (string v in graph.Vertices) { double distance = AlgorithmExtensions.ComputePredecessorCost( predecessorObserver.VertexPredecessors, CalculateEdgecost(graph), v); //Console.WriteLine("A -> {0}: {1}", v, distance); } }
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 }
/// <summary> /// Computes the maximum flow between Source and Sink. /// </summary> /// <returns></returns> protected override void InternalCompute() { if (this.Source == null) { throw new InvalidOperationException("Source is not specified"); } if (this.Sink == null) { throw new InvalidOperationException("Sink is not specified"); } if (this.Services.CancelManager.IsCancelling) { return; } var g = this.VisitedGraph; foreach (var u in g.Vertices) { foreach (var e in g.OutEdges(u)) { var capacity = this.Capacities(e); if (capacity < 0) { throw new InvalidOperationException("negative edge capacity"); } this.ResidualCapacities[e] = capacity; } } this.VertexColors[Sink] = GraphColor.Gray; while (this.VertexColors[Sink] != GraphColor.White) { var vis = new VertexPredecessorRecorderObserver <TVertex, TEdge>( this.Predecessors ); var queue = new QuickGraph.Collections.Queue <TVertex>(); var bfs = new BreadthFirstSearchAlgorithm <TVertex, TEdge>( this.ResidualGraph, queue, this.VertexColors ); using (vis.Attach(bfs)) bfs.Compute(this.Source); if (this.VertexColors[this.Sink] != GraphColor.White) { this.Augment(this.Source, this.Sink); } } // while this.MaxFlow = 0; foreach (var e in g.OutEdges(Source)) { this.MaxFlow += (this.Capacities(e) - this.ResidualCapacities[e]); } }
private void Dijkstra(node mNode) { dijkstra = new DijkstraShortestPathAlgorithm <node, Edge <node> >(myGraph, e => edgeCost[e]); predecessorObserver = new VertexPredecessorRecorderObserver <node, Edge <node> >(); using (predecessorObserver.Attach(dijkstra)) dijkstra.Compute(mNode); }
private static void CompareAlgorithms <TVertex, TEdge, TGraph>( [NotNull] AdjacencyGraph <TVertex, TEdge> graph, [NotNull, InstantHandle] Func <TEdge, double> getDistances, [NotNull, InstantHandle] Func <AdjacencyGraph <TVertex, TEdge>, Func <TEdge, double>, ShortestPathAlgorithmBase <TVertex, TEdge, TGraph> > shortestPathAlgorithmFactory) where TEdge : IEdge <TVertex> where TGraph : IVertexSet <TVertex> { // Compute all paths var algorithm = new FloydWarshallAllShortestPathAlgorithm <TVertex, TEdge>(graph, getDistances); algorithm.Compute(); TVertex[] vertices = graph.Vertices.ToArray(); foreach (TVertex source in vertices) { ShortestPathAlgorithmBase <TVertex, TEdge, TGraph> otherAlgorithm = shortestPathAlgorithmFactory(graph, getDistances); var predecessors = new VertexPredecessorRecorderObserver <TVertex, TEdge>(); using (predecessors.Attach(otherAlgorithm)) otherAlgorithm.Compute(source); TryFunc <TVertex, IEnumerable <TEdge> > otherPaths = predecessors.TryGetPath; foreach (TVertex target in vertices) { if (source.Equals(target)) { continue; } bool pathExists = algorithm.TryGetPath(source, target, out IEnumerable <TEdge> floydPath); Assert.AreEqual(pathExists, otherPaths(target, out IEnumerable <TEdge> otherPath)); if (pathExists) { TEdge[] floydEdges = floydPath.ToArray(); CheckPath(source, target, floydEdges); TEdge[] otherEdges = otherPath.ToArray(); CheckPath(source, target, otherEdges); // All distances are usually 1 in this test, so it should at least // be the same number if (otherEdges.Length != floydEdges.Length) { Assert.Fail("Path do not have the same length."); } // Check path length are the same double floydLength = floydEdges.Sum(getDistances); double otherLength = otherEdges.Sum(getDistances); if (Math.Abs(floydLength - otherLength) > double.Epsilon) { Assert.Fail("Path do not have the same length."); } } } } }
/// <summary> /// Computes the maximum flow between Source and Sink. /// </summary> protected override void InternalCompute() { if (Source == null) { throw new InvalidOperationException("Source is not specified."); } if (Sink == null) { throw new InvalidOperationException("Sink is not specified."); } if (Services.CancelManager.IsCancelling) { return; } var graph = VisitedGraph; foreach (TVertex vertex in graph.Vertices) { foreach (TEdge edge in graph.OutEdges(vertex)) { double capacity = Capacities(edge); if (capacity < 0) { throw new InvalidOperationException("Negative edge capacity."); } ResidualCapacities[edge] = capacity; } } VerticesColors[Sink] = GraphColor.Gray; while (VerticesColors[Sink] != GraphColor.White) { var verticesPredecessors = new VertexPredecessorRecorderObserver <TVertex, TEdge>(Predecessors); var queue = new Queue <TVertex>(); var bfs = new BreadthFirstSearchAlgorithm <TVertex, TEdge>( ResidualGraph, queue, VerticesColors); using (verticesPredecessors.Attach(bfs)) bfs.Compute(Source); if (VerticesColors[Sink] != GraphColor.White) { Augment(Source, Sink); } } MaxFlow = 0; foreach (TEdge edge in graph.OutEdges(Source)) { MaxFlow += (Capacities(edge) - ResidualCapacities[edge]); } }
private void Search(IVertexAndEdgeListGraph<string,Edge<string>> g, string root) { DijkstraShortestPathAlgorithm<string,Edge<string>> algo = new DijkstraShortestPathAlgorithm<string,Edge<string>>(g, DijkstraShortestPathAlgorithm<string,Edge<string>>.UnaryWeightsFromEdgeList(g) ); VertexPredecessorRecorderObserver<string,Edge<string>> predecessors = new VertexPredecessorRecorderObserver<string,Edge<string>>(); predecessors.Attach(algo); algo.Compute(root); Verify(algo, predecessors); }
public static IDictionary <int, Edge <int> > Get(AdjacencyGraph <int, Edge <int> > g) { var dfs = new DepthFirstSearchAlgorithm <int, Edge <int> >(g); var recorder = new VertexPredecessorRecorderObserver <int, Edge <int> >(); using (recorder.Attach(dfs)) { dfs.Compute(); return(recorder.VerticesPredecessors); } }
public static IDictionary <int, Edge <int> > GetVertexPredecessor(IBidirectionalGraph <int, Edge <int> > g, int root, int target) { IDistanceRelaxer distanceRelaxer = DistanceRelaxers.EdgeShortestDistance; var algorithm = new BestFirstFrontierSearchAlgorithm <int, Edge <int> >(g, edgeWeights => 1.0, distanceRelaxer); var recorder = new VertexPredecessorRecorderObserver <int, Edge <int> >(); using (recorder.Attach(algorithm)) algorithm.Compute(root, target); return(recorder.VerticesPredecessors); }
public static IDictionary <string, TaggedEdge <string, string> > GetVertexPredecessor(IBidirectionalGraph <string, TaggedEdge <string, string> > g, string root, string target) { IDistanceRelaxer distanceRelaxer = DistanceRelaxers.EdgeShortestDistance; var algorithm = new BestFirstFrontierSearchAlgorithm <string, TaggedEdge <string, string> >(g, edgeWeights => double.Parse(edgeWeights.Tag), distanceRelaxer); var recorder = new VertexPredecessorRecorderObserver <string, TaggedEdge <string, string> >(); using (recorder.Attach(algorithm)) algorithm.Compute(root, target); return(recorder.VerticesPredecessors); }
private void Search(IVertexAndEdgeListGraph <string, Edge <string> > g, string root) { DijkstraShortestPathAlgorithm <string, Edge <string> > algo = new DijkstraShortestPathAlgorithm <string, Edge <string> >(g, DijkstraShortestPathAlgorithm <string, Edge <string> > .UnaryWeightsFromEdgeList(g) ); VertexPredecessorRecorderObserver <string, Edge <string> > predecessors = new VertexPredecessorRecorderObserver <string, Edge <string> >(); predecessors.Attach(algo); algo.Compute(root); Verify(algo, predecessors); }
private static void RunDagShortestPathAndCheck <TVertex, TEdge>( [NotNull] IVertexListGraph <TVertex, TEdge> graph, [NotNull] TVertex root, [NotNull] IDistanceRelaxer relaxer) where TEdge : IEdge <TVertex> { var algorithm = new DagShortestPathAlgorithm <TVertex, TEdge>( graph, _ => 1.0, relaxer); algorithm.InitializeVertex += vertex => { Assert.AreEqual(GraphColor.White, algorithm.VerticesColors[vertex]); }; algorithm.DiscoverVertex += vertex => { Assert.AreEqual(GraphColor.Gray, algorithm.VerticesColors[vertex]); }; algorithm.StartVertex += vertex => { Assert.AreNotEqual(GraphColor.Black, algorithm.VerticesColors[vertex]); }; algorithm.ExamineVertex += vertex => { Assert.AreEqual(GraphColor.Gray, algorithm.VerticesColors[vertex]); }; algorithm.FinishVertex += vertex => { Assert.AreEqual(GraphColor.Black, algorithm.VerticesColors[vertex]); }; var predecessors = new VertexPredecessorRecorderObserver <TVertex, TEdge>(); using (predecessors.Attach(algorithm)) algorithm.Compute(root); Assert.AreEqual(graph.VertexCount, algorithm.VerticesColors.Count); foreach (TVertex vertex in graph.Vertices) { Assert.AreEqual(GraphColor.Black, algorithm.VerticesColors[vertex]); } CollectionAssert.IsNotEmpty(algorithm.GetDistances()); Assert.AreEqual(graph.VertexCount, algorithm.GetDistances().Count()); Verify(algorithm, predecessors); }
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 DijkstraSimpleGraph() { var graph = new AdjacencyGraph <string, Edge <string> >(true); // Add some vertices to the graph graph.AddVertex("A"); graph.AddVertex("B"); graph.AddVertex("D"); graph.AddVertex("C"); graph.AddVertex("E"); // Create the edges // ReSharper disable InconsistentNaming var a_b = new Edge <string>("A", "B"); var a_c = new Edge <string>("A", "C"); var b_e = new Edge <string>("B", "E"); var c_d = new Edge <string>("C", "D"); var d_e = new Edge <string>("D", "E"); // ReSharper restore InconsistentNaming // Add edges to the graph graph.AddEdge(a_b); graph.AddEdge(a_c); graph.AddEdge(c_d); graph.AddEdge(d_e); graph.AddEdge(b_e); // Define some weights to the edges var weight = new Dictionary <Edge <string>, double>(graph.EdgeCount) { [a_b] = 30, [a_c] = 30, [b_e] = 60, [c_d] = 40, [d_e] = 4 }; var algorithm = new DijkstraShortestPathAlgorithm <string, Edge <string> >(graph, e => weight[e]); // Attach a Vertex Predecessor Recorder Observer to give us the paths var predecessorObserver = new VertexPredecessorRecorderObserver <string, Edge <string> >(); using (predecessorObserver.Attach(algorithm)) // Run the algorithm with A set to be the source algorithm.Compute("A"); Assert.AreEqual(74, algorithm.Distances["E"], double.Epsilon); }
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); }
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 void Compute(IUndirectedGraph<string, Edge<string>> g) { Dictionary<Edge<string>, double> distances = new Dictionary<Edge<string>,double>(); foreach(Edge<string> edge in g.Edges) distances.Add(edge, 1); PrimMinimumSpanningTreeAlgorithm<string, Edge<string>> prim = new PrimMinimumSpanningTreeAlgorithm<string, Edge<string>>(g, distances); VertexPredecessorRecorderObserver<string, Edge<string>> predecessors = new VertexPredecessorRecorderObserver<string, Edge<string>>(); predecessors.Attach(prim); prim.Compute(); foreach (string v in g.Vertices) { Edge<string> edge; if (predecessors.VertexPredecessors.TryGetValue(v, out edge)) Console.WriteLine("{0}: {1}", v, edge); else Console.WriteLine("{0}", v); } }
public void CreateGraph() { graph = new AdjacencyGraph<string, Edge<string>>(true); // Add some vertices to the graph graph.AddVertex("A"); graph.AddVertex("B"); graph.AddVertex("D"); graph.AddVertex("C"); graph.AddVertex("E"); // Create the edges var a_b = new Edge<string>("A", "B"); var a_c = new Edge<string>("A", "C"); var b_e = new Edge<string>("B", "E"); var c_d = new Edge<string>("C", "D"); var d_e = new Edge<string>("D", "E"); // Add edges to the graph graph.AddEdge(a_b); graph.AddEdge(a_c); graph.AddEdge(c_d); graph.AddEdge(d_e); graph.AddEdge(b_e); // Define some weights to the edges var weight = new Dictionary<Edge<string>, double>(graph.EdgeCount); weight.Add(a_b, 30); weight.Add(a_c, 30); weight.Add(b_e, 60); weight.Add(c_d, 40); weight.Add(d_e, 4); algo = new DijkstraShortestPathAlgorithm<string, Edge<string>>(graph, e => weight[e]); // Attach a Vertex Predecessor Recorder Observer to give us the paths predecessorObserver = new VertexPredecessorRecorderObserver<string, Edge<string>>(); using (predecessorObserver.Attach(algo)) // Run the algorithm with A set to be the source algo.Compute("A"); Assert.IsTrue(algo.Distances["E"] == 74); }
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; }
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; }
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 CheckPredecessorLineGraph() { AdjacencyGraph<int, Edge<int>> g = new AdjacencyGraph<int, Edge<int>>(true); g.AddVertex(1); g.AddVertex(2); g.AddVertex(3); Edge<int> e12 = new Edge<int>(1, 2); g.AddEdge(e12); Edge<int> e23 = new Edge<int>(2, 3); g.AddEdge(e23); Dictionary<Edge<int>, double> weights = DijkstraShortestPathAlgorithm<int, Edge<int>>.UnaryWeightsFromEdgeList(g); DijkstraShortestPathAlgorithm<int, Edge<int>> dij = new DijkstraShortestPathAlgorithm<int, Edge<int>>(g, weights); VertexPredecessorRecorderObserver<int, Edge<int>> vis = new VertexPredecessorRecorderObserver<int, Edge<int>>(); vis.Attach(dij); dij.Compute(1); IList<Edge<int>> col = vis.Path(2); Assert.AreEqual(1, col.Count); Assert.AreEqual(e12, col[0]); col = vis.Path(3); Assert.AreEqual(2, col.Count); Assert.AreEqual(e12, col[0]); Assert.AreEqual(e23, col[1]); }
public void Scenario() { 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); // We want to use Dijkstra on this graph var dijkstra = new DijkstraShortestPathAlgorithm<string, Edge<string>>(graph, e => edgeCost[e]); // Attach a Vertex Predecessor Recorder Observer to give us the paths var 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, 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); foreach (string v in graph.Vertices) { double distance = AlgorithmExtensions.ComputePredecessorCost( predecessorObserver.VertexPredecessors, edgeCost,v); Console.WriteLine("A -> {0}: {1}", v, distance); } }
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); }
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); }
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"); }
private void Search( IVertexListGraph<string, Edge<string>> g, string root, IDistanceRelaxer relaxer) { DagShortestPathAlgorithm<string, Edge<string>> algo = new DagShortestPathAlgorithm<string, Edge<string>>( g, DagShortestPathAlgorithm<string, Edge<string>>.UnaryWeightsFromVertexList(g), relaxer ); VertexPredecessorRecorderObserver<string, Edge<string>> predecessors = new VertexPredecessorRecorderObserver<string, Edge<string>>(); predecessors.Attach(algo); algo.Compute(root); Verify(algo, predecessors); }
/// <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; }
/// <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; }
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 void Compute() { var g = new AdjacencyGraph<char, Edge<char>>(); var distances = new Dictionary<Edge<char>, double>(); g.AddVertexRange("ABCDE"); AddEdge(g, distances, 'A', 'C', 1); AddEdge(g, distances, 'B', 'B', 2); AddEdge(g, distances, 'B', 'D', 1); AddEdge(g, distances, 'B', 'E', 2); AddEdge(g, distances, 'C', 'B', 7); AddEdge(g, distances, 'C', 'D', 3); AddEdge(g, distances, 'D', 'E', 1); AddEdge(g, distances, 'E', 'A', 1); AddEdge(g, distances, 'E', 'B', 1); var dijkstra = new DijkstraShortestPathAlgorithm<char, Edge<char>>(g, distances); var predecessors = new VertexPredecessorRecorderObserver<char, Edge<char>>(); predecessors.Attach(dijkstra); dijkstra.Compute('A'); Assert.AreEqual(0, dijkstra.Distances['A']); Assert.AreEqual(6, dijkstra.Distances['B']); Assert.AreEqual(1, dijkstra.Distances['C']); Assert.AreEqual(4, dijkstra.Distances['D']); Assert.AreEqual(5, dijkstra.Distances['E']); }
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; }