logo

¿Qué es el algoritmo de Dijkstra? | Introducción al algoritmo de ruta más corta de Dijkstra

En este artículo, analizaremos uno de los algoritmos de ruta más corta más conocidos, es decir, el algoritmo de ruta más corta de Dijkstra, que fue desarrollado por el informático holandés Edsger W. Dijkstra en 1956. Además, haremos un análisis de complejidad para este algoritmo y también vea en qué se diferencia de otros algoritmos de camino más corto.

Tabla de contenidos



algoritmo-dijkstra-(1)

Algoritmo de Dijkstra:

El algoritmo de Dijkstra es un algoritmo popular para resolver muchos problemas de ruta más corta de una sola fuente que tienen un peso de borde no negativo en los gráficos, es decir, es para encontrar la distancia más corta entre dos vértices en un gráfico. Fue concebido por un informático holandés. Edsger W. Dijkstra en 1956.

El algoritmo mantiene un conjunto de vértices visitados y un conjunto de vértices no visitados. Comienza en el vértice de origen y selecciona iterativamente el vértice no visitado con la distancia tentativa más pequeña desde el origen. Luego visita a los vecinos de este vértice y actualiza sus distancias tentativas si encuentra un camino más corto. Este proceso continúa hasta que se alcanza el vértice de destino o se visitan todos los vértices alcanzables.



Necesidad del algoritmo de Dijkstra (propósito y casos de uso)

La necesidad del algoritmo de Dijkstra surge en muchas aplicaciones donde es crucial encontrar el camino más corto entre dos puntos.

Por ejemplo Puede usarse en los protocolos de enrutamiento para redes informáticas y también en los sistemas de mapas para encontrar el camino más corto entre el punto de partida y el destino (como se explica en ¿Cómo funciona Google Maps? )

¿Puede el algoritmo de Dijkstra funcionar tanto en gráficos dirigidos como en gráficos no dirigidos?

, el algoritmo de Dijkstra puede funcionar tanto en gráficos dirigidos como en gráficos no dirigidos, ya que este algoritmo está diseñado para funcionar en cualquier tipo de gráfico siempre que cumpla con los requisitos de tener pesos de borde no negativos y estar conectado.



  • En un gráfico dirigido, cada borde tiene una dirección, que indica la dirección de viaje entre los vértices conectados por el borde. En este caso, el algoritmo sigue la dirección de los bordes cuando busca el camino más corto.
  • En un gráfico no dirigido, los bordes no tienen dirección y el algoritmo puede recorrer los bordes hacia adelante y hacia atrás cuando busca el camino más corto.

Algoritmo para el algoritmo de Dijkstra:

  1. Marque el nodo de origen con una distancia actual de 0 y el resto con infinito.
  2. Establezca el nodo no visitado con la distancia actual más pequeña como el nodo actual.
  3. Para cada vecino, N del nodo actual suma la distancia actual del nodo adyacente con el peso del borde que conecta 0->1. Si es menor que la distancia actual de Nodo, configúrelo como la nueva distancia actual de N.
  4. Marque el nodo 1 actual como visitado.
  5. Vaya al paso 2 si hay nodos no visitados.

¿Cómo funciona el algoritmo de Dijkstra?

Veamos cómo funciona el algoritmo de Dijkstra con el siguiente ejemplo:

El algoritmo de Dijkstra generará el camino más corto desde el nodo 0 a todos los demás nodos del gráfico.

Considere el siguiente gráfico:

Dijkstra

Algoritmo de Dijkstra

El algoritmo generará la ruta más corta desde el nodo 0 a todos los demás nodos del gráfico.

Para este gráfico, asumiremos que el peso de los bordes representa la distancia entre dos nodos.

ejemplos de autómatas dfa

Como podemos ver, tenemos el camino más corto desde,
Nodo 0 al Nodo 1, desde
Nodo 0 al Nodo 2, desde
Nodo 0 al Nodo 3, desde
Nodo 0 al Nodo 4, desde
Nodo 0 al Nodo 6.

