Está en la página 1de 19

1.

ALGORITMO DE LA RUTA MAS CORTA El algoritmo de Dijkstra (algoritmo de caminos mnimos), es un algoritmo para la distancia ms corta de un punto a cualquier otro. Su nombre se refiere a Edsger Dijkstra, quien lo describi por primera vez en 1959. La idea subyacente en este algoritmo consiste en ir explorando todos los caminos ms cortos que parten del nodo origen y que llevan a todos los dems nodos; cuando se obtiene el camino ms corto desde el nodo origen, al resto de nodos que componen el grafo, el algoritmo se detiene. Explicacin del Algoritmo: Supongamos que tenemos los siguientes nodos con sus respectivas distancias entre ellos.

Para este ejemplo, se calcular la distancia ms corta del Nodo 4 a cualquier otro. Primero se calcular las etiquetas correspondientes a cada nodo. Una etiqueta consta de dos partes: la distancia a cumulada y el nodo de procedencia. [Acumulado, procedencia] Distancia = distancia entre el nodo base y el nodo actual. Distancia acumulada = acumulado del nodo base + distancia Nodo de procedencia = nodo base Conforme se vaya calculando las etiquetas se irn marcando los nodos para que no se forme un ciclo infinito. En este caso el Nodo 4 es el punto de inicio, por ahora ser el Nodo base, se marca y como no tiene distancia acumulada y nodo de procedencia su etiqueta ser: [0,0].

Paso 1: Ahora se busca que nodos estn conectados al Nodo 4, los cuales son: 1, 3, 6 y 7. Calcular la etiqueta de cada uno de los nodos conectados al Nodo base: Etiqueta del Nodo 1: Nodo actual = Nodo 1 Distancia = Distancia del Nodo base al Nodo actual = 3 Distancia acumulada = Acumulado del Nodo base + Distancia = 0+3 = 3 Procedencia = Nodo 4 La etiqueta del Nodo 1 quedara: [3, Nodo 4]

Etiqueta del Nodo 3: Nodo actual = Nodo 3 Distancia = Distancia del Nodo base al Nodo actual = 2 Distancia acumulada =Acumulado del Nodo base + Distancia =0+2 = 2 Procedencia = Nodo 4 La etiqueta del Nodo 3 quedara: [2, Nodo 4]

Etiqueta del Nodo 6: Nodo actual = Nodo 6 Distancia = Distancia del Nodo base al Nodo actual = 1 Distancia acumulada =Acumulado del Nodo base + Distancia =0+1 = 1 Procedencia = Nodo 4 La etiqueta del Nodo 6 quedara: [1, Nodo 4]

Etiqueta del Nodo 7: Nodo actual = Nodo 7 Distancia = Distancia del Nodo base al Nodo actual = 3 Distancia acumulada =Acumulado del Nodo base + Distancia =0+3 = 3 Procedencia = Nodo 4 La etiqueta del Nodo 7 quedara: [3, Nodo 4]

Una vez calculadas las etiquetas de los nodos, se busca el Nodo que tenga la etiqueta con menor distancia acumulada y que no est marcado, como vemos es el Nodo 6. Ahora el Nodo 6 pasar a ser el Nodo base y se marca.

Paso 2: Se buscan los Nodos conectados al Nodo 6 y que NO estn marcados: 3, 5 y 7. Calcular la etiqueta de cada uno de los nodos conectados al Nodo base: Etiqueta del Nodo 3: Nodo actual = Nodo 3 Distancia = Distancia del Nodo base al Nodo actual = 2 Distancia acumulada = Acumulado del Nodo base + Distancia = 1+2 = 3 Procedencia = Nodo 6 Como la distancia acumulada es mayor que la distancia acumulada que tiene establecida en su etiqueta el Nodo 3, entonces la etiqueta actual no se asigna, ya que solo se busca etiquetas menores o iguales a la ya establecida. Por tanto la etiqueta del Nodo 3 quedara: [2, Nodo 4]

Etiqueta del Nodo 7: Nodo actual = Nodo 7 Distancia = Distancia del Nodo base al Nodo actual = 2 Distancia acumulada = Acumulado del Nodo base + Distancia = 1+2 = 3 Procedencia = Nodo 6 En este caso la distancia acumulada es igual que la distancia acumulada que tiene establecida en su etiqueta el Nodo 7, entonces la etiqueta actual se aade, ya que solo buscamos etiquetas menores o iguales a la ya establecida. Las etiquetas del Nodo 7 quedaran: [3, Nodo 4], [3, Nodo 6]

