/** * Get the shortest path among all that connecting source with targe. * * @return */ public Path Next() { //3.1 prepare for removing vertices and arcs Path curPath = pathCandidates.Poll(); resultList.Add(curPath); BaseVertex curDerivation = pathDerivationVertexIndex[curPath]; int curPathHash = curPath.GetVertexList().subList(0, curPath.GetVertexList().indexOf(curDerivation)).GetHashCode(); int count = resultList.Count; //3.2 remove the vertices and arcs in the graph for (int i = 0; i < count - 1; ++i) { Path curResultPath = resultList[i]; int curDevVertexId = curResultPath.GetVertexList().indexOf(curDerivation); if (curDevVertexId < 0) { continue; } // Note that the following condition makes sure all candidates should be considered. /// The algorithm in the paper is not correct for removing some candidates by mistake. int pathHash = curResultPath.GetVertexList().subList(0, curDevVertexId).GetHashCode(); if (pathHash != curPathHash) { continue; } BaseVertex curSuccVertex = curResultPath.GetVertexList().get(curDevVertexId + 1); graph.DeleteEdge(new Pair <int, int>( curDerivation.GetId(), curSuccVertex.GetId())); } int pathLength = curPath.GetVertexList().size(); java.util.LinkedList <BaseVertex> curPathVertexList = curPath.GetVertexList(); for (int i = 0; i < pathLength - 1; ++i) { graph.DeleteVertex(curPathVertexList.get(i).GetId()); graph.DeleteEdge(new Pair <int, int>( curPathVertexList.get(i).GetId(), curPathVertexList.get(i + 1).GetId())); } //3.3 calculate the shortest tree rooted at target vertex in the graph DijkstraShortestPathAlg reverseTree = new DijkstraShortestPathAlg(graph); reverseTree.GetShortestPathFlower(targetVertex); //3.4 recover the deleted vertices and update the cost and identify the new candidate results bool isDone = false; for (int i = pathLength - 2; i >= 0 && !isDone; --i) { //3.4.1 get the vertex to be recovered BaseVertex curRecoverVertex = curPathVertexList.get(i); graph.RecoverDeletedVertex(curRecoverVertex.GetId()); //3.4.2 check if we should stop continuing in the next iteration if (curRecoverVertex.GetId() == curDerivation.GetId()) { isDone = true; } //3.4.3 calculate cost using forward star form Path subPath = reverseTree.UpdateCostForward(curRecoverVertex); //3.4.4 get one candidate result if possible if (subPath != null) { ++generatedPathNum; //3.4.4.1 get the prefix from the concerned path double cost = 0; IList <BaseVertex> prePathList = new List <BaseVertex>(); reverseTree.CorrectCostBackward(curRecoverVertex); for (int j = 0; j < pathLength; ++j) { BaseVertex curVertex = curPathVertexList.get(j); if (curVertex.GetId() == curRecoverVertex.GetId()) { j = pathLength; } else { cost += graph.GetEdgeWeightOfGraph(curPathVertexList.get(j), curPathVertexList.get(j + 1)); prePathList.Add(curVertex); } } prePathList.AddAll(subPath.GetVertexList()); //3.4.4.2 compose a candidate subPath.SetWeight(cost + subPath.GetWeight()); subPath.GetVertexList().clear(); subPath.GetVertexList().addAll(prePathList); //3.4.4.3 put it in the candidate pool if new if (!pathDerivationVertexIndex.ContainsKey(subPath)) { pathCandidates.Add(subPath); pathDerivationVertexIndex.Add(subPath, curRecoverVertex); } } //3.4.5 restore the edge BaseVertex succVertex = curPathVertexList.get(i + 1); graph.RecoverDeletedEdge(new Pair <int, int>( curRecoverVertex.GetId(), succVertex.GetId())); //3.4.6 update cost if necessary double cost1 = graph.GetEdgeWeight(curRecoverVertex, succVertex) + reverseTree.GetStartVertexDistanceIndex()[succVertex]; if (reverseTree.GetStartVertexDistanceIndex()[curRecoverVertex] > cost1) { reverseTree.GetStartVertexDistanceIndex().AddOrReplace(curRecoverVertex, cost1); reverseTree.GetPredecessorIndex().AddOrReplace(curRecoverVertex, succVertex); reverseTree.CorrectCostBackward(curRecoverVertex); } } //3.5 restore everything graph.RecoverDeletedEdges(); graph.RecoverDeletedVertices(); return(curPath); }
/** * Obtain the shortest path connecting the source and the target, by using the * classical Dijkstra shortest path algorithm. * * @param sourceVertex * @param targetVertex * @return */ public Path GetShortestPath(BaseVertex sourceVertex, BaseVertex targetVertex) { DijkstraShortestPathAlg dijkstraAlg = new DijkstraShortestPathAlg(graph); return(dijkstraAlg.GetShortestPath(sourceVertex, targetVertex)); }