public static ShortestPathTree ShortestPathTree(Graph graph, String sourceLabel) { G.IDictionary <String, Node> nodes = graph.GetNodes(); if (!nodes.ContainsKey(sourceLabel)) { throw new Exception("Source node not found in graph."); } ShortestPathTree predecessorTree = new ShortestPathTree(sourceLabel); ISet <DijkstraNode> visited = new HashSet <DijkstraNode>(); java.util.PriorityQueue <DijkstraNode> pq = new java.util.PriorityQueue <DijkstraNode>(); foreach (String nodeLabel in nodes.Keys) { DijkstraNode newNode = new DijkstraNode(nodeLabel); newNode.SetDist(double.MaxValue); newNode.SetDepth(int.MaxValue); predecessorTree.Add(newNode); } DijkstraNode sourceNode = predecessorTree.GetNodes()[predecessorTree.GetRoot()]; sourceNode.SetDist(0); sourceNode.SetDepth(0); pq.add(sourceNode, sourceNode.GetDist()); int count = 0; while (!pq.isEmpty()) { DijkstraNode current = pq.poll(); String currLabel = current.GetLabel(); visited.Add(current); count++; G.IDictionary <String, Double> neighbors = nodes[currLabel].GetNeighbors(); foreach (String currNeighborLabel in neighbors.Keys) { DijkstraNode neighborNode = predecessorTree.GetNodes()[currNeighborLabel]; Double currDistance = neighborNode.GetDist(); Double newDistance = current.GetDist() + nodes[currLabel].GetNeighbors()[currNeighborLabel]; if (newDistance < currDistance) { DijkstraNode neighbor = predecessorTree.GetNodes()[currNeighborLabel]; pq.remove(neighbor); neighbor.SetDist(newDistance); neighbor.SetDepth(current.GetDepth() + 1); neighbor.SetParent(currLabel); pq.add(neighbor, neighbor.GetDist()); } } } return(predecessorTree); }
/** * Computes the K shortest paths in a graph from node s to node t using Yen's algorithm * * @param graph the graph on which to compute the K shortest paths from s to t * @param sourceLabel the starting node for all of the paths * @param targetLabel the ending node for all of the paths * @param K the number of shortest paths to compute * @return a list of the K shortest paths from s to t, ordered from shortest to longest */ public IList <Path> Ksp(Graph graph, String sourceLabel, String targetLabel, int K) { // Initialize containers for candidate paths and k shortest paths List <Path> ksp = new List <Path>(); java.util.PriorityQueue <Path> candidates = new java.util.PriorityQueue <Path>(); //try { /* Compute and add the shortest path */ Path kthPath = Dijkstra.ShortestPath(graph, sourceLabel, targetLabel); ksp.Add(kthPath); /* Iteratively compute each of the k shortest paths */ for (int k = 1; k < K; k++) { // Get the (k-1)st shortest path Path previousPath = ksp[k - 1]; /* Iterate over all of the nodes in the (k-1)st shortest path except for the target node; for each node, * (up to) one new candidate path is generated by temporarily modifying the graph and then running * Dijkstra's algorithm to find the shortest path between the node and the target in the modified * graph */ for (int i = 0; i < previousPath.Size(); i++) { // Initialize a container to store the modified (removed) edges for this node/iteration java.util.LinkedList <Edge> removedEdges = new java.util.LinkedList <Edge>(); // Spur node = currently visited node in the (k-1)st shortest path String spurNode = previousPath.GetEdges().get(i).GetFromNode(); // Root path = prefix portion of the (k-1)st path up to the spur node Path rootPath = previousPath.CloneTo(i); /* Iterate over all of the (k-1) shortest paths */ foreach (Path p in ksp) { Path stub = p.CloneTo(i); // Check to see if this path has the same prefix/root as the (k-1)st shortest path if (rootPath.Equals((object)stub)) { /* If so, eliminate the next edge in the path from the graph (later on, this forces the spur * node to connect the root path with an un-found suffix path) */ Edge re = p.GetEdges().get(i); graph.RemoveEdge(re.GetFromNode(), re.GetToNode()); removedEdges.add(re); } } /* Temporarily remove all of the nodes in the root path, other than the spur node, from the graph */ foreach (Edge rootPathEdge in rootPath.GetEdges()) { String rn = rootPathEdge.GetFromNode(); if (!rn.Equals(spurNode)) { removedEdges.addAll(graph.RemoveNode(rn)); } } // Spur path = shortest path from spur node to target node in the reduced graph Path spurPath = Dijkstra.ShortestPath(graph, spurNode, targetLabel); // If a new spur path was identified... if (spurPath != null) { // Concatenate the root and spur paths to form the new candidate path Path totalPath = rootPath.Clone(); totalPath.AddPath(spurPath); // If candidate path has not been generated previously, add it if (!candidates.contains(totalPath)) { candidates.add(totalPath, totalPath.GetTotalCost()); } } // Restore all of the edges that were removed during this iteration graph.AddEdges(removedEdges); } /* Identify the candidate path with the shortest cost */ bool isNewPath; do { kthPath = candidates.poll(); isNewPath = true; if (kthPath != null) { foreach (Path p in ksp) { // Check to see if this candidate path duplicates a previously found path if (p.Equals(kthPath)) { isNewPath = false; break; } } } } while(!isNewPath); // If there were not any more candidates, stop if (kthPath == null) { break; } // Add the best, non-duplicate candidate identified as the k shortest path ksp.Add(kthPath); } //} catch (Exception e) { // SystemOut.println(e); // e.printStackTrace(); //} // Return the set of k shortest paths return(ksp); }
public static Path ShortestPath(Graph graph, String sourceLabel, String targetLabel) { //if (!nodes.containsKey(sourceLabel)) // throw new Exception("Source node not found in graph."); G.IDictionary <String, Node> nodes = graph.GetNodes(); ShortestPathTree predecessorTree = new ShortestPathTree(sourceLabel); java.util.PriorityQueue <DijkstraNode> pq = new java.util.PriorityQueue <DijkstraNode>(); foreach (String nodeLabel in nodes.Keys) { DijkstraNode newNode = new DijkstraNode(nodeLabel); newNode.SetDist(double.MaxValue); newNode.SetDepth(int.MaxValue); predecessorTree.Add(newNode); } DijkstraNode sourceNode = predecessorTree.GetNodes()[predecessorTree.GetRoot()]; sourceNode.SetDist(0); sourceNode.SetDepth(0); pq.add(sourceNode, sourceNode.GetDist()); int count = 0; while (!pq.isEmpty()) { DijkstraNode current = pq.poll(); String currLabel = current.GetLabel(); if (currLabel.Equals(targetLabel)) { Path shortestPath = new Path(); String currentN = targetLabel; String parentN = predecessorTree.GetParentOf(currentN); while (parentN != null) { shortestPath.AddFirst(new Edge(parentN, currentN, nodes[parentN].GetNeighbors()[currentN])); currentN = parentN; parentN = predecessorTree.GetParentOf(currentN); } return(shortestPath); } count++; G.IDictionary <String, Double> neighbors = nodes[currLabel].GetNeighbors(); foreach (String currNeighborLabel in neighbors.Keys) { DijkstraNode neighborNode = predecessorTree.GetNodes()[currNeighborLabel]; Double currDistance = neighborNode.GetDist(); Double newDistance = current.GetDist() + nodes[currLabel].GetNeighbors()[currNeighborLabel]; if (newDistance < currDistance) { DijkstraNode neighbor = predecessorTree.GetNodes()[currNeighborLabel]; pq.remove(neighbor); neighbor.SetDist(newDistance); neighbor.SetDepth(current.GetDepth() + 1); neighbor.SetParent(currLabel); pq.add(neighbor, neighbor.GetDist()); } } } return(null); }