Menu
Coddy logo textTech

Algoritmo Bellman-Ford

Última atualização

O Bellman-Ford encontra o caminho mais curto de um nó de origem para todos os outros nós e, ao contrário de Dijkstra, funciona mesmo quando alguns pesos de aresta são negativos. Ele funciona por relaxamento por força bruta: percorre repetidamente cada aresta e, se passar por ela dá uma distância menor, atualiza a distância do nó de destino. Pressione reproduzir acima para ver as distâncias tentativas caírem passagem a passagem.

Após V - 1 passagens sobre todas as arestas, cada caminho mais curto (que pode ter no máximo V - 1 arestas) foi encontrado. Isso o torna O(V · E) - mais lento que Dijkstra, mas lida com pesos negativos e pode detectar um ciclo de peso negativo (se uma V-ésima passagem ainda relaxa uma aresta, não existe caminho mais curto).

Complexidade de tempo e espaço

MedidaComplexidadeNotas
TempoO(V · E)V − 1 passagens sobre todas as E arestas
EspaçoO(V)Uma distância por nó
Pesos negativosSuportadosSua vantagem chave sobre Dijkstra
Ciclos negativosDetectáveisUma V-ésima passagem que relaxa indica um

Passo a passo

PassoO que acontece
1Defina a distância da origem como 0 e todas as outras como infinito.
2Repita o próximo passo V − 1 vezes.
3Para cada aresta (u → v, w), verifique se dist[u] + w < dist[v].
4Se sim, relaxe-a: defina dist[v] = dist[u] + w.
5Pare antes se uma passagem completa não mudar nada.

Exemplo resolvido

Origem S em 4 nós S, A, B, C com arestas S→A (4), S→B (5), A→C (3), B→A (-3), relaxadas nessa ordem. As distâncias começam em S=0 e tudo o mais em :

PassagemDistâncias [S, A, B, C]Ação
Init[0, ∞, ∞, ∞]A distância da origem é 0, todas as outras infinito.
1[0, 2, 5, 7]Relaxa S→A para 4, S→B para 5, A→C para 7, e então B→A baixa A para 5 + (-3) = 2.
2[0, 2, 5, 5]A→C agora melhora C para 2 + 3 = 5; nenhuma outra aresta relaxa.
3[0, 2, 5, 5]Nenhuma aresta relaxa, então as distâncias são finais: A custa 2 via S→B→A.

Quando usar Bellman-Ford

Use quandoEvite quando
Os pesos de aresta podem ser negativos.Todos os pesos são não negativos (Dijkstra é mais rápido).
Você precisa detectar ciclos de peso negativo.O grafo é enorme e denso - O(V · E) é lento demais.
O grafo é pequeno ou esparso.Você só precisa de uma consulta origem-destino em um grafo grande.
Você precisa de uma base simples e fácil de implementar.Os pesos são não negativos e a latência importa.

Código de Bellman-Ford Algorithm

Uma implementação limpa e executável de Bellman-Ford Algorithm em Python, JavaScript, Java, C++, C. Escolha uma linguagem, copie o código ou abra-o já carregado no Playground da Coddy.

Código de Bellman-Ford Algorithm em Python

Python
1def bellman_ford(vertices, edges, start):2    dist = {v: float("inf") for v in vertices}3    dist[start] = 04    # Relax every edge V-1 times5    for _ in range(len(vertices) - 1):6        for u, v, w in edges:7            if dist[u] + w < dist[v]:8                dist[v] = dist[u] + w9    # One more pass: any improvement means a negative cycle10    for u, v, w in edges:11        if dist[u] + w < dist[v]:12            raise ValueError("Graph contains a negative-weight cycle")13    return dist14
15
16vertices = ["A", "B", "C", "D", "E"]17edges = [18    ("A", "B", 6), ("A", "C", 7), ("B", "D", 5), ("B", "E", -4),19    ("C", "D", -3), ("D", "B", -2), ("E", "D", 7),20]21
22for node, d in bellman_ford(vertices, edges, "A").items():23    print(f"A -> {node}: {d}")
Execute este código no Playground de Python

Perguntas frequentes sobre Bellman-Ford

Qual é a complexidade de tempo do Bellman-Ford?
O Bellman-Ford roda em tempo O(V · E): faz V - 1 passagens e cada passagem relaxa todas as E arestas. Isso é mais lento que o O((V + E) log V) de Dijkstra, que é o preço de suportar pesos de aresta negativos.
Quando devo usar Bellman-Ford em vez de Dijkstra?
Use Bellman-Ford quando o grafo puder ter pesos de aresta negativos, ou quando você precisar detectar ciclos de peso negativo. Dijkstra é mais rápido, mas só é correto com pesos não negativos. Um uso real comum é a detecção de arbitragem em câmbio de moedas, onde ciclos negativos importam.
Como o Bellman-Ford detecta um ciclo negativo?
Após as V - 1 passagens de relaxamento, todos os caminhos mais curtos estão finalizados se não existir ciclo negativo. Se mais uma passagem ainda puder relaxar uma aresta, então há um ciclo de peso negativo alcançável, e os caminhos mais curtos ficam indefinidos (você poderia repetir o laço infinitamente para reduzir o custo).
Qual é a diferença entre Bellman-Ford e Floyd-Warshall?
O Bellman-Ford calcula os caminhos mais curtos a partir de uma única origem em O(V · E), enquanto o Floyd-Warshall calcula os caminhos mais curtos entre todos os pares em O(V³). Em um grafo denso, rodar Bellman-Ford a partir de cada origem custa O(V² · E), então Floyd-Warshall costuma ser a melhor escolha quando você precisa de todos os pares. Ambos lidam com arestas negativas e podem sinalizar ciclos negativos.
Por que o Bellman-Ford precisa de exatamente V - 1 passagens?
Qualquer caminho mais curto em um grafo sem ciclos negativos usa no máximo V - 1 arestas, porque um caminho que visita mais de V nós precisa repetir um. Cada passagem garante que pelo menos mais uma aresta de cada caminho mais curto seja relaxada corretamente, então V - 1 passagens bastam para fixar todos. Um equívoco comum é achar que mais passagens melhoram o resultado - nunca melhoram, a menos que exista um ciclo negativo.
O Bellman-Ford pode parar antes?
Sim. Se uma passagem completa sobre todas as arestas não relaxar nada, todas as distâncias já são ótimas e você pode parar antes de atingir as V - 1 passagens. Essa otimização de saída antecipada costuma torná-lo muito mais rápido em grafos que convergem cedo, embora o limite de pior caso continue sendo O(V · E).
Coddy programming languages illustration

Domine algoritmos com a Coddy

COMEÇAR