简体   繁体   English

Dijkstra在Java实现中

[英]Dijkstra in Java implementation

I have written the following dijkstra implementation in java for a project. 我已经在Java中为项目编写了以下dijkstra实现。 When I run the tests it works fine if the startNode is the 0 node but if the startNode is another one it just doesn't. 当我运行测试时,如果startNode是0节点,则工作正常,但是如果startNode是另一个节点,则它不是。 Could anyone help me? 有人可以帮我吗? I would be grateful... 我会很感激...

Here is the code: 这是代码:

    double[][] nodesDistance = new double[graph.getNumOfNodes()][graph.getNumOfNodes()];
    double[] distance = new double[graph.getNumOfNodes()];
    int[] preD = new int [graph.getNumOfNodes()];
    int[] visited = new int [graph.getNumOfNodes()];

    double min;
    int nextNode = 0;

    for (int i = startNode; i < 0; i--) {

        visited[i] = 0; 
        preD[i] = 0;

        for (int j = startNode; j < 0; j--) {

            if (graph.existsEdge(i, j) == true) {

                nodesDistance[i][j] = graph.getEdgeDistance(i, j);
            }else {

                nodesDistance[i][j] = Double.POSITIVE_INFINITY;
            }
        }
    }

    for (int i = startNode; i < graph.getNumOfNodes(); i++) {

        visited[i] = 0; 
        preD[i] = 0;

        for (int j = startNode; j < graph.getNumOfNodes(); j++) {

            if (graph.existsEdge(i, j) == true) {

                nodesDistance[i][j] = graph.getEdgeDistance(i, j);
            }else {

                nodesDistance[i][j] = Double.POSITIVE_INFINITY;
            }
        }
    }
    distance = nodesDistance[startNode];
    distance[startNode] = 0;
    visited[startNode] = 1;

    for (int i = startNode; i < 0; i--) {

        min = 999.0;

        for (int j = startNode; j < 0; j--) {

            if ((min > distance[j]) && (visited[j] != 1)) {

                min = distance[j];
                nextNode = j;
            }
        }

        visited[nextNode] = 1;

        for (int c = startNode; c < 0; c--) {

            if (visited[c] != 1) {

                if (min + nodesDistance[nextNode][c] < distance[c]) {

                    distance[c] = min + nodesDistance[nextNode][c];
                    preD[c] = nextNode;
                }
            }
        }
    }

    for (int i = startNode; i < graph.getNumOfNodes(); i++) {

        min = 999.0;

        for (int j = startNode; j < graph.getNumOfNodes(); j++) {

            if ((min > distance[j]) && (visited[j] != 1)) {

                min = distance[j];
                nextNode = j;
            }
        }

        visited[nextNode] = 1;

        for (int c = startNode; c < graph.getNumOfNodes(); c++) {

            if (visited[c] != 1) {

                if (min + nodesDistance[nextNode][c] < distance[c]) {

                    distance[c] = min + nodesDistance[nextNode][c];
                    preD[c] = nextNode;
                }
            }
        }
    }

    for (int i = 0; i < graph.getNumOfNodes(); i++) {

        result.nodeDistance[i] = distance[i];
        result.nodeThrough[i] = preD[i];
    }

Alright well since noone answered your question I guess I will try to. 好吧,因为没有人回答您的问题,我想我会尽力的。 The reason I didn't do it sooner is because I wasn't sure about whether or not I could in fact answer your question since I can't right away see what the problem is arising from your code. 我没有早点做的原因是因为我不确定我是否真的可以回答您的问题,因为我无法立即看到问题是由您的代码引起的。

You say your problem is that your code can't deal with a starting node not being identified with id 0. The only way i think I can help you is by just explaining how I would implement Dijkstra's algorithm, as my approach seems to differ somewhat from yours. 您说您的问题是您的代码无法处理未标识为ID 0的起始节点。我认为我能为您提供帮助的唯一方法是仅说明我将如何实现Dijkstra的算法,因为我的方法似乎有所不同从你的。


