public void ShortestPathTo_FindShortestPath_WhenThereIsPossibleMultiplePaths() { var graph = new DirectedWeightedSparseGraph <string>(); graph.AddVertex("a"); graph.AddVertex("b"); graph.AddVertex("c"); graph.AddVertex("d"); graph.AddEdge("a", "b", 1); graph.AddEdge("b", "c", 1); graph.AddEdge("c", "a", 1); graph.AddEdge("c", "d", 1); graph.AddEdge("b", "d", 1); var dijkstra = new DijkstraShortestPaths <DirectedWeightedSparseGraph <string>, string>(graph, "a"); var result = dijkstra.ShortestPathTo("d"); Assert.NotNull(result); Assert.Equal(3, result.Count()); Assert.Contains("a", result); Assert.Contains("b", result); Assert.Contains("d", result); Assert.Equal(2, dijkstra.DistanceTo("d")); }
DijkstraShortestPaths <TGraph, TVertex> GetDijkstraShortestPaths(TVertex from) { if (!dijkstraShortestPathsByVertex.TryGetValue(from, out var dijkstraShortestPaths)) { dijkstraShortestPaths = new DijkstraShortestPaths <TGraph, TVertex>(Graph, from); dijkstraShortestPathsByVertex.Add(from, dijkstraShortestPaths); } return(dijkstraShortestPaths); }
public void ShortestPathTo_Throw_WhenDestinationIsNotInGraph() { var graph = new DirectedWeightedSparseGraph <string>(); graph.AddVertex("a"); graph.AddVertex("b"); graph.AddVertex("c"); graph.AddVertex("d"); var dijkstra = new DijkstraShortestPaths <DirectedWeightedSparseGraph <string>, string>(graph, "a"); Assert.Throws <ArgumentException>(() => dijkstra.ShortestPathTo("z")); }
public void DistanceTo_ReturnInfinity_WhenVertexIsNotAchievable() { var graph = new DirectedWeightedSparseGraph <string>(); graph.AddVertex("a"); graph.AddVertex("b"); graph.AddVertex("c"); graph.AddEdge("a", "b", 1); var dijkstra = new DijkstraShortestPaths <DirectedWeightedSparseGraph <string>, string>(graph, "a"); Assert.Equal(long.MaxValue, dijkstra.DistanceTo("c")); }
public void DistanceTo_Throw_WhenVertexIsNotInGraph() { var graph = new DirectedWeightedSparseGraph <string>(); graph.AddVertex("a"); graph.AddVertex("b"); graph.AddVertex("c"); graph.AddEdge("a", "b", 1); var dijkstra = new DijkstraShortestPaths <DirectedWeightedSparseGraph <string>, string>(graph, "a"); Assert.Throws <ArgumentException>(() => dijkstra.DistanceTo("z")); }
public void HasPathTo_ReturnFalse_WhenVertexIsNotAchievable() { var graph = new DirectedWeightedSparseGraph <string>(); graph.AddVertex("a"); graph.AddVertex("b"); graph.AddVertex("c"); graph.AddEdge("a", "b", 1); var dijkstra = new DijkstraShortestPaths <DirectedWeightedSparseGraph <string>, string>(graph, "a"); Assert.False(dijkstra.HasPathTo("c")); }
public void ShortestPathTo_ReturnNull_WhenDestinationIsNotAchievable() { var graph = new DirectedWeightedSparseGraph <string>(); graph.AddVertex("a"); graph.AddVertex("b"); graph.AddVertex("c"); graph.AddVertex("d"); graph.AddEdge("a", "b", 1); graph.AddEdge("b", "c", 1); graph.AddEdge("c", "a", 1); var dijkstra = new DijkstraShortestPaths <DirectedWeightedSparseGraph <string>, string>(graph, "a"); Assert.Null(dijkstra.ShortestPathTo("d")); }
public void ShortestPathTo_ReturnSingleVertex_WhenDestinationIsSameAsSource() { var graph = new DirectedWeightedSparseGraph <string>(); graph.AddVertex("a"); graph.AddVertex("b"); graph.AddVertex("c"); graph.AddVertex("d"); graph.AddEdge("a", "b", 1); graph.AddEdge("b", "c", 1); graph.AddEdge("c", "a", 1); var dijkstra = new DijkstraShortestPaths <DirectedWeightedSparseGraph <string>, string>(graph, "a"); var result = dijkstra.ShortestPathTo("a"); Assert.NotNull(result); Assert.Single(result); Assert.Equal("a", result.Single()); }
public void ShortestPathTo_FindShortestPath_WhenEdgeHaveDifferentWeight() { var vertices = new[] { "r", "s", "t", "x", "y", "z" }; var graph = new DirectedWeightedSparseGraph <string>(); graph.AddVertices(vertices); graph.AddEdge("r", "s", 7); graph.AddEdge("r", "t", 6); graph.AddEdge("s", "t", 5); graph.AddEdge("s", "x", 9); graph.AddEdge("t", "x", 10); graph.AddEdge("t", "y", 7); graph.AddEdge("t", "z", 5); graph.AddEdge("x", "y", 2); graph.AddEdge("x", "z", 4); graph.AddEdge("y", "z", 1); var dijkstra = new DijkstraShortestPaths <DirectedWeightedSparseGraph <string>, string>(graph, "s"); var shortestToZ = dijkstra.ShortestPathTo("z"); Assert.NotNull(shortestToZ); Assert.Equal(3, shortestToZ.Count()); Assert.Contains("s", shortestToZ); Assert.Contains("t", shortestToZ); Assert.Contains("z", shortestToZ); Assert.Equal(10, dijkstra.DistanceTo("z")); var shortestToY = dijkstra.ShortestPathTo("y"); Assert.NotNull(shortestToY); Assert.Equal(3, shortestToY.Count()); Assert.Contains("s", shortestToY); Assert.Contains("x", shortestToY); Assert.Contains("y", shortestToY); Assert.Equal(11, dijkstra.DistanceTo("y")); }
// GET: /<controller>/ public IActionResult Index() { string result = string.Empty; string[] V; IEnumerable <WeightedEdge <string> > E; DirectedWeightedSparseGraph <string> graph; DijkstraShortestPaths <DirectedWeightedSparseGraph <string>, string> dijkstra; // Init graph object graph = new DirectedWeightedSparseGraph <string>(); // Init V V = new string[6] { "r", "s", "t", "x", "y", "z" }; result = result + "Initial Verrtices: 'r', 's', 't', 'x', 'y', 'z'" + "\n"; // Insert V graph.AddVertices(V); result = result + "# of vertices: " + V.Length + "\n"; // Insert E var status = graph.AddEdge("r", "s", 7); status = graph.AddEdge("r", "t", 6); status = graph.AddEdge("s", "t", 5); status = graph.AddEdge("s", "x", 9); status = graph.AddEdge("t", "x", 10); status = graph.AddEdge("t", "y", 7); status = graph.AddEdge("t", "z", 5); status = graph.AddEdge("x", "y", 2); status = graph.AddEdge("x", "z", 4); status = graph.AddEdge("y", "z", 1); // Get E E = graph.Edges; //Debug.Assert(graph.EdgesCount == 10, "Wrong Edges Count."); result = result + "# of edges: " + graph.EdgesCount + "\n\n"; // // PRINT THE GRAPH result = result + "[*] DIJKSTRA ON DIRECTED WEIGHTED GRAPH:\r\n"; result = result + "Graph representation:"; result = result + graph.ToReadable() + "\r\n\n"; // Init DIJKSTRA dijkstra = new DijkstraShortestPaths <DirectedWeightedSparseGraph <string>, string>(graph, "s"); result = result + "dijkstra.HasPathTo('r') is " + dijkstra.HasPathTo("r") + "\n"; result = result + "dijkstra.HasPathTo('z') is " + dijkstra.HasPathTo("z") + "\n\n"; // Get shortest path to Z var pathToZ = string.Empty; foreach (var node in dijkstra.ShortestPathTo("z")) { pathToZ = String.Format("{0}({1}) -> ", pathToZ, node); } pathToZ = pathToZ.TrimEnd(new char[] { ' ', '-', '>' }); result = result + "Shortest path to node 'z': " + pathToZ + "\r\n"; var pathToY = string.Empty; foreach (var node in dijkstra.ShortestPathTo("y")) { pathToY = String.Format("{0}({1}) -> ", pathToY, node); } pathToY = pathToY.TrimEnd(new char[] { ' ', '-', '>' }); result = result + "Shortest path to node 'y': " + pathToY + "\r\n\n"; ///***************************************************************************************/ //// Clear the graph and insert new V and E to the instance //graph.Clear(); //V = new string[] { "A", "B", "C", "D", "E" }; //// Insert new values of V //graph.AddVertices(V); //Debug.Assert(graph.VerticesCount == V.Length, "Wrong Vertices Count."); //// Insert new value for edges //status = graph.AddEdge("A", "C", 7); //Debug.Assert(status == true); //status = graph.AddEdge("B", "A", 19); //Debug.Assert(status == true); //status = graph.AddEdge("B", "C", 11); //Debug.Assert(status == true); //status = graph.AddEdge("C", "E", 5); //Debug.Assert(status == true); //status = graph.AddEdge("C", "D", 15); //Debug.Assert(status == true); //status = graph.AddEdge("D", "B", 4); //Debug.Assert(status == true); //status = graph.AddEdge("E", "D", 13); //Debug.Assert(status == true); //Debug.Assert(graph.EdgesCount == 7, "Wrong Edges Count."); //// //// PRINT THE GRAPH //Console.Write("[*] DIJKSTRA ON DIRECTED WEIGHTED GRAPH - TEST 01:\r\n"); //Console.WriteLine("Graph representation:"); //Console.WriteLine(graph.ToReadable() + "\r\n"); //// Init DIJKSTRA //dijkstra = new DijkstraShortestPaths<DirectedWeightedSparseGraph<string>, string>(graph, "A"); //var pathToD = string.Empty; //foreach (var node in dijkstra.ShortestPathTo("D")) // pathToD = String.Format("{0}({1}) -> ", pathToD, node); //pathToD = pathToD.TrimEnd(new char[] { ' ', '-', '>' }); //Console.WriteLine("Shortest path from 'A' to 'D': " + pathToD + "\r\n"); //Console.WriteLine("*********************************************\r\n"); ///***************************************************************************************/ var dijkstraAllPairs = new DijkstraAllPairsShortestPaths <DirectedWeightedSparseGraph <string>, string>(graph); var vertices = graph.Vertices; result = result + "Dijkstra All Pairs Shortest Paths: \r\n"; foreach (var source in vertices) { foreach (var destination in vertices) { var shortestPath = string.Empty; if (dijkstraAllPairs.ShortestPath(source, destination) != null) { foreach (var node in dijkstraAllPairs.ShortestPath(source, destination)) { shortestPath = String.Format("{0}({1}) -> ", shortestPath, node); } shortestPath = shortestPath.TrimEnd(new char[] { ' ', '-', '>' }); result = result + "Shortest path from '" + source + "' to '" + destination + "' is: " + shortestPath + "\r\n"; } } } //Console.ReadLine(); HtmlString html = StringHelper.GetHtmlString(result); return(View(html)); }
public static void DoTest() { string[] V; IEnumerable <WeightedEdge <string> > E; DirectedWeightedSparseGraph <string> graph; DijkstraShortestPaths <DirectedWeightedSparseGraph <string>, string> dijkstra; // Init graph object graph = new DirectedWeightedSparseGraph <string>(); // Init V V = new string[6] { "r", "s", "t", "x", "y", "z" }; // Insert V graph.AddVertices(V); Assert.True(graph.VerticesCount == V.Length, "Wrong Vertices Count."); // Insert E var status = graph.AddEdge("r", "s", 7); Assert.True(status == true); status = graph.AddEdge("r", "t", 6); Assert.True(status == true); status = graph.AddEdge("s", "t", 5); Assert.True(status == true); status = graph.AddEdge("s", "x", 9); Assert.True(status == true); status = graph.AddEdge("t", "x", 10); Assert.True(status == true); status = graph.AddEdge("t", "y", 7); Assert.True(status == true); status = graph.AddEdge("t", "z", 5); Assert.True(status == true); status = graph.AddEdge("x", "y", 2); Assert.True(status == true); status = graph.AddEdge("x", "z", 4); Assert.True(status == true); status = graph.AddEdge("y", "z", 1); Assert.True(status == true); // Get E E = graph.Edges; Assert.True(graph.EdgesCount == 10, "Wrong Edges Count."); // PRINT THE GRAPH // [*] DIJKSTRA ON DIRECTED WEIGHTED GRAPH - TEST 01: // Graph representation: // Init DIJKSTRA dijkstra = new DijkstraShortestPaths <DirectedWeightedSparseGraph <string>, string>(graph, "s"); Assert.True(dijkstra.HasPathTo("r") == false); Assert.True(dijkstra.HasPathTo("z") == true); // Get shortest path to Z var pathToZ = string.Empty; foreach (var node in dijkstra.ShortestPathTo("z")) { pathToZ = String.Format("{0}({1}) -> ", pathToZ, node); } pathToZ = pathToZ.TrimEnd(new char[] { ' ', '-', '>' }); var pathToY = string.Empty; foreach (var node in dijkstra.ShortestPathTo("y")) { pathToY = String.Format("{0}({1}) -> ", pathToY, node); } pathToY = pathToY.TrimEnd(new char[] { ' ', '-', '>' }); // Console.WriteLine("Shortest path to node 'y': " + pathToY + "\r\n"); // Clear the graph and insert new V and E to the instance graph.Clear(); V = new string[] { "A", "B", "C", "D", "E" }; // Insert new values of V graph.AddVertices(V); Assert.True(graph.VerticesCount == V.Length, "Wrong Vertices Count."); // Insert new value for edges status = graph.AddEdge("A", "C", 7); Assert.True(status == true); status = graph.AddEdge("B", "A", 19); Assert.True(status == true); status = graph.AddEdge("B", "C", 11); Assert.True(status == true); status = graph.AddEdge("C", "E", 5); Assert.True(status == true); status = graph.AddEdge("C", "D", 15); Assert.True(status == true); status = graph.AddEdge("D", "B", 4); Assert.True(status == true); status = graph.AddEdge("E", "D", 13); Assert.True(status == true); Assert.True(graph.EdgesCount == 7, "Wrong Edges Count."); // [*] DIJKSTRA ON DIRECTED WEIGHTED GRAPH - TEST 01: // Graph representation: // Init DIJKSTRA dijkstra = new DijkstraShortestPaths <DirectedWeightedSparseGraph <string>, string>(graph, "A"); var pathToD = string.Empty; foreach (var node in dijkstra.ShortestPathTo("D")) { pathToD = String.Format("{0}({1}) -> ", pathToD, node); } pathToD = pathToD.TrimEnd(new char[] { ' ', '-', '>' }); var vertices = graph.Vertices; var dijkstraAllPairs = new DijkstraAllPairsShortestPaths <DirectedWeightedSparseGraph <string>, string>(graph); // Dijkstra All Pairs Shortest Paths: foreach (var source in vertices) { foreach (var destination in vertices) { var shortestPath = string.Empty; foreach (var node in dijkstraAllPairs.ShortestPath(source, destination)) { shortestPath = String.Format("{0}({1}) -> ", shortestPath, node); } shortestPath = shortestPath.TrimEnd(new char[] { ' ', '-', '>' }); // Console.WriteLine("Shortest path from '" + source + "' to '" + destination + "' is: " + shortestPath + "\r\n"); } } }
public void LRwPathSearchTest() { DPNProblemContext ctx = GenerateProblemContext(); DiscreteTimeAdapter adapter = new DiscreteTimeAdapter(ctx.StartTime, ctx.EndTime, 1); var travelgraph = new BasicTravelHyperNetwork(ctx, adapter); travelgraph.Build(); /* Train01 Station A*/ var train = ctx.Wor.RailwayTimeTable.Trains.First(); var station = ctx.Wor.Net.StationCollection.First(); //路径集 Dictionary <CustomerArrival, List <TravelPath> > pathDict = new Dictionary <CustomerArrival, List <TravelPath> >(); foreach (CustomerArrival c in ctx.Pal) { var ori = (ctx.Wor.Mar[c.Customer.MarSegID] as IRailwayMarketSegment).OriSta; var des = (ctx.Wor.Mar[c.Customer.MarSegID] as IRailwayMarketSegment).DesSta; var paths = DepthFirstSearcher.FindAllPaths(travelgraph, new TravelHyperNode() { Time = adapter.ConvertToDiscreteTime(c.ArriveTime), Station = ori, Price = 0 }, new TravelHyperNode() { Time = adapter.Horizon + 1440, Station = des, Price = 0 }); pathDict.Add(c, new List <TravelPath>()); foreach (var path in paths) { pathDict[c].Add(new TravelPath(travelgraph, path)); } } //拉格朗日乘子 mu Dictionary <CustomerArrival, Dictionary <TravelPath, decimal> > LM_mu = new Dictionary <CustomerArrival, Dictionary <TravelPath, decimal> >(); foreach (CustomerArrival customer in ctx.Pal) { LM_mu.Add(customer, new Dictionary <TravelPath, decimal>()); foreach (var path in pathDict[customer]) { LM_mu[customer].Add(path, 2); } } // 拉格朗日乘子 lambda Dictionary <IEdge <TravelHyperNode>, decimal> LM_lambda = new Dictionary <IEdge <TravelHyperNode>, decimal>(); foreach (CustomerArrival customer in ctx.Pal) { foreach (var path in pathDict[customer]) { if (!LM_lambda.ContainsKey(path.ReservationArc)) { LM_lambda.Add(path.ReservationArc, 1); } } } var graph = DpnAlgorithm.BuildLRwGraph(ctx, adapter, train, station, pathDict, travelgraph.LinkTrainDict, LM_mu, LM_lambda); DijkstraShortestPaths <DirectedWeightedSparseGraph <string>, string> dijkstra = new DijkstraShortestPaths <DirectedWeightedSparseGraph <string>, string>(graph, "Start"); Assert.IsTrue(dijkstra.HasPathTo("End") == true); var pathToC = string.Empty; var pricepath = dijkstra.ShortestPathTo("End"); PricePath p = new PricePath(graph, pricepath); Assert.IsTrue(p.GetWrapPoints(0.9m, 2).Count() > 0); Assert.IsFalse(p.GetWrapPoints(1.1m, 2).Count() > 0); foreach (var node in pricepath) { pathToC = String.Format("{0}({1}) -> ", pathToC, node); } pathToC = pathToC.TrimEnd(new char[] { ' ', '-', '>' }); Console.WriteLine("Shortest path to Station 'C': " + pathToC + "\r\n"); Assert.AreEqual(23m, Math.Round(dijkstra.DistanceTo("End"))); }
public void LRxPathSearchTest() { DPNProblemContext ctx = GenerateProblemContext(); CustomerArrival customer = new CustomerArrival(); DiscreteTimeAdapter adapter = new DiscreteTimeAdapter(ctx.StartTime, ctx.EndTime, 1); TravelPath p = new TravelPath(); var graph = new LRxTravelHyperNetwork(ctx, adapter, ObjectNetworkFactory.Create("", ctx, adapter), customer, new Dictionary <CustomerArrival, List <TravelPath> >()//path dict { { customer, new List <TravelPath>() { p } } }, new Dictionary <IServiceSegment, decimal>()//rho { { ctx.Wor.RailwayTimeTable.Trains.First().ServiceSegments.First(), 0 }, { ctx.Wor.RailwayTimeTable.Trains.First().ServiceSegments.Last(), 0 }, { ctx.Wor.RailwayTimeTable.Trains.Last().ServiceSegments.First(), 0 } }, new Dictionary <CustomerArrival, Dictionary <TravelPath, decimal> >() { { customer, new Dictionary <TravelPath, decimal>() { { p, 1 } } } },//mu new Dictionary <IEdge <TravelHyperNode>, decimal>()); graph.Build(); DijkstraShortestPaths <DirectedWeightedSparseGraph <TravelHyperNode>, TravelHyperNode> dijkstra = new DijkstraShortestPaths <DirectedWeightedSparseGraph <TravelHyperNode>, TravelHyperNode>(graph, new TravelHyperNode() { Time = 0, Station = ctx.Wor.Net.StationCollection.First(), Price = 0 }); Assert.IsTrue(dijkstra.HasPathTo(new TravelHyperNode() { Time = adapter.Horizon + 1440, Station = ctx.Wor.Net.StationCollection.Last(), Price = 0 }) == true); var desNode = new TravelHyperNode() { Time = adapter.Horizon + 1440, Station = ctx.Wor.Net.StationCollection.Last(), Price = 0 }; var pathToC = string.Empty; var shortestPath = dijkstra.ShortestPathTo(desNode); foreach (var node in shortestPath) { pathToC = String.Format("{0}({1}) -> ", pathToC, node); } pathToC = pathToC.TrimEnd(new char[] { ' ', '-', '>' }); Console.WriteLine("Shortest path to Station 'C': " + pathToC + "\r\n"); Assert.AreEqual(202m, Math.Round(dijkstra.DistanceTo(desNode))); }
public static void DoTest() { string[] V; IEnumerable<WeightedEdge<string>> E; DirectedWeightedSparseGraph<string> graph; DijkstraShortestPaths<DirectedWeightedSparseGraph<string>, string> dijkstra; // Init graph object graph = new DirectedWeightedSparseGraph<string>(); // Init V V = new string[6] { "r", "s", "t", "x", "y", "z" }; // Insert V graph.AddVertices(V); Debug.Assert(graph.VerticesCount == V.Length, "Wrong Vertices Count."); // Insert E var status = graph.AddEdge("r", "s", 7); Debug.Assert(status == true); status = graph.AddEdge("r", "t", 6); Debug.Assert(status == true); status = graph.AddEdge("s", "t", 5); Debug.Assert(status == true); status = graph.AddEdge("s", "x", 9); Debug.Assert(status == true); status = graph.AddEdge("t", "x", 10); Debug.Assert(status == true); status = graph.AddEdge("t", "y", 7); Debug.Assert(status == true); status = graph.AddEdge("t", "z", 5); Debug.Assert(status == true); status = graph.AddEdge("x", "y", 2); Debug.Assert(status == true); status = graph.AddEdge("x", "z", 4); Debug.Assert(status == true); status = graph.AddEdge("y", "z", 1); Debug.Assert(status == true); // Get E E = graph.Edges; Debug.Assert(graph.EdgesCount == 10, "Wrong Edges Count."); // // PRINT THE GRAPH Console.Write("[*] DIJKSTRA ON DIRECTED WEIGHTED GRAPH - TEST 01:\r\n"); Console.WriteLine("Graph representation:"); Console.WriteLine(graph.ToReadable() + "\r\n"); // Init DIJKSTRA dijkstra = new DijkstraShortestPaths<DirectedWeightedSparseGraph<string>, string>(graph, "s"); Debug.Assert(dijkstra.HasPathTo("r") == false); Debug.Assert(dijkstra.HasPathTo("z") == true); // Get shortest path to Z var pathToZ = string.Empty; foreach (var node in dijkstra.ShortestPathTo("z")) pathToZ = String.Format("{0}({1}) -> ", pathToZ, node); pathToZ = pathToZ.TrimEnd(new char[] { ' ', '-', '>' }); Console.WriteLine("Shortest path to node 'z': " + pathToZ + "\r\n"); var pathToY = string.Empty; foreach (var node in dijkstra.ShortestPathTo("y")) pathToY = String.Format("{0}({1}) -> ", pathToY, node); pathToY = pathToY.TrimEnd(new char[] { ' ', '-', '>' }); Console.WriteLine("Shortest path to node 'y': " + pathToY + "\r\n"); Console.WriteLine("*********************************************\r\n"); /***************************************************************************************/ // Clear the graph and insert new V and E to the instance graph.Clear(); V = new string[] { "A", "B", "C", "D", "E" }; // Insert new values of V graph.AddVertices(V); Debug.Assert(graph.VerticesCount == V.Length, "Wrong Vertices Count."); // Insert new value for edges status = graph.AddEdge("A", "C", 7); Debug.Assert(status == true); status = graph.AddEdge("B", "A", 19); Debug.Assert(status == true); status = graph.AddEdge("B", "C", 11); Debug.Assert(status == true); status = graph.AddEdge("C", "E", 5); Debug.Assert(status == true); status = graph.AddEdge("C", "D", 15); Debug.Assert(status == true); status = graph.AddEdge("D", "B", 4); Debug.Assert(status == true); status = graph.AddEdge("E", "D", 13); Debug.Assert(status == true); Debug.Assert(graph.EdgesCount == 7, "Wrong Edges Count."); // // PRINT THE GRAPH Console.Write("[*] DIJKSTRA ON DIRECTED WEIGHTED GRAPH - TEST 01:\r\n"); Console.WriteLine("Graph representation:"); Console.WriteLine(graph.ToReadable() + "\r\n"); // Init DIJKSTRA dijkstra = new DijkstraShortestPaths<DirectedWeightedSparseGraph<string>, string>(graph, "A"); var pathToD = string.Empty; foreach (var node in dijkstra.ShortestPathTo("D")) pathToD = String.Format("{0}({1}) -> ", pathToD, node); pathToD = pathToD.TrimEnd(new char[] { ' ', '-', '>' }); Console.WriteLine("Shortest path from 'A' to 'D': " + pathToD + "\r\n"); Console.ReadLine(); }
public override void Work() { //获取求解设置 decimal terminalFactor = _ctx.GetParameter("TerminalFactor", 0.001m); int iteration = _ctx.GetParameter("Iteration", 10); int resolution = _ctx.GetParameter("Resolution", 60); decimal initMultipler = _ctx.GetParameter("InitMultiper", 0.1m); string objectiveType = _ctx.GetParameter("ObjectiveType", ""); // 相对-绝对时间转化器 DiscreteTimeAdapter adapter = new DiscreteTimeAdapter(_ctx.StartTime, _ctx.EndTime, resolution); // 路径集 Dictionary <CustomerArrival, List <TravelPath> > pathDict = new Dictionary <CustomerArrival, List <TravelPath> >(); #region 建立初始网络,搜索可行路径 //目标函数网络 var objgraph = ObjectNetworkFactory.Create(objectiveType, _ctx, adapter); //new ObjectTravelHyperNetwork(_ctx, adapter); objgraph.Build(); //基础网络 var basicGraph = new BasicTravelHyperNetwork(_ctx, adapter); basicGraph.Build(); SubTasks.Clear(); foreach (CustomerArrival customer in _ctx.Pal) { Task ta = factory.StartNew(() => { var ori = (_ctx.Wor.Mar[customer.Customer.MarSegID] as IRailwayMarketSegment).OriSta; var des = (_ctx.Wor.Mar[customer.Customer.MarSegID] as IRailwayMarketSegment).DesSta; var paths = DepthFirstSearcher.FindAllPaths(basicGraph, new TravelHyperNode() { Time = adapter.ConvertToDiscreteTime(customer.ArriveTime), Station = ori, Price = 0 }, new TravelHyperNode() { Time = adapter.Horizon + 1440, Station = des, Price = 0 }); pathDict.Add(customer, new List <TravelPath>()); foreach (var path in paths) { pathDict[customer].Add(new TravelPath(basicGraph, path)); } }); SubTasks.Add(ta); } Task.WaitAll(SubTasks.ToArray()); #endregion #region 构建对偶问题 with CPLEX Cplex model = new Cplex(); model.SetOut(null); INumVar theta = model.NumVar(double.MinValue, double.MaxValue); //θ model.AddMaximize(theta); Dictionary <IServiceSegment, INumVar> dual_rho = _ctx.Wor.RailwayTimeTable.Trains .SelectMany(i => i.ServiceSegments).ToDictionary(i => i, i => model.NumVar(0, double.MaxValue)); Dictionary <CustomerArrival, Dictionary <TravelPath, INumVar> > dual_mu = new Dictionary <CustomerArrival, Dictionary <TravelPath, INumVar> >(); foreach (CustomerArrival customer in _ctx.Pal) { dual_mu.Add(customer, new Dictionary <TravelPath, INumVar>()); foreach (var path in pathDict[customer]) { dual_mu[customer].Add(path, model.NumVar(0, double.MaxValue)); } } Dictionary <IEdge <TravelHyperNode>, INumVar> dual_lambda = new Dictionary <IEdge <TravelHyperNode>, INumVar>(); foreach (CustomerArrival customer in _ctx.Pal) { foreach (var path in pathDict[customer]) { if (!dual_lambda.ContainsKey(path.ReservationArc)) { dual_lambda.Add(path.ReservationArc, model.NumVar(0, double.MaxValue)); } } } #endregion #region 变量与乘子 //决策变量 x Dictionary <CustomerArrival, TravelPath> x = new Dictionary <CustomerArrival, TravelPath>(); foreach (CustomerArrival customer in _ctx.Pal) { x.Add(customer, new TravelPath()); } //决策变量 w Dictionary <ITrainTrip, Dictionary <IRailwayStation, PricePath> > w = new Dictionary <ITrainTrip, Dictionary <IRailwayStation, PricePath> >(); foreach (var train in _ctx.Wor.RailwayTimeTable.Trains) { w.Add(train, new Dictionary <IRailwayStation, PricePath>()); foreach (var sta in _ctx.Wor.Net.StationCollection) { w[train].Add(sta, null); } } //辅助变量 y //记录每条弧在当前w的取值下是否可行(available),值为true = 可行;false = 不可行 //超出了y记录的reservation arc 不会有人走 Dictionary <IEdge <TravelHyperNode>, bool> y = new Dictionary <IEdge <TravelHyperNode>, bool>(); foreach (var p in pathDict.Values.SelectMany(i => i)) { if (p.ReservationArc != null && !y.ContainsKey(p.ReservationArc)) { y.Add(p.ReservationArc, false); } } //拉格朗日乘子 rho Dictionary <IServiceSegment, decimal> LM_rho = _ctx.Wor.RailwayTimeTable.Trains .SelectMany(i => i.ServiceSegments).ToDictionary(i => i, i => initMultipler); //拉格朗日乘子 rho 迭代方向 Dictionary <IServiceSegment, decimal> Grad_rho = _ctx.Wor.RailwayTimeTable.Trains .SelectMany(i => i.ServiceSegments).ToDictionary(i => i, i => initMultipler); //拉格朗日乘子 mu Dictionary <CustomerArrival, Dictionary <TravelPath, decimal> > LM_mu = new Dictionary <CustomerArrival, Dictionary <TravelPath, decimal> >(); foreach (CustomerArrival customer in _ctx.Pal) { LM_mu.Add(customer, new Dictionary <TravelPath, decimal>()); foreach (var path in pathDict[customer]) { LM_mu[customer].Add(path, initMultipler); } } //拉格朗日乘子 mu 迭代方向 Dictionary <CustomerArrival, Dictionary <TravelPath, decimal> > Grad_mu = new Dictionary <CustomerArrival, Dictionary <TravelPath, decimal> >(); foreach (CustomerArrival customer in _ctx.Pal) { Grad_mu.Add(customer, new Dictionary <TravelPath, decimal>()); foreach (var path in pathDict[customer]) { Grad_mu[customer].Add(path, initMultipler); } } //拉格朗日乘子 lambda Dictionary <IEdge <TravelHyperNode>, decimal> LM_lambda = new Dictionary <IEdge <TravelHyperNode>, decimal>(); //WARNING: 这里缺少了没有旅客选择的reservation arc foreach (CustomerArrival customer in _ctx.Pal) { foreach (var path in pathDict[customer]) { if (!LM_lambda.ContainsKey(path.ReservationArc)) { LM_lambda.Add(path.ReservationArc, initMultipler); } } } //拉格朗日乘子 lambda 迭代方向 Dictionary <IEdge <TravelHyperNode>, decimal> Grad_lambda = new Dictionary <IEdge <TravelHyperNode>, decimal>(); foreach (CustomerArrival customer in _ctx.Pal) { foreach (var path in pathDict[customer]) { if (!Grad_lambda.ContainsKey(path.ReservationArc)) { Grad_lambda.Add(path.ReservationArc, initMultipler); } } } #endregion decimal bigM1 = pathDict.Max(i => i.Value.Max(j => basicGraph.GetPathCost(j))); decimal bigM2 = _ctx.Pal.Count(); decimal bigM = Math.Max(bigM1, bigM2); decimal lowerBound = decimal.MinValue; decimal upperBound = decimal.MaxValue; bool flag = false;//对偶问题有解 PrintIterationInfo($"Iteration Number, Lower Bound, Upper Bound, Best Lower Bound, Best Upper Bound, Total Gap(%) "); for (int iter = 0; iter < iteration; iter++) { Log($"--------------第{iter}轮求解开始--------------"); bool hasFeasibleSolution = true; #region 求解LR问题 SubTasks.Clear(); foreach (CustomerArrival customer in _ctx.Pal)// 求解x { Task ta = factory.StartNew(() => { var graph = new LRxTravelHyperNetwork(_ctx, adapter, objgraph, customer, pathDict, LM_rho, LM_mu, LM_lambda); graph.Build(); var ori = (_ctx.Wor.Mar[customer.Customer.MarSegID] as IRailwayMarketSegment).OriSta; var des = (_ctx.Wor.Mar[customer.Customer.MarSegID] as IRailwayMarketSegment).DesSta; DijkstraShortestPaths <DirectedWeightedSparseGraph <TravelHyperNode>, TravelHyperNode> dijkstra = new DijkstraShortestPaths <DirectedWeightedSparseGraph <TravelHyperNode>, TravelHyperNode>(graph, new TravelHyperNode() { Time = adapter.ConvertToDiscreteTime(customer.ArriveTime), Station = ori, Price = 0 }); //考虑该旅客到达时间 x[customer] = new TravelPath(graph, dijkstra.ShortestPathTo( new TravelHyperNode() { Time = adapter.Horizon + 1440, Station = des, Price = 0 })); }); SubTasks.Add(ta); } foreach (var train in _ctx.Wor.RailwayTimeTable.Trains) { foreach (IRailwayStation station in _ctx.Wor.Net.StationCollection)// 求解w { Task ta = factory.StartNew(() => { var graph = DpnAlgorithm.BuildLRwGraph(_ctx, adapter, train, station, pathDict, basicGraph.LinkTrainDict, LM_mu, LM_lambda); DijkstraShortestPaths <DirectedWeightedSparseGraph <string>, string> dijkstra = new DijkstraShortestPaths <DirectedWeightedSparseGraph <string>, string>(graph, "Start");//考虑该旅客到达时间 var nodepath = dijkstra.ShortestPathTo("End"); if (nodepath == null) { throw new System.Exception("No path found"); } else { w[train][station] = new PricePath(graph, nodepath); } }); SubTasks.Add(ta); } } Task.WaitAll(SubTasks.ToArray()); foreach (var edge in y.Keys.ToArray())//更新y { var sta = edge.Source.Station; var train = basicGraph.GetTrainByReservationLink(edge); y[edge] = w[train][sta].GetWrapPoints(edge.Destination.Price, edge.Source.Time).Any(); } #endregion #region 计算拉格朗日函数值作为下界 decimal templowerBound = 0m; decimal templowerBound_part1 = 0m; decimal templowerBound_part2 = 0m; decimal templowerBound_part3 = 0m; decimal templowerBound_part4 = 0m; Dictionary <CustomerArrival, decimal> lbValueDic = new Dictionary <CustomerArrival, decimal>(); //1 计算在基础网络中的路径cost foreach (CustomerArrival customer in _ctx.Pal) { lbValueDic.Add(customer, objgraph.GetPathCost(x[customer])); templowerBound_part1 += lbValueDic[customer]; } //2计算BRUE项 templowerBound_part2 += _ctx.Pal.Sum(c => pathDict[c].Sum(p => { decimal secondItem = 0m; secondItem += basicGraph.GetPathCost(x[c]) - basicGraph.GetPathCost(p) - _ctx.SitaDic[c.Customer.MarSegID]; secondItem -= (p.ReservationArc != null && y[p.ReservationArc]) ? 0 : bigM; return(secondItem * LM_mu[c][p]); })); //3计算In-train Capacity项 Dictionary <IServiceSegment, int> ServiceDic = _ctx.Wor.RailwayTimeTable .Trains.SelectMany(i => i.ServiceSegments) .ToDictionary(i => i, i => 0);//当前service segment使用情况 foreach (var p in x.Values) { foreach (IServiceSegment seg in p.GetSegments(basicGraph)) { ServiceDic[seg] += 1; } } foreach (var train in _ctx.Wor.RailwayTimeTable.Trains) { foreach (var seg in train.ServiceSegments) { templowerBound_part3 += LM_rho[seg] * (ServiceDic[seg] - train.Carriage.Chairs.Count()); } } //4 计算reservation constraint 项 Dictionary <IEdge <TravelHyperNode>, int> reservationDic = new Dictionary <IEdge <TravelHyperNode>, int>(); foreach (var p in x.Values) { if (reservationDic.ContainsKey(p.ReservationArc)) { reservationDic[p.ReservationArc] += 1; } else { reservationDic.Add(p.ReservationArc, 1); } } foreach (var pair in y.Keys) { //y是所有的reservation 的集合 reservationDic 是已经使用的reservation 集合 var res = reservationDic.Keys.FirstOrDefault(i => i.Source == pair.Source && i.Destination == pair.Destination); templowerBound_part4 += LM_lambda[pair] * ((res != null ? reservationDic[res] : 0) - (y[pair] ? bigM : 0)); } templowerBound = templowerBound_part1 + templowerBound_part2 + templowerBound_part3 + templowerBound_part4; //Log($"Lower Bound = { Math.Round(templowerBound, 2)}," + // $"({ Math.Round(templowerBound_part1, 2) }" + // $"+{ Math.Round(templowerBound_part2, 2)}" + // $"+{ Math.Round(templowerBound_part3, 2)}" + // $"+{ Math.Round(templowerBound_part4, 2)})"); PrintLBSolution(DpnAlgorithm.GetTravelPathString(_ctx, adapter, objgraph, x, lbValueDic)); #endregion #region 更新乘子 if (flag) { decimal LagLowerBound = Convert.ToDecimal(model.GetValue(theta)); Log($"LagLower Bound = { LagLowerBound }"); Log($"Lower Bound = { templowerBound }"); lowerBound = Math.Max(lowerBound, templowerBound); decimal lagGap = LagLowerBound - templowerBound; if (lagGap <= 0)//判断拉格朗日对偶问题是否达到最优 { Log($"求解终止:对偶函数已最优。"); break; } else { /* 更新乘子值 */ foreach (var pair in dual_rho) { LM_rho[pair.Key] = Convert.ToDecimal(model.GetValue(pair.Value)); } foreach (var pair in dual_lambda) { LM_lambda[pair.Key] = Convert.ToDecimal(model.GetValue(pair.Value)); } foreach (CustomerArrival customer in _ctx.Pal) { foreach (var path in pathDict[customer]) { LM_mu[customer][path] = Convert.ToDecimal(model.GetValue(dual_mu[customer][path])); } } } } else /* 如果对偶问题无可行解,通过次梯度的方式更新乘子 */ { //decimal step = 1.618m / (iter + 1); //foreach (CustomerArrival c in _ctx.Pal)//更新mu //{ // foreach (TravelPath p in pathDict[c]) // { // Grad_mu[c][p] = basicGraph.GetPathCost(x[c]) - basicGraph.GetPathCost(p) - _ctx.SitaDic[c.Customer.MarSegID] // - ((p.ReservationArc != null && y[p.ReservationArc]) ? 0 : bigM); // LM_mu[c][p] = Math.Max(0, LM_mu[c][p] + step * Grad_mu[c][p]); // } //} //foreach (var pair in y.Keys) //更新lambda //{ // var res = reservationDic.Keys.FirstOrDefault(i => i.Source == pair.Source && i.Destination == pair.Destination); // Grad_lambda[pair] = ((res != null ? reservationDic[res] : 0) - (y[pair] ? bigM : 0)); // LM_lambda[pair] = Math.Max(0, LM_lambda[pair] + step * Grad_lambda[pair]); //} //foreach (var train in _ctx.Wor.RailwayTimeTable.Trains)//更新rho //{ // foreach (var seg in train.ServiceSegments) // { // Grad_rho[seg] = ServiceDic[seg] - train.Carriage.Chairs.Count(); // LM_rho[seg] = Math.Max(0, LM_rho[seg] + step * Grad_rho[seg]); // } //} } #endregion #region 求解拉格朗日对偶问题 /* 求解 几何乘子 */ // 增加 一个约束 INumExpr exp = model.NumExpr(); //2 计算BRUE项 foreach (var c in _ctx.Pal) { foreach (var p in pathDict[c]) { decimal secondItem = 0m; secondItem += basicGraph.GetPathCost(x[c]) - basicGraph.GetPathCost(p) - _ctx.SitaDic[c.Customer.MarSegID]; secondItem -= (p.ReservationArc != null && y[p.ReservationArc]) ? 0 : bigM; exp = model.Sum(exp, model.Prod(Convert.ToDouble(secondItem), dual_mu[c][p])); } } //3计算In-train Capacity项 (这里直接用了计算下界时候的 Service_dic foreach (var train in _ctx.Wor.RailwayTimeTable.Trains) { foreach (var seg in train.ServiceSegments) { exp = model.Sum(exp, model.Prod(Convert.ToDouble(ServiceDic[seg] - train.Carriage.Chairs.Count()), dual_rho[seg])); } } //4 计算reservation constraint 项 (这里直接用了计算下界时候的 reservationDic foreach (var pair in y.Keys) { var res = reservationDic.Keys.FirstOrDefault(i => i.Source == pair.Source && i.Destination == pair.Destination); exp = model.Sum(exp, model.Prod(Convert.ToDouble(((res != null ? reservationDic[res] : 0) - (y[pair] ? bigM : 0))), dual_lambda[pair])); } model.AddGe(model.Sum(Convert.ToDouble(templowerBound_part1), exp), theta); /* Trust-Region */ //var trExpr = model.Add() flag = model.Solve(); Log($"Is Dual Problem Feasible: { flag }"); #endregion #region 通过一个启发式规则计算上界(按照w模拟到达) var pathcost = lbValueDic.ToDictionary(i => i.Key, i => i.Value); var x_least = x.ToDictionary(i => i.Key, i => i.Value);//当前w下每个旅客的最短路径 var x_upperbound = x.ToDictionary(i => i.Key, i => i.Value); var x_controlled = x.ToDictionary(i => i.Key, i => i.Value); #region 1-构建当前y下的最优x值 SubTasks.Clear(); foreach (CustomerArrival customer in _ctx.Pal)// 求解x { Task ta = factory.StartNew(() => { var controlledLRxgraph = new ControlledLRxTravelHyperNetwork( _ctx, adapter, objgraph, customer, pathDict, LM_rho, LM_mu, LM_lambda, y); controlledLRxgraph.Build(); var ori = (_ctx.Wor.Mar[customer.Customer.MarSegID] as IRailwayMarketSegment).OriSta; var des = (_ctx.Wor.Mar[customer.Customer.MarSegID] as IRailwayMarketSegment).DesSta; TravelHyperNode startNode = new TravelHyperNode() { Time = adapter.ConvertToDiscreteTime(customer.ArriveTime), Station = ori, Price = 0 }; TravelHyperNode endNode = new TravelHyperNode() { Time = adapter.Horizon + 1440, Station = des, Price = 0 }; DijkstraShortestPaths <DirectedWeightedSparseGraph <TravelHyperNode>, TravelHyperNode> dijkstra = new DijkstraShortestPaths <DirectedWeightedSparseGraph <TravelHyperNode>, TravelHyperNode> (controlledLRxgraph, startNode);//考虑该旅客到达时间 if (!dijkstra.HasPathTo(endNode)) { throw new System.Exception("没有路径!"); } else { x_controlled[customer] = new TravelPath(controlledLRxgraph, dijkstra.ShortestPathTo(endNode)); } }); SubTasks.Add(ta); } Task.WaitAll(SubTasks.ToArray()); #endregion # region 2-构建当前y下的出行最小值 var solutiongraph = new ControlledTravelHyperNetwork(_ctx, adapter, y); solutiongraph.Build(); Parallel.ForEach(_ctx.Pal, customer => //foreach (var customer in _ctx.Pal)//求此网络下每个旅客的最短路径 { var ori = (_ctx.Wor.Mar[customer.Customer.MarSegID] as IRailwayMarketSegment).OriSta; var des = (_ctx.Wor.Mar[customer.Customer.MarSegID] as IRailwayMarketSegment).DesSta; TravelHyperNode startNode = new TravelHyperNode() { Time = adapter.ConvertToDiscreteTime(customer.ArriveTime), Station = ori, Price = 0 }; TravelHyperNode endNode = new TravelHyperNode() { Time = adapter.Horizon + 1440, Station = des, Price = 0 }; DijkstraShortestPaths <DirectedWeightedSparseGraph <TravelHyperNode>, TravelHyperNode> dijkstra = new DijkstraShortestPaths <DirectedWeightedSparseGraph <TravelHyperNode>, TravelHyperNode> (solutiongraph, startNode); if (!dijkstra.HasPathTo(endNode)) { throw new System.Exception("没有路径!"); } else { x_least[customer] = new TravelPath(solutiongraph, dijkstra.ShortestPathTo(endNode)); } }); #endregion #region 3-修复可行解 var solutiongraphTemp = new SimNetwork(_ctx, adapter, y);//建立仿真网络 solutiongraphTemp.Build(); foreach (var customer in _ctx.Pal) { x_upperbound[customer] = x_controlled[customer]; TravelPath path = x_controlled[customer]; if (!solutiongraphTemp.IsPathFeasible(path) || solutiongraphTemp.GetPathCost(path) > solutiongraph.GetPathCost(x_least[customer]) + _ctx.SitaDic[customer.Customer.MarSegID])//如果违反了容量约束或者BRUE约束 { var ori = (_ctx.Wor.Mar[customer.Customer.MarSegID] as IRailwayMarketSegment).OriSta; var des = (_ctx.Wor.Mar[customer.Customer.MarSegID] as IRailwayMarketSegment).DesSta; DijkstraShortestPaths <DirectedWeightedSparseGraph <TravelHyperNode>, TravelHyperNode> dijkstra = new DijkstraShortestPaths <DirectedWeightedSparseGraph <TravelHyperNode>, TravelHyperNode>(solutiongraphTemp, new TravelHyperNode() { Time = adapter.ConvertToDiscreteTime(customer.ArriveTime), Station = ori, Price = 0 }); //重新查找路径,如果存在路径 if (dijkstra.HasPathTo(new TravelHyperNode() { Time = adapter.Horizon + 1440, Station = des, Price = 0 })) { x_upperbound[customer] = new TravelPath(solutiongraphTemp, dijkstra.ShortestPathTo(new TravelHyperNode() { Time = adapter.Horizon + 1440, Station = des, Price = 0 })); if (solutiongraphTemp.GetPathCost(x_upperbound[customer]) <= //满足BRUE约束 solutiongraph.GetPathCost(x_least[customer]) + _ctx.SitaDic[customer.Customer.MarSegID]) { path = x_upperbound[customer]; } else { hasFeasibleSolution = false; break; } } else { hasFeasibleSolution = false; break; } } pathcost[customer] = objgraph.GetPathCost(path); //加载路径 foreach (var seg in path.GetSegments(basicGraph)) { solutiongraphTemp.AddUsage(seg, 1); } } var tempUpperbound = _ctx.Pal.Sum(c => objgraph.GetPathCost(x_upperbound[c])); #endregion //如果有最优解再更新上界 bool hasBetterUpperbound = tempUpperbound < upperBound; if (hasFeasibleSolution) { upperBound = Math.Min(upperBound, tempUpperbound); } Log($"Upper Bound = { Math.Round(tempUpperbound, 2) },找到可行解 : { hasFeasibleSolution.ToString()}"); #endregion #region Terminatation 判定 Log($"Upper Bound = { tempUpperbound }"); decimal absoluteGap = 0; string gapStr = ""; //如果上限是无穷,那么此时gap也是无穷 if (upperBound == decimal.MaxValue || lowerBound == decimal.MinValue) { absoluteGap = decimal.MaxValue; gapStr = $"+∞"; } else { absoluteGap = upperBound - lowerBound; gapStr = $"{ Math.Round(absoluteGap, 2)}"; } if (absoluteGap < terminalFactor && absoluteGap > 0) { Log($"求解终止:Gap以满足终止条件,Gap={ absoluteGap }"); break; } Log($"Total Gap = { gapStr }"); #endregion #region 输出信息 //SendMessage($"#Iteration Number, Lower Bound, Upper Bound, Best Lower Bound, Best Upper Bound, Total Gap(%) "); PrintIterationInfo($"#{iter},{ Math.Round(templowerBound) },{ Math.Round(tempUpperbound) },{ Math.Round(lowerBound)}" + $",{ Math.Round(upperBound) },{ gapStr }"); string ss = "###,"; foreach (var s in LM_rho) { ss += ($"{s.Key.ToString()}:{ s.Value.ToString() },"); } PrintIterationInfo(ss); if (hasFeasibleSolution && hasBetterUpperbound) { ObjValue = pathcost.Sum(i => i.Value); PrintSolution( DpnAlgorithm.GetTravelPathString(_ctx, adapter, solutiongraph, x_upperbound, pathcost), DpnAlgorithm.GetPricingPathString(_ctx, adapter, w)); } #endregion Log($"--------------第{iter}轮求解结束--------------"); }
public static void DoTest() { string[] V; IEnumerable <WeightedEdge <string> > E; DirectedWeightedSparseGraph <string> graph; DijkstraShortestPaths <DirectedWeightedSparseGraph <string>, string> dijkstra; // Init graph object graph = new DirectedWeightedSparseGraph <string>(); // Init V V = new string[6] { "r", "s", "t", "x", "y", "z" }; // Insert V graph.AddVertices(V); Debug.Assert(graph.VerticesCount == V.Length, "Wrong Vertices Count."); // Insert E var status = graph.AddEdge("r", "s", 7); Debug.Assert(status == true); status = graph.AddEdge("r", "t", 6); Debug.Assert(status == true); status = graph.AddEdge("s", "t", 5); Debug.Assert(status == true); status = graph.AddEdge("s", "x", 9); Debug.Assert(status == true); status = graph.AddEdge("t", "x", 10); Debug.Assert(status == true); status = graph.AddEdge("t", "y", 7); Debug.Assert(status == true); status = graph.AddEdge("t", "z", 5); Debug.Assert(status == true); status = graph.AddEdge("x", "y", 2); Debug.Assert(status == true); status = graph.AddEdge("x", "z", 4); Debug.Assert(status == true); status = graph.AddEdge("y", "z", 1); Debug.Assert(status == true); // Get E E = graph.Edges; Debug.Assert(graph.EdgesCount == 10, "Wrong Edges Count."); // // PRINT THE GRAPH Console.Write("[*] DIJKSTRA ON DIRECTED WEIGHTED GRAPH - TEST 01:\r\n"); Console.WriteLine("Graph representation:"); Console.WriteLine(graph.ToReadable() + "\r\n"); // Init DIJKSTRA dijkstra = new DijkstraShortestPaths <DirectedWeightedSparseGraph <string>, string>(graph, "s"); Debug.Assert(dijkstra.HasPathTo("r") == false); Debug.Assert(dijkstra.HasPathTo("z") == true); // Get shortest path to Z var pathToZ = string.Empty; foreach (var node in dijkstra.ShortestPathTo("z")) { pathToZ = String.Format("{0}({1}) -> ", pathToZ, node); } pathToZ = pathToZ.TrimEnd(new char[] { ' ', '-', '>' }); Console.WriteLine("Shortest path to node 'z': " + pathToZ + "\r\n"); var pathToY = string.Empty; foreach (var node in dijkstra.ShortestPathTo("y")) { pathToY = String.Format("{0}({1}) -> ", pathToY, node); } pathToY = pathToY.TrimEnd(new char[] { ' ', '-', '>' }); Console.WriteLine("Shortest path to node 'y': " + pathToY + "\r\n"); Console.WriteLine("*********************************************\r\n"); /***************************************************************************************/ // Clear the graph and insert new V and E to the instance graph.Clear(); V = new string[] { "A", "B", "C", "D", "E" }; // Insert new values of V graph.AddVertices(V); Debug.Assert(graph.VerticesCount == V.Length, "Wrong Vertices Count."); // Insert new value for edges status = graph.AddEdge("A", "C", 7); Debug.Assert(status == true); status = graph.AddEdge("B", "A", 19); Debug.Assert(status == true); status = graph.AddEdge("B", "C", 11); Debug.Assert(status == true); status = graph.AddEdge("C", "E", 5); Debug.Assert(status == true); status = graph.AddEdge("C", "D", 15); Debug.Assert(status == true); status = graph.AddEdge("D", "B", 4); Debug.Assert(status == true); status = graph.AddEdge("E", "D", 13); Debug.Assert(status == true); Debug.Assert(graph.EdgesCount == 7, "Wrong Edges Count."); // // PRINT THE GRAPH Console.Write("[*] DIJKSTRA ON DIRECTED WEIGHTED GRAPH - TEST 01:\r\n"); Console.WriteLine("Graph representation:"); Console.WriteLine(graph.ToReadable() + "\r\n"); // Init DIJKSTRA dijkstra = new DijkstraShortestPaths <DirectedWeightedSparseGraph <string>, string>(graph, "A"); var pathToD = string.Empty; foreach (var node in dijkstra.ShortestPathTo("D")) { pathToD = String.Format("{0}({1}) -> ", pathToD, node); } pathToD = pathToD.TrimEnd(new char[] { ' ', '-', '>' }); Console.WriteLine("Shortest path from 'A' to 'D': " + pathToD + "\r\n"); Console.ReadLine(); }