在图表中打印所有可能的最短路径

时间:2014-05-22 14:17:52

标签: c dijkstra

我正在编写一些代码,使用Dijkstra算法的修改版本打印图表中所有可能的最短路径。在经典实现中,您有一个存储每个节点的前导的数组,我创建了一个矩阵,您可以在其中为每个节点使用多个前驱,这样您就可以遵循从节点到源的多个路径。 问题是,我无法弄清楚如何打印它。我编写了这段代码,但它没有提供正确的解决方案:

void print(graph grf, int node) {
    int n;
    if (grf->preds[node][0] == NIL) {
        printf("\n%i", node);
        return;
    }
    else {
        for (n = 0; n<grf->number; n++) {
            if (grf->preds[node][n] != NIL) {
                print(grf, grf->preds[node][n]);
                printf("->%i", node);
            }
        }
    }
    return;
}

它打印以下解决方案:

1->0
1->9->8
1->3->7
1->0->7->8->2
1->3
1->9->4
1->3->5
1->0->5
1->3->7
1->0->7->6
1->9->8
1->3->7
1->0->7->8->6
1->3->7
1->0->7
1->9->8
1->3->7
1->0->7->8
1->9

虽然这是正确的(请注意,顺序并不重要):

1->9
1->9->8
1->9->8->6
1->9->8->2
1->9->4
1->3
1->3->7
1->3->7->8
1->3->7->8->6
1->3->7->8->2
1->3->7->6
1->3->5
1->0
1->0->7
1->0->7->8
1->0->7->8->6
1->0->7->8->2
1->0->7->6
1->0->5

我认为这是因为当你有两个可能的前任并且你从另一个电话回来时,for循环再次调用该函数,但我不知道如何避免这种情况并且仍然有一个简单而良好的工作代码。

我的一个建议是使用BFS或DFS打印路径,但我还没有理解。

1 个答案:

答案 0 :(得分:0)

好的,如果有人有兴趣我解决了这个问题。我创建了一个临时数组,我在其中存储路径,当函数到达终点时,它会打印所有数组。有一个变量在每次调用时递增,它存储递归的深度,并对数组中存储节点的位置的函数说。 这是代码:

void stampa(p_grafo grf, int nodo, int depth) {
int contatore, i;
if (grf->preds[nodo][0] == NIL) {
    printf("%i", nodo);
    for(i=grf->numero-1;i>=0;i--)
        if(grf->temp[i]!=NIL)
            printf("->%i", grf->temp[i]);
    printf("\n");
    return;
}
else {
    for (contatore = 0; contatore<grf->numero; contatore++) {
        if (grf->preds[nodo][contatore] != NIL) {
            grf->temp[depth]=nodo;
            stampa(grf, grf->preds[nodo][contatore], depth+1);
        }
    }
}
return;
}