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]); }
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 <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); }
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); }
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); }
public static bool FoundTarget <TVertex, TEdge>(IBidirectionalGraph <TVertex, TEdge> g, TVertex root, TVertex target) where TEdge : IEdge <TVertex> { IDistanceRelaxer distanceRelaxer = DistanceRelaxers.EdgeShortestDistance; var algorithm = new BestFirstFrontierSearchAlgorithm <TVertex, TEdge>(g, edgeWeights => 1.0, distanceRelaxer); bool targetReached = false; algorithm.TargetReached += (sender, args) => targetReached = true; var recorder = new VertexPredecessorRecorderObserver <TVertex, TEdge>(); using (recorder.Attach(algorithm)) algorithm.Compute(root, target); return(targetReached); }
static void Dijkstra <TVertex, TEdge>( IVertexAndEdgeListGraph <TVertex, TEdge> g, Dictionary <TEdge, double> distances, TVertex root) where TEdge : IEdge <TVertex> { var algo = new DijkstraShortestPathAlgorithm <TVertex, TEdge>( g, AlgorithmExtensions.GetIndexer(distances) ); var predecessors = new VertexPredecessorRecorderObserver <TVertex, TEdge>(); using (predecessors.Attach(algo)) algo.Compute(root); }
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 static void Verify(DijkstraShortestPathAlgorithm<string, Edge<string>> algo, VertexPredecessorRecorderObserver<string, Edge<string>> predecessors) { // let's verify the result foreach (string v in algo.VisitedGraph.Vertices) { Edge<string> predecessor; if (!predecessors.VertexPredecessors.TryGetValue(v, out predecessor)) continue; if (predecessor.Source == v) continue; Assert.AreEqual( algo.Distances[v], algo.Distances[predecessor.Source] + 1 ); } }
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 void Check(IVertexSet <IGeometry> graph, IDictionary <IEdge <IGeometry>, double> consts, VertexPredecessorRecorderObserver <IGeometry, IEdge <IGeometry> > predecessorObserver) { foreach (IGeometry v in graph.Vertices) { double distance = 0; IGeometry vertex = v; IEdge <IGeometry> predecessor; while (predecessorObserver.VertexPredecessors.TryGetValue(vertex, out predecessor)) { distance += consts[predecessor]; vertex = predecessor.Source; } Console.WriteLine("A -> {0}: {1}", v, distance); } }
public static VertexPredecessorRecorderObserver <TVertex, TEdge> GetPredecessors <TVertex, TEdge> (this IVertexListGraph <TVertex, TEdge> graph, TVertex obj, VertexAction <TVertex> onVertex) where TEdge : IEdge <TVertex> { var bfsa = new BreadthFirstSearchAlgorithm <TVertex, TEdge> (graph); bfsa.ExamineVertex += (vertex) => { onVertex?.Invoke(vertex); }; var vertexPredecessorRecorderObserver = new VertexPredecessorRecorderObserver <TVertex, TEdge> (); using (vertexPredecessorRecorderObserver.Attach(bfsa)) { bfsa.Compute(obj); } return(vertexPredecessorRecorderObserver); }
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 CentralityApproximationAlgorithm( IVertexListGraph <TVertex, TEdge> visitedGraph, Func <TEdge, double> distances ) : base(visitedGraph) { Contract.Requires(distances != null); this.dijkstra = new DijkstraShortestPathAlgorithm <TVertex, TEdge>( this.VisitedGraph, distances, DistanceRelaxers.ShortestDistance ); this.predecessorRecorder = new VertexPredecessorRecorderObserver <TVertex, TEdge>(); this.predecessorRecorder.Attach(this.dijkstra); }
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 Calculate() { Func <LabelledEdge <ExtendedWarp>, double> edgeCost = (x) => x.Cost; //TryFunc<ExtendedWarp, LabelledEdge<ExtendedWarp>> tryGetPaths = this var alg = new DijkstraShortestPathAlgorithm <ExtendedWarp, LabelledEdge <ExtendedWarp> >(this, edgeCost); var distObserver = new VertexDistanceRecorderObserver <ExtendedWarp, LabelledEdge <ExtendedWarp> >(edgeCost); distObserver.Attach(alg); var predecessorObserver = new VertexPredecessorRecorderObserver <ExtendedWarp, LabelledEdge <ExtendedWarp> >(); predecessorObserver.Attach(alg); alg.Compute(this.Vertices.ElementAt(0)); // Example: Get to town from farm hous }
public void Populate() { foreach (GameLocation location in this.gameLocations) { var partialGraph = new PartialGraph(location); partialGraph.Populate(); this.PartialGraphs.Add(partialGraph); } var farmBuildings = Game1.getFarm().buildings; foreach (Building building in farmBuildings) { var indoors = building.indoors.Value; if (indoors != null && indoors is AnimalHouse) { var partialGraph = new PartialGraph((AnimalHouse)indoors); partialGraph.Populate(); this.PartialGraphs.Add(partialGraph); } } foreach (PartialGraph pgSource in this.PartialGraphs) { foreach (PartialGraph pgTarget in this.PartialGraphs) { if (pgSource != pgTarget) { this.ConnectPartialGraph(pgSource, pgTarget); } } } foreach (PartialGraph partialGraph in this.PartialGraphs) { this.AddVertexRange(partialGraph.Vertices); this.AddEdgeRange(partialGraph.Edges); } Func <StardewEdge, double> edgeCost = (x) => x.Cost; this.dijkstra = new DijkstraShortestPathAlgorithm <StardewVertex, StardewEdge>(this, edgeCost); this.distObserver = new VertexDistanceRecorderObserver <StardewVertex, StardewEdge>(edgeCost); this.distObserver.Attach(this.dijkstra); this.predecessorObserver = new VertexPredecessorRecorderObserver <StardewVertex, StardewEdge>(); this.predecessorObserver.Attach(this.dijkstra); }
/// <summary> /// Computes the maximum flow between <paramref name="src"/> and /// <paramref name="sink"/> /// </summary> /// <param name="src"></param> /// <param name="sink"></param> /// <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"); } foreach (TVertex u in VisitedGraph.Vertices) { foreach (TEdge e in VisitedGraph.OutEdges(u)) { ResidualCapacities[e] = Capacities[e]; } } VertexColors[Sink] = GraphColor.Gray; while (VertexColors[Sink] != GraphColor.White) { VertexPredecessorRecorderObserver <TVertex, TEdge> vis = new VertexPredecessorRecorderObserver <TVertex, TEdge>( Predecessors ); VertexBuffer <TVertex> Q = new VertexBuffer <TVertex>(); BreadthFirstSearchAlgorithm <TVertex, TEdge> bfs = new BreadthFirstSearchAlgorithm <TVertex, TEdge>( ResidualGraph, Q, VertexColors ); vis.Attach(bfs); bfs.Compute(this.Source); vis.Detach(bfs); if (VertexColors[this.Sink] != GraphColor.White) { Augment(this.Source, this.Sink); } } // while this.MaxFlow = 0; foreach (TEdge e in VisitedGraph.OutEdges(Source)) { this.MaxFlow += (Capacities[e] - ResidualCapacities[e]); } }
/// <summary> /// Computes the maximum flow between <see cref="MaximumFlowAlgorithm{TVertex,TEdge}.Source"/> /// and <see cref="MaximumFlowAlgorithm{TVertex,TEdge}.Sink"/>. /// </summary> protected override void InternalCompute() { 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 NegativeCapacityException(); } 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]); } }
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); }
public static IEnumerable <TVertex> Roots <TVertex, TEdge>( IVertexListGraph <TVertex, TEdge> visitedGraph) where TEdge : IEdge <TVertex> { DepthFirstSearchAlgorithm <TVertex, TEdge> dfs = new DepthFirstSearchAlgorithm <TVertex, TEdge>(visitedGraph); VertexPredecessorRecorderObserver <TVertex, TEdge> vis = new VertexPredecessorRecorderObserver <TVertex, TEdge>(); vis.Attach(dfs); foreach (KeyValuePair <TVertex, TEdge> predecessor in vis.VertexPredecessors) { if (predecessor.Value.Equals(default(TEdge))) { yield return(predecessor.Key); } } }
public IEnumerable <SEdge <CurveVertex>[]> SearchLoops() { _allLoops.Clear(); // create algorithm var dfs = new DepthFirstSearchAlgorithm <CurveVertex, SEdge <CurveVertex> >(_graph); _observer = new VertexPredecessorRecorderObserver <CurveVertex, SEdge <CurveVertex> >(); using (var attacher = _observer.Attach(dfs)) { dfs.BackEdge += OnDfsBackEdge; dfs.ForwardOrCrossEdge += OnDfsForwardOrCrossEdge; //do the search dfs.Compute(); return(_allLoops); } }
private static void Search <TVertex, TEdge>( [NotNull] IVertexListGraph <TVertex, TEdge> graph, [NotNull] TVertex root, [NotNull] IDistanceRelaxer relaxer) where TEdge : IEdge <TVertex> { var algorithm = new DagShortestPathAlgorithm <TVertex, TEdge>( graph, e => 1, relaxer); var predecessors = new VertexPredecessorRecorderObserver <TVertex, TEdge>(); using (predecessors.Attach(algorithm)) algorithm.Compute(root); Verify(algorithm, predecessors); }
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); }
private void Search <TVertex, TEdge>( IVertexListGraph <TVertex, TEdge> g, TVertex root, IDistanceRelaxer relaxer) where TEdge : IEdge <TVertex> { var algo = new DagShortestPathAlgorithm <TVertex, TEdge>( g, e => 1, relaxer ); var predecessors = new VertexPredecessorRecorderObserver <TVertex, TEdge>(); using (predecessors.Attach(algo)) algo.Compute(root); Verify(algo, predecessors); }
public static void RhinoBFS(List <int> N, List <int> U, List <int> V, List <double> W = null) { //Create undirected graph UndirectedGraph <int, Edge <int> > g = new UndirectedGraph <int, Edge <int> >(); g.AddVertexRange(N); for (int i = 0; i < U.Count; i++) { g.AddEdge(new QuickGraph.Edge <int>(U[i], V[i])); } //BFS var bfs = new QuickGraph.Algorithms.Search.UndirectedBreadthFirstSearchAlgorithm <int, QuickGraph.Edge <int> >(g); var observer = new VertexPredecessorRecorderObserver <int, QuickGraph.Edge <int> >(); //using (ObserverScope.Create(bfs, observer)) // attach, detach to dfs events //bfs.Compute(); }
public void Constructor() { var recorder = new VertexPredecessorRecorderObserver <int, Edge <int> >(); CollectionAssert.IsEmpty(recorder.VerticesPredecessors); var predecessors = new Dictionary <int, Edge <int> >(); recorder = new VertexPredecessorRecorderObserver <int, Edge <int> >(predecessors); Assert.AreSame(predecessors, recorder.VerticesPredecessors); predecessors = new Dictionary <int, Edge <int> > { [1] = new Edge <int>(2, 1) }; recorder = new VertexPredecessorRecorderObserver <int, Edge <int> >(predecessors); Assert.AreSame(predecessors, recorder.VerticesPredecessors); }
public CentralityApproximationAlgorithm( IVertexListGraph <TVertex, TEdge> visitedGraph, IDictionary <TEdge, double> distances ) : base(visitedGraph) { if (distances == null) { throw new ArgumentNullException("distances"); } this.dijkstra = new DijkstraShortestPathAlgorithm <TVertex, TEdge>( this.VisitedGraph, distances, new ShortestDistanceRelaxer() ); this.predecessorRecorder = new VertexPredecessorRecorderObserver <TVertex, TEdge>(); this.predecessorRecorder.Attach(this.dijkstra); }
static void FrontierDijkstra <TVertex, TEdge>( IBidirectionalGraph <TVertex, TEdge> g, Dictionary <TEdge, double> distances, TVertex root, TVertex target) where TEdge : IEdge <TVertex> { var algo = new BestFirstFrontierSearchAlgorithm <TVertex, TEdge>( null, g, AlgorithmExtensions.GetIndexer(distances), DistanceRelaxers.ShortestDistance ); var predecessors = new VertexPredecessorRecorderObserver <TVertex, TEdge>(); using (predecessors.Attach(algo)) algo.Compute(root, target); }
/// <summary> /// Initializes a new instance of the <see cref="CentralityApproximationAlgorithm{TVertex,TEdge}"/> class. /// </summary> /// <param name="visitedGraph">Graph to visit.</param> /// <param name="distances">Function to compute the distance given an edge.</param> public CentralityApproximationAlgorithm( [NotNull] IVertexListGraph <TVertex, TEdge> visitedGraph, [NotNull] Func <TEdge, double> distances) : base(visitedGraph) { if (distances is null) { throw new ArgumentNullException(nameof(distances)); } _dijkstra = new DijkstraShortestPathAlgorithm <TVertex, TEdge>( VisitedGraph, distances, DistanceRelaxers.ShortestDistance); var predecessorRecorder = new VertexPredecessorRecorderObserver <TVertex, TEdge>(); _predecessorRecorderSubscription = predecessorRecorder.Attach(_dijkstra); }
public static IEnumerable <Edge <GraphVertex> > ShortestWayAstarAlgorithm(List <GraphVertex> listVertex, List <GraphEdge> listEdge, GraphVertex start, GraphVertex end) { AdjacencyGraph <GraphVertex, Edge <GraphVertex> > graph = new AdjacencyGraph <GraphVertex, Edge <GraphVertex> >(); foreach (var vert in listVertex) { graph.AddVertex(vert); } foreach (var edge in listEdge) { graph.AddEdge(new Edge <GraphVertex>(edge.StartVertex, edge.EndVertex)); } Dictionary <Edge <GraphVertex>, double> edgeCost = new Dictionary <Edge <GraphVertex>, double>(); int i = 0; foreach (var edge in graph.Edges) { double eCost = EdgeCostSearching(edge.Source, edge.Target, listEdge); edgeCost.Add(edge, eCost); i++; } Func <Edge <GraphVertex>, double> getW = edge => edgeCost[edge]; //--------------------------------- IEnumerable <Edge <GraphVertex> > edgessAstar; AStarShortestPathAlgorithm <GraphVertex, Edge <GraphVertex> > astar = new AStarShortestPathAlgorithm <GraphVertex, Edge <GraphVertex> >(graph, getW, x => 0.0); VertexDistanceRecorderObserver <GraphVertex, Edge <GraphVertex> > distObsA = new VertexDistanceRecorderObserver <GraphVertex, Edge <GraphVertex> >(getW); using (distObsA.Attach(astar)) { VertexPredecessorRecorderObserver <GraphVertex, Edge <GraphVertex> > predObs = new VertexPredecessorRecorderObserver <GraphVertex, Edge <GraphVertex> >(); using (predObs.Attach(astar)) { astar.Compute(start); if (predObs.TryGetPath(end, out edgessAstar)) { return(edgessAstar); } } } return(null); }
public void 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 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 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']); }
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, weight); // Attach a Vertex Predecessor Recorder Observer to give us the paths predecessorObserver = new VertexPredecessorRecorderObserver<string, Edge<string>>(); using (ObserverScope.Create<IVertexPredecessorRecorderAlgorithm<string, Edge<string>>>(algo, predecessorObserver)) { // Run the algorithm with A set to be the source algo.Compute("A"); } path = new List<string>(); PopulatePath("E"); Assert.IsTrue(algo.Distances["E"] == 74); path.Reverse(); Console.WriteLine(String.Join(" -> ", path.ToArray())); }
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"); }
/// <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; }
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); }
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; }
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 void Check(IVertexSet<IGeometry> graph, IDictionary<IEdge<IGeometry>, double> consts, VertexPredecessorRecorderObserver<IGeometry, IEdge<IGeometry>> predecessorObserver) { foreach (IGeometry v in graph.Vertices) { double distance = 0; IGeometry vertex = v; IEdge<IGeometry> predecessor; while (predecessorObserver.VertexPredecessors.TryGetValue(vertex, out predecessor)) { distance += consts[predecessor]; vertex = predecessor.Source; } 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 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 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); }
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); } }
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(); }
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 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); }
/// <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; }