Inicialmente tenemos un conjunto de recursos que se detallan a continuación:

patrón de diseño de fábrica
  • La distancia desde el nodo de origen a sí mismo es 0. En este ejemplo, el nodo de origen es 0.
  • Se desconoce la distancia desde el nodo de origen a todos los demás nodos, por lo que los marcamos todos como infinito.

Ejemplo: 0 -> 0, 1-> ∞,2-> ∞,3-> ∞,4-> ∞,5-> ∞,6-> ∞.

  • También tendremos una serie de elementos no visitados que realizarán un seguimiento de los nodos no visitados o no marcados.
  • El algoritmo se completará cuando todos los nodos marcados como visitados y la distancia entre ellos se agreguen a la ruta. Nodos no visitados:- 0 1 2 3 4 5 6.

Paso 1: Comience desde el Nodo 0 y marque el Nodo como visitado, como puede comprobar en la imagen a continuación. El Nodo visitado está marcado en rojo.

Dijkstra

Algoritmo de Dijkstra

Paso 2: Verifique si hay nodos adyacentes. Ahora tenemos dos opciones (elegir el Nodo 1 con distancia 2 o elegir el Nodo 2 con distancia 6) y elegir el Nodo con distancia mínima. en este paso Nodo 1 es la distancia mínima al nodo adyacente, así que márquelo como visitado y sume la distancia.

Distancia: Nodo 0 -> Nodo 1 = 2

Dijkstra

Algoritmo de Dijkstra

Paso 3: Luego avance y verifique el nodo adyacente, que es el nodo 3, así que márquelo como visitado y sume la distancia. Ahora la distancia será:

Distancia: Nodo 0 -> Nodo 1 -> Nodo 3 = 2 + 5 = 7

Dijkstra

Algoritmo de Dijkstra

Etapa 4: Nuevamente tenemos dos opciones para los nodos adyacentes (podemos elegir el nodo 4 con una distancia de 10 o podemos elegir el nodo 5 con una distancia de 15), así que elija el nodo con una distancia mínima. en este paso Nodo 4 es la distancia mínima al nodo adyacente, así que márquelo como visitado y sume la distancia.

Distancia: Nodo 0 -> Nodo 1 -> Nodo 3 -> Nodo 4 = 2 + 5 + 10 = 17

Dijkstra

Algoritmo de Dijkstra

Paso 5: Nuevamente, avance y verifique el nodo adyacente que esté Nodo 6 , así que márquelo como visitado y sume la distancia. Ahora la distancia será:

Distancia: Nodo 0 -> Nodo 1 -> Nodo 3 -> Nodo 4 -> Nodo 6 = 2 + 5 + 10 + 2 = 19

Dijkstra

Algoritmo de Dijkstra

Entonces, la distancia más corta desde el vértice fuente es 19, que es la óptima

Pseudocódigo para el algoritmo de Dijkstra

función Dijkstra(Gráfico, fuente):
// Inicializa las distancias a todos los nodos como infinito y al nodo de origen como 0.

distancias = mapa (todos los nodos -> infinito)

distancias = 0

// Inicializa un conjunto vacío de nodos visitados y una cola de prioridad para realizar un seguimiento de los nodos a visitar.
visitado = conjunto vacío
cola = nueva PriorityQueue()
cola.encola(fuente, 0)

// Realiza un bucle hasta que se hayan visitado todos los nodos.
mientras la cola no esté vacía:
// Retire de la cola el nodo con la distancia más pequeña de la cola de prioridad.
actual = cola.dequeue()

// Si el nodo ya ha sido visitado, omítelo.
si es actual en visitado:
continuar

js cadena multilínea

// Marca el nodo como visitado.
visitado.add(actual)

// Verifique todos los nodos vecinos para ver si es necesario actualizar sus distancias.
para vecino en Graph.neighbors(actual):
// Calcula la distancia tentativa al vecino a través del nodo actual.
distancia_tentativa = distancias[actual] + Graph.distance(actual, vecino)

