UNIVERSIDAD TECNOLÓGICA NACIONAL Materia: Algoritmos Complejos y Estructuras Complejas de Datos Curso: K3051 Docente: Pablo A. Sznajdleder Tema de investigación: Algoritmo de Dijkstra Apellido y Nombre Numero de Legajo Croce Agustin 143.356-8 Hamie, Lucas Tamburro, Fernando Gabriel 140.703-0 Relañez, Alejandro 142.070-7 Milar, Tomás 143.409-3 Página 1 de 10 Indice 0. 1. 2. 3. 4. 5. 6. 7. Indice . ………………………………………………………………………………....Pag. 2 Nociones previas sobre grafos ……………………………………………………..Pag. 3 Introducción ………………………………………………..………………………….Pag. 3 Estrategia del algoritmo ……………………………..……………………………….Pag. 4 Complejidad …….……………………………..………………………………………Pag. 5 Casos de uso o aplicaciones prácticas …………………………………………….Pag. 9 Conclusión……………………………………………………………………………..Pag. 10 Fuentes…………………………………………….…………………………………..Pag. 10 Página 2 de 10 Nociones previas sobre grafos ● Grafo: Conjunto de vértices o nodos unido por aristas o arcos con el fin de representar las relaciones binarias entre los elementos del mismo. ● Vértice: Unidad fundamental e indivisible de un grafo. De estos parten y llegan las aristas ● Arista: Relación entre dos vértices de un grafo sin dirección. ● Arista Dirigida: Arista la cual también contiene una direccion. ● Arista Ponderada: Arista que tiene asociado un peso. ● Vértice adyacente: Un vértice a es adyacente al vértice b si existe una arista que parte de a y llega a b. ● Grafo Dirigido: Grafo donde todas sus aristas son dirigidas. ● Grafo Ponderado: Grafo donde todas las aristas son ponderadas. ● Camino de X a Y: Conjunto de aristas que conectan los vértices X e Y. Introduccion. El algoritmo de Dijkstra, también conocido como el algoritmo del camino mínimo fue creado en 1950 por el holandés Edsger Wybe Dijkstra. Entre los otros aportes de Dijkstra a la computación se destaca la notación polaca inversa, el algoritmo del banquero y la estructura del semáforo para coordinar el uso de recursos compartidos entre diferentes procesos. Este algoritmo resuelve el problema del camino más corto, es decir, encontrar en un grafo dirigido ponderado el camino entre dos vértices tal que la suma del peso de sus aristas sea mínima. Página 3 de 10 Estrategia del algoritmo Paso #1: Se marcan todos los vértices como no visitados. Paso #2: Se establece la distancia del vértice inicial como cero y la del resto de los vértices como infinita. Paso #3: Se establece como vértice actual el nodo inicial. Paso #4: Por cada vértice no visitado adyacente al vértice actual se establece como la nueva distancia al mínimo entre la distancia actual y la suma de la distancia del vértice actual más el peso de la arista que conecta ambos vértices. Paso #5: Se marca el vértice actual como visitado. Paso #6: Si el nodo destino ha sido marcado el algoritmo es finalizado siendo la distancia del camino mínimo la distancia del nodo destino. En caso de que el nodo marcado no sea el nodo destino se elige como nodo actual al nodo no visitado con la menor distancia y se vuelve a #4. Versión con cola de prioridad Las colas con prioridad (y por tanto la estructura de datos montículo con la que se representan en memoria) se utilizan a menudo para mejorar la eficiencia de algoritmos en los que iterativamente se precisa conocer el mínimo (o máximo) de un conjunto de valores y eliminarlo del conjunto. 1 método Dijkstra(Grafo,origen): 2 creamos una cola de prioridad Q 3 agregamos origen a la cola de prioridad Q 4 mientras Q no este vacío: 5 sacamos un elemento de la cola Q llamado u 6 si u ya fue visitado continuo sacando elementos de Q 7 marcamos como visitado u 8 para cada vértice v adyacente a u en el Grafo: 9 sea w el peso entre vértices ( u , v ) 10 si v no ha sido visitado: 11 Relajacion( u , v , w ) 1 método Relajacion( actual , adyacente , peso ): 2 si distancia[ actual ] + peso < distancia[ adyacente ] 3 distancia[ adyacente ] = distancia[ actual ] + peso 4 agregamos adyacente a la cola de prioridad Q Página 4 de 10 Complejidad algorítmica Sin utilizar cola de prioridad: O(|V|2+|E|) = O(|V|2) Utilizando cola de prioridad: O((|E|+|V|).log |V|) Siendo |V| la cantidad de vértices, y |E| la cantidad de aristas del grafo. Sin cola de prioridad Con cola de prioridad Crear Arreglo = O(1) Montículo = O(V) EXTRAER-MIN O(V) O(lg V) x V veces RELAJACION O(1) O(lg V) x E veces a lo mas Total O(V2+E) = O(V2) O((V+E)lg V) = O(E lg V) Página 5 de 10 Ejemplo aplicado. (Para simplificar, se condensaron y redujeron los pasos de la estrategia en la pág. 4, y se llamó “vértice” al nodo, y “distancia” al camino o peso a recorrer para avanzar de un nodo a otro). 1- Me paro en el primer vertice, inicializando distancia actual o "recorrida" en 0. En todos los demas vertices, inicializo en infinito. Una distancia infinita representa que aún no conozco o no calculé un camino para llegar hasta ese vértice, desde donde estoy parado actualmente. 2- Obtengo los vertices candidatos (aquellos con paso directo desde el vertice actual). Como ahora los conozco, calculo la distancia que tengo para recorrer hasta cada uno de ellos, y si es menor que la que tenían previamente, la actualizo con el menor valor. Esta distancia se calcula como la distancia actual o recorrida hasta el momento + distancia a recorrer para llegar a dicho candidato. Actualizo su distancia que es la suma de la distancia que recorri hasta ahora + la distancia a recorrer para llegar a dicho candidato. 3- De los candidatos, avanzo a aquel con menor distancia final, que es la que calculé en (2). 4- Ahora la distancia recorrida, pasa a ser la que calculé en (2) para llegar hasta el vértice donde estoy parado. Si el vértice actual no es final: vuelvo al paso (2) y repito el proceso para los candidatos próximos que tengo en este momento. Puede pasar que algunos ya haya calculado su distancia anteriormente, pero no importa porque si la nueva distancia calculada es menor a la anterior, la piso, sino; si es mayor o igual, dejo la que estaba antes. De esta forma, garantizo que la distancia total hasta ese vértice próximo, vaya siendo achicándose a medida que exploro los distintos caminos en el grafo. Tenemos este grafo. Queremos encontrar el camino mínimo desde a hasta z, asumiendo que el sentido del grafo es de izquierda a derecha. Paso #1: inicializo distancia del vértice inicial en 0, todas las demás en infinito. Camino: A Distancia: 0 Página 6 de 10 Paso #2: obtengo los vértices adyacentes (nodos próximos), y actualizo las distancias a cada uno de ellos. Camino: A Distancia: 0 Paso #3: Vemos que la menor distancia es al vértice C entonces avanzamos a C. Camino: AC Distancia: 2 Paso #4: como no llegamos al vértice final, repetimos el paso 2 pero esta vez con respecto al vértice actual, es decir C. Sus vértices adyacentes son B, D y E. - La distancia a E es 2+10 = 12, y como 12 es menor a infinito, actualizo la distancia minima de E; - la distancia a D es 2+8=10, menor que infinito entonces actualizo. Lo mismo para B, la distancia a B ahora es 2+1=3, y como 3 es menor a 4 actualizo su distancia mínima. Camino: AC Distancia: 2 Continuo con el Paso #3, vemos que ahora la menor distancia de los nodos adyacentes es B con 3. Camino: ACB Distancia: 3 Paso #4: como B no es final, vuelvo al paso #2, exploro los vértices adyacentes y actualizo las distancias cuando sean menores a las que tenían calculadas. En este caso para llegar a D, tengo 3+5 = 8, es menor que 10 entonces lo actualizo. Camino: ACBD Distancia: 8 Página 7 de 10 Avanzo al vértice a menor distancia (en este caso D), y exploro los vértices adyacentes. La distancia a E desde D es 8+2=10, menor que su valor anterior 12, entonces la actualizo. Para Z lo mismo, 8+6=14 es menor que infinito. Camino: ACBD Distancia: 8 Desde D el vértice a menor distancia es E con 10, con respecto a Z que tiene 14. Camino: ACBDE Distancia: 10 Finalmente, la distancia a Z es 10+3=13, menor que 14, entonces avanzo a Z y es el vértice final. Por lo tanto, el camino mínimo entre A y Z es : Camino: ACBDEZ Distancia: 13 Ahora, qué hubiera pasado si de E a Z teníamos una distancia mayor a 14? Si el próximo paso me hubiera dado una distancia mayor a la distancia precalculada (10+10=20 es mayor que 14), no podría ni actualizar la distancia del destino Z porque no es menor, ni podría avanzar allí porque no sería un camino mínimo. Entonces tengo que regresar por donde vine (vértice D), descartar el vértice que acabo de recorrer y retroceder (E), y volver a repetir el paso #3 del algoritmo nuevamente desde D. Es decir, el camino que tenía calculado antes y no seguí, ahora es candidato nuevamente a ser mínimo. Finalmente, el camino A-Z en esta variante del grafo queda: Camino: ACBDZ Distancia: 14 Página 8 de 10 Otro ejemplo de aplicación http://jariasf.files.wordpress.com/2012/03/270px-dijksta_anim.gif Casos de uso o aplicaciones prácticas Las aplicaciones del algoritmo de Dijkstra son muy diversas y de gran importancia en distintas áreas del conocimiento. Vamos a presentar algunas de ellas. Encaminamiento de paquetes por los routers: En un momento dado, un mensaje puede tardar cierta cantidad de tiempo en atravesar cada línea (por ejemplo, por efectos de congestión). En este caso, tenemos una red con dos nodos especiales, el de inicio y el de llegada. Los pesos de las aristas serían los costes. El objetivo del algoritmo es encontrar un camino entre estos dos nodos cuyo coste total sea el mínimo. Aplicaciones para Sistemas de información geográficos: extracción de características curvilíneas de imágenes usando técnicas de minimización del camino: La imagen se representa como una matriz de puntos, cada uno con una intensidad. Cada nodo es un punto (píxel) de la imagen. El peso de las aristas es la diferencia de color. Reconocimiento de lenguaje hablado: Se puede construir un grafo cuyos vértices correspondan a palabras posibles y las aristas unan palabras que pueden ir colocadas al lado de las otras. Si el peso de las aristas corresponde a la probabilidad de que estén así colocadas, el camino más corto en el grafo será la mejor interpretación de la frase. Enrutamiento de aviones y tráfico aéreo: Consiste en un agente de solicitudes de viaje software para hacer un programa de vuelos para los clientes. El agente tiene acceso a una base de datos con todos los aeropuertos y los vuelos como el número de vuelo, el aeropuerto de origen y destino y los horarios de salida y de llegada. La aplicación se usa para determinar la hora de llegada más temprana para el destino dado un aeropuerto de origen y hora de inicio. Página 9 de 10 Conclusión: El presente algoritmo debe tomarse como lo que es: una herramienta más para resolver problemas. Su utilidad yace con respecto a otros como el Breadth First Search, al poder trabajar con grafos ponderados cuyas distancias puedan ser mayores a 1, garantizando así siempre el camino mínimo no sólo en número de pasos dados, sino también en distancia acumulada recorrida. Por otro lado da lugar también a complejizar la noción de “distancia” entre dos nodos, por ejemplo en un GPS, tomando en cuenta otros factores como el tráfico, la seguridad de la zona, el clima, etc. De esta forma es posible encontrar el camino mínimo de un punto a otro de acuerdo a más de un parámetro relevante. Fuentes: Implementacion en codigo java http://www.algolist.com/code/java/Dijkstra%27s_algorithm Ejemplo explicado – “Shortest Path using Dijkstra's Algorithm“ https://www.youtube.com/watch?v=WN3Rb9wVYDY Algoritmo de dijstra – Wikipedia http://es.wikipedia.org/wiki/Algoritmo_de_Dijkstra http://en.wikipedia.org/wiki/Dijkstra's_algorithm Aplicaciones del algoritmo http://bioinfo.uib.es/~joemiro/aenui/procJenui/ProcWeb/actas2001/saalg223.pdf Complejidad algoritmica http://personal.cimat.mx:8181/~cesteves/cursos/comp420/pdf/AlgoritmosCaminosCortos.pdf Página 10 de 10