Menu
Coddy logo textTech

Algoritmo de Dijkstra

Última actualización

El algoritmo de Dijkstra encuentra el camino más corto desde un nodo origen hasta todos los demás nodos de un grafo con pesos de arista no negativos. Mantiene una distancia tentativa para cada nodo, fija repetidamente el nodo no fijado con la menor distancia tentativa y relaja sus aristas, actualizando la distancia de un vecino cada vez que se encuentra una ruta más corta a través del nodo actual. Pulsa reproducir arriba para ver cómo bajan las distancias a medida que se fija cada nodo.

La idea clave es voraz: una vez que se elige el nodo no fijado más cercano, su distancia es definitiva, porque cualquier otra ruta hacia él tendría que pasar por un nodo que ya está más lejos. Con una cola de prioridad basada en montículo binario, Dijkstra se ejecuta en tiempo O((V + E) log V). Requiere pesos no negativos: usa Bellman-Ford si las aristas pueden ser negativas.

Complejidad temporal y espacial

ImplementaciónComplejidadNotas
Montículo binarioO((V + E) log V)La opción común y práctica
Barrido de arrayO(V²)Más simple; adecuado para grafos densos
EspacioO(V)Distancias + cola de prioridad
RequierePesos no negativosLas aristas negativas rompen la elección voraz

Paso a paso

PasoQué ocurre
1Fija la distancia del origen en 0 y todas las demás en infinito.
2Elige el nodo no fijado con la menor distancia tentativa.
3Márcalo como fijado: su distancia más corta ya es definitiva.
4Para cada vecino, calcula distancia-a-través-del-actual + peso de la arista.
5Si es menor que la distancia actual del vecino, relájala.
6Repite hasta fijar todos los nodos alcanzables.

Ejemplo resuelto

Caminos más cortos desde el origen A en el grafo con aristas A-B=4, A-C=1, C-B=2, C-D=5, B-D=1:

PasoFijarDistanciasAcción
0-A=0, B=∞, C=∞, D=∞Inicializa: origen A=0, todos los demás infinito.
1A (0)B=4, C=1, D=∞Relaja las aristas desde A: fija B=4, C=1.
2C (1)B=3, D=6A través de C: B=1+2=3 mejora 4; D=1+5=6.
3B (3)D=4A través de B: D=3+1=4 mejora 6.
4D (4)A=0, C=1, B=3, D=4Fija D; no queda nada por relajar. Listo.

Cuándo usar el algoritmo de Dijkstra

Úsalo cuandoEvítalo cuando
Todos los pesos de arista son no negativosCualquier arista puede ser negativa: usa Bellman-Ford
Necesitas los caminos más cortos desde un origen a todos los nodosNecesitas caminos más cortos entre todos los pares: Floyd-Warshall es más simple
El grafo es ponderado y quieres distancias exactasEl grafo no es ponderado: un BFS simple es más rápido y sencillo
Dispones de un buen montículo o cola de prioridadQuieres llegar rápido a un único destino con una heurística: usa A*

Código de Dijkstra's Algorithm

Una implementación limpia y ejecutable de Dijkstra's 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 Dijkstra's Algorithm en Python

Python
1import heapq2
3
4def dijkstra(graph, start):5    dist = {node: float("inf") for node in graph}6    dist[start] = 07    pq = [(0, start)]8    while pq:9        d, node = heapq.heappop(pq)10        if d > dist[node]:11            continue  # stale entry, a shorter path was already found12        for neighbor, weight in graph[node]:13            new_dist = d + weight14            if new_dist < dist[neighbor]:15                dist[neighbor] = new_dist16                heapq.heappush(pq, (new_dist, neighbor))17    return dist18
19
20graph = {21    "A": [("B", 4), ("C", 1)],22    "B": [("D", 1)],23    "C": [("B", 2), ("D", 5)],24    "D": [("E", 3)],25    "E": [],26}27
28for node, d in dijkstra(graph, "A").items():29    print(f"A -> {node}: {d}")
Ejecuta este código en el Playground de Python

Preguntas frecuentes sobre el algoritmo de Dijkstra

¿Cuál es la complejidad temporal del algoritmo de Dijkstra?
Con una cola de prioridad basada en montículo binario se ejecuta en O((V + E) log V). Una versión simple que barre un array buscando el mínimo en cada paso es O(V²), que en realidad puede ser más rápida en grafos densos. Ambas usan espacio O(V).
¿Por qué Dijkstra no funciona con pesos de arista negativos?
Dijkstra supone que, una vez que fija el nodo no fijado más cercano, esa distancia es definitiva. Una arista negativa podría crear después un camino más corto hacia un nodo ya fijado, rompiendo esa suposición. Para grafos con pesos negativos, usa el algoritmo de Bellman-Ford.
¿Cuál es la diferencia entre Dijkstra y BFS?
BFS encuentra los caminos más cortos contando aristas (cada peso de arista es efectivamente 1), usando una cola simple. Dijkstra generaliza esto a grafos ponderados expandiendo siempre el nodo con la menor distancia total, usando una cola de prioridad. En un grafo no ponderado ambos producen los mismos caminos.
¿Cuál es la diferencia entre Dijkstra y la búsqueda A*?
A* es Dijkstra más una heurística que estima la distancia restante hasta un destino, de modo que dirige la búsqueda hacia esa meta en lugar de expandirse uniformemente en todas direcciones. Cuando la heurística es cero, A* se reduce exactamente a Dijkstra. Usa A* cuando tienes un único destino y una buena heurística admisible; usa Dijkstra cuando necesitas distancias a todos los nodos.
¿Cuándo debería usar Dijkstra en lugar de Bellman-Ford?
Usa Dijkstra siempre que todos los pesos de arista sean no negativos: es más rápido, O((V + E) log V) frente a O(V·E) de Bellman-Ford. Elige Bellman-Ford solo cuando las aristas pueden ser negativas o necesitas detectar ciclos negativos. En grafos no negativos Dijkstra casi siempre es la mejor opción.
¿Puede Dijkstra volver a visitar un nodo después de fijarlo?
No: una vez que un nodo se fija, su distancia es definitiva y nunca se vuelve a relajar. Un error común en las implementaciones con montículo es dejar entradas obsoletas en la cola de prioridad después de que mejora la distancia de un nodo; debes ignorar un nodo extraído si ya está fijado (su distancia extraída supera la distancia registrada). Olvidar esta comprobación sigue dando respuestas correctas, pero desperdicia trabajo.
Coddy programming languages illustration

Domina los algoritmos con Coddy

COMENZAR