Step 1. Initialization: 步骤1.初始化:

  • Define your node class with as a member a list of edges (with their cost/length) that represent the connections to the nodes that are adjacent to the node that is the owner of the instance. 用边缘列表(及其成本/长度)作为节点成员来定义您的节点类,这些边缘列表表示与实例所有者所在节点相邻的节点的连接。 Also give each node an ID, a property that represents whether or not the node is visited, a property that determines its current distance travelled, and a property that represents its predecessor node in the optimal path. 还为每个节点提供一个ID,一个表示是否已访问该节点的属性,一个确定其当前行进距离的属性以及一个表示其最佳路径中先前节点的属性。
  • Define your edge class with two nodes as members that define its endpoints. 用两个节点定义边缘类作为定义其端点的成员。 Also give it a property that holds its cost/length. 还给它一个保留其成本/长度的属性。
  • Create an array or dictionary of nodes with the nodes ID as keys and the nodes themselves as value. 创建一个节点数组或字典,其中节点ID为键,节点本身为值。 This array will function as a way of seeing which node has been visited or not. 该数组将用作查看已访问或未访问哪个节点的方式。
  • Create a sorting datastructure (ie a binary heap or priorityqueue) of nodes that will function as the list of adjacent (or open) nodes that you can choose to visit. 创建节点的排序数据结构(即二进制堆或优先级队列),将其用作您可以选择访问的相邻(或开放)节点的列表。 Make sure that your datastructure sorts the nodes by their distance travelled from low to high. 确保您的数据结构按从低到高的距离对节点进行排序。
  • Make sure that all members of all nodes and edges have been set correctly (ie all neighbours have been configured). 确保正确设置了所有节点和边缘的所有成员(即,已配置所有邻居)。 You should be able to do this with the input you get for the problem. 您应该能够使用针对问题获得的输入来执行此操作。 Also set every distance travelled in each node to infinity (or something really high). 还要将每个节点中经过的每个距离设置为无穷大(或很高)。 However, give the starting node distance 0, and place it in the adjacent nodes datastructure. 但是,将起始节点距离设置为0,并将其放置在相邻节点的数据结构中。

Step 2. Searching: 第2步:搜索:

  • Extract the node with the minimum distance travelled (that has not yet been visited) from the adjacent nodes datastructure and set its visisted property to true. 从相邻节点数据结构中提取出具有最小行进距离(尚未访问)的节点,并将其visisted属性设置为true。
    • If the current visited node is the node you were looking for, stop the searching procedure. 如果当前访问的节点是您要查找的节点,请停止搜索过程。
  • For each of the nodes adjacent nodes, see if their distance travelled value is higher than the sum of the distance travelled by the current node, and the distance between the current node and the neighbour. 对于相邻节点中的每个节点,请查看它们的行进距离值是否大于当前节点行进的距离以及当前节点与邻居之间的距离之和。

    • If this is the case, update the neighbours distance travelled value to the sum you just calculated, and add the node to the open nodes datastructure if it was not already in there (also make sure the datastructure updates its order). 如果是这种情况,请将邻居距离旅行的值更新为刚计算出的总和,然后将该节点添加到开放节点数据结构中(如果尚未存在)(还要确保该数据结构更新其顺序)。 Also set the neighbours predecessor node to the current node. 还将邻居的前任节点设置为当前节点。
    • If this is not the case, then the node has been already added to the datastructure, so you can leave it be. 如果不是这种情况,则该节点已经被添加到数据结构中,因此您可以保留它。
  • Repeat. 重复。

Step 3. Backtracing 步骤3.回溯

  • This step is pretty: just create an list of nodes and add the goal node to it. 这一步很漂亮:只需创建节点列表并将目标节点添加到其中即可。 Then add the node that the goal has set as its predecessor in the previous procedure. 然后,在上一过程中将目标已设置为前一节点的节点添加。 Then do the same for that node, and keep doing this untill you find the starting node. 然后对该节点执行相同操作,并继续执行此操作,直到找到起始节点为止。 Then return the list in the preferred format and pat yourself on the back for finding the shortest path. 然后以首选格式返回列表,并轻拍背面以找到最短路径。

Now I know this explanation contains a lot of information you already knew, though like I said at the start, I wasn't sure where the problem in your knowledge/code existed. 现在,我知道这个解释包含了许多您已经知道的信息,尽管就像我刚开始所说的那样,我不确定您的知识/代码中的问题是否存在。 Hopefully by reading this you can find what you need. 希望通过阅读本文可以找到所需的内容。 If not, I'll try to find a better solution. 如果没有,我将尝试找到更好的解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM