Java 迪克斯特拉';带';必须通过';节点

Java 迪克斯特拉';带';必须通过';节点,java,algorithm,dijkstra,depth-first-search,Java,Algorithm,Dijkstra,Depth First Search,我正在尝试实现Dijkstra算法,该算法可以找到起始节点和结束节点之间的最短路径。在到达结束节点之前,有一些“必须通过”中间节点(不止一个),例如2或3个必须通过的节点,它们必须在到达结束节点之前通过 如果我有一个必须传递节点,我找到的解决方案是找到从必须传递节点到目的地和从必须传递节点到开始节点的两条不同路径 我不知道如何实现这样的算法。 有什么建议吗 谢谢 List<Node> closestPathFromOrigin = null; double maxD = Doubl

我正在尝试实现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;
}
List closestPathFromOrigin=null;
double maxD=double.POSITIVE_无穷大;
双倍距离=0;
int temp1=0;
List referencePath=new ArrayList();
布尔检查=假;
节点startNode=null;
公共列表递归(ArrayList点、ArrayList中间点){
如果(!检查){
System.out.println(“--DATA--”);
System.out.println(“中间点:“+中间点”);
System.out.println(“点:”+points.get(0.lat+”+points.get(1.lat));
System.out.println(“--找到距离驱动程序--”起点最近的中间点”;
startNode=points.get(0);
System.out.println(“驱动程序的起点:+startNode.lat+”+startNode.lon);
对于(int i=0;i递归,是->停止”);
如果(!intermediatePoints.isEmpty()){
System.out.println(“递归!!!使用新数据:中间点:“+intermediatePoints”);
递归(点、中间点);
}否则{
系统输出打印项次(“停止”);
返回referencePath;
}
}否则{
System.out.println(“递归:startNode:+startNode.lat+”+startNode.lon);
对于(int i=0;i1){
System.out.println(“从新起点到下一个最近的中间点,如果超过一个点”);
List _path=dijkstra(startNode,intermediatePoints.get(i));
_距离=0;
对于(int j=0;j<_path.size()-1;j++){
_距离+=计算距离(_path.get(j),_path.get(j+1));
}
如果(_距离<最大值){
最大距离=_距离;
closestPathFromOrigin=\u路径;
temp1=i;
}
referencePath.addAll(closestPathFromOrigin);
startNode=intermediatePoints.get(temp1);
检查=正确;
mediatePoints.remove(mediatePoints.get(temp1));
如果(!intermediatePoints.isEmpty()){
递归(点、中间点);
}否则{
返回referencePath;
}
}否则{
System.out.println(“从新起点到下一个最近的中间点,如果只有一个点”);
List _path=dijkstra(startNode,intermediatePoints.get(i));
//Collections.reverse(_路径);
referencePath.addAll(_路径);
}
if(i==intermediatePoints.size()-1){
System.out.println(“中间点中的最后一个条目-查找到目的地的路径:”+points.get(1.lat+”+intermediatePoints.get(i));
//List_path1=dijkstra(points.get(1),intermediatePoints.get(i));
List_path1=dijkstra(intermediatePoints.get(i),points.get(1));
集合。反向(路径1);
referencePath.addAll(_path1);
//referencePath.addAll(_path2);
}
}
}
返回referencePath;
}

这是旅行推销员问题的推广。TSP出现在所有顶点都是“必须通过”的情况下


查找每对必须通过顶点之间、从源到每个必须通过顶点以及从每个必须通过顶点到汇的最短路径。然后使用著名的O(n2^n)动态规划算法求解TSP,找到满足约束条件的从源到汇的最短路径;这里n是两个加上必须经过的顶点数。

通过查找必须包含节点和两个(结束和开始)节点之间的最短路径。形成图形,然后运行最短路径算法(Dijkstra算法)。开始节点和结束节点将是相同的。

不幸的是,此问题被简化为TSP,因此不要期望多项式解决方案,但如果中间节点不小,则可以按如下方式合理快速地执行此操作:-

  • 尽可能尝试访问每个节点序列
  • 假设你有s->a->b->c->d
  • 然后用dijkstra计算min(s,d)+min(d,a)+min(c,d)
  • 有最小距离的序列就是你的答案
  • 时间复杂度:
    O(k!*ElogV)
    其中k不是mus