【问题标题】:Dijkstra in Java implementationJava实现中的Dijkstra
【发布时间】:2016-01-04 10:31:26
【问题描述】:

我已经为一个项目用 java 编写了以下 dijkstra 实现。当我运行测试时,如果 startNode 是 0 节点,它可以正常工作,但如果 startNode 是另一个节点,它就不会。谁能帮助我?不胜感激……

代码如下:

    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];
    }

【问题讨论】:

  • for (int i = startNode; i &lt; 0; i--) 什么都不做。也许改成i &gt;= 0;
  • 由于 Dijkstra 是基于 BFS 的算法,它需要访问所有节点。如果您从不是搜索树的起始节点的地方开始,您将跳过某些节点。您的起始节点应始终为 0,如果您希望另一个节点成为您的起始节点,则需要更改输入树。显然你不必这样做,但从它的外观看你的代码坚持它(我可能错了)
  • 你为什么要把它放在一个不错的 answrr 伙计身上??
  • startNode 为 0 时它什么也不做,我在 startNode 不为 0 时写了这个。
  • 问题是@Glubus,我没有定义哪个 startNode 将是测试,我有 77 个测试要运行。其中 10 个的 startNode 为 0,但其他的没有,这是我的问题。

标签: java graph nodes dijkstra shortest-path


【解决方案1】:

好吧,因为没有人回答你的问题,我想我会尝试的。我没有早点这样做的原因是因为我不确定我是否真的可以回答您的问题,因为我无法立即看到您的代码出现了什么问题。 p>

您说您的问题是您的代码无法处理未标识为 id 0 的起始节点。我认为我可以帮助您的唯一方法是解释我将如何实现 Dijkstra 算法,就像我的方法似乎与您的有所不同。


第 1 步。初始化:

  • 定义您的节点类,将边列表(及其成本/长度)作为成员,这些边表示与作为实例所有者的节点相邻的节点的连接。还要给每个节点一个 ID、一个表示该节点是否被访问的属性、一个确定其当前行进距离的属性以及一个表示其在最佳路径中的前驱节点的属性。
  • 使用两个节点定义边缘类作为定义其端点的成员。还要给它一个持有其成本/长度的属性。
  • 创建一个节点数组或字典,节点 ID 作为键,节点本身作为值。该数组将用作查看已访问或未访问的节点的一种方式。
  • 创建节点的排序数据结构(即二进制堆或优先级队列),用作您可以选择访问的相邻(或打开)节点的列表。确保您的数据结构按照节点从低到高的距离对节点进行排序。
  • 确保所有节点和边的所有成员都已正确设置(即所有邻居都已配置)。您应该能够使用您为问题获得的输入来执行此操作。还将每个节点中经过的每个距离设置为无穷大(或非常高的值)。但是,将起始节点距离设为 0,并将其放在相邻节点数据结构中。

第 2 步。搜索:

  • 从相邻节点数据结构中提取具有最小行进距离(尚未访问)的节点,并将其已访问属性设置为 true。
    • 如果当前访问的节点是您要查找的节点,则停止搜索过程。
  • 对于相邻节点中的每一个节点,查看它们的距离值是否大于当前节点所走过的距离与当前节点与邻居之间的距离之和。

    • 如果是这种情况,请将邻居的行进距离值更新为您刚刚计算的总和,如果节点尚不存在,则将节点添加到开放节点数据结构中(同时确保数据结构更新其顺序)。还将邻居前置节点设置为当前节点。
    • 如果不是这种情况,则该节点已添加到数据结构中,因此您可以保留它。
  • 重复。

第 3 步。回溯

  • 这一步很漂亮:只需创建一个节点列表并将目标节点添加到其中。然后添加目标在上一个过程中设置为其前身的节点。然后对该节点执行相同的操作,并继续执行此操作,直到找到起始节点。然后以首选格式返回列表并拍拍自己的后背以找到最短路径。

现在我知道这个解释包含很多你已经知道的信息,尽管就像我在开始时所说的那样,我不确定你的知识/代码中的问题存在于哪里。希望通过阅读本文,您可以找到所需的内容。如果没有,我会尝试找到更好的解决方案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-04-02
    • 2014-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-12
    • 2022-01-05
    相关资源
    最近更新 更多