Etiqueta del Nodo 5: Nodo actual = Nodo 5 Distancia = Distancia del Nodo base al Nodo actual = 3 Distancia acumulada = Acumulado del Nodo base + Distancia = 1+3 = 4 Procedencia = Nodo 6 La etiqueta del Nodo 5 quedara: [4, Nodo 6]

Una vez calculadas las etiquetas de los nodos, se busca el Nodo que tenga la etiqueta con menor distancia acumulada y que no est marcado, el cual ahora es el

Nodo 3. Ahora el Nodo 3 pasar a ser el Nodo base y se marca.

Paso 3: Se buscan los Nodos conectados al Nodo 3 y que NO estn marcados: 2 y 5. Calcular la etiqueta de cada uno de los nodos conectados al Nodo base: Etiqueta del Nodo 2: Nodo actual = Nodo 2 Distancia = Distancia del Nodo base al Nodo actual = 1 Distancia acumulada = Acumulado del Nodo base + Distancia = 2+1 = 3 Procedencia = Nodo 3 La etiqueta del Nodo 2 quedara: [3, Nodo 3]

Etiqueta del Nodo 5: Nodo actual = Nodo 5 Distancia = Distancia del Nodo base al Nodo actual = 3 Distancia acumulada = Acumulado del Nodo base + Distancia = 2+3 = 5 Procedencia = Nodo 3 Como la distancia acumulada es mayor que la distancia acumulada que tiene establecida en su etiqueta el Nodo 5, entonces la etiqueta actual no se asigna, ya que solo buscamos etiquetas menores o iguales a la ya establecida. La etiqueta del Nodo 5 quedara: [4, Nodo 6]

Ya encontradas las etiquetas de los nodos, se busca el Nodo que tenga la etiqueta con menor acumulado y que no est marcado. Ahora, se puede observar que los Nodos 1, 2 y 7 tienen igual distancia acumulada, cuando esto ocurre se opta por tomar cualquiera de ellos aleatoriamente como el Nodo base, en este caso se tomara el Nodo 7. Ahora el Nodo 7 pasar a ser el Nodo base y se marca.

Paso4: Se buscan los Nodos conectados al Nodo 7 y que NO estn marcados. En este caso no tiene nodos conectados que no estn marcados. Buscamos el Nodo que tenga la etiqueta con menor acumulado y que no est marcado, como vemos ahora los Nodos 1 y 2 tienen igual distancia acumulada, tomamos cualquiera de ellos aleatoriamente, en este caso tomaremos el Nodo 2 Ahora el Nodo 2 pasar a ser el Nodo base y se marca.

Paso 5: Se buscan los Nodos conectados al Nodo 2 y que NO estn marcados: 1 y 5. Calcular la etiqueta de cada uno de los nodos conectados al Nodo base:

Etiqueta del Nodo 5: Nodo actual = Nodo 5 Distancia = Distancia del Nodo base al Nodo actual = 2 Distancia acumulada = Acumulado del Nodo base + Distancia = 3+2 = 5 Procedencia = Nodo 2 Ahora, como la distancia acumulada es mayor que la distancia acumulada que tiene establecida en su etiqueta el Nodo 5, entonces la etiqueta actual no se asigna, ya que solo se buscan etiquetas menores o iguales a la ya establecida. La etiqueta del Nodo 5 quedara: [4, Nodo 6]

Etiqueta del Nodo 1: Nodo actual = Nodo 1 Distancia = Distancia del Nodo base al Nodo actual = 3 Distancia acumulada = Acumulado del Nodo base + Distancia = 3+3 = 3 Procedencia = Nodo 2 Como la distancia acumulada es mayor que la distancia acumulada que tiene establecida en su etiqueta el Nodo 1, entonces la etiqueta actual no se asigna, ya que solo se buscan etiquetas menores o iguales a la ya establecida. La etiqueta del Nodo 1 quedara: [3, Nodo 4]

Ahora se busca el Nodo que tenga la etiqueta con menor acumulado y que no est marcado, ahora es el Nodo 1. Ahora el Nodo 1 pasar a ser el Nodo base y se marca.

Paso6: Ahora se buscan los Nodos conectados al Nodo 1 y que NO estn marcados. Como se ve no tiene nodos conectados que no estn marcados. Se busca el Nodo que tenga la etiqueta con menor acumulado y que no est marcado, como vemos el nico que queda libre es el Nodo 5. Ahora el Nodo 5 pasar a ser el Nodo base y se marca.

