Saltar al contenido principal

Abrir el simulador

Mira Dijkstra paso a paso sobre un grafo: frontera, distancias y camino más corto.
¿Cuál es la ruta más rápida de Madrid a Barcelona? ¿Por qué camino debe enviar un router cada paquete? Son problemas de caminos mínimos en un grafo con pesos. El algoritmo de Dijkstra (1956) los resuelve de forma eficiente cuando los pesos no son negativos, y es uno de los algoritmos más usados del mundo. Para los casos que Dijkstra no cubre están Bellman-Ford, Floyd-Warshall y A*.

Lo que vas a aprender

  • Qué es un grafo ponderado y el problema del camino mínimo.
  • El algoritmo de Dijkstra paso a paso y con cola de prioridad.
  • Por qué Dijkstra falla con pesos negativos.
  • Bellman-Ford y la detección de ciclos negativos.
  • Floyd-Warshall para todas las parejas de nodos.
  • La idea de A* con una heurística.

Fundamentos teóricos

El problema

Un grafo ponderado tiene un peso (distancia, tiempo, coste) en cada arista. El camino mínimo entre dos nodos es el de menor suma de pesos. Sin pesos (o con todos iguales), basta con un recorrido en anchura, como en el simulador de recorridos de grafos.

La idea de Dijkstra

Se mantiene una distancia provisional d[v]d[v] a cada nodo, empezando con d[origen]=0d[\text{origen}] = 0 e infinito para el resto. En cada paso:
  1. Se elige el nodo no visitado con menor dd. Su distancia ya es definitiva.
  2. Se relaja cada arista (u,v)(u, v) que sale de él: si d[u]+w(u,v)<d[v]d[u] + w(u, v) < d[v], se actualiza d[v]d[v] y se apunta que se llega a vv desde uu.
  3. Se repite hasta visitar todos los nodos (o el destino).
Es un algoritmo voraz: en cada paso fija el nodo más cercano. Funciona porque, con pesos no negativos, ningún camino que pase por nodos más lejanos puede mejorar esa distancia.

Implementación con cola de prioridad

Con un montículo binario, el coste es O((V+E)log⁡V)O((V + E)\log V). Con un array en lugar de montículo, O(V2)O(V^2), que es mejor para grafos muy densos. Para recuperar el camino se sigue previo desde el destino hasta el origen.

Pesos negativos

Dijkstra no funciona con pesos negativos: puede fijar un nodo cuya distancia luego mejoraría un camino con una arista negativa. Y si hay un ciclo de peso negativo, el camino mínimo ni siquiera existe (se podría dar vueltas para bajar el coste sin fin).

Bellman-Ford

Relaja todas las aristas V−1V - 1 veces:
Coste O(V E)O(V\,E), más lento que Dijkstra, pero admite pesos negativos y detecta ciclos negativos. Lo usaba el protocolo de enrutamiento RIP.

Floyd-Warshall

Calcula las distancias entre todos los pares de nodos con programación dinámica: permite usar como intermedios los nodos 1,2,…,k1, 2, \dots, k poco a poco.
Coste O(V3)O(V^3). Muy simple y práctico para grafos de unos pocos cientos de nodos.

A*

Dijkstra explora en todas direcciones. A* prioriza los nodos con menor d[v]+h(v)d[v] + h(v), donde hh es una heurística que estima la distancia restante al destino (por ejemplo, la distancia en línea recta en un mapa). Si hh nunca sobreestima, A* encuentra el camino óptimo explorando muchos menos nodos. Se usa en videojuegos y navegadores.

Comparación

Ejemplos resueltos

Ejemplo 1 · Dijkstra paso a paso

Aristas (no dirigidas): A–B 4, A–C 2, B–C 1, B–D 5, C–D 8, C–E 10, D–E 2. Origen: A.Camino mínimo a E: A → C → B → D → E, de coste 2+1+5+2=102 + 1 + 5 + 2 = 10.
Aristas dirigidas: A→B 2, A→C 3, C→B −2. Dijkstra fija B con distancia 2 en el primer paso. Después, el camino A→C→B cuesta 3−2=13 - 2 = 1, pero B ya estaba fijado: el resultado es incorrecto. Bellman-Ford da 1.
Con 3 nodos y d=(04116023∞0)d = \begin{pmatrix} 0 & 4 & 11 \\ 6 & 0 & 2 \\ 3 & \infty & 0 \end{pmatrix} (dirigido):Pasando por el nodo 2: d[1][3]=min⁡(11,4+2)=6d[1][3] = \min(11, 4 + 2) = 6. Pasando por el 3: d[2][1]=min⁡(6,2+3)=5d[2][1] = \min(6, 2 + 3) = 5 y d[3][2]=min⁡(∞,3+4)=7d[3][2] = \min(\infty, 3 + 4) = 7.Resultado: (046502370)\begin{pmatrix} 0 & 4 & 6 \\ 5 & 0 & 2 \\ 3 & 7 & 0 \end{pmatrix}.
  • Mapa de carreteras, ruta entre dos ciudades: Dijkstra o A*.
  • Tabla de distancias entre las 50 capitales de provincia: Floyd-Warshall.
  • Grafo de tipos de cambio entre monedas (con logaritmos negativos) para buscar arbitraje: Bellman-Ford, que detecta el ciclo negativo.

Errores frecuentes

  • Usar Dijkstra con pesos negativos.
  • No descartar las entradas antiguas de la cola de prioridad, que tienen distancias ya mejoradas.
  • Parar Bellman-Ford sin la última pasada, que es la que detecta ciclos negativos.
  • Poner el bucle de kk por dentro en Floyd-Warshall. Tiene que ser el exterior.
  • Usar una heurística que sobreestima en A*: deja de garantizar el camino óptimo.

Preguntas frecuentes

Con un mapa de millones de cruces, Dijkstra puro sería lento. Se preprocesa el grafo (contraction hierarchies, transit nodes) para que cada consulta explore solo unos pocos miles de nodos, y se combina con datos de tráfico en tiempo real.
El protocolo OSPF, que usan los routers dentro de una red grande, ejecuta Dijkstra en cada router con el mapa completo de la red. Se explica en el tema de redes de computadores.

Temas relacionados

Recorridos de grafos

BFS y DFS animados.

Montículos

La cola de prioridad de Dijkstra.

Programación dinámica

La idea detrás de Floyd-Warshall.
Última modificación el 12 de octubre de 2026