我正在尝试实现Dijkstra的算法,该算法可以找到起始节点和结束节点之间的最短路径。在到达末端节点之前,有一些“必须通过”的中间节点(不止一个),例如2或3个必须通过的节点,这些节点必须在到达末端节点之前通过。
如果我有一个必须通过节点,则找到的解决方案是找到从必须通过节点到目的地以及从必须通过节点到开始节点的两条不同路径。
我不知道如何实现这种算法。有什么建议?
谢谢。
List<Node> closestPathFromOrigin = null; double maxD = Double.POSITIVE_INFINITY; double _distance = 0; int temp1 = 0; List<Node> referencePath = new ArrayList<>(); boolean check = false; Node startNode = null; public List<Node> recursion(ArrayList<Node> points, ArrayList<Node> intermediatePoints) { if (!check) { System.out.println("--- DATA ---"); System.out.println("Intermediate points: " + intermediatePoints); System.out.println("points: " + points.get(0).lat + " " + points.get(1).lat); System.out.println("--Find the nearest intermediate point from the start point of driver--"); startNode = points.get(0); System.out.println("Start point of driver: " + startNode.lat + " " + startNode.lon); for (int i = 0; i < intermediatePoints.size(); i++) { List<Node> _path = dijkstra(startNode, intermediatePoints.get(i)); _distance = 0; for (int j = 0; j < _path.size() - 1; j++) { _distance += calculateDistance(_path.get(j), _path.get(j + 1)); } if (_distance < maxD) { maxD = _distance; closestPathFromOrigin = _path; temp1 = i; } } System.out.println("NearestPoint from driver's origin: " + intermediatePoints.get(temp1)); referencePath.addAll(closestPathFromOrigin); startNode = intermediatePoints.get(temp1); System.out.println("New StartNode: the nearestPoint from driver's origin: " + startNode.lat + " " + startNode.lon); check = true; intermediatePoints.remove(intermediatePoints.get(temp1)); System.out.println("New Intermediate points: " + intermediatePoints); System.out.println("Intermediate points empty? No -> recursion, Yes -> stop"); if (!intermediatePoints.isEmpty()) { System.out.println("Recursion!!! with new data of: intermediatePoints: " + intermediatePoints); recursion(points, intermediatePoints); } else { System.out.println("Stop"); return referencePath; } } else { System.out.println("Recursion: startNode: " + startNode.lat + " " + startNode.lon); for (int i = 0; i < intermediatePoints.size(); i++) { if (intermediatePoints.size() > 1) { System.out.println("From the new start point to the next nearest intermediate points if more than one points"); List<Node> _path = dijkstra(startNode, intermediatePoints.get(i)); _distance = 0; for (int j = 0; j < _path.size() - 1; j++) { _distance += calculateDistance(_path.get(j), _path.get(j + 1)); } if (_distance < maxD) { maxD = _distance; closestPathFromOrigin = _path; temp1 = i; } referencePath.addAll(closestPathFromOrigin); startNode = intermediatePoints.get(temp1); check = true; intermediatePoints.remove(intermediatePoints.get(temp1)); if (!intermediatePoints.isEmpty()) { recursion(points, intermediatePoints); } else { return referencePath; } } else { System.out.println("From the new start point to the next nearest intermediate points if just one point"); List<Node> _path = dijkstra(startNode, intermediatePoints.get(i)); //Collections.reverse(_path); referencePath.addAll(_path); } if (i == intermediatePoints.size() - 1) { System.out.println("Last Entry in intermediate points - find path to destination: " + points.get(1).lat + " " + intermediatePoints.get(i)); //List<Node> _path1 = dijkstra(points.get(1), intermediatePoints.get(i)); List<Node> _path1 = dijkstra(intermediatePoints.get(i), points.get(1)); Collections.reverse(_path1); referencePath.addAll(_path1); // referencePath.addAll(_path2); } } } return referencePath; }
这是旅行商问题的一般化。当所有顶点都是“必须通过”时,TSP出现。
在每对必须通过的顶点之间找到最短路径,从源到每个必须通过的顶点,再从每个必须通过的顶点到接收点。然后使用著名的O(n 2 ^ n)动态规划算法进行TSP,找到从源到宿的最短路径以满足您的约束。这里n将是两个加上必须通过的顶点数。