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")); }
public void ShortestPathTo_FindShortestPath_WhenThereIsPossibleMultiplePaths(ShortestPathAlgorithm alg) { 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 algorithm = CreateAlgorithm(alg, graph, "a"); var result = algorithm.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, algorithm.DistanceTo("d")); }
public void Constructor_Throw_WhenSourceIsNotPartOfGraph() { var graph = new DirectedWeightedSparseGraph <string>(); graph.AddVertex("a"); graph.AddVertex("b"); graph.AddVertex("c"); graph.AddVertex("d"); Assert.Throws <ArgumentException>(() => new DijkstraShortestPaths <DirectedWeightedSparseGraph <string>, string>(graph, "x")); }
public void Constructor_Throw_WhenSourceIsNotPartOfGraph(ShortestPathAlgorithm alg) { var graph = new DirectedWeightedSparseGraph <string>(); graph.AddVertex("a"); graph.AddVertex("b"); graph.AddVertex("c"); graph.AddVertex("d"); Assert.Throws <ArgumentException>(() => CreateAlgorithm(alg, graph, "x")); }
public void Constructor_Throw_WhenAnyEdgeWeightIsLessThanZero() { var graph = new DirectedWeightedSparseGraph <string>(); graph.AddVertex("a"); graph.AddVertex("b"); graph.AddEdge("a", "b", -1); Assert.Throws <ArgumentException>(() => new DijkstraShortestPaths <DirectedWeightedSparseGraph <string>, string>(graph, "a")); }
public void Constructor_Throw_WhenAnyEdgeWeightIsLessThanZeroShortestPathAlgorithm(ShortestPathAlgorithm alg) { var graph = new DirectedWeightedSparseGraph <string>(); graph.AddVertex("a"); graph.AddVertex("b"); graph.AddEdge("a", "b", -1); Assert.Throws <ArgumentException>(() => CreateAlgorithm(alg, graph, "a")); }
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 ShortestPathTo_Throw_WhenDestinationIsNotInGraph(ShortestPathAlgorithm alg) { var graph = new DirectedWeightedSparseGraph <string>(); graph.AddVertex("a"); graph.AddVertex("b"); graph.AddVertex("c"); graph.AddVertex("d"); var algorithm = CreateAlgorithm(alg, graph, "a"); Assert.Throws <ArgumentException>(() => algorithm.ShortestPathTo("z")); }
public void DistanceTo_ReturnInfinity_WhenVertexIsNotAchievable(ShortestPathAlgorithm alg) { var graph = new DirectedWeightedSparseGraph <string>(); graph.AddVertex("a"); graph.AddVertex("b"); graph.AddVertex("c"); graph.AddEdge("a", "b", 1); var algorithm = CreateAlgorithm(alg, graph, "a"); Assert.Equal(long.MaxValue, algorithm.DistanceTo("c")); }
public void HasPathTo_ReturnFalse_WhenVertexIsNotAchievable(ShortestPathAlgorithm alg) { var graph = new DirectedWeightedSparseGraph <string>(); graph.AddVertex("a"); graph.AddVertex("b"); graph.AddVertex("c"); graph.AddEdge("a", "b", 1); var algorithm = CreateAlgorithm(alg, graph, "a"); Assert.False(algorithm.HasPathTo("c")); }
public void DistanceTo_Throw_WhenVertexIsNotInGraph(ShortestPathAlgorithm alg) { var graph = new DirectedWeightedSparseGraph <string>(); graph.AddVertex("a"); graph.AddVertex("b"); graph.AddVertex("c"); graph.AddEdge("a", "b", 1); var algorithm = CreateAlgorithm(alg, graph, "a"); Assert.Throws <ArgumentException>(() => algorithm.DistanceTo("z")); }
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 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 ShortestPathTo_ReturnNull_WhenDestinationIsNotAchievable(ShortestPathAlgorithm alg) { 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 algorithm = CreateAlgorithm(alg, graph, "a"); Assert.Null(algorithm.ShortestPathTo("d")); }
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(ShortestPathAlgorithm alg) { 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 algorithm = CreateAlgorithm(alg, graph, "a"); var result = algorithm.ShortestPathTo("a"); Assert.NotNull(result); Assert.Single(result); Assert.Equal("a", result.Single()); }
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 static void DoTest() { var graph = new DirectedWeightedSparseGraph<string>(); var verticesSet1 = new string[] { "a", "z", "s", "x", "d", "c", "f", "v" }; graph.AddVertices(verticesSet1); graph.AddEdge("a", "s", 1); graph.AddEdge("a", "z", 2); graph.AddEdge("s", "x", 3); graph.AddEdge("x", "d", 1); graph.AddEdge("x", "c", 2); graph.AddEdge("x", "a", 3); graph.AddEdge("d", "f", 1); graph.AddEdge("d", "c", 2); graph.AddEdge("d", "s", 3); graph.AddEdge("c", "f", 1); graph.AddEdge("c", "v", 2); graph.AddEdge("c", "d", 3); graph.AddEdge("v", "f", 1); graph.AddEdge("f", "c", 2); var allEdges = graph.Edges.ToList(); Debug.Assert(graph.VerticesCount == 8, "Wrong vertices count."); Debug.Assert(graph.EdgesCount == 14, "Wrong edges count."); Debug.Assert(graph.EdgesCount == allEdges.Count, "Wrong edges count."); Debug.Assert(graph.OutgoingEdges("a").ToList().Count == 2, "Wrong outgoing edges from 'a'."); Debug.Assert(graph.OutgoingEdges("s").ToList().Count == 1, "Wrong outgoing edges from 's'."); Debug.Assert(graph.OutgoingEdges("d").ToList().Count == 3, "Wrong outgoing edges from 'd'."); Debug.Assert(graph.OutgoingEdges("x").ToList().Count == 3, "Wrong outgoing edges from 'x'."); Debug.Assert(graph.OutgoingEdges("c").ToList().Count == 3, "Wrong outgoing edges from 'c'."); Debug.Assert(graph.OutgoingEdges("v").ToList().Count == 1, "Wrong outgoing edges from 'v'."); Debug.Assert(graph.OutgoingEdges("f").ToList().Count == 1, "Wrong outgoing edges from 'f'."); Debug.Assert(graph.OutgoingEdges("z").ToList().Count == 0, "Wrong outgoing edges from 'z'."); Debug.Assert(graph.IncomingEdges("a").ToList().Count == 1, "Wrong incoming edges from 'a'."); Debug.Assert(graph.IncomingEdges("s").ToList().Count == 2, "Wrong incoming edges from 's'."); Debug.Assert(graph.IncomingEdges("d").ToList().Count == 2, "Wrong incoming edges from 'd'."); Debug.Assert(graph.IncomingEdges("x").ToList().Count == 1, "Wrong incoming edges from 'x'."); Debug.Assert(graph.IncomingEdges("c").ToList().Count == 3, "Wrong incoming edges from 'c'."); Debug.Assert(graph.IncomingEdges("v").ToList().Count == 1, "Wrong incoming edges from 'v'."); Debug.Assert(graph.IncomingEdges("f").ToList().Count == 3, "Wrong incoming edges from 'f'."); Debug.Assert(graph.IncomingEdges("z").ToList().Count == 1, "Wrong incoming edges from 'z'."); Console.WriteLine("[*] Directed Weighted Sparse Graph:"); Console.WriteLine("Graph nodes and edges:"); Console.WriteLine(graph.ToReadable() + "\r\n"); // ASSERT RANDOMLY SELECTED EDGES var f_to_c = graph.HasEdge("f", "c"); var f_to_c_weight = graph.GetEdgeWeight("f", "c"); Debug.Assert(f_to_c == true, "Edge f->c doesn't exist."); Debug.Assert(f_to_c_weight == 2, "Edge f->c must have a weight of 2."); Console.WriteLine("Is there an edge from f to c? " + f_to_c + ". If yes it's weight is: " + f_to_c_weight + "."); // ASSERT RANDOMLY SELECTED EDGES var d_to_s = graph.HasEdge("d", "s"); var d_to_s_weight = graph.GetEdgeWeight("d", "s"); Debug.Assert(d_to_s == true, "Edge d->s doesn't exist."); Debug.Assert(d_to_s_weight == 3, "Edge d->s must have a weight of 3."); Console.WriteLine("Is there an edge from d to d? " + d_to_s + ". If yes it's weight is: " + d_to_s_weight + "."); Console.WriteLine(); // TRY ADDING DUPLICATE EDGES BUT WITH DIFFERENT WEIGHTS var add_d_to_s_status = graph.AddEdge("d", "s", 6); Debug.Assert(add_d_to_s_status == false, "Error! Added a duplicate edge."); var add_c_to_f_status = graph.AddEdge("c", "f", 12); Debug.Assert(add_c_to_f_status == false, "Error! Added a duplicate edge."); var add_s_to_x_status = graph.AddEdge("s", "x", 123); Debug.Assert(add_s_to_x_status == false, "Error! Added a duplicate edge."); var add_x_to_d_status = graph.AddEdge("x", "d", 34); Debug.Assert(add_x_to_d_status == false, "Error! Added a duplicate edge."); // TEST DELETING EDGES graph.RemoveEdge("d", "c"); Debug.Assert(graph.HasEdge("d", "c") == false, "Error! The edge d->c was deleted."); graph.RemoveEdge("c", "v"); Debug.Assert(graph.HasEdge("c", "v") == false, "Error! The edge c->v was deleted."); graph.RemoveEdge("a", "z"); Debug.Assert(graph.HasEdge("a", "z") == false, "Error! The edge a->z was deleted."); // ASSERT VERTICES AND EDGES COUNT Debug.Assert(graph.VerticesCount == 8, "Wrong vertices count."); Debug.Assert(graph.EdgesCount == 11, "Wrong edges count."); Console.WriteLine("After removing edges (d-c), (c-v), (a-z):"); Console.WriteLine(graph.ToReadable() + "\r\n"); // TEST DELETING VERTICES graph.RemoveVertex("x"); Debug.Assert(graph.HasEdge("x", "a") == false, "Error! The edge x->a was deleted because vertex x was deleted."); // ASSERT VERTICES AND EDGES COUNT Debug.Assert(graph.VerticesCount == 7, "Wrong vertices count."); Debug.Assert(graph.EdgesCount == 7, "Wrong edges count."); Console.WriteLine("After removing node (x):"); Console.WriteLine(graph.ToReadable() + "\r\n"); graph.AddVertex("x"); graph.AddEdge("s", "x", 3); graph.AddEdge("x", "d", 1); graph.AddEdge("x", "c", 2); graph.AddEdge("x", "a", 3); graph.AddEdge("d", "c", 2); graph.AddEdge("c", "v", 2); graph.AddEdge("a", "z", 2); Console.WriteLine("Re-added the deleted vertices and edges to the graph."); Console.WriteLine(graph.ToReadable() + "\r\n"); // BFS from A Console.WriteLine("Walk the graph using BFS from A:"); var bfsWalk = graph.BreadthFirstWalk("a"); // output: (s) (a) (x) (z) (d) (c) (f) (v) foreach (var node in bfsWalk) Console.Write(String.Format("({0})", node)); Console.WriteLine("\r\n"); // DFS from A Console.WriteLine("Walk the graph using DFS from A:"); var dfsWalk = graph.DepthFirstWalk("a"); // output: (s) (a) (x) (z) (d) (c) (f) (v) foreach (var node in dfsWalk) Console.Write(String.Format("({0})", node)); Console.WriteLine("\r\n"); // BFS from F Console.WriteLine("Walk the graph using BFS from F:"); bfsWalk = graph.BreadthFirstWalk("f"); // output: (s) (a) (x) (z) (d) (c) (f) (v) foreach (var node in bfsWalk) Console.Write(String.Format("({0})", node)); Console.WriteLine("\r\n"); // DFS from F Console.WriteLine("Walk the graph using DFS from F:"); dfsWalk = graph.DepthFirstWalk("f"); // output: (s) (a) (x) (z) (d) (c) (f) (v) foreach (var node in dfsWalk) Console.Write(String.Format("({0})", node)); Console.WriteLine("\r\n"); Console.ReadLine(); /********************************************************************/ Console.WriteLine("***************************************************\r\n"); graph.Clear(); Console.WriteLine("Cleared the graph from all vertices and edges.\r\n"); var verticesSet2 = new string[] { "a", "b", "c", "d", "e", "f" }; graph.AddVertices(verticesSet2); graph.AddEdge("a", "b", 1); graph.AddEdge("a", "d", 2); graph.AddEdge("b", "e", 3); graph.AddEdge("d", "b", 1); graph.AddEdge("d", "e", 2); graph.AddEdge("e", "c", 3); graph.AddEdge("c", "f", 1); graph.AddEdge("f", "f", 1); Debug.Assert(graph.VerticesCount == 6, "Wrong vertices count."); Debug.Assert(graph.EdgesCount == 8, "Wrong edges count."); Console.WriteLine("[*] NEW Directed Weighted Sparse Graph:"); Console.WriteLine("Graph nodes and edges:"); Console.WriteLine(graph.ToReadable() + "\r\n"); Console.WriteLine("Walk the graph using DFS:"); dfsWalk = graph.DepthFirstWalk(); // output: (a) (b) (e) (d) (c) (f) foreach (var node in dfsWalk) Console.Write(String.Format("({0})", node)); Console.ReadLine(); }
public static void DoTest() { var graph = new DirectedWeightedSparseGraph <string>(); var verticesSet1 = new string[] { "a", "z", "s", "x", "d", "c", "f", "v" }; graph.AddVertices(verticesSet1); graph.AddEdge("a", "s", 1); graph.AddEdge("a", "z", 2); graph.AddEdge("s", "x", 3); graph.AddEdge("x", "d", 1); graph.AddEdge("x", "c", 2); graph.AddEdge("x", "a", 3); graph.AddEdge("d", "f", 1); graph.AddEdge("d", "c", 2); graph.AddEdge("d", "s", 3); graph.AddEdge("c", "f", 1); graph.AddEdge("c", "v", 2); graph.AddEdge("c", "d", 3); graph.AddEdge("v", "f", 1); graph.AddEdge("f", "c", 2); var allEdges = graph.Edges.ToList(); Debug.Assert(graph.VerticesCount == 8, "Wrong vertices count."); Debug.Assert(graph.EdgesCount == 14, "Wrong edges count."); Debug.Assert(graph.EdgesCount == allEdges.Count, "Wrong edges count."); Debug.Assert(graph.OutgoingEdges("a").ToList().Count == 2, "Wrong outgoing edges from 'a'."); Debug.Assert(graph.OutgoingEdges("s").ToList().Count == 1, "Wrong outgoing edges from 's'."); Debug.Assert(graph.OutgoingEdges("d").ToList().Count == 3, "Wrong outgoing edges from 'd'."); Debug.Assert(graph.OutgoingEdges("x").ToList().Count == 3, "Wrong outgoing edges from 'x'."); Debug.Assert(graph.OutgoingEdges("c").ToList().Count == 3, "Wrong outgoing edges from 'c'."); Debug.Assert(graph.OutgoingEdges("v").ToList().Count == 1, "Wrong outgoing edges from 'v'."); Debug.Assert(graph.OutgoingEdges("f").ToList().Count == 1, "Wrong outgoing edges from 'f'."); Debug.Assert(graph.OutgoingEdges("z").ToList().Count == 0, "Wrong outgoing edges from 'z'."); Debug.Assert(graph.IncomingEdges("a").ToList().Count == 1, "Wrong incoming edges from 'a'."); Debug.Assert(graph.IncomingEdges("s").ToList().Count == 2, "Wrong incoming edges from 's'."); Debug.Assert(graph.IncomingEdges("d").ToList().Count == 2, "Wrong incoming edges from 'd'."); Debug.Assert(graph.IncomingEdges("x").ToList().Count == 1, "Wrong incoming edges from 'x'."); Debug.Assert(graph.IncomingEdges("c").ToList().Count == 3, "Wrong incoming edges from 'c'."); Debug.Assert(graph.IncomingEdges("v").ToList().Count == 1, "Wrong incoming edges from 'v'."); Debug.Assert(graph.IncomingEdges("f").ToList().Count == 3, "Wrong incoming edges from 'f'."); Debug.Assert(graph.IncomingEdges("z").ToList().Count == 1, "Wrong incoming edges from 'z'."); Console.WriteLine("[*] Directed Weighted Sparse Graph:"); Console.WriteLine("Graph nodes and edges:"); Console.WriteLine(graph.ToReadable() + "\r\n"); // ASSERT RANDOMLY SELECTED EDGES var f_to_c = graph.HasEdge("f", "c"); var f_to_c_weight = graph.GetEdgeWeight("f", "c"); Debug.Assert(f_to_c == true, "Edge f->c doesn't exist."); Debug.Assert(f_to_c_weight == 2, "Edge f->c must have a weight of 2."); Console.WriteLine("Is there an edge from f to c? " + f_to_c + ". If yes it's weight is: " + f_to_c_weight + "."); // ASSERT RANDOMLY SELECTED EDGES var d_to_s = graph.HasEdge("d", "s"); var d_to_s_weight = graph.GetEdgeWeight("d", "s"); Debug.Assert(d_to_s == true, "Edge d->s doesn't exist."); Debug.Assert(d_to_s_weight == 3, "Edge d->s must have a weight of 3."); Console.WriteLine("Is there an edge from d to d? " + d_to_s + ". If yes it's weight is: " + d_to_s_weight + "."); Console.WriteLine(); // TRY ADDING DUPLICATE EDGES BUT WITH DIFFERENT WEIGHTS var add_d_to_s_status = graph.AddEdge("d", "s", 6); Debug.Assert(add_d_to_s_status == false, "Error! Added a duplicate edge."); var add_c_to_f_status = graph.AddEdge("c", "f", 12); Debug.Assert(add_c_to_f_status == false, "Error! Added a duplicate edge."); var add_s_to_x_status = graph.AddEdge("s", "x", 123); Debug.Assert(add_s_to_x_status == false, "Error! Added a duplicate edge."); var add_x_to_d_status = graph.AddEdge("x", "d", 34); Debug.Assert(add_x_to_d_status == false, "Error! Added a duplicate edge."); // TEST DELETING EDGES graph.RemoveEdge("d", "c"); Debug.Assert(graph.HasEdge("d", "c") == false, "Error! The edge d->c was deleted."); graph.RemoveEdge("c", "v"); Debug.Assert(graph.HasEdge("c", "v") == false, "Error! The edge c->v was deleted."); graph.RemoveEdge("a", "z"); Debug.Assert(graph.HasEdge("a", "z") == false, "Error! The edge a->z was deleted."); // ASSERT VERTICES AND EDGES COUNT Debug.Assert(graph.VerticesCount == 8, "Wrong vertices count."); Debug.Assert(graph.EdgesCount == 11, "Wrong edges count."); Console.WriteLine("After removing edges (d-c), (c-v), (a-z):"); Console.WriteLine(graph.ToReadable() + "\r\n"); // TEST DELETING VERTICES graph.RemoveVertex("x"); Debug.Assert(graph.HasEdge("x", "a") == false, "Error! The edge x->a was deleted because vertex x was deleted."); // ASSERT VERTICES AND EDGES COUNT Debug.Assert(graph.VerticesCount == 7, "Wrong vertices count."); Debug.Assert(graph.EdgesCount == 7, "Wrong edges count."); Console.WriteLine("After removing node (x):"); Console.WriteLine(graph.ToReadable() + "\r\n"); graph.AddVertex("x"); graph.AddEdge("s", "x", 3); graph.AddEdge("x", "d", 1); graph.AddEdge("x", "c", 2); graph.AddEdge("x", "a", 3); graph.AddEdge("d", "c", 2); graph.AddEdge("c", "v", 2); graph.AddEdge("a", "z", 2); Console.WriteLine("Re-added the deleted vertices and edges to the graph."); Console.WriteLine(graph.ToReadable() + "\r\n"); // BFS from A Console.WriteLine("Walk the graph using BFS from A:"); var bfsWalk = graph.BreadthFirstWalk("a"); // output: (s) (a) (x) (z) (d) (c) (f) (v) foreach (var node in bfsWalk) { Console.Write(String.Format("({0})", node)); } Console.WriteLine("\r\n"); // DFS from A Console.WriteLine("Walk the graph using DFS from A:"); var dfsWalk = graph.DepthFirstWalk("a"); // output: (s) (a) (x) (z) (d) (c) (f) (v) foreach (var node in dfsWalk) { Console.Write(String.Format("({0})", node)); } Console.WriteLine("\r\n"); // BFS from F Console.WriteLine("Walk the graph using BFS from F:"); bfsWalk = graph.BreadthFirstWalk("f"); // output: (s) (a) (x) (z) (d) (c) (f) (v) foreach (var node in bfsWalk) { Console.Write(String.Format("({0})", node)); } Console.WriteLine("\r\n"); // DFS from F Console.WriteLine("Walk the graph using DFS from F:"); dfsWalk = graph.DepthFirstWalk("f"); // output: (s) (a) (x) (z) (d) (c) (f) (v) foreach (var node in dfsWalk) { Console.Write(String.Format("({0})", node)); } Console.WriteLine("\r\n"); Console.ReadLine(); /********************************************************************/ Console.WriteLine("***************************************************\r\n"); graph.Clear(); Console.WriteLine("Cleared the graph from all vertices and edges.\r\n"); var verticesSet2 = new string[] { "a", "b", "c", "d", "e", "f" }; graph.AddVertices(verticesSet2); graph.AddEdge("a", "b", 1); graph.AddEdge("a", "d", 2); graph.AddEdge("b", "e", 3); graph.AddEdge("d", "b", 1); graph.AddEdge("d", "e", 2); graph.AddEdge("e", "c", 3); graph.AddEdge("c", "f", 1); graph.AddEdge("f", "f", 1); Debug.Assert(graph.VerticesCount == 6, "Wrong vertices count."); Debug.Assert(graph.EdgesCount == 8, "Wrong edges count."); Console.WriteLine("[*] NEW Directed Weighted Sparse Graph:"); Console.WriteLine("Graph nodes and edges:"); Console.WriteLine(graph.ToReadable() + "\r\n"); Console.WriteLine("Walk the graph using DFS:"); dfsWalk = graph.DepthFirstWalk(); // output: (a) (b) (e) (d) (c) (f) foreach (var node in dfsWalk) { Console.Write(String.Format("({0})", node)); } Console.ReadLine(); }
//增加了拉格朗日乘子之后的LR-w网络 public static DirectedWeightedSparseGraph <string> BuildLRwGraph( DPNProblemContext ctx, DiscreteTimeAdapter adapter, ITrainTrip train, IRailwayStation station, Dictionary <CustomerArrival, List <TravelPath> > PathDict, Dictionary <IEdge <TravelHyperNode>, ITrainTrip> linkTrainDict, Dictionary <CustomerArrival, Dictionary <TravelPath, decimal> > LM_mu, //拉格朗日乘子 μ TODO:int 改为path , Dictionary <IEdge <TravelHyperNode>, decimal> LM_lambda) { DirectedWeightedSparseGraph <string> graph = new DirectedWeightedSparseGraph <string>(); //Build price_transfer links decimal[] priceLevelList = ctx.PriceLevelList.ToArray(); int last = 0; int interval = ctx.ControlInterval / adapter.Resolution; if (interval >= adapter.Horizon) { throw new Exception("控制频率应小于预售期"); } for (int level = 0; level < priceLevelList.Count(); level++) { for (int time = 0; time + interval < adapter.Horizon; time += interval) { decimal cost_part1 = ctx.Pal.Sum(c => PathDict[c].Where(path => path.StartStation == station && priceLevelList[level] == path.Price && linkTrainDict[path.ReservationArc] == train && time <= path.ReservationTime && time + interval > path.ReservationTime).Sum(p => LM_mu[c][p])); decimal cost_part2 = LM_lambda.Where(i => i.Key.Source.Station == station && i.Key.Destination.Price == priceLevelList[level] && linkTrainDict[i.Key] == train && time <= i.Key.Source.Time && time + interval > i.Key.Source.Time).Sum(i => i.Value); string selfnode = $"{priceLevelList[level]}_{time}"; //价格不变 string nextnode = $"{priceLevelList[level]}_{time + interval}"; if (!graph.HasVertex(selfnode)) { graph.AddVertex(selfnode); } if (!graph.HasVertex(nextnode)) { graph.AddVertex(nextnode); } if (!graph.AddEdge(selfnode, nextnode, cost_part1 - cost_part2)) { throw new Exception("存在相同的Edge"); } //上升一段 if (level < priceLevelList.Count() - 1) { string ariseNode = $"{priceLevelList[level + 1]}_{time + interval}"; if (!graph.HasVertex(ariseNode)) { graph.AddVertex(ariseNode); } if (!graph.AddEdge(selfnode, ariseNode, cost_part1 - cost_part2 + DpnAlgorithm.ASmallCost)) { throw new Exception("存在相同的Edge"); } } //下降一段 if (level > 0) { string decreaseNode = $"{priceLevelList[level - 1]}_{time + interval}";//价格等级默认是1 if (!graph.HasVertex(decreaseNode)) { graph.AddVertex(decreaseNode); } if (!graph.AddEdge(selfnode, decreaseNode, cost_part1 - cost_part2 - DpnAlgorithm.ASmallCost)) { throw new Exception("存在相同的Edge"); } } last = time + interval; } } //Build dummy nodes and links. string dummystart = $"Start";//价格等级默认是1 if (!graph.HasVertex(dummystart)) { graph.AddVertex(dummystart); } for (int level = 0; level < priceLevelList.Count(); level++) { string selfnode = $"{priceLevelList[level]}_0";//价格等级默认是1 if (!graph.AddEdge(dummystart, selfnode, (level + 1) * ASmallCost)) { throw new Exception("存在相同的Edge"); } } string dummyend = $"End";//价格等级默认是1 if (!graph.HasVertex(dummyend)) { graph.AddVertex(dummyend); } for (int level = 0; level < priceLevelList.Count(); level++) { string selfnode = $"{priceLevelList[level]}_{last}";//价格等级默认是1 if (!graph.AddEdge(selfnode, dummyend, ASmallCost)) { throw new Exception("存在相同的Edge"); } } var min = graph.Edges.Min(e => e.Weight); if (min <= 0) { foreach (var edge in graph.Edges) { edge.Weight += -min + DpnAlgorithm.ASmallCost; } } return(graph); }
public static decimal ASmallCost = 0.000001m;//为不考虑weight的arc增加一个极小的weight //给定w的网络 public static DirectedWeightedSparseGraph <string> BuildSolutionGraph( DPNProblemContext ctx, DiscreteTimeAdapter adapter, Dictionary <WeightedEdge <string>, bool> y) { int transferThreshold = ctx.TransferThreshold; List <decimal> priceLevelList = ctx.PriceLevelList; DirectedWeightedSparseGraph <string> graph = new DirectedWeightedSparseGraph <string>(); //Build In-train links foreach (var train in ctx.Wor.RailwayTimeTable.Trains) { foreach (var price in priceLevelList) { //Build In-train links in Section foreach (var seg in train.ServiceSegments) { string depNode = $"{adapter.Horizon + seg.DepTime.Hour * 60 + seg.DepTime.Minute}" + $"_{seg.DepStation.RailwayStationID}_{price}";//价格等级默认是1 if (!graph.HasVertex(depNode)) { graph.AddVertex(depNode); } string arrNode = $"{adapter.Horizon + seg.ArrTime.Hour * 60 + seg.ArrTime.Minute}" + $"_{seg.ArrStation.RailwayStationID}_{price}";//价格等级默认是1 if (!graph.HasVertex(arrNode)) { graph.AddVertex(arrNode); } graph.AddEdge(depNode, arrNode, (ctx.BasicPriceDic[seg] * price + (decimal)(seg.ArrTime - seg.DepTime).TotalMinutes * ctx.Vot)); }//Build In-train links in stop station foreach (var stop in train.StopStaions.Skip(1).Take(train.StopStaions.Count() - 2)) { string arrNode = $"{adapter.Horizon + stop.ArrTime.Hour * 60 + stop.ArrTime.Minute}" + $"_{stop.Station.RailwayStationID}_{price}"; //价格等级默认是1 string depNode = $"{adapter.Horizon + stop.DepTime.Hour * 60 + stop.DepTime.Minute}" + $"_{stop.Station.RailwayStationID}_{price}"; //价格等级默认是1 graph.AddEdge(arrNode, depNode, ((decimal)(stop.DepTime - stop.ArrTime).TotalMinutes * ctx.Vot)); } } } //Build waiting links foreach (var ms in ctx.Wor.Mar as IEnumerable <IRailwayMarketSegment> ) { for (int i = 0; i < adapter.Horizon; i++) { if (!graph.HasVertex($"{i}_{ms.OriSta.RailwayStationID}_0")) { graph.AddVertex($"{i}_{ms.OriSta.RailwayStationID}_0"); } if (!graph.HasVertex($"{i + 1}_{ms.OriSta.RailwayStationID}_0")) { graph.AddVertex($"{i + 1}_{ms.OriSta.RailwayStationID}_0"); } graph.AddEdge($"{i}_{ms.OriSta.RailwayStationID}_0", $"{i + 1}_{ms.OriSta.RailwayStationID}_0", adapter.Resolution * ctx.WaitingVot); // One minute each link } } //Build Reservation links foreach (var sta in ctx.Wor.Net.StationCollection) { //获取车次出发点 var depSegs = ctx.Wor.RailwayTimeTable.Trains.SelectMany(i => i.ServiceSegments.Where(s => s.DepStation == sta)); foreach (var seg in depSegs) { foreach (var price in priceLevelList) { string depNode = $"{adapter.Horizon + seg.DepTime.Hour * 60 + seg.DepTime.Minute}_{seg.DepStation.RailwayStationID}_{price}"; for (int i = 0; i < adapter.Horizon; i++) { var edge = y.Keys.FirstOrDefault(link => link.Source == $"{i}_{sta.RailwayStationID.ToString()}_0" && link.Destination == depNode); if (edge != null && y[edge]) { graph.AddEdge($"{i}_{sta.RailwayStationID.ToString()}_0", depNode, ASmallCost); // 一次预订花费一分钟 } } } } } //Build finishing links foreach (var price in priceLevelList) { foreach (var sta in ctx.Wor.Net.StationCollection) { var arrSegs = ctx.Wor.RailwayTimeTable.Trains.SelectMany(i => i.ServiceSegments.Where(s => s.ArrStation == sta)); foreach (var seg in arrSegs) { string arrNode = $"{adapter.Horizon + seg.ArrTime.Hour * 60 + seg.ArrTime.Minute}_{seg.ArrStation.RailwayStationID}_{price}";//价格等级 string endNode = $"End_{sta.RailwayStationID.ToString()}_0"; if (!graph.HasVertex(endNode)) { graph.AddVertex(endNode); } graph.AddEdge(arrNode, endNode, ASmallCost); } } } //Build quit links /* * foreach (var ms in ctx.Wor.Mar as IEnumerable<IRailwayMarketSegment>) * { * graph.AddEdge($"{adapter.Horizon}_{ms.OriSta.RailwayStationID}_0", * $"End_{ms.DesSta.RailwayStationID}_0", 999m); * } */ return(graph); }
public static void DoTest() { var graph = new DirectedWeightedSparseGraph <string>(); var verticesSet1 = new string[] { "a", "z", "s", "x", "d", "c", "f", "v" }; graph.AddVertices(verticesSet1); graph.AddEdge("a", "s", 1); graph.AddEdge("a", "z", 2); graph.AddEdge("s", "x", 3); graph.AddEdge("x", "d", 1); graph.AddEdge("x", "c", 2); graph.AddEdge("x", "a", 3); graph.AddEdge("d", "f", 1); graph.AddEdge("d", "c", 2); graph.AddEdge("d", "s", 3); graph.AddEdge("c", "f", 1); graph.AddEdge("c", "v", 2); graph.AddEdge("c", "d", 3); graph.AddEdge("v", "f", 1); graph.AddEdge("f", "c", 2); var allEdges = graph.Edges.ToList(); Assert.True(graph.VerticesCount == 8, "Wrong vertices count."); Assert.True(graph.EdgesCount == 14, "Wrong edges count."); Assert.True(graph.EdgesCount == allEdges.Count, "Wrong edges count."); Assert.True(graph.OutgoingEdges("a").ToList().Count == 2, "Wrong outgoing edges from 'a'."); Assert.True(graph.OutgoingEdges("s").ToList().Count == 1, "Wrong outgoing edges from 's'."); Assert.True(graph.OutgoingEdges("d").ToList().Count == 3, "Wrong outgoing edges from 'd'."); Assert.True(graph.OutgoingEdges("x").ToList().Count == 3, "Wrong outgoing edges from 'x'."); Assert.True(graph.OutgoingEdges("c").ToList().Count == 3, "Wrong outgoing edges from 'c'."); Assert.True(graph.OutgoingEdges("v").ToList().Count == 1, "Wrong outgoing edges from 'v'."); Assert.True(graph.OutgoingEdges("f").ToList().Count == 1, "Wrong outgoing edges from 'f'."); Assert.True(graph.OutgoingEdges("z").ToList().Count == 0, "Wrong outgoing edges from 'z'."); Assert.True(graph.IncomingEdges("a").ToList().Count == 1, "Wrong incoming edges from 'a'."); Assert.True(graph.IncomingEdges("s").ToList().Count == 2, "Wrong incoming edges from 's'."); Assert.True(graph.IncomingEdges("d").ToList().Count == 2, "Wrong incoming edges from 'd'."); Assert.True(graph.IncomingEdges("x").ToList().Count == 1, "Wrong incoming edges from 'x'."); Assert.True(graph.IncomingEdges("c").ToList().Count == 3, "Wrong incoming edges from 'c'."); Assert.True(graph.IncomingEdges("v").ToList().Count == 1, "Wrong incoming edges from 'v'."); Assert.True(graph.IncomingEdges("f").ToList().Count == 3, "Wrong incoming edges from 'f'."); Assert.True(graph.IncomingEdges("z").ToList().Count == 1, "Wrong incoming edges from 'z'."); // ASSERT RANDOMLY SELECTED EDGES var f_to_c = graph.HasEdge("f", "c"); var f_to_c_weight = graph.GetEdgeWeight("f", "c"); Assert.True(f_to_c == true, "Edge f->c doesn't exist."); Assert.True(f_to_c_weight == 2, "Edge f->c must have a weight of 2."); // ASSERT RANDOMLY SELECTED EDGES var d_to_s = graph.HasEdge("d", "s"); var d_to_s_weight = graph.GetEdgeWeight("d", "s"); Assert.True(d_to_s == true, "Edge d->s doesn't exist."); Assert.True(d_to_s_weight == 3, "Edge d->s must have a weight of 3."); // TRY ADDING DUPLICATE EDGES BUT WITH DIFFERENT WEIGHTS var add_d_to_s_status = graph.AddEdge("d", "s", 6); Assert.True(add_d_to_s_status == false, "Error! Added a duplicate edge."); var add_c_to_f_status = graph.AddEdge("c", "f", 12); Assert.True(add_c_to_f_status == false, "Error! Added a duplicate edge."); var add_s_to_x_status = graph.AddEdge("s", "x", 123); Assert.True(add_s_to_x_status == false, "Error! Added a duplicate edge."); var add_x_to_d_status = graph.AddEdge("x", "d", 34); Assert.True(add_x_to_d_status == false, "Error! Added a duplicate edge."); // TEST DELETING EDGES graph.RemoveEdge("d", "c"); Assert.True(graph.HasEdge("d", "c") == false, "Error! The edge d->c was deleted."); graph.RemoveEdge("c", "v"); Assert.True(graph.HasEdge("c", "v") == false, "Error! The edge c->v was deleted."); graph.RemoveEdge("a", "z"); Assert.True(graph.HasEdge("a", "z") == false, "Error! The edge a->z was deleted."); // ASSERT VERTICES AND EDGES COUNT Assert.True(graph.VerticesCount == 8, "Wrong vertices count."); Assert.True(graph.EdgesCount == 11, "Wrong edges count."); // TEST DELETING VERTICES graph.RemoveVertex("x"); Assert.True(graph.HasEdge("x", "a") == false, "Error! The edge x->a was deleted because vertex x was deleted."); // ASSERT VERTICES AND EDGES COUNT Assert.True(graph.VerticesCount == 7, "Wrong vertices count."); Assert.True(graph.EdgesCount == 7, "Wrong edges count."); graph.AddVertex("x"); graph.AddEdge("s", "x", 3); graph.AddEdge("x", "d", 1); graph.AddEdge("x", "c", 2); graph.AddEdge("x", "a", 3); graph.AddEdge("d", "c", 2); graph.AddEdge("c", "v", 2); graph.AddEdge("a", "z", 2); // BFS from A // Walk the graph using BFS from A: var bfsWalk = graph.BreadthFirstWalk("a"); // output: (s) (a) (x) (z) (d) (c) (f) (v) foreach (var node in bfsWalk) { Console.Write(String.Format("({0})", node)); } // DFS from A // Walk the graph using DFS from A: var dfsWalk = graph.DepthFirstWalk("a"); // output: (s) (a) (x) (z) (d) (c) (f) (v) foreach (var node in dfsWalk) { Console.Write(String.Format("({0})", node)); } // BFS from F // Walk the graph using BFS from F: bfsWalk = graph.BreadthFirstWalk("f"); // output: (s) (a) (x) (z) (d) (c) (f) (v) foreach (var node in bfsWalk) { Console.Write(String.Format("({0})", node)); } // DFS from F Console.WriteLine("Walk the graph using DFS from F:"); dfsWalk = graph.DepthFirstWalk("f"); // output: (s) (a) (x) (z) (d) (c) (f) (v) foreach (var node in dfsWalk) { Console.Write(String.Format("({0})", node)); } /********************************************************************/ graph.Clear(); var verticesSet2 = new string[] { "a", "b", "c", "d", "e", "f" }; graph.AddVertices(verticesSet2); graph.AddEdge("a", "b", 1); graph.AddEdge("a", "d", 2); graph.AddEdge("b", "e", 3); graph.AddEdge("d", "b", 1); graph.AddEdge("d", "e", 2); graph.AddEdge("e", "c", 3); graph.AddEdge("c", "f", 1); graph.AddEdge("f", "f", 1); Assert.True(graph.VerticesCount == 6, "Wrong vertices count."); Assert.True(graph.EdgesCount == 8, "Wrong edges count."); // Walk the graph using DFS: dfsWalk = graph.DepthFirstWalk(); // output: (a) (b) (e) (d) (c) (f) foreach (var node in dfsWalk) { Console.Write(String.Format("({0})", node)); } }