我正在尝试实现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;
}
答案 0 :(得分:4)
这是旅行商问题的概括。 TSP出现的情况是所有顶点都是“必须通过”。
找到每对必须通过顶点之间的最短路径,从源到每个必须通过的顶点,以及从每个必须通过的顶点到接收器。然后使用着名的O(n 2 ^ n)动态编程算法为TSP找到满足约束条件的从源到接收器的最短路径;这里n将是两个加上必须通过顶点的数量。
答案 1 :(得分:1)
通过查找必须包含节点和两个(结束和开始)节点之间的最短路径。表格图,然后运行最短路径算法(Dijkstra算法)。开始和结束节点将是相同的。
答案 2 :(得分:1)
不幸的是这个问题被简化为TSP所以不要期望多项式解决方案,但如果没有中间节点那么小,那么你可以像下面这样快速地做到这一点: -
- 尝试每个节点序列都可以访问。
- 说你有s-&gt; a-&gt; b-&gt; c-&gt; d
- 然后使用dijkstra评估min(s,d)+ min(d,a)+ min(c,d)
- 最小距离的序列就是你的答案。
醇>
时间复杂度: O(k!*ElogV)
其中k表示必须传递节点