algoritmo de dijkstra

9
 Algoritmo de Dijkstra  Tenie ndo un gra fo dir igido 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 al resto de los nodos. 1. Inicializar tod as las dist ancias 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. 2. Sea a = x ( tomamos a como nodo actual). 3. Recorremos todos los nodos adyacentes de a, excepto los nodos marcados, llamaremos a estos vi. 4. Si la distancia desde x hasta vi guardada en D es mayor que la distancia desde x hasta a, sumada a la distancia desde a hasta v i ; esta se sustituye con la segunda nombrada, esto es: si (D i > D a + d(a, v i )) entonces D i = D a + d(a, v i ) 5. Marcamos como co mplet o el nodo a. 6. Tomamos c omo pr óximo nodo ac tual el de menor va lor en D (puede hacerse almacenando los valores en una cola de prioridad) y volvemos al paso 3 mientras existan nodos no marcados. Una vez terminado al al goritmo, D estará completamente lleno. 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 distancia[ s] = 0 Encolar (cola, grafo)  mientras que cola no es vacía hacer  u = extraer_minimo(cola)  para v  adyacencia[ u] hacer  si distancia[ v ] > distancia[u] + peso (u, v) hacer distancia[ v ] = distancia[u] + peso (u, v) padre[ v ] = u Actualizar(cola,distancia,v) Otra versión en pseudocód igo 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

Upload: manuel-destroza

Post on 20-Jul-2015

313 views

Category:

Documents


0 download

TRANSCRIPT

5/17/2018 Algoritmo de Dijkstra - slidepdf.com

http://slidepdf.com/reader/full/algoritmo-de-dijkstra-55b07bfd486f4 1/9

Algoritmo de Dijkstra

 Teniendo un grafo dirigido ponderado de N nodos no aislados, sea x elnodo inicial, un vector D de tamaño N guardará al final del algoritmolas distancias desde x al resto de los nodos.

1. Inicializar todas las distancias en D con un valor infinito relativoya que son desconocidas al principio, exceptuando la de x que sedebe colocar en 0 debido a que la distancia de x a x sería 0.

2. Sea a = x (tomamos a como nodo actual).3. Recorremos todos los nodos adyacentes de a, excepto los nodos

marcados, llamaremos a estos vi.4. Si la distancia desde x hasta vi guardada en D es mayor que la

distancia desde x hasta a, sumada a la distancia desde a hastavi; esta se sustituye con la segunda nombrada, esto es:si (Di > Da + d(a, vi)) entonces Di = Da + d(a, vi)

5. Marcamos como completo el nodo a.6. Tomamos como próximo nodo actual el de menor valor en D

(puede hacerse almacenando los valores en una cola deprioridad) y volvemos al paso 3 mientras existan nodos nomarcados.

Una vez terminado al algoritmo, D estará completamente lleno.

Pseudocódigo

• Estructura de datos auxiliar: Q = Estructura de datos Cola deprioridad (se puede implementar con un montículo)

  DIJKSTRA (Grafo G, nodo_fuente s)para u ∈ V[G] hacer

distancia[u] = INFINITOpadre[u] = NULL

distancia[s] = 0Encolar (cola, grafo)

  mientras que cola no es vacía hacer  u = extraer_minimo(cola)

  para v  ∈ adyacencia[u] hacer  si distancia[v ] > distancia[u] + peso (u, v) hacer

distancia[v ] = distancia[u] + peso (u, v)padre[v ] = u

