簡體   English   中英

貝爾曼福特圖算法

[英]Bellman Ford graph algorithm

我有一個作業來實現貝爾曼福特的算法並在一些圖表上對其進行測試。 我實現了該算法,在 3 個圖表中的 2 個上對其進行了測試,並且它可以工作。 但是在第三張圖上,我在調用 function 時沒有 output。

Graph* temaTrecuta = createGraph(10, 12);
addOrientedEdge(temaTrecuta, 0, 0, 1, 5);
addOrientedEdge(temaTrecuta, 1, 1, 2, 3);
addOrientedEdge(temaTrecuta, 2, 2, 3, 5);
addOrientedEdge(temaTrecuta, 4, 3, 9, 5);
addOrientedEdge(temaTrecuta, 5, 1, 9, 1);
addOrientedEdge(temaTrecuta, 6, 3, 4, 1);
addOrientedEdge(temaTrecuta, 7, 4, 8, 5);
addOrientedEdge(temaTrecuta, 8, 8, 7, 1);
addOrientedEdge(temaTrecuta, 9, 7, 5, 1);
addOrientedEdge(temaTrecuta, 10, 7, 6, 3);
addOrientedEdge(temaTrecuta, 11, 6, 0, 1);

這部分創建圖形及其邊緣。 createGraph function 將頂點和邊的數量作為參數。

void addOrientedEdge(Graph* graph, int index, int source, int destination, int cost) {
    graph->edge[index].src = source;
    graph->edge[index].dest = destination;
    graph->edge[index].cost = cost;

    graph->matrix[source][destination] = cost;
}

這是增加了新邊緣的 function。

下面是我對貝爾曼福特算法的實現。

void bellmanFord(Graph* gr, int src) {
    int* dist = (int*)malloc(sizeof(int) * gr->V);
    int* path = (int*)malloc(sizeof(int) * gr->V);

    if (!path || !dist) {
        printf("Nu am putut aloca.\n");
        exit(1);
    }

    for (int i = 0; i < gr->V; ++i) {
        dist[i] = INT_MAX;
        path[i] = 0;
    }

    path[src] = -1;

    dist[src] = 0;

    for (int i = 1; i <= gr->V - 1; ++i) {
        for (int j = 0; j < gr->E; ++j) {
            int m = gr->edge[j].src;
            int n = gr->edge[j].dest;
            int cost = gr->edge[j].cost;

            if (dist[m] != INT_MAX && dist[m] + cost < dist[n]) {
                dist[n] = dist[m] + cost;
                path[n] = m; 
            }
        }
    }

    for (int i = 0; i < gr->E; ++i) {
        int m = gr->edge[i].src;
        int n = gr->edge[i].dest;
        int cost = gr->edge[i].cost;

        if (dist[m] != INT_MAX && dist[m] + cost < dist[n]) {
            printf("Exista un ciclu negativ.");
            return;
        }
    }

    printBellmanSol(dist, gr->V, path);

    free(dist);
    free(path);
}

由於沒有引用邊緣索引,只要它是唯一且連續的,您應該考慮自動遞增。 除了邊緣索引E ,還有一個新的邊緣容量。 這是傳遞給createGraph的數字,最初設置計數器E = 0 你可以用少一個參數來編寫你的addOrientedEdge 取下一個邊緣索引。

static void addOrientedEdge(struct Graph* graph, int source, int destination, int cost) {
    const int index = graph->E;
    assert(graph && graph->E < graph->E_capacity);
    graph->edge[index].src = source;
    graph->edge[index].dest = destination;
    graph->edge[index].cost = cost;
    graph->E++;
    graph->matrix[source][destination] = cost;
}

這將使您不必擔心邊緣數字。

缺少導致問題的邊緣。 感謝@user3386109 看到它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM