// // Find the dual-shortest paths of the PathGraph; implements Suurballe's algorithm // public long dualShortestPath(int start, int goal, List <int> actualPath1, List <int> actualPath2) { actualPath1.Clear(); actualPath2.Clear(); // Are the given start and goal nodes valid? if (start <= 0 || goal > graph.NumVertices() || goal <= 0 || start > graph.NumVertices()) { Debug.WriteLine("Start Node or Goal Node specified is invalid."); return(-1); } // Create a new PathGraph such that every node is duplicated and split into x' and x'' // Incoming nodes go to x', outgoing edges go from x'' // The weight between x' and x'' is zero 0 graph.InduceVertexDisjoint(); updateStartGoalNodes(start, goal); // // Find the first shortest path using Dijkstra's algorithm // List <int> firstPath = new List <int>(); int firstLength = Dijkstra(firstPath); // Check if a path existed if (firstLength == -1) { Debug.WriteLine("No first path was found: (" + start + ", " + goal + ")"); return(-1); } if (DEBUG) { Debug.WriteLine("First Path: with length (" + firstLength + ")"); } // // Reverse the used edges // reverseShortestPathEdges(firstPath); // // Find the second shortest path using Dijkstra's algorithm on the PathGraph with reversed edges // List <int> secondPath = new List <int>(); int secondLength = Dijkstra(secondPath); // Check if a path existed if (secondLength == -1) { Debug.WriteLine("No second path was found: (" + start + ", " + goal + ")"); return(-1); } if (DEBUG) { Debug.WriteLine("Second Path: with length (" + secondLength + ")"); } // // Compare the paths looking for common edges // Calculate the length of the dual-shortest paths subtracting the common edges // Split the paths to creates two vertex-disjoint paths // List <int> tempPath1 = new List <int>(); List <int> tempPath2 = new List <int>(); int combinedPathLength = combinePaths(firstPath, secondPath, firstLength, secondLength, tempPath1, tempPath2); // // Condense the path back down from x'->x'' to x // condensePath(tempPath1, actualPath1); condensePath(tempPath2, actualPath2); return(combinedPathLength); }