Você está na página 1de 5

El algoritmo de Dijkstra, tambi�n llamado algoritmo de caminos m�nimos, es un

algoritmo para la determinaci�n del camino m�s corto, dado un v�rtice origen, hacia
el resto de los v�rtices en un grafo que tiene pesos en cada arista. Su nombre
alude a Edsger Dijkstra, cient�fico de la computaci�n de los Pa�ses Bajos que lo
describi� por primera vez en 1959.[cita requerida]

La idea subyacente en este algoritmo consiste en ir explorando todos los caminos


m�s cortos que parten del v�rtice origen y que llevan a todos los dem�s v�rtices;
cuando se obtiene el camino m�s corto desde el v�rtice origen hasta el resto de los
v�rtices que componen el grafo, el algoritmo se detiene. Se trata de una
especializaci�n de la b�squeda de costo uniforme y, como tal, no funciona en grafos
con aristas de coste negativo (al elegir siempre el nodo con distancia menor,
pueden quedar excluidos de la b�squeda nodos que en pr�ximas iteraciones bajar�an
el costo general del camino al pasar por una arista con costo negativo).[cita
requerida]

Una de sus aplicaciones m�s importantes reside en el campo de la telem�tica.


Gracias a �l, es posible resolver grafos con muchos nodos, lo que ser�a muy
complicado resolver sin dicho algoritmo, encontrando as� las rutas m�s cortas entre
un origen y todos los destinos en una red.[cita requerida]

�ndice
1 Algoritmo
2 Complejidad
3 Pseudoc�digo
4 Otra versi�n en pseudoc�digo sin cola de prioridad
5 Implementaci�n en Java
6 Otra versi�n en C++ del algoritmo de Dijkstra
7 V�ase tambi�n
8 Enlaces externos
Algoritmo
Teniendo un grafo dirigido ponderado de N nodos no aislados, sea x el nodo inicial.
Un vector D de tama�o N guardar� al final del algoritmo las distancias desde x
hasta el resto de los nodos.

Inicializar todas las distancias en D con un valor infinito relativo, ya que son
desconocidas al principio, exceptuando la de x, que se debe colocar en 0, debido a
que la distancia de x a x ser�a 0.
Sea a = x (Se toma a como nodo actual.)
Se recorren todos los nodos adyacentes de a, excepto los nodos marcados. Se les
llamar� nodos no marcados vi.
Para el nodo actual, se calcula la distancia tentativa desde dicho nodo hasta sus
vecinos con la siguiente f�rmula: dt(vi) = Da + d(a,vi). Es decir, la distancia
tentativa del nodo �vi� es la distancia que actualmente tiene el nodo en el vector
D m�s la distancia desde dicho nodo �a� (el actual) hasta el nodo vi. Si la
distancia tentativa es menor que la distancia almacenada en el vector, entonces se
actualiza el vector con esta distancia tentativa. Es decir, si dt(vi) < Dvi ? Dvi =
dt(vi)
Se marca como completo el nodo a.
Se toma como pr�ximo nodo actual el de menor valor en D (puede hacerse almacenando
los valores en una cola de prioridad) y se regresa al paso 3, mientras existan
nodos no marcados.
Una vez terminado al algoritmo, D estar� completamente lleno.

Complejidad
Orden de complejidad del algoritmo:

O(|V|2+|A|) = O(|V|2), sin utilizar cola de prioridad, :O((|A|+|V|) log |V|) = O(|
A| log |V|) utilizando cola de prioridad (por ejemplo, un mont�culo de Fibonacci).
Por otro lado, si se utiliza un mont�culo de Fibonacci, ser�a O(|V| log |V|+|A|).
La complejidad computacional del algoritmo de Dijkstra se puede calcular contando
las operaciones realizadas:

El algoritmo consiste en n-1 iteraciones, como m�ximo. En cada iteraci�n, se a�ade


un v�rtice al conjunto distinguido.
En cada iteraci�n, se identifica el v�rtice con la menor etiqueta entre los que no
est�n en Sk. El n�mero de estas operaciones est� acotado por n-1.
Adem�s, se realizan una suma y una comparaci�n para actualizar la etiqueta de cada
uno de los v�rtices que no est�n en Sk.
Luego, en cada iteraci�n se realizan a lo sumo 2(n-1) operaciones.

Entonces:

Teorema: El algoritmo de Dijkstra realiza O(n2) operaciones (sumas y comparaciones)


para determinar la longitud del camino m�s corto entre dos v�rtices de un grafo
ponderado simple, conexo y no dirigido con n v�rtices.

En general:

Tiempo de ejecuci�n = O(|A|.??_????+|v|.??_????)


|A|: N�mero de aristas
??_????: Complejidad de disminuir clave
|V|: Numero de v�rtices
??_????: Complejidad de extraer m�nimo
Pseudoc�digo
Estructura de datos auxiliar: Q = Estructura de datos cola de prioridad (se puede
implementar con un mont�culo)

DIJKSTRA (Grafo G, nodo_fuente s)