Paso 7: Se buscan los Nodos conectados al Nodo 5 y que NO estn marcados. Se puede observar que no tiene nodos conectados que no estn marcados. Ahora se busca el Nodo que tenga la etiqueta con menor acumulado y que no est marcado. Se puede observar que ya no existen nodos sin marcar, por lo tanto se ha terminado de calcular las etiquetas a cada Nodo. Las etiquetas son las siguientes: Nodo 1: [3,4] Nodo 2: [3,3] Nodo 3: [2,4] Nodo 4: [0,0] Nodo 5: [4,6] Nodo 6: [1,4] Nodo 7: [3,4], [3,6] 1.1 Ruta ms corta - Solucin por el algoritmo de Dijkstra en Java

Crea una listas de nodos para almacenar los nodos con distancia mnima ya calculada Crear una cola de prioridad para los nodos pendientes de evaluar Inserta el nodo origen a la cola de prioridad Mientras que haya nodos en la cola de prioridad o Extrae el primer nodo de la cola de prioridad (tmp)

o o o

Agrega el nodo tmp a la lista de nodos ya calculados Genera una lista de los nodos conectados al nodo tmp que no estn en la lista de ya calculados Para cada nodo de la lista (nod) Calcula la distancia al origen con la distancia entre tmp y nod ms la distancia calculada entre el origen y tmp. Si el nodo nod no est en la cola de prioridad lo agrega Si el nodo nod ya est en la cola de prioridad y la distancia con la que est guardado en la cola es menor, lo deja como est y sino, lo actualiza con la distancia calculada Fin

Fin

Al finalizar este procedimiento se tiene una lista con la menor distancia desde el origen a cada nodo. La clase Grafo descrita en un post anterior se puede modificar para incluir un nuevo mtodo que calcula la menor ruta usando el algoritmo de Dijkstra con dos nuevos mtodos: uno para calcular la distancia entre el origen y todos lo nodos, guardando estos resultados en una lista, y el segundo para mostrar la ruta entre el origen y el nodo destino tomando la informacin de la lista de distancias calculadas. Se implementa tambin un mtodo adicional para verificar si un nodo ya est en la lista de terminados: 1 import java.util.*; 2 3 public class Grafo { 4 char[] nodos; // Letras de identificacin de nodo 5 int[][] grafo; // Matriz de distancias entre nodos 6 String rutaMasCorta; // distancia ms corta 7 int longitudMasCorta = Integer.MAX_VALUE; // ruta ms corta 8 List<Nodo> listos=null; // nodos revisados Dijkstra 9 10 // construye el grafo con la serie de identificadores de nodo en una cadena 11 Grafo(String serieNodos) { 12 nodos = serieNodos.toCharArray(); 13 grafo = new int[nodos.length][nodos.length]; 14 } 15 16 // asigna el tamao de la arista entre dos nodos 17 public void agregarRuta(char origen, char destino, int distancia) { 18 int n1 = posicionNodo(origen); 19 int n2 = posicionNodo(destino); 20 grafo[n1][n2]=distancia; 21 grafo[n2][n1]=distancia; 22 } 23 24 // retorna la posicin en el arreglo de un nodo especfico 25 private int posicionNodo(char nodo) { 26 for(int i=0; i<nodos.length; i++) { 27 if(nodos[i]==nodo) return i;

28 } 29 return -1; 30 } 31 // encuentra la ruta ms corta desde un nodo origen a un nodo destino 32 public String encontrarRutaMinimaDijkstra(char inicio, char fin) { 33 // calcula la ruta ms corta del inicio a los dems 34 encontrarRutaMinimaDijkstra(inicio); 35 // recupera el nodo final de la lista de terminados 36 Nodo tmp = new Nodo(fin); 37 if(!listos.contains(tmp)) { 38 System.out.println("Error, nodo no alcanzable"); 39 return "Bye"; 40 } 41 tmp = listos.get(listos.indexOf(tmp)); 42 int distancia = tmp.distancia; 43 44 // crea una pila para almacenar la ruta desde el nodo final al origen 45 Stack<Nodo> pila = new Stack<Nodo>(); 46 while(tmp != null) { 47 pila.add(tmp); 48 tmp = tmp.procedencia; 49 } 50 String ruta = ""; 51 // recorre la pila para armar la ruta en el orden correcto 52 while(!pila.isEmpty()) ruta+=(pila.pop().id + " "); 53 return distancia + ": " + ruta; 54 } 55 // encuentra la ruta ms corta desde el nodo inicial a todos los dems 56 public void encontrarRutaMinimaDijkstra(char inicio) { 57 Queue<Nodo> cola = new PriorityQueue<Nodo>(); // cola de prioridad 58 Nodo ni = new Nodo(inicio); // nodo inicial 59 60 listos = new LinkedList<Nodo>(); // lista de nodos ya revisados 61 cola.add(ni);// Agregar nodo inicial a la cola de prioridad 62 while(!cola.isEmpty()){// mientras que la cola no esta vaca 63 Nodo tmp = cola.poll(); // saca el primer elemento 64 listos.add(tmp); // lo manda a la lista de terminados 65 int p = posicionNodo(tmp.id); 66 for(int j=0; j<grafo[p].length; j++) { // revisa los nodos hijos del nodo tmp 67 if(grafo[p][j]==0) continue; // si no hay conexin no lo evala 68 if(estaTerminado(j)) continue; // si ya fue agregado a la lista de 69 terminados 70 Nodo nod = new Nodo(nodos[j],tmp.distancia+grafo[p][j],tmp); 71 // si no est en la cola de prioridad, lo agrega 72 if(!cola.contains(nod)) { 73 cola.add(nod); 74 continue; 75 } 76 // si ya est en la cola de prioridad actualiza la distancia menor 77 for(Nodo x: cola) {

