algoritmo de dijkstra
Post on 20-Jul-2015
315 Views
Preview:
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
top related