para u ? V[G] hacer
distancia[u] = INFINITO
padre[u] = NULL
visto[u] = false
distancia[s] = 0
adicionar (cola, (s, distancia[s]))
mientras que cola no es vac�a hacer
u = extraer_m�nimo(cola)
visto[u] = true
para todos v ? adyacencia[u] hacer
si distancia[v] > distancia[u] + peso (u, v) hacer
distancia[v] = distancia[u] + peso (u, v)
padre[v] = u
adicionar(cola,(v, distancia[v]))
Otra versi�n en pseudoc�digo sin cola de prioridad
funci�n Dijkstra (Grafo G, nodo_salida s)
//Usaremos un vector para guardar las distancias del nodo salida al resto
entero distancia[n]
//Inicializamos el vector con distancias iniciales
booleano visto[n]
//vector de boleanos para controlar los v�rtices de los que ya tenemos la
distancia m�nima
para cada w ? V[G] hacer
Si (no existe arista entre s y w) entonces
distancia[w] = Infinito //puedes marcar la casilla con un -1 por ejemplo
Si_no
distancia[w] = peso (s, w)
fin si
fin para
distancia[s] = 0
visto[s] = cierto
//n es el n�mero de v�rtices que tiene el Grafo
mientras que (no_est�n_vistos_todos) hacer
v�rtice = tomar_el_m�nimo_del_vector distancia y que no est� visto;
visto[v�rtice] = cierto;
para cada w ? sucesores (G, v�rtice) hacer
si distancia[w]>distancia[v�rtice]+peso (v�rtice, w) entonces
distancia[w] = distancia[v�rtice]+peso (v�rtice, w)
fin si
fin para
fin mientras
fin funci�n.
Al final, tenemos en el vector distancia en cada posici�n la distancia m�nima del
v�rtice salida a otro v�rtice cualquiera.

Implementaci�n en Java
/**
* Realizar el algoritmo de Dijkstra sobre el grafo
* @param origen nodo inicial
* @param destino nodo destino
* @return camino ArrayList con el camino a seguir.
*/
public ArrayList<Integer> dijkstra(int origen, int destino) {
ArrayList<Integer> camino= new ArrayList<Integer>();
int distancia=Grafo.INFINITO;
int nodo=origen;
boolean fin=true;
camino.add(nodo);
while(fin) {
if(this.floydC[nodo][destino]<distancia) {
/*El metodo siguiente(nodo, destino), nos devuelve
el siguiente nodo a visitar*/
nodo=this.siguiente(nodo, destino);
camino.add(nodo);
}

if(nodo==destino) {
fin=false;
}
}

return camino;
}
Otra versi�n en C++ del algoritmo de Dijkstra
//Declarando variables
#define MAX_NODOS 1024 /* n�mero m�ximo de nodos */
#define INFINITO 1000000000 /* un n�mero mayor que cualquier ruta m�xima */
int n,i,k,minimo, dist[MAX_NODOS][MAX_NODOS]; /* dist[i][j] es la distancia de i a
j */

struct nodo { /* Indica eL estado del nodo,la ruta y quien lo precede a dicho nodo
*/
int predecesor; /* nodo previo */
int longitud; /* longitud del origen a este nodo */
bool etiqueta; /*verdadero para un nodo permanente y falso para nodo
tentativo*/
} nodo[MAX_NODOS];
void inicializacion(){
for (p = &nodo[0]; p < &nodo[n]; p++) { /* estado de inicializaci�n*/
p->predecesor = -1;
p->longitud = INFINITO;
p->etiqueta = false;
}
}
void relajar(){
for (int i = 0; i <n; i++){ /* este grafo tiene n nodos */
if (dist[k][i] != 0 && nodo[i].etiqueta == false) {
if (nodo[k].longitud + dist[k][i] < nodo[i].longitud) {
nodo[i].predecesor = k;
nodo[i].longitud = nodo[k].longitud + dist[k][i];
}
}
}
}
void extraer_minimo(){ /* Encuentra los nodo etiquetados tentativamente y
determina el menor entre estos nodos tentativos. */
k = 0;
minimo = INFINITO;
for (i = 0; i < n; i++){
if (nodo[i].etiqueta == false && nodo[i].longitud < minimo) {
minimo = nodo[i].longitud;
k = i;
}
}
}

void camino_corto(int s, int t, int camino[]) {


inicializacion();
nodo[t].longitud = 0; nodo[t].etiqueta = true;
k = t; /* k es el nodo de trabajo inicial */
do{ /* �hay una ruta mejor desde k? */
relajar();
extraer_minimo();
nodo[k].etiqueta = true;
} while (k != s);
/* Copia la ruta en el arreglo de salida y procede a ir imprimiendolo. */
i = 0; k = s;
cout<< "La ruta es: ";
do {
cout<< k<< " ";
camino[i] = k;
k = nodo[k].predecesor;
i++;
} while (k >= 0);
cout <<"La ruta minima es: "<<minimo<<endl ;
}
int main(){
int nodo_final,nodo_inicial,arista;
//solicita o ingresa directamente los valores de nodo_final,nodo_inicial
//Llenar de 0 la matriz
for (int i=0; i<n; i++){
for( int j=0; j<n; j++){
dist[i][j]=0;
}
}
// Llenar la matriz dist[i][j]
/*............................
............................*/
//Por ultimo llamar a la funci�n camino corto
camino_corto(nodo_final,nodo_inicial,camino)
return 0;
}

Você também pode gostar