Описание тега bellman-ford

The Bellman–Ford algorithm computes single-source shortest paths in a weighted digraph. For graphs with only non-negative edge weights, the faster Dijkstra's algorithm also solves the problem. Thus, Bellman–Ford is used primarily for graphs with negative edge weights. The algorithm is named after its developers, Richard Bellman and Lester Ford, Jr.

Overview

Bellman–Ford is in its basic structure very similar to Dijkstra's algorithm, but instead of greedily selecting the minimum-weight node not yet processed to relax, it simply relaxes all the edges, and does this |V | − 1 times, where |V | is the number of vertices in the graph. The repetitions allow minimum distances to accurately propagate throughout the graph, since, in the absence of negative cycles, the shortest path can only visit each node at most once. Unlike the greedy approach, which depends on certain structural assumptions derived from positive weights, this straightforward approach extends to the general case.

Bellman–Ford runs in O(|V|·|E|) time, where |V| and |E| are the number of vertices and edges respectively.

Pseudocode

        BELLMAN-FORD (G, w, s)

            INITIALIZE-SINGLE-SOURCE (G, s)
            for each vertex i = 1 to V[G] - 1 do
                for each edge (u, v) in E[G] do
                    RELAX (u, v, w)
            For each edge (u, v) in E[G] do
                if d[u] + w(u, v) < d[v] then
                    return FALSE
            return TRUE

Implementation Example

This is a simple implementation of the Bellman-Ford algorithm for finding the shortest path from a single source in a graph.

#include <stdio.h>

typedef struct {
    int u, v, w;
} Edge;

int n;                        /* the number of nodes */
int e;                        /* the number of edges */
Edge edges[1024];             /* large enough for n <= 2^5=32 */
int d[32];                    /* d[i] is the minimum distance from node s to node i */

#define INFINITY 10000

void printDist() {
    int i;

    printf("Distances:\n");

    for (i = 0; i < n; ++i)
        printf("to %d\t", i + 1);
    printf("\n");

    for (i = 0; i < n; ++i)
        printf("%d\t", d[i]);

    printf("\n\n");
}

void bellman_ford(int s) {
    int i, j;

    for (i = 0; i < n; ++i)
        d[i] = INFINITY;

    d[s] = 0;

    for (i = 0; i < n - 1; ++i)
        for (j = 0; j < e; ++j)
            if (d[edges[j].u] + edges[j].w < d[edges[j].v])
                d[edges[j].v] = d[edges[j].u] + edges[j].w;
}

int main(int argc, char *argv[]) {
    int i, j;
    int w;

    FILE *fin = fopen("dist.txt", "r");
    fscanf(fin, "%d", &n);
    e = 0;

    for (i = 0; i < n; ++i)
        for (j = 0; j < n; ++j) {
            fscanf(fin, "%d", &w);
            if (w != 0) {
                edges[e].u = i;
                edges[e].v = j;
                edges[e].w = w;
                ++e;
            }
        }
    fclose(fin);

    /* printDist(); */

    bellman_ford(0);

    printDist();

    return 0;
}