Anda di halaman 1dari 4

El algoritmo de Dijkstra

El algoritmo que vamos a utilizar para determinar la ruta más corta se llama el “algoritmo de
Dijkstra”. El algoritmo de Dijkstra es un algoritmo iterativo que nos proporciona la ruta más corta
desde un nodo inicial particular a todos los otros nodos en el grafo. De nuevo, esto es similar a
los resultados de una búsqueda en anchura.
Para llevar un seguimiento del costo total desde el nodo inicial a cada destino, utilizaremos la
variable de instancia dist en la clase Vertice. La variable de instancia dist contendrá la
ponderación total actual de la trayectoria de menor ponderación desde el inicio hasta el vértice
en cuestión. El algoritmo itera una vez por cada vértice del grafo; sin embargo, el orden en que
iteramos sobre los vértices es controlado por una cola de prioridad. dist es el valor que se usa
para determinar el orden de los objetos en la cola de prioridad. Cuando se crea un vértice,
a dist se le asigna un número muy grande. Teóricamente, a distse le asignaría infinito, pero en
la práctica simplemente asignamos un número que sea mayor que cualquier distancia real que
pudiéramos tener en el problema que estamos tratando de resolver.
El código para el algoritmo de Dijkstra se muestra en el Programa 1. Cuando el algoritmo
termine, las distancias estarán asignadas correctamente, así como lo estarán los enlaces a los
predecesores para cada vértice en el grafo.

Programa 1

from pythoned.grafos import ColaPrioridad, Grafo, Vertice

def dijkstra(unGrafo,inicio):

cp = ColaPrioridad()

inicio.asignarDistancia(0)

cp.construirMonticulo([(v.obtenerDistancia(),v) for v in unGrafo])

while not cp.estaVacia():

verticeActual = cp.eliminarMin()

for verticeSiguiente in verticeActual.obtenerConexiones():

nuevaDistancia = verticeActual.obtenerDistancia() \

+ verticeActual.obtenerPonderacion(verticeSiguiente)

if nuevaDistancia < verticeSiguiente.obtenerDistancia():

verticeSiguiente.asignarDistancia( nuevaDistancia )

verticeSiguiente.asignarPredecesor(verticeActual)

cp.decrementarClave(verticeSiguiente,nuevaDistancia)

El algoritmo de Dijkstra utiliza una cola de prioridad. Quizás usted recuerda que una cola de
prioridad está basada en el montículo que implementamos en el capítulo sobre árboles. Hay un
par de diferencias entre esa implementación sencilla y la implementación que usamos aquí
para el algoritmo de Dijkstra. En primer lugar, la clase ColaPrioridad almacena tuplas de parejas
clave-valor. Esto es importante para el algoritmo de Dijkstra ya que la clave en la cola de
prioridad debe coincidir con la clave del vértice en el grafo. En segundo lugar, el valor se utiliza
para decidir la prioridad y, por tanto, la posición de la clave en la cola de prioridad. En esta
implementación usamos la distancia al vértice como la prioridad ya que, como veremos cuando
exploremos el vértice siguiente, siempre queremos explorar el vértice que tenga la menor
distancia. La segunda diferencia es la adición del método decrementarClave. Como podrá notar,
este método se utiliza cuando se decrementa la distancia a un vértice que ya está en la cola, y
por lo tanto ese vértice se mueve hacia el frente de la cola.
Miremos una aplicación del algoritmo de Dijkstra, un vértice a la vez, usando la siguiente
secuencia de figuras como referencia. Comenzamos con el vértice uu. Los tres vértices
adyacentes a uu son v,w,v,w, y xx. Dado que las distancias iniciales a v,w,v,w, y xx están
todas inicializadas a sys.maxint, los nuevos costos para llegar a ellos a través del nodo de inicio
son todos sus costos directos. Así que actualizamos los costos a cada uno de estos tres nodos.
También asignamos uu al predecesor para cada nodo y agregamos cada nodo a la cola de
prioridad. Utilizamos la distancia como clave para la cola de prioridad. El estado del algoritmo
se muestra en la Figura 3.

En la siguiente iteración del ciclo while examinamos los vértices que son adyacentes a xx. El
vértice xx es el siguiente porque tiene el costo total más bajo y, por lo tanto, se movió hasta el
principio de la cola de prioridad. En xx miramos a sus vecinos u,v,wu,v,w y yy. Para cada
vértice vecino verificamos si la distancia a ese vértice a través de xx es menor que la distancia
conocida previamente. Obviamente éste es el caso de yy ya que su distancia era sys.maxint. No
es el caso de uu ni de vv ya que sus distancias son 0 y 2 respectivamente. Sin embargo, ahora
sabemos que la distancia a ww es menor si pasamos por xx que desde uu directamente a ww.
Dado que éste es el caso, actualizamos ww con una nueva distancia y cambiamos el
predecesor para ww de ser uu a ser xx. Mire la Figura 4 para ver el estado de todos los
vértices.
El paso siguiente es mirar los vértices vecinos de vv (ver la Figura 5). Este paso no produce
cambios en el grafo, por lo que pasamos al nodo yy. En el nodo yy (ver la Figura 6)
descubrimos que es más barato llegar a ambos ww y zz, por lo que ajustamos las distancias y
los enlaces predecesores de acuerdo con ello. Finalmente verificamos los nodos ww y zz (ver
la Figura 6 y la Figura 8). Sin embargo, no se encuentran cambios adicionales y por lo tanto la
cola de prioridad está vacía y el algoritmo de Dijkstra termina.

Figura 3: Seguimiento al algoritmo de Dijkstra


Figura 4: Seguimiento al algoritmo de Dijkstra

Figura 5: Seguimiento al algoritmo de Dijkstra

Figura 6: Seguimiento al algoritmo de Dijkstra


Figura 7: Seguimiento al algoritmo de Dijkstra

Figura 8: Seguimiento al algoritmo de Dijkstra

Es importante tener en cuenta que el algoritmo de Dijkstra funciona sólo cuando todas las
ponderaciones son positivas. Convénzase de que el algoritmo nunca terminaría si usted
introduce una ponderación negativa en una de las aristas del grafo.
Notemos que, para enrutar mensajes a través de Internet, se utilizan otros algoritmos para
encontrar la ruta más corta. Uno de los problemas con el uso del algoritmo de Dijkstra en el
caso de Internet es que usted debe tener una representación completa del grafo para que el
algoritmo funcione. La implicación de esto es que cada enrutador debería tener un mapa
completo de todos los enrutadores en Internet. En la práctica, éste no es el caso y otras
variaciones del algoritmo permiten que cada enrutador descubra el grafo sobre la marcha. Uno
de tales algoritmos, sobre el cual usted quizá quiera leer, se llama el algoritmo de enrutamiento
del “vector de distancias”.

Anda mungkin juga menyukai