78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127

// si la distancia en la cola es mayor que la distancia calculada if(x.id==nod.id && x.distancia > nod.distancia) { cola.remove(x); // remueve el nodo de la cola cola.add(nod); // agrega el nodo con la nueva distancia break; // no sigue revisando } } } } } // verifica si un nodo ya est en lista de terminados public boolean estaTerminado(int j) { Nodo tmp = new Nodo(nodos[j]); return listos.contains(tmp); } // encontrar la ruta mnima por fuerza bruta public void encontrarRutaMinimaFuerzaBruta(char inicio, char fin) { int p1 = posicionNodo(inicio); int p2 = posicionNodo(fin); // cola para almacenar cada ruta que est siendo evaluada Stack<Integer> resultado = new Stack<Integer>(); resultado.push(p1); recorrerRutas(p1, p2, resultado); } // recorre recursivamente las rutas entre un nodo inicial y un nodo final // almacenando en una cola cada nodo visitado private void recorrerRutas(int nodoI, int nodoF, Stack<Integer> resultado) { // si el nodo inicial es igual al final se evala la ruta en revisin if(nodoI==nodoF) { int respuesta = evaluar(resultado); if(respuesta < longitudMasCorta) { longitudMasCorta = respuesta; rutaMasCorta = ""; for(int x: resultado) rutaMasCorta+=(nodos[x]+" "); } return; } // Si el nodo Inicial no es igual al final se crea una lista con todos los nodos // adyacentes al nodo inicial que no estn en la ruta en evaluacin List<Integer> lista = new Vector<Integer>(); for(int i=0; i<grafo.length;i++) { if(grafo[nodoI][i]!=0 && !resultado.contains(i))lista.add(i); } // se recorren todas las rutas formadas con los nodos adyacentes al inicial for(int nodo: lista) { resultado.push(nodo); recorrerRutas(nodo, nodoF, resultado); resultado.pop(); } }

128 // evaluar la longitud de una ruta 129 public int evaluar(Stack<Integer> resultado) { 130 int resp = 0; 131 int[] r = new int[resultado.size()]; 132 int i = 0; 133 for(int x: resultado) r[i++]=x; 134 for(i=1; i<r.length; i++) resp+=grafo[r[i]][r[i-1]]; 135 return resp; 136 } 137 public static void main(String[] args) { 138 Grafo g = new Grafo("abcdef"); 139 g.agregarRuta('a','b', 3); 140 g.agregarRuta('a','e', 6); 141 g.agregarRuta('a','f',10); 142 g.agregarRuta('b','c', 5); 143 g.agregarRuta('b','e', 2); 144 g.agregarRuta('c','d', 8); 145 g.agregarRuta('c','e', 9); 146 g.agregarRuta('c','f', 7); 147 g.agregarRuta('d','f', 4); 148 g.agregarRuta('e','f', 4); 149 char inicio = 'a'; 150 char fin = 'd'; 151 String respuesta = g.encontrarRutaMinimaDijkstra(inicio, 152 System.out.println(respuesta); 153 } 154}

fin);

Esta clase requiere del uso adicionalmente de la clase Nodo, que va a servir para la cola de prioridad y para llevar registro de la distancia mnima desde el origen a un nodo, as como la referencia al nodo inmediatamente anterior: 1 public class Nodo implements Comparable<Nodo> { 2 char id; 3 int distancia = Integer.MAX_VALUE; 4 Nodo procedencia = null; 5 Nodo(char x, int d, Nodo p) { id=x; distancia=d; procedencia=p; } 6 Nodo(char x) { this(x, 0, null); } 7 public int compareTo(Nodo tmp) { return this.distancia-tmp.distancia; } 8 public boolean equals(Object o) { 9 Nodo tmp = (Nodo) o; 10 if(tmp.id==this.id) return true; 11 return false; 12 } 13}