// Si la distancia tentativa es menor que la distancia actual al vecino, actualiza la distancia.
si distancia_tentativa
distancias[vecino] = distancia_tentativa

// Poner en cola al vecino con su nueva distancia para ser considerado para visitas en el futuro.
cola.encola(vecino, distancias[vecino])

// Devuelve las distancias calculadas desde la fuente a todos los demás nodos del gráfico.
distancias de regreso

Implementación del algoritmo de Dijkstra:

Hay varias formas de implementar el algoritmo de Dijkstra, pero las más comunes son:

  1. Cola de prioridad (implementación basada en montón):
  2. Implementación basada en matrices:

1. Algoritmo de ruta más corta de Dijkstra usando Priority_queue (Heap)

En esta implementación, se nos proporciona un gráfico y un vértice fuente en el gráfico, encontrando los caminos más cortos desde la fuente hasta todos los vértices en el gráfico dado.

Ejemplo:

Aporte: Fuente = 0

Ejemplo

Producción: Vértice

Distancia del vértice desde la fuente

jpa vs hibernación

0 -> 0
1 -> 2
2 -> 6
3 -> 7
4 -> 17
5 -> 22
6 -> 19

A continuación se muestra el algoritmo basado en la idea anterior:

  • Inicialice los valores de distancia y la cola de prioridad.
  • Inserte el nodo de origen en la cola de prioridad con distancia 0.
  • Mientras la cola de prioridad no esté vacía:
    • Extraiga el nodo con la distancia mínima de la cola de prioridad.
    • Actualiza las distancias de sus vecinos si encuentra un camino más corto.
    • Inserte vecinos actualizados en la cola de prioridad.

A continuación se muestra la implementación en C++ del enfoque anterior:

