Menu
Coddy logo textTech

Algoritmo Bellman-Ford

Última actualización

Bellman-Ford encuentra el camino más corto desde un nodo origen hacia todos los demás nodos y, a diferencia de Dijkstra, funciona incluso cuando algunos pesos de arista son negativos. Funciona mediante relajación por fuerza bruta: recorre repetidamente cada arista y, si pasar por esa arista da una distancia menor, actualiza la distancia del nodo destino. Pulsa reproducir arriba para ver cómo bajan las distancias tentativas pasada a pasada.

Tras V - 1 pasadas sobre todas las aristas, se ha encontrado cada camino más corto (que puede tener como máximo V - 1 aristas). Esto lo hace O(V · E) - más lento que Dijkstra, pero maneja pesos negativos y puede detectar un ciclo de peso negativo (si una pasada V-ésima aún relaja una arista, no existe camino más corto).

Complejidad temporal y espacial

MedidaComplejidadNotas
TiempoO(V · E)V − 1 pasadas sobre todas las E aristas
EspacioO(V)Una distancia por nodo
Pesos negativosCompatibleSu ventaja clave frente a Dijkstra
Ciclos negativosDetectablesUna V-ésima pasada que relaja indica uno

Paso a paso

PasoQué ocurre
1Fija la distancia del origen en 0 y las demás en infinito.
2Repite el siguiente paso V − 1 veces.
3Para cada arista (u → v, w), comprueba si dist[u] + w < dist[v].
4Si es así, relájala: fija dist[v] = dist[u] + w.
5Detente antes si una pasada completa no cambia nada.

Ejemplo resuelto

Origen S sobre 4 nodos S, A, B, C con aristas S→A (4), S→B (5), A→C (3), B→A (-3), relajadas en ese orden. Las distancias empiezan en S=0 y todo lo demás en :

PasadaDistancias [S, A, B, C]Acción
Init[0, ∞, ∞, ∞]La distancia del origen es 0, todas las demás infinito.
1[0, 2, 5, 7]Relaja S→A a 4, S→B a 5, A→C a 7, y luego B→A baja A a 5 + (-3) = 2.
2[0, 2, 5, 5]A→C ahora mejora C a 2 + 3 = 5; ninguna otra arista se relaja.
3[0, 2, 5, 5]Ninguna arista se relaja, así que las distancias son definitivas: A cuesta 2 vía S→B→A.

Cuándo usar Bellman-Ford

Úsalo cuandoEvítalo cuando
Los pesos de arista pueden ser negativos.Todos los pesos son no negativos (Dijkstra es más rápido).
Debes detectar ciclos de peso negativo.El grafo es enorme y denso - O(V · E) es demasiado lento.
El grafo es pequeño o disperso.Solo necesitas una consulta origen-destino en un grafo grande.
Necesitas una base sencilla y fácil de implementar.Los pesos son no negativos y la latencia importa.

Código de Bellman-Ford Algorithm

Una implementación limpia y ejecutable de Bellman-Ford Algorithm en Python, JavaScript, Java, C++, C. Elige un lenguaje, copia el código o ábrelo ya cargado en el Playground de Coddy.

Código de Bellman-Ford Algorithm en 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}")
Ejecuta este código en el Playground de Python

Preguntas frecuentes sobre Bellman-Ford

¿Cuál es la complejidad temporal de Bellman-Ford?
Bellman-Ford se ejecuta en tiempo O(V · E): hace V - 1 pasadas y cada pasada relaja las E aristas. Eso es más lento que el O((V + E) log V) de Dijkstra, que es el precio de admitir pesos de arista negativos.
¿Cuándo debería usar Bellman-Ford en lugar de Dijkstra?
Usa Bellman-Ford cuando el grafo pueda tener pesos de arista negativos, o cuando necesites detectar ciclos de peso negativo. Dijkstra es más rápido pero solo es correcto con pesos no negativos. Un uso real común es la detección de arbitraje en cambio de divisas, donde importan los ciclos negativos.
¿Cómo detecta Bellman-Ford un ciclo negativo?
Tras las V - 1 pasadas de relajación, todos los caminos más cortos quedan finalizados si no existe un ciclo negativo. Si una pasada más aún puede relajar una arista, entonces hay un ciclo de peso negativo alcanzable, y los caminos más cortos quedan indefinidos (podrías repetir el bucle eternamente para reducir el coste).
¿Cuál es la diferencia entre Bellman-Ford y Floyd-Warshall?
Bellman-Ford calcula los caminos más cortos desde un único origen en O(V · E), mientras que Floyd-Warshall calcula los caminos más cortos entre todos los pares en O(V³). En un grafo denso, ejecutar Bellman-Ford desde cada origen cuesta O(V² · E), así que Floyd-Warshall suele ser la mejor opción cuando necesitas todos los pares. Ambos manejan aristas negativas y pueden señalar ciclos negativos.
¿Por qué Bellman-Ford necesita exactamente V - 1 pasadas?
Cualquier camino más corto en un grafo sin ciclos negativos usa como máximo V - 1 aristas, porque un camino que visite más de V nodos debe repetir uno. Cada pasada garantiza que se relaja correctamente al menos una arista más de cada camino más corto, así que V - 1 pasadas bastan para fijarlos todos. Un error común es creer que más pasadas mejoran el resultado - nunca lo hacen, salvo que exista un ciclo negativo.
¿Puede Bellman-Ford detenerse antes?
Sí. Si una pasada completa sobre todas las aristas no relaja nada, todas las distancias ya son óptimas y puedes detenerte antes de alcanzar las V - 1 pasadas. Esta optimización de salida anticipada suele hacerlo mucho más rápido en grafos que convergen pronto, aunque la cota en el peor caso sigue siendo O(V · E).
Coddy programming languages illustration

Domina los algoritmos con Coddy

COMENZAR