Caminos mínimos entre todos los pares
Floyd-Warshall resuelve las distancias entre todos los pares con tres ciclos anidados y una idea: permitir un vértice intermedio más por vez.
Para este tema conviene tener claro:Programación dinámica desde la recursión
Si hace falta la distancia entre todos los pares de vértices, correr Dijkstra desde cada uno es una opción razonable. Pero hay un algoritmo de tres ciclos anidados y cinco líneas que resuelve lo mismo, incluso con pesos negativos, y su idea central se explica en una frase.
Programación dinámica sobre los intermedios permitidos
Floyd-Warshall es programación dinámica sobre qué vértices se permiten como intermedios. El estado es: la mejor distancia de a usando sólo los primeros vértices como escalas.
Al habilitar el vértice , para cada par hay dos opciones: el camino no lo usa y queda igual, o lo usa y se parte en dos tramos que ya están calculados:
Antes de seguir, predecí
Tres ciclos, y un orden que no se puede alterar
Eso se escribe como tres ciclos sobre una matriz, y hay un orden que no se puede alterar: el ciclo de va afuera, y los de y adentro. Con adentro, el algoritmo mezcla estados de distintas etapas y da resultados incorrectos.
La otra sutileza es que no hace falta mantener dos matrices, una por etapa. Actualizar sobre la misma es correcto, porque la fila y la columna no cambian durante la iteración : ese detalle es lo que reduce la memoria a .
Distancias directas. ∞ significa que no hay arista.
Cuándo conviene contra correr Dijkstra V veces
El costo es pase lo que pase, sin importar cuántas aristas haya. La comparación con correr Dijkstra veces —— depende de la densidad: en grafos densos Floyd-Warshall gana, en ralos pierde.
Lo que siempre gana es en simplicidad y en constantes: es una matriz y tres ciclos sobre memoria contigua, sin colas de prioridad ni listas de adyacencia.
Pesos negativos y ciclos, leídos en la diagonal
Acepta pesos negativos sin cambios, cosa que Dijkstra no. Y detecta ciclos negativos con una lectura: si algún elemento de la diagonal quedó menor que cero, hay un ciclo que vuelve al mismo vértice con costo negativo.
Si hay ciclos negativos, el resto de los valores deja de tener sentido y conviene cortar ahí. La alternativa cuando el grafo es ralo y tiene negativos es Johnson: reetiqueta los pesos con Bellman-Ford para volverlos no negativos y después corre Dijkstra desde cada vértice.
Reconstruir el camino, no sólo la distancia
Para reconstruir los caminos, y no sólo las distancias, se lleva una segunda matriz con el próximo salto —o el vértice intermedio— de cada par, que se actualiza junto con la distancia.
Reconstruir un camino es después seguir esa matriz salto a salto. Cuesta lo que mide el camino, y evita guardar listas completas.
El mismo esquema para otras preguntas
El mismo esquema resuelve otras preguntas cambiando la operación. Con o lógico en vez de suma y mínimo, calcula la clausura transitiva: qué vértices son alcanzables desde cuáles, que es el algoritmo de Warshall.
Con máximo y mínimo da el camino de cuello de botella —la mayor capacidad mínima entre dos puntos—. Es el mismo recorrido de estados con otro semianillo, y sirve para redes de capacidad o rutas de confiabilidad.
Cuándo Floyd-Warshall y cuándo Dijkstra n veces
| Floyd-Warshall | Dijkstra desde cada vértice | Johnson | |
|---|---|---|---|
| Costo | O(V³) | O(V · E log V) | O(V · E log V) más O(V · E) |
| Pesos negativos | sí | no | sí, si no hay ciclos negativos |
| Conviene cuando | el grafo es denso o chico | el grafo es ralo | ralo y con pesos negativos |
| Memoria | O(V²) siempre | O(V²) para guardar el resultado | O(V²) |
| Código | tres ciclos anidados | un Dijkstra en un ciclo | repesar y después Dijkstra |
Más a fondo · nivel seniorLa misma forma sirve para otras cosas
Los tres ciclos de Floyd-Warshall son un esquema más general: si se reemplaza el mínimo por otra operación y la suma por otra, el mismo código resuelve otros problemas.
Con OR en vez de mínimo y AND en vez de suma, calcula la clausura transitiva: qué vértices son alcanzables desde cuáles. Ese es el algoritmo de Warshall, y es el que responde «¿este módulo depende, directa o indirectamente, de aquel?».
Con máximo en vez de mínimo y mínimo en vez de suma, calcula el camino de máxima capacidad entre cada par, que es la pregunta de una red de transporte: cuál es el cuello de botella del mejor camino.
Los tres son el mismo algoritmo sobre semianillos distintos. Reconocer esa estructura es lo que convierte tres algoritmos en uno, y es la clase de observación que hace que un área se vuelva manejable en vez de una lista de recetas.
Lo que preguntan sobre esto
Cierre
Floyd-Warshall pregunta, para cada par y cada vértice nuevo habilitado, si pasar por ahí mejora. Con en el ciclo externo da todas las distancias en y de memoria, acepta pesos negativos, detecta ciclos negativos en la diagonal y se adapta a otras preguntas cambiando las operaciones.
Autoevaluación
¿Lo entendiste?
Práctica