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); } }
/// <summary> /// Populates a DGML graph from a graph /// </summary> /// <typeparam name="TVertex"></typeparam> /// <typeparam name="TEdge"></typeparam> /// <param name="visitedGraph"></param> /// <param name="vertexColors"></param> /// <returns></returns> public static DirectedGraph ToDirectedGraphML <TVertex, TEdge>( #if !NET20 this #endif IVertexAndEdgeListGraph <TVertex, TEdge> visitedGraph, Func <TVertex, GraphColor> vertexColors) where TEdge : IEdge <TVertex> { Contract.Requires(visitedGraph != null); Contract.Requires(vertexColors != null); Contract.Ensures(Contract.Result <DirectedGraph>() != null); return(ToDirectedGraphML <TVertex, TEdge>( visitedGraph, AlgorithmExtensions.GetVertexIdentity <TVertex>(visitedGraph), AlgorithmExtensions.GetEdgeIdentity <TVertex, TEdge>(visitedGraph), (v, n) => { var color = vertexColors(v); switch (color) { case GraphColor.Black: n.Background = "Black"; break; case GraphColor.Gray: n.Background = "LightGray"; break; case GraphColor.White: n.Background = "White"; break; } }, null )); }
public void Compute <TVertex, TEdge>([PexAssumeNotNull] IVertexListGraph <TVertex, TEdge> g) where TEdge : IEdge <TVertex> { // is this a dag ? bool isDag = AlgorithmExtensions.IsDirectedAcyclicGraph(g); var relaxer = DistanceRelaxers.ShortestDistance; var vertices = new List <TVertex>(g.Vertices); foreach (var root in vertices) { if (isDag) { Search(g, root, relaxer); } else { try { Search(g, root, relaxer); } catch (NonAcyclicGraphException) { Console.WriteLine("NonAcyclicGraphException caught (as expected)"); } } } }
public double GetPathDistanceBetweenStations(string from, string to) { if (from == to) { // if wanna look for shortest path from a vertex back to the same vertex // i.e. shortest cycle included a given vertex // use the Floyd-Warshall algorithm O(V^3) var distance = 0.0; if (ShortestCycleIncludedAGivenVertex.TryGetDistanceFloydWarshall(_graph, _costs, from, out distance)) { return distance; } } else // otherwise use Dijkstra { var edgeCost = AlgorithmExtensions.GetIndexer(_costs); var tryGetPath = _graph.ShortestPathsDijkstra(edgeCost, from); IEnumerable<Edge<string>> path; var isPathExists = tryGetPath(to, out path); if (isPathExists) { var distance = path.Sum(edgeCost); return distance; } } return -1; }
/// <summary> /// Initializes a new instance of the <see cref="FibonacciQueue{TVertex,TDistance}"/> class. /// </summary> /// <param name="values">Dictionary of vertices associates to their distance.</param> /// <param name="distanceComparison">Comparer of distances.</param> public FibonacciQueue( [NotNull] Dictionary <TVertex, TDistance> values, [NotNull] Comparison <TDistance> distanceComparison) { if (values is null) { throw new ArgumentNullException(nameof(values)); } if (distanceComparison is null) { throw new ArgumentNullException(nameof(distanceComparison)); } _distanceFunc = AlgorithmExtensions.GetIndexer(values); _cells = new Dictionary <TVertex, FibonacciHeapCell <TDistance, TVertex> >(values.Count); foreach (KeyValuePair <TVertex, TDistance> pair in values) { _cells.Add( pair.Key, new FibonacciHeapCell <TDistance, TVertex> { Priority = pair.Value, Value = pair.Key, Removed = true } ); } _heap = new FibonacciHeap <TDistance, TVertex>(HeapDirection.Increasing, distanceComparison); }
public List <PricedRouteSegment> CalculateShortestPath(string from, string to) { var edgeCost = AlgorithmExtensions.GetIndexer(_costs); var tryGetPath = _graph.ShortestPathsDijkstra(edgeCost, from); List <PricedRouteSegment> result = new List <PricedRouteSegment>(); IEnumerable <CustomEdge> path; if (tryGetPath(to, out path)) { foreach (var segment in path) { result.Add(new PricedRouteSegment(segment.Source.ToString(), segment.Target.ToString(), segment.Time, segment.Price, segment.Company)); } } else { Console.WriteLine("No path found from {0} to {1}."); } return(result); }
public static int Answer(int numOfServers, int targetServer, int[,] connectionTimeMatrix) { for (int i = 0; i < connectionTimeMatrix.GetLength(0); i++) { for (int j = 0; j < numOfServers; j++) { var edge = new Edge <int>(i, j); graph.AddVerticesAndEdge(edge); costs.Add(edge, connectionTimeMatrix[i, j]); } } var edgeCost = AlgorithmExtensions.GetIndexer(costs); var tryGetPath = graph.ShortestPathsDijkstra(edgeCost, 0); IEnumerable <Edge <int> > path; tryGetPath(targetServer, out path); double cost = 0; foreach (var edge in path) { cost += costs[edge]; } return(Convert.ToInt32(cost)); }
public void Repro13482() { var graph = new AdjacencyGraph <Person, TaggedEdge <Person, string> >(); Person jacob = new Person("Jacob", "Hochstetler") { BirthDate = new DateTime(1712, 01, 01), BirthPlace = "Alsace, France", DeathDate = new DateTime(1776, 01, 01), DeathPlace = "Pennsylvania, USA", Gender = Gender.Male }; Person john = new Person("John", "Hochstetler") { BirthDate = new DateTime(1735, 01, 01), BirthPlace = "Alsace, France", DeathDate = new DateTime(1805, 04, 15), DeathPlace = "Summit Mills, PA", Gender = Gender.Male }; Person jonathon = new Person("Jonathon", "Hochstetler") { BirthPlace = "Pennsylvania", DeathDate = new DateTime(1823, 05, 08), Gender = Gender.Male, }; Person emanuel = new Person("Emanuel", "Hochstedler") { BirthDate = new DateTime(1855, 01, 01), DeathDate = new DateTime(1900, 01, 01), Gender = Gender.Male }; graph.AddVerticesAndEdge(new TaggedEdge <Person, string>(jacob, john, jacob.ChildRelationshipText)); graph.AddVerticesAndEdge(new TaggedEdge <Person, string>(john, jonathon, john.ChildRelationshipText)); graph.AddVerticesAndEdge(new TaggedEdge <Person, string>(jonathon, emanuel, jonathon.ChildRelationshipText)); var settings = new XmlWriterSettings() { Indent = true, IndentChars = @" " }; using (var writer = XmlWriter.Create(Console.Out, settings)) { SerializationExtensions.SerializeToXml( graph, writer, v => v.Id, AlgorithmExtensions.GetEdgeIdentity(graph), "graph", "person", "relationship", ""); } }
public YggdrasilNM2() { this.Nodes = new Dictionary <string, Topology.Node.Node>(); this.Links = new Dictionary <string, Topology.IGP.Link.Link>(); this.Graph = new BidirectionalGraph <string, TaggedEdge <string, Topology.IGP.Link.Link> >(); this.EdgeCost = new Dictionary <TaggedEdge <string, Topology.IGP.Link.Link>, double>(); this.HoffmanPavley = new HoffmanPavleyRankedShortestPathAlgorithm <string, TaggedEdge <string, Topology.IGP.Link.Link> > (this.Graph, AlgorithmExtensions.GetIndexer <TaggedEdge <string, Topology.IGP.Link.Link>, double>(this.EdgeCost)); this.HoffmanPavley.ShortestPathCount = 100; }
public void Prim<TVertex, TEdge>([PexAssumeNotNull]IUndirectedGraph<TVertex, TEdge> g) where TEdge : IEdge<TVertex> { var distances = new Dictionary<TEdge, double>(); foreach (var e in g.Edges) distances[e] = g.AdjacentDegree(e.Source) + 1; var edges = AlgorithmExtensions.MinimumSpanningTreePrim(g, e => distances[e]); AssertSpanningTree(g, edges); }
private string PrintShortestPath(string @from, string to, AdjacencyGraph <string, Edge <string> > graph, Dictionary <Edge <string>, double> costs, Dictionary <Edge <string>, int> busIDs, int mode) { var edgeCost = AlgorithmExtensions.GetIndexer(costs); var tryGetPath = graph.ShortestPathsDijkstra(edgeCost, @from); string type = ""; if (mode == 1) { type = "короткий"; } else if (mode == 2) { type = "дешёвый"; } IEnumerable <Edge <string> > path; StringBuilder builder = new StringBuilder(); if (tryGetPath(to, out path)) { builder.Append("Самый " + type + " путь от остановки "); builder.Append(from); builder.Append(" до остановки "); builder.Append(to); builder.Append(":\n"); builder.Append("{" + from + "}"); //MessageBox.Show("Path found from {" + from + "} to {" + to + "}: {" + from + "}"); foreach (var e in path) { builder.Append(" > {" + e.Target + "}"); } } else { builder.Append("Путь не найден."); } builder.Append(" на автобусе(ах): "); foreach (Edge <string> edge in path) { foreach (var item in busIDs) { if (item.Key == edge) { //MessageBox.Show(item.Value.ToString()); builder.Append(item.Value.ToString() + " "); } } } return(builder.ToString()); }
public void Repro12901() { var graph = new BidirectionalGraph <int, Edge <int> >(); int vertex = 1; graph.AddVerticesAndEdge(new Edge <int>(vertex, vertex)); var pathFinder = AlgorithmExtensions.ShortestPathsBellmanFord <int, Edge <int> >(graph, edge => - 1.0, vertex); IEnumerable <Edge <int> > path; pathFinder(vertex, out path); }
/// <summary> /// Populates a DGML graph from a graph /// </summary> /// <typeparam name="TVertex"></typeparam> /// <typeparam name="TEdge"></typeparam> /// <param name="visitedGraph"></param> /// <returns></returns> public static DirectedGraph ToDirectedGraphML <TVertex, TEdge>(this IVertexAndEdgeListGraph <TVertex, TEdge> visitedGraph) where TEdge : IEdge <TVertex> { Contract.Requires(visitedGraph != null); Contract.Ensures(Contract.Result <DirectedGraph>() != null); return(ToDirectedGraphML <TVertex, TEdge>( visitedGraph, AlgorithmExtensions.GetVertexIdentity <TVertex>(visitedGraph), AlgorithmExtensions.GetEdgeIdentity <TVertex, TEdge>(visitedGraph) )); }
protected LinkedList <Connector> GetPath(Connector stop) { // get graph var graph = new AdjacencyGraph <Connector, TaggedEdge <Connector, double> >(); var costs = new Dictionary <Edge <Connector>, double>(); //var list = new List<Connector>(WorkingConnectors); // get vertexes foreach (Connector connector in WorkingConnectors) { graph.AddVertex(connector); } // get edges for (int i = 0; i < WorkingConnectors.Count; i++) { for (int j = 0; j < WorkingConnectors.Count; j++) { if (i != j && WorkingConnectors[i].CanAccess(WorkingConnectors[j])) { var edge = new TaggedEdge <Connector, double>(WorkingConnectors[i], WorkingConnectors[j], Message.Time(WorkingConnectors[i], WorkingConnectors[j])); graph.AddVerticesAndEdge(edge); costs.Add(edge, Message.Time(WorkingConnectors[i], WorkingConnectors[j])); //Console.WriteLine(WorkingConnectors[i].ID + " " + WorkingConnectors[j].ID); } } } var edgeCost = AlgorithmExtensions.GetIndexer(costs); var tryGetPath = graph.ShortestPathsDijkstra(edgeCost, this); // get path IEnumerable <TaggedEdge <Connector, double> > epath; if (!tryGetPath(stop, out epath)) { // can't get path return(null); } // convert path to linked list var path = epath.ToList(); var result = new LinkedList <Connector>(); foreach (TaggedEdge <Connector, double> edge in path) { result.AddLast(edge.Source); } result.AddLast(stop); return(result); }
private static double RunMaxFlowAlgorithm <TVertex, TEdge>(IMutableVertexAndEdgeListGraph <TVertex, TEdge> g, EdgeFactory <TVertex, TEdge> edgeFactory, TVertex source, TVertex sink) where TEdge : IEdge <TVertex> { TryFunc <TVertex, TEdge> flowPredecessors; var flow = AlgorithmExtensions.MaximumFlowEdmondsKarp <TVertex, TEdge>( g, e => 1, source, sink, out flowPredecessors, edgeFactory ); return(flow); }
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 void PrintShortestPath(string @from, string to) { var edgeCost = AlgorithmExtensions.GetIndexer(_costs); var tryGetPath = _graph.ShortestPathsDijkstra(edgeCost, @from); IEnumerable <Edge <string> > path; if (tryGetPath(to, out path)) { PrintPath(@from, to, path); } else { Console.WriteLine("No path found from {0} to {1}."); } }
public static void Serialize(Stream stream, MyGraph graph) { var settings = new XmlWriterSettings { Indent = true }; using (var writer = XmlWriter.Create(stream, settings)) { graph.SerializeToXml(writer, AlgorithmExtensions.GetVertexIdentity(graph), AlgorithmExtensions.GetEdgeIdentity(graph), "MyGraph", "Job", "MyEdge", "", (wr, gr) => { }, SerializeNode, (wr, ed) => { } ); } stream.Close(); }
/// <summary> /// 'Helper' method to identify the shortest path between 2 hexes (Fiefs), /// then to convert path into a string for visual display /// </summary> /// <returns>String to display</returns> /// <param name="from">Source Fief</param> /// <param name="to">Target Fief</param> public string GetShortestPathString(Fief @from, Fief to) { string output = ""; var edgeCost = AlgorithmExtensions.GetIndexer(costs); var tryGetPath = myMap.ShortestPathsDijkstra(edgeCost, @from); IEnumerable <TaggedEdge <Fief, string> > path; if (tryGetPath(to, out path)) { output = PrintPath(@from, to, path); } else { output = "No path found from " + @from.id + " to " + to.id; } return(output); }
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); }
public static void SerializeToGraphML <TVertex, TEdge, TGraph>( this TGraph graph, XmlWriter writer) where TEdge : IEdge <TVertex> where TGraph : IEdgeListGraph <TVertex, TEdge> { Contract.Requires(graph != null); Contract.Requires(writer != null); var vertexIdentity = AlgorithmExtensions.GetVertexIdentity <TVertex>(graph); var edgeIdentity = AlgorithmExtensions.GetEdgeIdentity <TVertex, TEdge>(graph); SerializeToGraphML <TVertex, TEdge, TGraph>( graph, writer, vertexIdentity, edgeIdentity ); }
public string GetShortestPath(List <ICity> vertexes, string from, string to) { LoadCosts(vertexes); var edgeCost = AlgorithmExtensions.GetIndexer(_costs); var tryGetPath = _graph.ShortestPathsDijkstra(edgeCost, from); IEnumerable <Edge <string> > path; if (tryGetPath(to, out path)) { object[] arr = path.ToArray(); return(string.Join(",", arr)); } else { return(string.Format("No path found from {0} to {1}.", from, to)); } }
public static bool TryGetDistanceFloydWarshall <TVertex, TEdge, TGraph>(TGraph visitedGraph, Dictionary <TEdge, double> costs, TVertex vertexToInclude, out double shortestCycleVertexIncludedTotalCost) where TEdge : IEdge <TVertex> where TGraph : IVertexAndEdgeListGraph <TVertex, TEdge> { //var obj = (TEdge)Activator.CreateInstance(typeof(TEdge), vertexToInclude, vertexToInclude); var infiniteSelfCostForAGivenVertex = new Dictionary <TEdge, double>(costs); infiniteSelfCostForAGivenVertex.Add( (TEdge)Activator.CreateInstance(typeof(TEdge), vertexToInclude, vertexToInclude), Double.PositiveInfinity); var edgeCost = AlgorithmExtensions.GetIndexer(costs); IVertexAndEdgeListGraph <TVertex, TEdge> g = visitedGraph; var algorithm = new FloydWarshallAllShortestPathAlgorithmAllowNotZeroSelfCost <TVertex, TEdge, TGraph>(visitedGraph, edgeCost); algorithm.Compute(); return(algorithm.TryGetDistance(vertexToInclude, vertexToInclude, out shortestCycleVertexIncludedTotalCost)); }
private static void PrintShortestPath(string @from, string to) { var edgeCost = AlgorithmExtensions.GetIndexer(_costs); // Defines the algorithm to be used. var tryGetPath = _graph.ShortestPathsDijkstra(edgeCost, @from); IEnumerable <Edge <string> > path; // Checks for a valid path for the given points. if (tryGetPath(to, out path)) { PrintPath(@from, to, path); } else { Console.WriteLine("No path found from {0} to {1}.", from, to); Console.Read(); } }
/// <summary> /// Identify the shortest path between 2 hexes (Fiefs) /// </summary> /// <returns>Queue of Fiefs to move to</returns> /// <param name="from">Source Fief</param> /// <param name="to">Target Fief</param> public Queue <Fief> GetShortestPath(Fief @from, Fief to) { Queue <Fief> pathNodes = new Queue <Fief>(); var edgeCost = AlgorithmExtensions.GetIndexer(costs); // get shortest route using Dijkstra algorithm var tryGetPath = myMap.ShortestPathsDijkstra(edgeCost, @from); IEnumerable <TaggedEdge <Fief, string> > path; // iterate through resulting routes (edges) if (tryGetPath(to, out path)) { // extract target Fiefs and add to queue foreach (var e in path) { pathNodes.Enqueue(e.Target); } } return(pathNodes); }
protected override void InternalCompute() { if (this.VisitedGraph.VertexCount == 0) { return; } TVertex rootVertex; IEnumerable <TVertex> roots; if (this.TryGetRootVertex(out rootVertex)) { roots = new TVertex[] { rootVertex } } ; else { roots = AlgorithmExtensions.Roots(this.VisitedGraph); } VisitRoots(roots); }
protected override void InternalCompute() { if (this.VisitedGraph.VertexCount == 0) { return; } TVertex rootVertex; if (!this.TryGetRootVertex(out rootVertex)) { // enqueue roots foreach (var root in AlgorithmExtensions.Roots(this.VisitedGraph)) { this.EnqueueRoot(root); } } else // enqueue select root only { this.EnqueueRoot(rootVertex); } this.FlushVisitQueue(); }
public void IncrementalConnectedComponent() { var g = new AdjacencyGraph <int, SEquatableEdge <int> >(); g.AddVertexRange(new int[] { 0, 1, 2, 3 }); var components = AlgorithmExtensions.IncrementalConnectedComponents(g); var current = components(); Assert.AreEqual(4, current.Key); g.AddEdge(new SEquatableEdge <int>(0, 1)); current = components(); Assert.AreEqual(3, current.Key); g.AddEdge(new SEquatableEdge <int>(2, 3)); current = components(); Assert.AreEqual(2, current.Key); g.AddEdge(new SEquatableEdge <int>(1, 3)); current = components(); Assert.AreEqual(1, current.Key); }
private decimal AmountPerTransaction(string @from, string to, decimal amount, IEnumerable <ConversionRate> conversionRates) { var edgeCost = AlgorithmExtensions.GetIndexer(costs); var tryGetPath = graph.ShortestPathsDijkstra(edgeCost, @from); var totalAmount = amount; IEnumerable <Edge <string> > path; if (tryGetPath(to, out path)) { foreach (var item in path) { costs.TryGetValue(item, out double cost); if (Decimal.TryParse(ratesPerCost[cost], NumberStyles.Any, CultureInfo.InvariantCulture, out decimal rate)) { totalAmount *= rate; totalAmount = Math.Round(totalAmount, 2); } } } return(totalAmount); }
public void ComputeNoInit(TVertex s) { var orderedVertices = AlgorithmExtensions.TopologicalSort(this.VisitedGraph); OnDiscoverVertex(s); foreach (var v in orderedVertices) { OnExamineVertex(v); foreach (var e in VisitedGraph.OutEdges(v)) { OnDiscoverVertex(e.Target); bool decreased = Relax(e); if (decreased) { OnTreeEdge(e); } else { OnEdgeNotRelaxed(e); } } OnFinishVertex(v); } }