2. EJERCICIO a) Ruta mas corta b) Red Elctrica (menor cantidad de conector c) Carga mxima permitida

2 5

H
3

J
4

=14

G J
3

L J
4

=14

B
1

E
4

G H
1

L L

=13

=12

5 2

G
1

=17

B E
1 3 4

C
3

G H

J
1

L J
4

=16

E
2

H J

=15

J F
3

4 4

L L
=13

=15

I
5

K H F

L J H

=18

D
2

F C

L J

=17

=16

a) Ruta ms corta: A-B-E-H-J-L b) Menor cantidad de conector: 12

3. EJERCICIO Carga mxima de acuerdo con la cantidad mxima permitida.

15 15

16

11

A
17 0 0 11 13 0 12

B
10 0 0 14 0

G
0 0 10 8 0

J
0

9 12 0 0

L
0 10

C
9 0 0 0 16

E
15

D
20

17

18 0

K
0 13 13

13

Ruta: A-B-G-J-L
6 15 9 7 9 2 9

A
17 0 0 11 13 0 12

B
10 0 0 14 0

G
0 0 10 8 0

J
0

9 12 0 0

L
0 10

C
9 0 0 0 16

E
15

D
20

17

18 0

K
0 13 13

13

Ruta: A-C-E-H-K-L
6 15 9 7 9 2 9

A
9 8 0 3 13 0 12

B
10 0 8 14 0

G
0 0 10 0 8

J
0

9 4 8 0

L
8 10

C
9 0 0 0 16

E
15

D
20

17

18 0

K
0 13 13

9+8

Ruta: A-D-F-I-K-L
6 10 9 7 9 2 9

A
9 8 0 3 13 0 12

B
10 0 8 14 0

G
0 0 10 0 8

J
0

9 4 8 0

L
13 10

C
9 0 5 0 16

E
15

D
20

12

11 5

K
5 13 8

9+8+5=22

c) Carga mxima: 22

4. EJERCICIO Determinar la ruta mas corta entre Seattle y el Paso para la siguiente red de carreteras.
SEATTLE Butte

1
497 432

599

2
420

691 Cheyenne

180

Boise

4
345 Saltlakecity

440

102

7
432 526 Las Vegas

Portland

3
602 138

Denver

6
Reno 280 155

Sac

5
291

11
108 469

12

Albuque

Bakersfiel

10
Borstow 114

14

207

15
Kigman

19

EL PASO

Los Angeles

13
Phoenix 386

16 17
425

403 314

118

18
Tucson

SanDiego

102 691

9 7
432

12 11
108 210

19 15 16

=1,392

8
420 469

12 19
=2,028

19
=2,755

=2,719

599

2
420

7
432

403

11

108

15

469

12

19

11

210 108

16 15
469

403

19

=1,887

14 12 10
280

207

15

469

12

19
=2,387

19
114

=1,851

497

345

7
526

432

16
138

403

19 18

=2,586

386

291

13
118

17 12

425

314

19

=2,798

11
155 210

108

15
403

469

19

=2,654

16
207

19 12

=2,690

14

15

469

19

=2,908

526

440 432

8 11
210

102

9 15
403 469 469

12 12 19
=2,491

19 19

=1588

108

6
138

=2,455

16
207

180

602

5
291

10

114

13
386

14 16

15 19 18

12

19

=1,893

403

=2,006

118

17

425

314

19

=2,074

Ruta ms corta: 1-2-8-9-12-19 5. EJERCICIO Una empresa distribuida Surte 7 supermercados con distintas ubicaciones. Los administradores desean conocer la distancia ms corta.
1 8

3 3

0
4

5
1 2

3 2
6

7
3

6 6

5 5

=12

=13

4
2

5 3 3

=10

2 2 5

5 5

=12

=8

=12

La distancia ms corta es: 8 km Ruta: 0-1-3-2-5 COSULTAS QUE FALTAN (No se les olvide la Cibergrafia) 6. ANLISIS DE TRANSICIN 7. DISTRIBUCIN DE POISSON

CIBERGRAFIA http://jorgep.blogspot.com/2010/10/ruta-mas-corta-solucion-por-el.html http://www.arquimedex.com/index.php?accion=1&id=80

También podría gustarte