Actualizar(cola,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

restoentero distancia[n] //Inicializamos el vector con distancias iniciales

5/17/2018 Algoritmo de Dijkstra - slidepdf.com

http://slidepdf.com/reader/full/algoritmo-de-dijkstra-55b07bfd486f4 2/9

booleano visto[n] //vector de boleanos para controlar los vertices delos 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 paradistancia[s] = 0visto[s] = cierto//n es el número de vertices que tiene el Grafo

  mientras que (no_esten_vistos_todos) hacer vertice = coger_el_minimo_del_vector distancia y que no este visto;visto[vertice] = cierto;

  para cada w∈ sucesores (G, vertice) hacer  si distancia[w]>distancia[vertice]+peso (vertice, w) entonces

distancia[w] = distancia[vertice]+peso (vertice, w)  fin si  fin para  fin mientrasfin función

Al final tenemos en el vector distancia en cada posición la distanciamínima del vertice salida a otro vertice cualquiera.

Implementación

C++// Declaraciones en el archivo .h

int cn; //cantidad de nodos

vector< vector<int> > ady; //matriz de adyacencia

deque<int> path; // camino minimo de dijkstra

int caminosPosibles; // cantidad de caminos posibles

 

vector<int> dijkstra(int nodo, int final = 0); // el parámetro 'final' esopcional

 

// Devuelve un vector con las distancias minimas del nodo inicial alresto de los vertices.

// Guarda en path los nodos que forman el camino minimo y muestra lacantidad de caminos posibles

5/17/2018 Algoritmo de Dijkstra - slidepdf.com

http://slidepdf.com/reader/full/algoritmo-de-dijkstra-55b07bfd486f4 3/9

vector<int> Grafo :: dijkstra(int inicial, int final){

vector<int> distancias;

list<int> noVisitados;

list<int> :: iterator itList;

 

caminosPosibles = 0;

 

//decremento para manejarme en [0, cn)

inicial--; final--;

 

// Seteo las distancias en infinito y marco todos los nodos como novisitados

for(int i = 0; i < cn; i++){

distancias.push_back(INF);

noVisitados.push_back(i);

}

 

// Actual es el nodo inicial y la distancia a si mismo es 0

int actual = inicial;

distancias[inicial] = 0;

 

// Inicializo el camino minimo en infinito.

path = deque<int>(cn, INF);

 

while(!noVisitados.empty()){

// Para cada nodo no visitado, calculo la distancia tentativa alnodo actual;

// si es menor que la distancia seteada, la sobreescribo.

for(itList = noVisitados.begin(); itList != noVisitados.end(); itList+

+){

5/17/2018 Algoritmo de Dijkstra - slidepdf.com

http://slidepdf.com/reader/full/algoritmo-de-dijkstra-55b07bfd486f4 4/9

// distancia tentativa = distancia del inicial al actual + distanciadel actual al noVisitado

int dt = distancias[actual] + ady[actual][*itList];

if(distancias[*itList] > dt){

distancias[*itList] = dt;

 

// Agrego a camino el nodo (actual) a traves del cual el nodoinicial se conecta con *itList

path[*itList] = actual;

}

else if(distancias[*itList] == dt && *itList == final)

caminosPosibles++;

 

}

// Marco como visitado el nodo actual, la distancia seteada es laminima.

noVisitados.remove(actual);

 

// Si no lo pase como parametro final vale -1, en ese caso el if nunca da true.

if(actual == final) break;

 

// El nodo actual ahora es el nodo no visitado que tiene la menordistancia al nodo inicial.

int min = INF;

for(itList = noVisitados.begin(); itList != noVisitados.end(); itList++)

if(min >= distancias[*itList]){

min = distancias[*itList];

actual = *itList;

}

}

5/17/2018 Algoritmo de Dijkstra - slidepdf.com

http://slidepdf.com/reader/full/algoritmo-de-dijkstra-55b07bfd486f4 5/9

 

// Si final vino como parámetro obtengo el camino minimo y loguardo en path

if(final != -1){

deque<int> temp;

int nodo = final;

 

while(nodo != inicial){

temp.push_front(nodo);

nodo = path[nodo];

}

 

path = temp;

 

if(ady[inicial][final] != INF)

caminosPosibles++;

 

cout << "Caminos Posibles " << caminosPosibles << endl;

}

return distancias;

}

Ejemplo

El siguiente ejemplo se desarrollará con el fin de encontrar el caminomás corto desde a hasta z:

5/17/2018 Algoritmo de Dijkstra - slidepdf.com

http://slidepdf.com/reader/full/algoritmo-de-dijkstra-55b07bfd486f4 6/9

Leyenda:

• Rojo: Aristas y vértices pertenecientes a la soluciónmomentánea.

• Azul: Aristas y vértices candidatos.

Paso 1

En este primer paso, podemos apreciar que hay tres candidatos: Losvértices b, c y d. En este caso, hacemos el camino desde el vértice a,hasta el vértice d, ya que es el camino más corto de los tres.

Solución momentánea:

• Camino: AD• Distancia:5

5/17/2018 Algoritmo de Dijkstra - slidepdf.com

http://slidepdf.com/reader/full/algoritmo-de-dijkstra-55b07bfd486f4 7/9

Paso 2

Ahora, vemos que se añade un nuevo candidato, el vértice e, y elvértice c, pero esta vez a través del d. Pero el camino mínimo surge al

añadir el vértice c.

Solución momentánea:

• Camino: ADC• Distancia:9

Paso 3

En este paso no se añade ningún candidato más puesto que el últimovértice es el mismo que en el paso anterior. En este caso el caminomínimo hallado es el siguiente:

Solución momentánea:

• Camino: ADCB• Distancia:11

5/17/2018 Algoritmo de Dijkstra - slidepdf.com

http://slidepdf.com/reader/full/algoritmo-de-dijkstra-55b07bfd486f4 8/9

Paso 4

Como podemos comprobar, se han añadido dos candidatos nuevos, losvértices f y g, ambos a través del vértice b. El mínimo camino halladoen todo el grafo hasta ahora es el siguiente:

Solución momentánea:

• Camino: ADCBF• Distancia:15

Paso 5

En este antepenúltimo paso, se añaden tres vértices candidatos, losvértices g, z y e. Este último ya estaba pero en esta ocasión aparece através del vértice f. En este caso el camino mínimo, que cambia unpoco con respecto al enterior, es:

Solución momentánea:

• Camino: ADCBF• Distancia:19

5/17/2018 Algoritmo de Dijkstra - slidepdf.com

http://slidepdf.com/reader/full/algoritmo-de-dijkstra-55b07bfd486f4 9/9

Paso 6

En el penúltimo paso, vuelve a aparecer otro candidato: el vértice e,pero esta vez a través del vértice f. De todas formas, el camino mínimovuelve a cambiar para retomar el camino que venía siguiendo en lospasos anteriores:

Solución momentánea:

• Camino: ADCBFE• Distancia:18

Paso 7

Por fin, llegamos al último paso, en el que sólo se añade un candidato,el vértice z a través del e. El camino mínimo y final obtenido es:

Solución Final:

• Camino: ADCBFEZ• Distancia:23