【问题标题】:Dijkstra algorithm implemented in C++ and converted to Java用 C++ 实现并转换为 Java 的 Dijkstra 算法
【发布时间】:2013-05-28 18:30:48
【问题描述】:

请帮我解决这个问题: 我正在尝试将 Dijkstra 算法(由教授用 C++ 实现)翻译成 Java,但它不起作用。

int     *cost = new int[numVert],
        *frj = new int[numVert],
        *parent = new int[numVert],
         w, w0;

for (w = 0; w < numVert; w++) {
    parent[w] = -1;
    cost[w] = matrizAdj[_vertInicial][w];
    frj[w] = _vertInicial;
}

parent[_vertInicial] = _vertInicial;
cost[_vertInicial] = 0;

while (1) {
    int mincost = -1;
    for (w = 0; w < numVert; w++) {
        if (parent[w] != -1 || cost[w] == 0)
            continue; // vert ja alcancado ou nao possui aresta com vert atual.

        // se menor que mincost ou mincost == infinito
        if (mincost > cost[w] || mincost == -1)
            mincost = cost[w0 = w];
    }
    if (mincost == -1) break;
    parent[w0] = frj[w0];
    for (w = 0; w < numVert; w++)
        if (cost[w] > cost[w0] + matrizAdj[w0][w]) {
            cost[w] = cost[w0] + matrizAdj[w0][w];
            frj[w] = w0;
        }
}

for (w = 0; w < numVert; w++)
    cout << " " << parent[w];

教授的版本运行良好。最后,它会打印一个父节点列表,其中 parent[w] 是节点 w 的父节点。

输出示例:0 1 2 0 0 1 0 4 0 2 0。

好吧,我用 Java 编写了这段代码:

double mincost, cost[] = new double[_m.length];
int frj[], parent[], w0;

frj = new int[_m.length];
parent = new int[_m.length];

for (int w = 0; w < _m.length; w++) {
    parent[w] = -1;
    cost[w] = _m[_root][w];
    frj[w] = _root;
}

parent[_root] = _root;
cost[_root] = 0;
w0 = 0;

while (true) {
    mincost = -1;

    for (int w = 0; w < _m.length; w++) {
        if (parent[w] != -1 || cost[w] == 0) {
            continue;
        }

        if (mincost > cost[w] || mincost == -1) {
            mincost = cost[w0 = w];
        }
    }

    if (mincost == -1) {
        break;
    }

    parent[w0] = frj[w0];
    for (int w = 0; w < _m.length; w++) {
        if (cost[w] > cost[w0] + _m[w0][w]) {
            cost[w] = cost[w0] + _m[w0][w];
            frj[w] = w0;
        }
    }
}

for (int i = 0; i < parent.length; i++) {
    System.out.print(" " + parent[i]);
}

这基本上是一样的,除了我的版本使用 double 来定义成本(边权重)。 (双精度值非常接近整数,所以我怀疑这是导致问题的原因)。 最后,它打印出父列表,但列表中的元素始终是_root 值。换句话说,条件"if (cost[w] &gt; cost[w0] + _m[w0][w])" 总是false(这显然是错误的!)。

输出示例:

0 0 0 0 0 0 0 0 0 0 0.

我错过了这里的某个地方吗?我是不是写错了什么?我试图在这个代码中找到大约一小时的错误,但它们看起来一样......

谢谢!

【问题讨论】:

  • 这看起来很糟糕。您最好从头开始实施它。
  • 到目前为止,您尝试了哪些方法来调试此代码?贴一堵代码并说“找到其中的问题”根本不可能让人想帮助你。
  • 双精度数不是整数;这可能会导致问题。另外,_m[][] 声明在哪里?
  • 这甚至不是 Dijkstra。在我看来,它更像是贝尔曼福特。
  • 您的输入在哪里(即_m)?

标签: java c++ graph dijkstra


【解决方案1】:

我测试了你的算法,它似乎工作得很好。我使用了来自 here 的示例图,它返回了预期的结果。

示例图(和判断矩阵):

      b       d
      O-------O
     /|\      |\             0,    2,    3, 1000, 1000, 1000
   2/ | \3    | \2           2,    0,    6,    5,    3, 1000
   /  |  \   1|  \           3,    6,    0, 1000,    1, 1000
a O   |   \   |   O z     1000,    5, 1000,    0,    1,    2
   \  |6   \  |  /        1000,    3,    1,    1,    0,    4
   3\ |     \ | /4        1000, 1000, 1000,    2,    4,    0
     \|      \|/
      O-------O
      c       d

父母输出:

0 0 0 4 2 3

另请参阅此short demo。

根据以上事实,您的输入(_m)一定有问题。

【讨论】:

  • 您好!是的,我开始测试随机创建的图表,一切都很顺利。但是 _m 参数工作正常。
  • 是的,我认为 _m 也可能是错误的,但打印图形 _m 显示了正确的输出。然后我搜索了一个带有整数边权重的图,并在两种语言上都进行了尝试。两者都返回相同的结果:一个带有零的列表。所以我意识到我正在测试欧几里得图(dijkstra 永远不会改变父列表,因为两个节点之间的最短路径是它们之间的边)。这么早没看明白我觉得很傻,所以我真诚地为打扰各位道歉。感谢每一个人!
猜你喜欢
  • 2014-06-23
  • 1970-01-01
  • 2019-04-02
  • 1970-01-01
  • 2022-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多