C++
// Program to find Dijkstra's shortest path using // priority_queue in STL #include  using namespace std; #define INF 0x3f3f3f3f // iPair ==>par entero typedef par par; // Esta clase representa un gráfico dirigido usando // representación de lista de adyacencia class Graph { int V; // Número de vértices // En un gráfico ponderado, necesitamos almacenar el vértice // y el par de pesos para cada lista de aristas>* adj; público: Gráfico (int V); // Constructor // función para agregar un borde al gráfico void addEdge(int u, int v, int w);  // imprime la ruta más corta desde s voidshortPath(int s); }; // Asigna memoria para la lista de adyacencia Graph::Graph(int V) { this->V = V;  adj = nueva lista [V]; } void Graph::addEdge(int u, int v, int w) { adj[u].push_back(make_pair(v, w));  adj[v].push_back(make_pair(u, w)); } // Imprime las rutas más cortas desde src a todos los demás vértices void Graph::shortestPath(int src) { // Crea una cola de prioridad para almacenar los vértices que // están siendo preprocesados. Esta es una sintaxis extraña en C++.  // Consulte el enlace a continuación para obtener detalles de esta sintaxis // https://www.techcodeview.com prioridad_queue , mayor que >pq;  // Crea un vector para distancias e inicializa todas // las distancias como un vector infinito (INF) dist(V,INF);  // Inserta la fuente en la cola de prioridad e inicializa // su distancia como 0. pq.push(make_pair(0, src));  dist[fuente] = 0;  /* Recorriendo hasta que la cola de prioridad se vacíe (o no se finalicen todas las distancias) */ while (!pq.empty()) { // El primer vértice del par es la distancia mínima // vértice, extráigalo de la cola de prioridad.  // la etiqueta del vértice se almacena en el segundo del par ( // debe hacerse de esta manera para mantener los vértices // distancia ordenada (la distancia debe ser el primer elemento // del par) int u = pq.top().segundo; pq.pop(); // 'i' se usa para obtener todos los vértices adyacentes de una // lista de vértices>::iterador i;  for (i = adj[u].begin(); i != adj[u].end(); ++i) { // Obtener la etiqueta del vértice y el peso del // actual adyacente de u.  int v = (*i).primero;  peso int = (*i).segundo;  // Si hay un camino corto de v a través de u.  if (dist[v]> dist[u] + peso) { // Actualizando la distancia de v dist[v] = dist[u] + peso;  pq.push(make_pair(dist[v], v));  } } } // Imprime las distancias más cortas almacenadas en dist[] printf('Distancia de vértice desde la fuente
');  para (int i = 0; i< V; ++i)  printf('%d 		 %d
', i, dist[i]); } // Driver program to test methods of graph class int main() {  // create the graph given in above figure  int V = 7;  Graph g(V);  // making above shown graph  g.addEdge(0, 1, 2);  g.addEdge(0, 2, 6);  g.addEdge(1, 3, 5);  g.addEdge(2, 3, 8);  g.addEdge(3, 4, 10);  g.addEdge(3, 5, 15);  g.addEdge(4, 6, 2);  g.addEdge(5, 6, 6);  g.shortestPath(0);  return 0; }>
Java
import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.PriorityQueue; public class DijkstraAlgoForShortestDistance {  static class Node implements Comparable{  En televisión;  distancia interna;  Nodo público (int v, int distancia) { this.v = v;  esta.distancia = distancia;  } @Override public int compareTo(Nodo n) { if (esta.distancia<= n.distance) {  return -1;  }  else {  return 1;  }  }  }  static int[] dijkstra(  int V,  ArrayList >> adj, int S) { booleano[] visitado = nuevo booleano[V];  HashMap mapa = nuevo HashMap();  Cola de prioridadq = nueva PriorityQueue();  map.put(S, nuevo Nodo(S, 0));  q.add(nuevo Nodo(S, 0));  while (!q.isEmpty()) { Nodo n = q.poll();  int v = n.v;  int distancia = n.distancia;  visitado[v] = verdadero;  Lista de arreglo > adjList = adj.get(v);  para (ListaArray adjLink: adjList) { if (visitado[adjLink.get(0)] == false) { if (!map.containsKey(adjLink.get(0))) { map.put( adjLink.get(0), nuevo nodo (v, distancia + adjLink.get(1)));  } else { Nodo sn = map.get(adjLink.get(0));  si (distancia + adjLink.get(1)< sn.distance) {  sn.v = v;  sn.distance  = distance + adjLink.get(1);  }  }  q.add(new Node(adjLink.get(0),  distance  + adjLink.get(1)));  }  }  }  int[] result = new int[V];  for (int i = 0; i < V; i++) {  result[i] = map.get(i).distance;  }  return result;  }  public static void main(String[] args)  {  ArrayList >> adj = nueva ArrayList();  HashMap >> mapa = nuevo HashMap();  int V = 6;  int E = 5;  int[] u = { 0, 0, 1, 2, 4 };  int[] v = {3, 5, 4, 5, 5};  int[]w = {9, 4, 4, 10, 3};  para (int i = 0; i< E; i++) {  ArrayList borde = nueva ArrayList();  borde.add(v[i]);  borde.add(w[i]);  Lista de arreglo > listaadj;  if (!map.containsKey(u[i])) { adjList = nueva ArrayList();  } else { adjList = map.get(u[i]);  } adjList.add(borde);  map.put(u[i], adjList);  Lista de arreglo borde2 = nueva ArrayList();  borde2.add(u[i]);  borde2.add(w[i]);  Lista de arreglo > listaadj2;  if (!map.containsKey(v[i])) { adjList2 = nueva ArrayList();  } else { adjList2 = map.get(v[i]);  } adjList2.add(edge2);  map.put(v[i], adjList2);  } para (int i = 0; i< V; i++) {  if (map.containsKey(i)) {  adj.add(map.get(i));  }  else {  adj.add(null);  }  }  int S = 1;  // Input sample  //[0 [[3, 9], [5, 4]],  // 1 [[4, 4]],  // 2 [[5, 10]],  // 3 [[0, 9]],  // 4 [[1, 4], [5, 3]],  // 5 [[0, 4], [2, 10], [4, 3]]  //]  int[] result  = DijkstraAlgoForShortestDistance.dijkstra(  V, adj, S);  System.out.println(Arrays.toString(result));  } }>
Pitón
# Python implementation of Dijkstra Algorithm import heapq class Node: def __init__(self, v, distance): self.v = v self.distance = distance def __lt__(self, other): return self.distance < other.distance def dijkstra(V, adj, S): visited = [False] * V map = {} q = [] map[S] = Node(S, 0) heapq.heappush(q, Node(S, 0)) while q: n = heapq.heappop(q) v = n.v distance = n.distance visited[v] = True adjList = adj[v] for adjLink in adjList: if not visited[adjLink[0]]: if adjLink[0] not in map: map[adjLink[0]] = Node(v, distance + adjLink[1]) else: sn = map[adjLink[0]] if distance + adjLink[1] < sn.distance: sn.v = v sn.distance = distance + adjLink[1] heapq.heappush(q, Node(adjLink[0], distance + adjLink[1])) result = [0] * V for i in range(V): result[i] = map[i].distance return result def main(): adj = [[] for _ in range(6)] V = 6 E = 5 u = [0, 0, 1, 2, 4] v = [3, 5, 4, 5, 5] w = [9, 4, 4, 10, 3] for i in range(E): edge = [v[i], w[i]] adj[u[i]].append(edge) edge2 = [u[i], w[i]] adj[v[i]].append(edge2) S = 1 result = dijkstra(V, adj, S) print(result) if __name__ == '__main__': main() # This code is contributed by ragul21>
C#
// C# Code: using System; using System.Collections.Generic; public class Graph {  // No. of vertices  private int V;  // adjacency list  private List>[] adj;  // Constructor public Graph(int v) { V = v;  adj = nueva lista>[ v ];  para (int i = 0; i< v; ++i)  adj[i] = new List>();  } // función para agregar un borde al gráfico public void addEdge(int u, int v, int w) { adj[u].Add(Tuple.Create(v, w));  adj[v].Add(Tuple.Create(u, w));  } // imprime la ruta más corta desde s public voidshortPath(int s) { // Crea una cola de prioridad para almacenar los vértices que // se están preprocesando.  var pq = nueva cola de prioridad>();  // Crea un vector para distancias e inicializa todas // las distancias como infinitas (INF) var dist = new int[V];  para (int i = 0; i< V; i++)  dist[i] = int.MaxValue;  // Insert source itself in priority queue and  // initialize its distance as 0.  pq.Enqueue(Tuple.Create(0, s));  dist[s] = 0;  /* Looping till priority queue becomes empty (or all  distances are not finalized) */  while (pq.Count != 0) {  // The first vertex in pair is the minimum  // distance vertex, extract it from priority  // queue. vertex label is stored in second of  // pair (it has to be done this way to keep the  // vertices sorted distance (distance must be  // first item in pair)  var u = pq.Dequeue().Item2;  // 'i' is used to get all adjacent vertices of a  // vertex  foreach(var i in adj[u])  {  // Get vertex label and weight of current  // adjacent of u.  int v = i.Item1;  int weight = i.Item2;  // If there is shorted path to v through u.  if (dist[v]>dist[u] + peso) { // Actualizando la distancia de v dist[v] = dist[u] + peso;  pq.Enqueue(Tuple.Create(dist[v], v));  } } } // Imprime las distancias más cortas almacenadas en dist[] Console.WriteLine('Vertex Distance from Source');  para (int i = 0; i< V; ++i)  Console.WriteLine('{0}		{1}', i, dist[i]);  } } public class PriorityQueue{Lista privada de solo lectura_datos;  Comparación privada de solo lectura_comparado;  PriorityQueue pública(): esto(Comparar.Predeterminado) { } PriorityQueue pública (IComparercomparar): this(compare.Compare) { } public PriorityQueue(Comparacióncomparación) { _data = nueva lista();  _comparar = comparación;  } public void Enqueue (elemento T) { _data.Add(elemento);  var childIndex = _data.Count - 1;  mientras (childIndex> 0) { var parentIndex = (childIndex - 1) / 2;  if (_compare(_data[childIndex], _data[parentIndex])>= 0) descanso;  T tmp = _data[childIndex];  _data[childIndex] = _data[parentIndex];  _data[parentIndex] = tmp;  índiceniño = índicepadre;  } } public T Dequeue() { // asume que pq no está vacío; hasta llamar al código var lastElement = _data.Count - 1;  var frontItem = _data[0];  _datos[0] = _datos[últimoElemento];  _data.RemoveAt(últimoElemento);  --últimoElemento;  var índicepadre = 0;  mientras (verdadero) { var childIndex = parentIndex * 2 + 1;  si (childIndex> lastElement) se rompe; // Fin del árbol var rightChild = childIndex + 1;  si (derechaNiño<= lastElement  && _compare(_data[rightChild],  _data[childIndex])  < 0)  childIndex = rightChild;  if (_compare(_data[parentIndex],  _data[childIndex])  <= 0)  break; // Correct position  T tmp = _data[parentIndex];  _data[parentIndex] = _data[childIndex];  _data[childIndex] = tmp;  parentIndex = childIndex;  }  return frontItem;  }  public T Peek()  {  T frontItem = _data[0];  return frontItem;  }  public int Count  {  get { return _data.Count; }  } } class Program {  // Driver program to test methods of graph class  static void Main(string[] args)  {  // create the graph given in above figure  int V = 7;  Graph g = new Graph(V);  // making above shown graph  g.addEdge(0, 1, 2);  g.addEdge(0, 2, 6);  g.addEdge(1, 3, 5);  g.addEdge(2, 3, 8);  g.addEdge(3, 4, 10);  g.addEdge(3, 5, 15);  g.addEdge(4, 6, 2);  g.addEdge(5, 6, 6);  g.shortestPath(0);  } }>
JavaScript
class PriorityQueue {  constructor() {  this.queue = [];  }  enqueue(element, priority) {  this.queue.push({ element, priority });  this.queue.sort((a, b) =>a.prioridad - b.prioridad);  } quitar de cola() { if (this.isEmpty()) { return null;  } devolver this.queue.shift().elemento;  } está vacío() { return this.queue.length === 0;  } } clase Gráfico { constructor(V) { this.V = V;  this.adj = nueva matriz (V);  para (sea i = 0; i< V; i++) {  this.adj[i] = [];  }  }  addEdge(u, v, w) {  this.adj[u].push({ v, w });  this.adj[v].push({ v: u, w });  }  shortestPath(src) {  const pq = new PriorityQueue();  const dist = new Array(this.V).fill(Infinity);  const visited = new Array(this.V).fill(false);  pq.enqueue(src, 0);  dist[src] = 0;  while (!pq.isEmpty()) {  const u = pq.dequeue();  if (visited[u]) continue;  visited[u] = true;  for (const { v, w } of this.adj[u]) {  if (!visited[v] && dist[u] + w < dist[v]) {  dist[v] = dist[u] + w;  pq.enqueue(v, dist[v]);  }  }  }  console.log('Vertex Distance from Source');  for (let i = 0; i < this.V; i++) {  console.log(`${i}		${dist[i] === Infinity ? 'Infinity' : dist[i]}`);  }  } } function main() {  const V = 7;  const g = new Graph(V);  g.addEdge(0, 1, 2);  g.addEdge(0, 2, 6);  g.addEdge(1, 3, 5);  g.addEdge(2, 3, 8);  g.addEdge(3, 4, 10);  g.addEdge(3, 5, 15);  g.addEdge(4, 6, 2);  g.addEdge(5, 6, 6);  g.shortestPath(0); } main();>

Respuesta final:

Producción

Análisis de complejidad del algoritmo de Dijkstra :

  • Complejidad del tiempo: O((V + E) Iniciar sesión V) , donde V es el número de vértices y E es el número de aristas.
  • Espacio Auxiliar: O (V), donde V es el número de vértices y E es el número de aristas del gráfico.

2.Implementación basada en matrices del algoritmo de Dijkstra (enfoque ingenuo):

El algoritmo de Dijkstra también se puede implementar utilizando matrices sin utilizar una cola de prioridad. Esta implementación es sencilla pero puede ser menos eficiente, especialmente en gráficos grandes.

El algoritmo procede como sigue:

  • Inicialice una matriz para almacenar distancias desde la fuente hasta cada nodo.
  • Marque todos los nodos como no visitados.
  • Establezca la distancia al nodo de origen como 0 e infinito para todos los demás nodos.
  • Repita hasta que se visiten todos los nodos:
    • Encuentre el nodo no visitado con la distancia más pequeña conocida.
    • Para el nodo actual, actualice las distancias de sus vecinos no visitados.
    • Marque el nodo actual como visitado.

Análisis de complejidad:

  • Complejidad del tiempo: O(V^2) en el peor de los casos, donde V es el número de vértices. Esto se puede mejorar a O(V^2) con algunas optimizaciones.
  • Espacio Auxiliar: O (V), donde V es el número de vértices y E es el número de aristas del gráfico.

Algoritmos de Dijkstra versus algoritmo de Bellman-Ford

El algoritmo de Dijkstra y Algoritmo de Bellman-Ford Ambos se utilizan para encontrar el camino más corto en un gráfico ponderado, pero tienen algunas diferencias clave. Estas son las principales diferencias entre el algoritmo de Dijkstra y el algoritmo de Bellman-Ford:

Característica:Dijkstra'sbotones Ford
Mejoramientooptimizado para encontrar la ruta más corta entre un único nodo de origen y todos los demás nodos en un gráfico con pesos de borde no negativosEl algoritmo de Bellman-Ford está optimizado para encontrar la ruta más corta entre un único nodo de origen y todos los demás nodos en un gráfico con pesos de borde negativos.
RelajaciónEl algoritmo de Dijkstra utiliza un enfoque codicioso en el que elige el nodo con la distancia más pequeña y actualiza sus vecinos.El algoritmo Bellman-Ford relaja todos los bordes en cada iteración, actualizando la distancia de cada nodo considerando todos los caminos posibles hacia ese nodo.
Complejidad del tiempoEl algoritmo de Dijkstra tiene una complejidad temporal de O(V^2) para un gráfico denso y O(E log V) para un gráfico disperso, donde V es el número de vértices y E es el número de aristas del gráfico.El algoritmo de Bellman-Ford tiene una complejidad temporal de O (VE), donde V es el número de vértices y E es el número de aristas del gráfico.
Pesos negativosEl algoritmo de Dijkstra no funciona con gráficos que tienen pesos de arista negativos, ya que supone que todos los pesos de aristas no son negativos.El algoritmo de Bellman-Ford puede manejar pesos de borde negativos y puede detectar ciclos de peso negativo en el gráfico.

Algoritmo de Dijkstra versus algoritmo de Floyd-Warshall

El algoritmo de Dijkstra y Algoritmo de Floyd-Warshall Ambos se utilizan para encontrar el camino más corto en un gráfico ponderado, pero tienen algunas diferencias clave. Estas son las principales diferencias entre el algoritmo de Dijkstra y el algoritmo de Floyd-Warshall:

Característica:Dijkstra'sAlgoritmo de Floyd-Warshall
MejoramientoOptimizado para encontrar la ruta más corta entre un único nodo de origen y todos los demás nodos en un gráfico con pesos de borde no negativosEl algoritmo Floyd-Warshall está optimizado para encontrar el camino más corto entre todos los pares de nodos en un gráfico.
TécnicaEl algoritmo de Dijkstra es un algoritmo de ruta más corta de fuente única que utiliza un enfoque codicioso y calcula la ruta más corta desde el nodo de origen a todos los demás nodos en el gráfico.El algoritmo Floyd-Warshall, por otro lado, es un algoritmo de ruta más corta para todos los pares que utiliza programación dinámica para calcular la ruta más corta entre todos los pares de nodos en el gráfico.
Complejidad del tiempoEl algoritmo de Dijkstra tiene una complejidad temporal de O(V^2) para un gráfico denso y O(E log V) para un gráfico disperso, donde V es el número de vértices y E es el número de aristas del gráfico.El algoritmo Floyd-Warshall, por otro lado, es un algoritmo de ruta más corta para todos los pares que utiliza programación dinámica para calcular la ruta más corta entre todos los pares de nodos en el gráfico.
Pesos negativosEl algoritmo de Dijkstra no funciona con gráficos que tienen pesos de arista negativos, ya que supone que todos los pesos de aristas no son negativos.El algoritmo Floyd-Warshall, por otro lado, es un algoritmo de ruta más corta para todos los pares que utiliza programación dinámica para calcular la ruta más corta entre todos los pares de nodos en el gráfico.

Algoritmo de Dijkstra versus algoritmo A*

El algoritmo de Dijkstra y Un algoritmo* Ambos se utilizan para encontrar el camino más corto en un gráfico ponderado, pero tienen algunas diferencias clave. Estas son las principales diferencias entre el algoritmo de Dijkstra y el algoritmo A*:

Característica: Un* Algoritmo
Técnica de búsquedaOptimizado para encontrar la ruta más corta entre un único nodo de origen y todos los demás nodos en un gráfico con pesos de borde no negativosEl algoritmo A* es un algoritmo de búsqueda informado que utiliza una función heurística para guiar la búsqueda hacia el nodo objetivo.
Función heurísticaEl algoritmo de Dijkstra no utiliza ninguna función heurística y considera todos los nodos del gráfico.El algoritmo A* utiliza una función heurística que estima la distancia desde el nodo actual hasta el nodo objetivo. Esta función heurística es admisible, lo que significa que nunca sobreestima la distancia real al nodo objetivo.
Complejidad del tiempoEl algoritmo de Dijkstra tiene una complejidad temporal de O(V^2) para un gráfico denso y O(E log V) para un gráfico disperso, donde V es el número de vértices y E es el número de aristas del gráfico.La complejidad temporal del algoritmo A* depende de la calidad de la función heurística.
SolicitudEl algoritmo de Dijkstra se utiliza en muchas aplicaciones, como algoritmos de enrutamiento, sistemas de navegación GPS y análisis de redes.. El algoritmo A* se utiliza comúnmente en problemas de búsqueda de rutas y recorrido de gráficos, como videojuegos, robótica y algoritmos de planificación.

Problemas de práctica sobre el algoritmo de Dijkstra:

  1. Algoritmo del camino más corto de Dijkstra | Algo codicioso-7
  2. Algoritmo de Dijkstra para la representación de listas de adyacencia | Algo codicioso-8
  3. Algoritmo de Dijkstra: implementación de matrices y colas de prioridad
  4. El algoritmo de ruta más corta de Dijkstra usando set en STL
  5. El algoritmo de ruta más corta de Dijkstra usando STL en C++
  6. Algoritmo de ruta más corta de Dijkstra usando prioridad_queue de STL
  7. Algoritmo de ruta más corta de Dijkstra usando matriz en C++
  8. Algoritmo de Dijkstra para la ruta más corta de fuente única en un DAG
  9. Algoritmo de Dijkstra usando Fibonacci Heap
  10. Algoritmo de ruta más corta de Dijkstra para gráficos dirigidos con pesos negativos
  11. Impresión de rutas en el algoritmo de ruta más corta de Dijkstra
  12. Algoritmo de ruta más corta de Dijkstra con cola de prioridad en Java