Vous êtes sur la page 1sur 50

Facultad Ciencias Empresariales. Escuela de Ingeniera Civil Informtica. Chillan.

Tarea de Anlisis y Diseos de Algoritmos.

ALGORITMO DE JOHNSON

Integrantes:

Alfredo Parra Urrea. Carlos San Juan Contreras.

Profesor: Fecha:

Pablo Sez Gonzlez. 12-octubre-2011

Introduccin
En el anlisis de algoritmos muchas veces nos encontramos con problemas difciles de resolver o simplemente no hallamos las herramientas adecuadas para poder desarrollar dichos inconvenientes. Entre los grandes problemas que nos podemos topar, estn los grafos, ya que son difciles de analizar, producto de sus mltiples formas y gran variedad de estos, hay grafos simples, grafos completos, grafo conexo, inconexo, dirigidos, entre varios otros. Por esto mismo estudiarlos ya sea por sus estructuras, tipo y/o su complejidad debido a que son esenciales para encontrar respuestas a complicaciones cotidianas tan simples como encontrar rutas cortas entre puntos de un mapa. Es por ello que muchas personas han querido disear algoritmos que nos permitan evaluar y analizar los diferentes grafos, para as tener la mejor solucin de forma ms rpida. Existen varias herramientas para grafos especficos, encontramos los algoritmos de DIJKSTRA que es un algoritmo usado para encontrar los caminos mnimos de un grafo dirigido ponderado de N nodos no aislados, donde sea x el nodo inicial, un vector D de tamao N guardar el final del algoritmo las distancia desde x al resto de los nodos. Tambin otro algoritmo usado para resolver grafos es el de Bellman-Ford que se usa para encontrar el camino minimo de un grafo dirigido ponderado, el cual puede poseer aristas negativas, a diferencia con Dijkstra.

Donald Johnson tuvo la inquietud de resolver grafos dirigidos dispersos, y decidi mezclar los algoritmos de Dijkstra y Bellman-Ford para poder realizar este nuevo algoritmo llamado Algoritmo de Johnson en su honor.
Este informe apunta al trabajo que hizo Johnson explicando cmo realizo su algoritmo.

Algoritmo de Johnson y Comentarios.


Clase AdjacencyListGraph:
package algoritmojohnson; /** * @author Alfredo Parra y Carlos San Juan */ import java.util.Iterator; public class AdjacencyListGraph implements Graph { //verificamos si el grafo es o no direccionado protected boolean directed; /* El ndice del ltimo vrtice agregado a esta grfica. */ protected int lastAdded; /*cantidad de aristas*/ protected int e; /** lista adjacente */ protected AdjListInfo[] adj; /** recibimos la cantidad de vertices y si el grafico es direccionado o no */ public AdjacencyListGraph(int cardV, boolean directed) { this.directed = directed; lastAdded = -1; adj = new AdjListInfo[cardV]; e = 0; } /*inicializa los vertices con un nombre*/ public Vertex addVertex(String name) { lastAdded++; // the index for this vertex adj[lastAdded] = new AdjListInfo(new Vertex(lastAdded, name)); return adj[lastAdded].thisVertex; } /** asigna indice y nombre al vertice */ public Vertex addVertex(int index, String name) { lastAdded = index; adj[lastAdded] = new AdjListInfo(new Vertex(lastAdded, name)); return adj[lastAdded].thisVertex; } /*agragamos un nuevo vertice */ public Vertex addVertex(Vertex v) { if (v.getIndex() == Vertex.UNKNOWN_INDEX) {

lastAdded++; v.setIndex(lastAdded); } else { lastAdded = v.getIndex(); } adj[lastAdded] = new AdjListInfo(v); return v;

} /*retorna el vertice que posee el mismo "index" */ public Vertex getVertex(int index) { return adj[index].thisVertex; } /*va verificando un vertice con los otros

*/

public void addEdge(Vertex u, Vertex v) { // Put v on u's list. int uIndex = u.getIndex(); Edge x = new Edge(v, adj[uIndex].head); adj[uIndex].head = x; // If undirected, put u on v's list. if (!directed) { int vIndex = v.getIndex(); x = new Edge(u, adj[vIndex].head); adj[vIndex].head = x; } e++; } /*va comparando el index de u con los otros de v */ public void addEdge(int u, int v) { // poner v en la lista de u Edge x = new Edge(adj[v].thisVertex, adj[u].head); adj[u].head = x; // Si no es dirigido, poner u en la lista v if (!directed) { x = new Edge(adj[u].thisVertex, adj[v].head); adj[v].head = x; } e++; } /*Clase interna de la matriz de lista de adyacencia. */ protected static class AdjListInfo { /** El vrtice de adyacencia, cuya lista es esto. */ public Vertex thisVertex; /** El primer borde en la lista de adyacencia de este vrtice.*/

public Edge head; /* Crea que un objeto de tipo AdjListInfo vacio*/ public AdjListInfo(Vertex v) { thisVertex = v; head = null; } } /*Clase interna de los bordes lista de adyacencia. Listas de adyacencia son simplemente enlazada.*/ protected static class Edge { public Vertex vertex; public Edge next; /** Crea un nuevo borde. v El lado del vrtice. succesor borde sucesor de ste. */ public Edge(Vertex v, Edge successor) { vertex = v; next = successor; } } //retornamos el iterador que pesa los vertices del grafo public Iterator vertexIterator() { return new VertexIterator(); } /*Clase interna para el vertice itertor */ public class VertexIterator implements Iterator { /** El ndice del vrtice devuelto por la llamada ms reciente Inicialmente, su valor es -1.*/ protected int lastVisited; /** Inicia una iteracin a travs de los vrtices */ public VertexIterator() { lastVisited = -1; } /*verifica si hay el iterator tiene ms vertices */ public boolean hasNext() { return lastVisited < adj.length - 1; } /** Devuelve el siguiente vrtice en la iteracin.*/ public Object next() { return adj[++lastVisited].thisVertex; }

public void remove() {//verifica errores throw new UnsupportedOperationException(); } } public Iterator edgeIterator(Vertex u) { return new EdgeIterator(u.getIndex()); } public Iterator edgeIterator(int u) { return new EdgeIterator(u); } /*Clase interna para un iterador que recorre las aristas incidentes en un vrtice dado.*/ public class EdgeIterator implements Iterator { /*retorna el borde de la llamada ms reciente*/ protected Edge current; /*El ndice del vrtice cuyos bordes este iterador recorre.*/ protected int index; /*Inicia una iteracin a travs de las aristas incidentes en un vrtice dado. donde v es un indice*/ public EdgeIterator(int v) { index = v; current = null; } /*verifica si hay ms vertices */ public boolean hasNext() { if (current == null) { return adj[index].head != null; } else { return current.next != null; } } /*Devuelve el siguiente borde de la iteracin*/ public Object next() { if (current == null) { current = adj[index].head; } else { current = current.next; } return current.vertex; } /*en caso de errores

*/ public void remove() { throw new UnsupportedOperationException(); } } /** retorna el numero de vertices*/ public int getCardV() { return adj.length; } /*retorna el nmero de bordes */ public int getCardE() { return e; } /*verifica si el grafo es o no dirigido*/ public boolean isDirected() { return directed; } /** Crea y devuelve un grfico que utiliza el mismo conjunto de * vrtices en la grfica. El grfico creado no tiene bordes*/ public AdjacencyListGraph useSameVertices() { // inicializa un grafo vacio. AdjacencyListGraph newGraph = makeEmptyGraph(adj.length, directed); //Ahora agregue cada vrtice del grafo en el grafo nuevo, //utilizando los objetos de Vertex . for (int i = 0; i < adj.length; i++) { newGraph.addVertex(adj[i].thisVertex); } } return newGraph;

/** *Crea y devuelve una AdjacencyListGraph vacia * cardV nmero de vrtices y una booleana * directed indica si el grafo es dirigido. */ protected AdjacencyListGraph makeEmptyGraph(int cardV, boolean directed) { return new AdjacencyListGraph(cardV, directed); } /** representa el grafo*/ public String toString() {//imprime las iteraciones String result = ""; Iterator vertexIter = vertexIterator(); while (vertexIter.hasNext()) { Vertex u = (Vertex) vertexIter.next(); result += u + ":\n"; Iterator edgeIter = edgeIterator(u);

while (edgeIter.hasNext()) { Vertex v = (Vertex) edgeIter.next(); result += " " + v + "\n"; } } return result; } }

Clase BellmanFord:
package algoritmojohnson; import java.util.Iterator; /* * @author Alfredo Parra y Carlos San Juan */ class BellmanFord extends SingleSourceShortestPaths{ /* Establece las variables de instancia, incluida la asignacin SpInfo pero no la asignacin de los ShortestPathInfo, objetos referenciado por la matriz de initializeSingleSource theGraph para encontrar los caminos ms cortos. */ public BellmanFord(WeightedAdjacencyListGraph theGraph){ super(theGraph); } /*Calcula una sola fuente de rutas ms cortas desde un origen determinado Vrtice, el llenado de los pesos y sus predecesores del tipo SpInfo. Tambin establece la variable de instancia NoNegWeightCycle adecuada, para no encotrar ciclos negativos. "s" La origen vrtice. */ public void computeShortestPaths(Vertex s) { initializeSingleSource(s); int cardV = g.getCardV(); // Ejecutar a travs de todos los bordes | V | -1 veces. for (int i = 1; i <= cardV-1; i++) { Iterator vertexIter = g.vertexIterator(); while (vertexIter.hasNext()) { Vertex u = (Vertex) vertexIter.next(); double du = getShortestPathInfo(u).getEstimate(); WeightedEdgeIterator edgeIter = g.weightedEdgeIterator(u); while (edgeIter.hasNext()) { Vertex v = (Vertex) edgeIter.next(); double w = edgeIter.getWeight();

getShortestPathInfo(v).relax(u, du, w); } } }

// Un pase ms para ver si hay un cambio ventajoso Iterator vertexIter = g.vertexIterator(); while (vertexIter.hasNext()) { Vertex u = (Vertex) vertexIter.next(); double du = getShortestPathInfo(u).getEstimate(); WeightedEdgeIterator edgeIter = g.weightedEdgeIterator(u); while (edgeIter.hasNext()) { Vertex v = (Vertex) edgeIter.next(); double w = edgeIter.getWeight(); if (getShortestPathInfo(v).getEstimate() > du + w) { noNegWeightCycle = false; return; } } } } }

Clase Dijkstra:
package algoritmojohnson; import java.util.Vector; /* * @author Alfredo Parra y Carlos San Juan */ class Dijkstra extends SingleSourceShortestPaths { /** *Establece las variables de instancia, incluida la asignacin SpInfo pero no la asignacin de los ShortestPathInfo, objetos referenciado por la matriz de initializeSingleSource theGraph para encontrar los caminos ms cortos. */ public Dijkstra(WeightedAdjacencyListGraph theGraph) { super(theGraph); } /*Calcular una sola fuente rutas ms cortas desde un origen determinado vrtice, llenando en los pesos y los predecesores de la matriz */ public void computeShortestPaths(Vertex s) { initializeSingleSource(s); Vector recorrido=new Vector(1,1);

10

//crear una cola de prioridad minima minPriorityQueue MinPriorityQueue q = new MinHeapPriorityQueue(); /*La informacin que estamos manteniendo para cada vrtice es un objeto DijkstraInfo. Tenemos que establecer el theVertex y manejar los campos. Mediante la insercin de cada objeto DijkstraInfo en la cola de priorityMin-, tenemos la manija que se almacenan en el objeto.*/ int cardV = g.getCardV(); for (int i = 0; i < cardV; i++) { DijkstraInfo info = (DijkstraInfo) getShortestPathInfo(i); info.theVertex = g.getVertex(i); info.handle = q.insert(info); } q.decreaseKey(((DijkstraInfo) getShortestPathInfo(s)).handle, new Double(0)); System.out.print("Recorrido mas corto: "); while (!q.isEmpty()) { // Encontrar el vrtice de la cola con la llave ms pequea. DijkstraInfo uInfo = (DijkstraInfo) q.extractMin(); uInfo.handle = null; //ya no est en la cola Vertex u = uInfo.theVertex; double du = getShortestPathInfo(u).getEstimate(); //Compruebe cada borde incidente. WeightedEdgeIterator edgeIter = g.weightedEdgeIterator(u); while (edgeIter.hasNext()) { Vertex v = (Vertex) edgeIter.next(); DijkstraInfo vInfo = (DijkstraInfo) getShortestPathInfo(v); double weight = edgeIter.getWeight(); if (vInfo.relax(u, du, weight)) { //"v" la ruta ms corta de estimacin ha cambiado, //por lo que actualizar la cola de priorityMin. q.decreaseKey(vInfo.handle,new Double(vInfo.getEstimate())); } } recorrido.add(u.getName()); } for(int i=0;i<cardV-2;i++)//se imprime el camino System.out.print(recorrido.elementAt(i)+"->"); System.out.print(recorrido.elementAt(cardV-2)+"\n\n");

/*retorna nuevo DijkstraInfo*/ protected ShortestPathInfo newShortestPathInfo(){ return new DijkstraInfo(); }

11

/*Clase interna para mantener el Vertice y la manija de la cola de prioridad para cada vertice, los padres se heredan de la cola de prioridad de la super clase ShortestPathInfo */ private static class DijkstraInfo extends ShortestPathInfo implements DynamicSetElement { public Vertex theVertex; public Object handle; public DijkstraInfo() { super(); } /*selecciona la clave */ public void setKey(Comparable key){ setEstimate(((Double) key).doubleValue()); } /** retorna clave */ public Comparable getKey(){ return new Double(getEstimate()); } /*Compara la clave del vrtice de este objeto a la de otro. vrtice es menor; 0 si las claves son iguales, un entero positivo si la clave del vrtice de este objeto es mayor */ public int compareTo(Object e){ return DynamicSetElement.Helper.compareTo(this, e); }

} }

Clase DynamicSetElement:
package algoritmojohnson; /* * @author Alfredo Parra y Carlos San Juan */ interface DynamicSetElement extends Comparable { /*Establece la clave de un elemento. */ public void setKey(Comparable key); /*retorna la clave de un elemento.*/ public Comparable getKey(); public int compareTo(Object e);//compara elementos 12

/*Clase interna para definir los mtodos estticos de ayuda.*/ public static class Helper { /** * Compara un DynamicSetElement a otro * Objeto. Si el otro objeto es tambin un * DynamicSetElement, las llaves de ambos se comparan. * Si el otro objeto no es un DynamicSetElement, pero la aplicacin no * es Comparables, y luego la clave de la DynamicSetElement se compara * con los otros Objeto. De lo contrario, el otro objeto no implementa * Comparables, se tira una ClassCastException. */ public static int compareTo(DynamicSetElement e, Object o){ if (o instanceof DynamicSetElement) return e.getKey().compareTo(((DynamicSetElement) o).getKey()); else if (o instanceof Comparable) return e.getKey().compareTo(o); else throw new ClassCastException("Intento comparar una " +"DynamicSetElement a un objeto que no es Comparable."); } /*Lanza un objeto DynamicSetElement si el objeto no se ha podido implementar */ public static DynamicSetElement cast(Object o){ if (o instanceof DynamicSetElement) return (DynamicSetElement) o; else throw new ClassCastException("Objeto no implementa la interfaz" + " DynamicSetElement."); }

Clase Graph:
package algoritmojohnson; /*@author Alfredo Parra y Carlos San Juan*/ import java.util.Iterator; public interface Graph { /* Aade un vrtice a la grafo. Teniendo en cuenta el nombre del vrtice, un Vertex se crea y se agrega. El ndice disponible siguiente se utiliza. */ public Vertex addVertex(String name); /*agrega un vertice al grafo con un nombre */

13

public Vertex addVertex(int index, String name); /*agrega un vertice al grafo con un nombre y un indice public Vertex addVertex(Vertex v); /*Devuelve el vrtice con un ndice determinado.*/ public Vertex getVertex(int index); /*Agrega un borde al grafo, especificado por un par de vertices */ public void addEdge(Vertex u, Vertex v); /*Agrega un borde a esta grfica. El borde es especificado por un par de ndices de vrtice. public void addEdge(int u, int v); /*Devuelve un iterador que itera ppasando por todos los vrtices del grafo.*/ public Iterator vertexIterator(); /*Devuelve un iterador que recorre las aristas incidentes en un vrtice dado. Cada arista incidente se indica mediante el correspondiente vrtice adyacente.*/ public Iterator edgeIterator(Vertex u); /* Devuelve un iterador que recorre las aristas incidentes en un vrtice dado. Cada arista incidente se indica mediante el correspondiente vrtice adyacente.*/ public Iterator edgeIterator(int u); /*Retorna el nmero de vertices */ public int getCardV(); /*retorna el nmero de bordes del grafo*/ public int getCardE(); /*retorna si el grafo es direccionado o no*/ public boolean isDirected(); */ */

Clase Heap:
package algoritmojohnson; /*@author Alfredo Parra y Carlos San Juan*/ abstract public class Heap{ /*El arreglo que contiene la pila.*/ protected Comparable[] array; /*tamao del arreglo*/ protected int heapSize; /*Restaura la propiedad del montculo. Asume que en el momento de la llamada, la propiedad del HEAP tiene en todas partes,

14

con la posible excepcin de una posicin y sus hijos. Deben ser implementadas en las subclases. */ abstract public void heapify(int i); /** creamos un heap vacio */ public Heap(){ array = null; heapSize = 0; } /*Hace un HEAP en lugar del argumento, y asegura que tiene la propiedad del HEAP.*/ public Heap(Comparable[] array) { this.array = array; heapSize = array.length; buildHeap(); } /*Intercambia los elementos en dos ndices. */ protected void exchange(int i, int j) { Comparable c = array[i]; array[i] = array[j]; array[j] = c; } /*Devuelve el ndice del padre de un nodo.*/ public static final int parent(int i){ return (i-1) / 2; } /*retorna el indice del hijo izquierdo */ public static final int left(int i) { return 2 * i + 1; } /*retorna el indice del hijo derecho*/ public static final int right(int i) { return 2 * i + 2; } /*retorna true si esta vacio el HEAP */ public final boolean isEmpty() { return heapSize < 1; } /*Devuelve el primer elemento de la pila sin eliminarlo. Para un mx-heap, el elemento ms grande, y por un montn de minutos,

15

el elemento ms pequeo.*/ public Comparable head(){ return array[0]; } /* Reorganiza la matriz dentro de la pila para que cumpla con la propiedad del HEAP.*/ public void buildHeap(){ //HEAPIFY de abajo hacia arriba. for (int i = array.length/2; i >= 0; i--) heapify(i); } /*Devuelve un objeto que va al heap usando Heapsort*/ public Sorter makeSorter(){ return new Heapsort(); } /*Implementa Heapsort */ public class Heapsort implements Sorter{ public void sort(Comparable[] arrayToSort) { //Dado que este mtodo est dentro de una clase anidada dentro del //HEAP, debe haber un montn de objetos existentes que podemos utilizar. array = arrayToSort; heapSize = array.length; //hacemos cumplir la propiedad del HEAP buildHeap(); //Hace el resto del algoritmo heapsort. for (int i = array.length-1; i >= 1; i--) { exchange(0, i); heapSize--; heapify(0); } } }

/*Las clases anidadas para las manijas de un montn. Para ser utilizado por las subclases MinHeapPriorityQueue y MaxHeapPriorityQueue.*/ protected static class Handle implements Comparable{ /* ndice en la matriz HEAP*/ protected int index; /*Informacin almacenada */ protected DynamicSetElement info; /*Inicializacion de Handle*/ protected Handle(int index, DynamicSetElement info){ this.index = index; this.info = info;

16

} /*compara objetos*/ public int compareTo(Object e){ return info.compareTo(((Handle) e).info); } } }

Clase HeapUnderflowException:
package algoritmojohnson; /* @author Alfredo Parra y Carlos San Juan */ /*Clase verifica errores del HEAP*/ public class HeapUnderflowException extends RuntimeException{ }

Clase Johnson:
package algoritmojohnson; import java.util.Iterator; /* @author Alfredo Parra y Carlos San Juan */ class Johnson { /*indica un grafo ponderado*/ private WeightedAdjacencyListGraph g; /*verifica si es un grafo dirigido o no*/ private boolean noNegWeightCycle; /*El resultado de ejecutar un algoritmo de Johnson. El objeto ShortestPathInfo en spInfo [u] [v] contiene el peso del camino ms corto de u a v, donde u y v son los ndices de vrtice, junto con el predecesor de v en un camino ms corto desde u. Puede consultar esta informacin llamando a los mtodos de la clase ShortestPathInfo. */ private ShortestPathInfo[][] spInfo; /*Inicializa las variables de instancia, a excepcin de la asignacin de los objetos acutal ShortestPathInfo en spInfo.*/ public Johnson(WeightedAdjacencyListGraph theGraph) { g = theGraph; noNegWeightCycle = true; int n = g.getCardV(); spInfo = new ShortestPathInfo[n][n];

17

/*se verifica si hay ciclos negativos*/ public boolean hasNoNegativeWeightCycle(){ return noNegWeightCycle; } /*Devuelve una referencia al objeto ShortestPathInfo para un determinado par de vrtices.*/ public ShortestPathInfo getShortestPathInfo(Vertex u, Vertex v) { return getShortestPathInfo(u.getIndex(), v.getIndex()); } /*Devuelve una referencia al objeto ShortestPathInfo para un determinado par de indices. */ public ShortestPathInfo getShortestPathInfo(int u, int v) { return spInfo[u][v]; } /*Calcula todos los pares de los caminos ms cortos usando el algoritmo de Johnson. Los resultados son los objetos ShortestPathInfo referencia a la matriz spInfo, junto con la bandera noNegWeightCycle.*/ public void computeShortestPaths() { /* Hacer un grafo Gprime , que es lo mismo que g, pero con un vrtice adicional y bordes 0-peso desde el vrtice adicional a todos los otros vrtices. El vrtice extra "s" es V0, pero aqu vamos a hacer que el ndice disponible. Los objetos vrtice en G ser compartida con Gprime. Por lo que s se encuentra en el ndice disponible siguiente, todos los vrtices de G tienen el mismo ndice, que es necesario*/ int cardV = g.getCardV(); WeightedAdjacencyListGraph gPrime = new WeightedAdjacencyListGraph(cardV+1, true); Iterator vertexIter = g.vertexIterator(); while (vertexIter.hasNext()) gPrime.addVertex((Vertex) vertexIter.next()); Vertex s = new Vertex("s"); gPrime.addVertex(s); vertexIter = g.vertexIterator(); while (vertexIter.hasNext()) { Vertex u = (Vertex) vertexIter.next(); WeightedEdgeIterator edgeIter = g.weightedEdgeIterator(u); while (edgeIter.hasNext()) gPrime.addEdge(u, (Vertex) edgeIter.next(), edgeIter.getWeight()); gPrime.addEdge(s, u, 0); } System.out.println("Grafo con nodo nuevo 's':\n"); //crea un nodo nuevo llamado "s" System.out.println(gPrime);// y los conecta a todos con peso cero

18

//Ejecutar el algoritmo de Bellman-Ford en Gprime de la fuente. BellmanFord bf = new BellmanFord(gPrime); bf.computeShortestPaths(s); if (bf.hasNoNegativeWeightCycle()) { /*El grfico no contiene un ciclo negativo de peso, por lo que puede proceder. Calcular los valores de h para todos los vrtices en Gprime.*/ System.out.println("Muestra los nuevos pesos h(v)\n"); double[] h = new double[cardV+1]; for (int i = 0; i <= cardV; i++){ h[i] = bf.getShortestPathInfo(i).getEstimate(); System.out.println(h[i]);//Calcula los nuevos pesos } //Volver a pesar de todos los bordes Gprime. vertexIter = gPrime.vertexIterator(); while (vertexIter.hasNext()) { Vertex u = (Vertex) vertexIter.next(); int uIndex = u.getIndex(); double hu = h[uIndex]; WeightedEdgeIterator edgeIter = gPrime.weightedEdgeIterator(u); while (edgeIter.hasNext()) { Vertex v = (Vertex) edgeIter.next(); double w = edgeIter.getWeight(); double hv = h[v.getIndex()]; edgeIter.setWeight(w + hu - hv); } } System.out.println("Grafo con pesos recalculados: " + "w(u, v) + h(u) h(v)\n"); System.out.println("\t"+gPrime); //Se ejecuta el algoritmo de Dijkstra en cada vrtice de G //en el grfico pesados por ltima vez. System.out.println("Ejecucion Dijkstra:\n"); Iterator uIter = g.vertexIterator(); while (uIter.hasNext()) { Vertex u = (Vertex) uIter.next(); System.out.println("Desde: "+u+" "); int uIndex = u.getIndex(); double hu = h[uIndex]; Dijkstra dijk = new Dijkstra(gPrime); dijk.computeShortestPaths(u); Iterator vIter = g.vertexIterator(); while (vIter.hasNext()) { Vertex v = (Vertex) vIter.next(); System.out.print("\tHacia: "+v); int vIndex = v.getIndex();

19

double hv = h[vIndex]; spInfo[uIndex][vIndex] = dijk.getShortestPathInfo(vIndex); spInfo[uIndex][vIndex].setEstimate( spInfo[uIndex][vIndex].getEstimate() + hv - hu); //Muestra el peso System.out.print(spInfo[uIndex][vIndex]+"\n"); } } } } }

Clase KeyUpdateException:
package algoritmojohnson; /* @author Alfredo Parra y Carlos San Juan */ /*Verifica errores en la actualizacion de las claves*/ public class KeyUpdateException extends RuntimeException{ }

Clase Main:
package algoritmojohnson; /* @author Alfredo Parra y Carlos San Juan */ import java.util.Iterator; public class Main { public static void main(String[] args) { long tfinal; // Se crea un grafo para la prueva 1, con 5 vertices y direccionado WeightedAdjacencyListGraph graph = new WeightedAdjacencyListGraph(5, true); //inicializamos los vertices que usaremos Vertex a = new Vertex("a"); Vertex b = new Vertex("b"); Vertex c = new Vertex("c"); Vertex d = new Vertex("d"); Vertex e = new Vertex("e"); //agregamos los vectores al grafo graph.addVertex(a); graph.addVertex(b); graph.addVertex(c); graph.addVertex(d); graph.addVertex(e);

20

//damos la direccion y el peso a los bordes graph.addEdge(a, b, 3); graph.addEdge(a, c, 8); graph.addEdge(a, e, -4); graph.addEdge(b, e, 7); graph.addEdge(b, d, 1); graph.addEdge(c, b, 4); graph.addEdge(d, c, -5); graph.addEdge(d, a, 2); graph.addEdge(e, d, 6); System.out.println("PRIMER GRAFO:");//tomado Grafo del Libro de Cormen System.out.println(graph);//mostramos el grafo System.out.println("\n**** Uso de Johnson 1 ***"); //comienza el algoritmo //iniciamos el tiempo para luego calcular la demora long time=System.currentTimeMillis(); Johnson jon=new Johnson(graph); //creamos un grafo de jonhoson //busca las rutas ms cortas entre los vertices jon.computeShortestPaths(); System.out.println("\n\n\t ** FIN JOHNSON 1**\n"); tfinal=System.currentTimeMillis()-time;//calculamos el tiempo final System.out.println("tiempo de ejecucion 1: "+tfinal+" miliseg\n"); /*de aqui en adelante se repiten los pasos anteriores pero con diferentes grafos*/ time=System.currentTimeMillis(); //ejemplo BellmanFord Wikipedia System.out.println("\n\n\t SEGUND GRAFO \n"); //se inicializa el grafo con 5 verices y direccionado WeightedAdjacencyListGraph graph2 = new WeightedAdjacencyListGraph(5, true); Vertex a1,a2,a3,a4,a5;//inicializamos los vertices a1=new Vertex("(1)"); a2=new Vertex("(2)"); a3=new Vertex("(3)"); a4=new Vertex("(4)"); a5=new Vertex("(5)"); //agrega los vertices al grafo graph2.addVertex(a1); graph2.addVertex(a2); graph2.addVertex(a3); graph2.addVertex(a4); graph2.addVertex(a5); //asigna direccion y valor a los bordes graph2.addEdge(a2,a1,1); graph2.addEdge(a3,a1,4); graph2.addEdge(a2,a3,2); graph2.addEdge(a3,a2,1); graph2.addEdge(a5,a3,2); graph2.addEdge(a5,a4,2); graph2.addEdge(a4,a2,8);

21

graph2.addEdge(a4,a5,4); //muestra el grafo System.out.println(graph2); //inicia el clculo de johnson System.out.println("**** Uso de Johnson 2***\n"); time=System.currentTimeMillis();//inicializa el tiempo Johnson jon2=new Johnson(graph2);//se inicializa el grafo jon2.computeShortestPaths();//se calcula los caminos ms cortos System.out.println("\n\n\t ** FIN JOHNSON 2**\n"); tfinal=System.currentTimeMillis()-time; System.out.println("Tiempo de ejecucion 2: "+tfinal+" miliseg\n"); //////////Grafo 3 System.out.println("\n\n\tTERCERA PRUEBA \n");//LuckyPuck Cormen WeightedAdjacencyListGraph graph3 = new WeightedAdjacencyListGraph(6, true); Vertex b0,b1,b2,b3,b4,b5; b0=new Vertex("(0)"); b1=new Vertex("(1)"); b2=new Vertex("(2)"); b3=new Vertex("(3)"); b4=new Vertex("(4)"); b5=new Vertex("(5)"); graph3.addVertex(b0); graph3.addVertex(b1); graph3.addVertex(b2); graph3.addVertex(b3); graph3.addVertex(b4); graph3.addVertex(b5); graph3.addEdge(b0,b1,16); graph3.addEdge(b0,b2,13); graph3.addEdge(b1,b2,10); graph3.addEdge(b1,b3,12); graph3.addEdge(b2,b1,4); graph3.addEdge(b2,b4,14); graph3.addEdge(b3,b2,9); graph3.addEdge(b3,b5,20); graph3.addEdge(b4,b3,7); graph3.addEdge(b4,b5,4); System.out.println(graph3); System.out.println("\n**** Uso de Johnson 3 ***\n"); time=System.currentTimeMillis(); Johnson jon3=new Johnson(graph3); jon3.computeShortestPaths(); System.out.println(jon3.getShortestPathInfo(b4, b1)+"\n ** FIN JOHNSON 3**\n"); tfinal=System.currentTimeMillis()-time; System.out.println("tiempo de ejecucion grafo 3: "+tfinal+" miliseg"); /////////////Cuarto grafo

22

System.out.println("\n\n\tCUARTA PRUEBA \n"); //grafo Algoritmo de Johnson ejemplo de WIKIPEDIA WeightedAdjacencyListGraph graph4 = new WeightedAdjacencyListGraph(4, true); Vertex v1,v2,v3,v4; v1=new Vertex("(W)"); v2=new Vertex("(X)"); v3=new Vertex("(Y)"); v4=new Vertex("(Z)"); graph4.addVertex(v1); graph4.addVertex(v2); graph4.addVertex(v3); graph4.addVertex(v4); graph4.addEdge(v1,v4,2); graph4.addEdge(v2,v3,3); graph4.addEdge(v2,v1,6); graph4.addEdge(v3,v1,4); graph4.addEdge(v3,v4,5); graph4.addEdge(v4,v3,3); graph4.addEdge(v4,v2,-7); System.out.println(graph3); System.out.print("\n**** Uso de Johnson 4***\n"); time=System.currentTimeMillis(); Johnson jon4=new Johnson(graph4); jon4.computeShortestPaths(); System.out.println("\n\n\t ** FIN JOHNSON 4**\n"); tfinal=System.currentTimeMillis()-time; System.out.println("tiempo de ejecucion 4: "+tfinal+" miliseg\n"); //Grafo 5 System.out.println("\n\n\tQUINTA PRUEBA \n");//GRAFO 8 vertices //grafo Algoritmo internet WeightedAdjacencyListGraph graph5 = new WeightedAdjacencyListGraph(8, true); Vertex q1,q2,q3,q4,q5,q6,q7,q8; q1=new Vertex("(A)"); q2=new Vertex("(B)"); q3=new Vertex("(C)"); q4=new Vertex("(D)"); q5=new Vertex("(E)"); q6=new Vertex("(F)"); q7=new Vertex("(G)"); q8=new Vertex("(H)"); graph5.addVertex(q1); graph5.addVertex(q2); graph5.addVertex(q3); graph5.addVertex(q4); graph5.addVertex(q5); graph5.addVertex(q6);

23

graph5.addVertex(q7); graph5.addVertex(q8); graph5.addEdge(q1,q5,2); graph5.addEdge(q2,q1,1); graph5.addEdge(q2,q3,1); graph5.addEdge(q3,q4,3); graph5.addEdge(q4,q5,-1); graph5.addEdge(q5,q2,-2); graph5.addEdge(q6,q1,-4); graph5.addEdge(q6,q5,-1); graph5.addEdge(q7,q6,1); graph5.addEdge(q8,q1,10); graph5.addEdge(q8,q7,1); System.out.println(graph5); System.out.print("\n**** Uso de Johnson 5 ***\n"); time=System.currentTimeMillis(); Johnson jon5=new Johnson(graph5); jon5.computeShortestPaths(); System.out.println("\n\n\t ** FIN JOHNSON 5**\n"); tfinal=System.currentTimeMillis()-time; System.out.println("tiempo de ejecucion 5: "+tfinal+" miliseg\n");

} }

package algoritmojohnson; /* @author Alfredo Parra y Carlos San Juan */ public class MinHeap extends Heap{ /*Crea un MinHeap vacio*/ MinHeap() { super(); } /*Hace un HEAP en lugar del argumento, y asegura que tenga la propiedad min-heap.*/ MinHeap(Comparable[] array) { super(array); } /*Restaura la propiedad min-heap. Asume que en el momento de la llamada, la propiedad min-heap tiene en todas partes, con la posible excepcin de una posicin y sus hijos*/ public void heapify(int i) { int l = left(i); int r = right(i); int smallest = i; if (l < heapSize && array[l].compareTo(array[i]) < 0)

24

smallest = l; if (r < heapSize && array[r].compareTo(array[smallest]) < 0) smallest = r; if (smallest != i) { exchange(i, smallest); heapify(smallest); } } }

Clase MinHeapPriorityQueue:
package algoritmojohnson; /* @author Alfredo Parra y Carlos San Juan */ public class MinHeapPriorityQueue extends MinHeap implements MinPriorityQueue{ /*Crea una cola de prioridad vacia*/ public MinHeapPriorityQueue() { super(); } /*Reemplaza el mtodo de cambio para actualizar la parte del ndice de cada Handle */ protected void exchange(int i, int j) { ((Handle) array[i]).index = j; ((Handle) array[j]).index = i; super.exchange(i,j); } /*Inserta un elemento dinmico, puesto en la cola de prioridad minima*/ public Object insert(DynamicSetElement x) { // Si la matriz an no existe, lo crea. if (array == null) { array = new Comparable[1]; heapSize = 0; } //Si no hay suficiente espacio para el nuevo elemento, el doble del //tamao de la matriz. else if (heapSize >= array.length) { Comparable[] temp = new Comparable[heapSize * 2]; for (int i = 0; i < heapSize; i++) temp[i] = array[i]; array = temp; } //Crear una nueva "Handle", y lo puso en el ndice disponible. Handle handle = new Handle(heapSize, x); array[heapSize] = handle;

25

heapSize++; //Burbuja hasta la pila. bubbleUp(heapSize-1); //devuelve el handle return handle; } /*Devuelve el elemento ms pequeo en la cola de prioridad min-sin eliminar el elemento.*/ public DynamicSetElement minimum() throws HeapUnderflowException{ if (heapSize > 0) return ((Handle) array[0]).info; else { throw new HeapUnderflowException(); } } /*Quita y devuelve el elemento ms pequeo en la cola de prioridad min. Con el fin de la "manija" del elemento volvi a ser elegible para la recoleccin de basura, el usuario de la MinPriorityQueue debe incluir en los datos de un satlite DynamicSetElement es una referencia a la "manija". Esta referencia se debe establecer en nulo para el elemento devuelto por extractMin. */ public DynamicSetElement extractMin(){ if (heapSize < 1) throw new HeapUnderflowException(); // Obtenga una referencia al elemento ms pequeo. DynamicSetElement min = ((Handle) array[0]).info; //Mueva el ltimo elemento de la pila a la raz, y claro //la referencia en su posicin actual de la matriz. array[0] = array[heapSize-1]; ((Handle) array[0]).index = 0; array[heapSize-1] = null; heapSize--; // restaura las propiedades del min-heap heapify(0); return min; } /* Disminuye la clave de un elemento dado a un nuevo valor.*/ public void decreaseKey(Object element, Comparable newKey) throws KeyUpdateException { Handle handle = (Handle) element; if (newKey.compareTo(handle.info.getKey()) > 0) throw new KeyUpdateException(); // all done

26

handle.info.setKey(newKey); // seleccionar nueva clave bubbleUp(handle.index); // restaurar la propiedad min-heap } /*Bubbles ordena el elemento en un ndice dado en la pila hasta que sea mayor o igual a su padre.*/ private void bubbleUp(int i) { while (i > 0 && array[parent(i)].compareTo(array[i]) > 0) { exchange(i, parent(i)); i = parent(i); } }

Clase MinPriorityQueue:
package algoritmojohnson; /* @author Alfredo Parra y Carlos San Juan */ public interface MinPriorityQueue { /*Inserta un elemento dinmico, puesto en la cola de prioridad min.*/ public Object insert(DynamicSetElement x); /*Devuelve el elemento ms pequeo en la cola "min-priority" sin la eliminacin del elemento.*/ public DynamicSetElement minimum(); public DynamicSetElement extractMin(); /*Quita y devuelve el elemento ms pequeo en la cola de prioridad min.*/ public void decreaseKey(Object element, Comparable newKey) throws KeyUpdateException; /*verifica si esta vacia */ public boolean isEmpty(); }

Clase ShortestPathInfo:
package algoritmojohnson; /* @author Alfredo Parra y Carlos San Juan */ class ShortestPathInfo { private double d; /* El predecesor actual (padre) para este vrtice.*/ private Vertex pi;

27

/* Inicializa el clculo de ruta ms corta hasta el infinito y el predecesor de nulo. */ public ShortestPathInfo(){ d = Double.POSITIVE_INFINITY; pi = null; } /*Establece la estimacin de la ruta ms corta.*/ public void setEstimate(double newEstimate) { d = newEstimate; } /*Devuelve el clculo de ruta ms corta.*/ public double getEstimate(){ return d; } /*Establece el predecesor.*/ public void setPredecessor(Vertex v){ pi = v; } /** Retorna el predecesor. */ public Vertex getPredecessor() { return pi; } /*relaja un borde*/ public boolean relax(Vertex u, double du, double w){ double newWeight = du + w; if (newWeight < d) { d = newWeight; pi = u; return true; } else return false; } /*retorna la representacion de este objeto*/ public String toString() { String parentName; if (pi == null) parentName = "(null)"; else parentName = pi.getName(); return "d = " + d + ", pi = " + parentName; } }

28

Clase SingleSourceShortestPaths:
package algoritmojohnson; abstract public class SingleSourceShortestPaths{ /*El grfico que se est calculando una sola ruta de los caminos ms cortos. */ protected WeightedAdjacencyListGraph g; //verifica si el grafo es dirigido protected boolean noNegWeightCycle; /* El resultado de ejecutar el algoritmo para la ruta ms corta. Cada objeto de esta matriz corresponde a un vrtice de la grfica, y puede consultar sus respuestas llamando a los mtodos de la clase ShortestPathInfo.*/ private ShortestPathInfo[] spInfo; /*Establece las variables de instancia, incluida la asignacin de la matriz spInfo pero no la asignacin de los objetos ShortestPathInfo referencia a la matriz.*/ protected SingleSourceShortestPaths(WeightedAdjacencyListGraph theGraph) { g = theGraph; noNegWeightCycle = true; //no han encontrado todava una spInfo = new ShortestPathInfo[g.getCardV()]; } /*Calcula una sola fuente de rutas ms cortas desde un origen determinado vrtice, el llenado de los pesos y los predecesores de la matriz spInfo. */ abstract public void computeShortestPaths(Vertex s); /*inicializa la ruta ms corta*/ public void initializeSingleSource(Vertex s){ for (int i = 0; i < spInfo.length; i++) spInfo[i] = newShortestPathInfo(); getShortestPathInfo(s).setEstimate(0); } /** retorna un nuevo objeto*/ protected ShortestPathInfo newShortestPathInfo(){ return new ShortestPathInfo(); } /*detecta ciclos negativos */ public boolean hasNoNegativeWeightCycle() { return noNegWeightCycle; } /*retorna la ruta ms corta*/

29

public ShortestPathInfo getShortestPathInfo(Vertex v) { return getShortestPathInfo(v.getIndex()); } /*Retorna una referencia de un objeto ShortestPathInfo para un vertice*/ public ShortestPathInfo getShortestPathInfo(int v){ return spInfo[v]; }

Clase Sorter:
package algoritmojohnson; /* @author Alfredo Parra y Carlos San Juan */ public interface Sorter{ /*Ordena una matriz de objetos comparables.*/ public void sort(Comparable[] array); }

Clase Vertex:
package algoritmojohnson; /* @author Alfredo Parra y Carlos San Juan */ public class Vertex { /*Valor que indica que este vrtice an no cuenta con un ndice, es decir, el ndice se desconoce. */ public static final int UNKNOWN_INDEX = -1; /* ndice de este vrtice de su grfica, de 0 a cardV-1. */ private int index; /*Nombre del vertice */ private String name; /*Crea un vrtice cuyo ndice se desconoce.*/ public Vertex(String name) { index = UNKNOWN_INDEX; this.name = name; } /*Crea un vrtice cuyo ndice y nombre se conoce.*/ public Vertex(int index, String name){ this.index = index; this.name = name; } /*modifica el indice */

30

public void setIndex(int index){ this.index = index; } /* retorna el indice del vertice */ public int getIndex(){ return index; } /*Modifica el nombre de vertice*/ public void setName(String name){ this.name = name; } /*Retorna el nombre del vertice. */ public String getName(){ return name; } /**retorna la representacion del vertice */ public String toString(){ return name + " (index = " + index + ")"; } }

Clase WeigthtedAdjancencyListGraph:
package algoritmojohnson; import java.util.Iterator; /* @author Alfredo Parra y Carlos San Juan */ public class WeightedAdjacencyListGraph extends AdjacencyListGraph{ /** cardV:Se recive la cantidad de vertices del Grafo directed: indetificar si el grafo es direccionado o no. */ public WeightedAdjacencyListGraph(int cardV, boolean directed){ super(cardV, directed); } public void addEdge(Vertex u, Vertex v){ //Verifica que los bordes del grafo tengan peso throw new UnsupportedOperationException(); } public void addEdge(int u, int v) { throw new UnsupportedOperationException(); } /**

31

Agrega un margen ponderado de este grfico. El borde es especificado por un par de vertices "u" un vertice. "v" el otro vertice. "weight" el peso del borde*/ public void addEdge(Vertex u, Vertex v, double weight) { // Ponemos v en u su lista. int uIndex = u.getIndex(); Edge x = new WeightedEdge(v, adj[uIndex].head, weight); adj[uIndex].head = x; // Si no es dirigido ponemos el vertice "u" en la lista de "v" if (!directed) { int vIndex = v.getIndex(); x = new WeightedEdge(u, adj[vIndex].head, weight); adj[vIndex].head = x; } e++; } /*Agrega un margen al grafo. el borde especificado por un par de vertices u indicador del primer vertice. v el indicador del otro vertice weight el valor del arco. */ public void addEdge(int u, int v, double weight) { // Poner v en lista de u Edge x = new WeightedEdge(adj[v].thisVertex, adj[u].head, weight); adj[u].head = x; //si no es dirigido, poner u en lista de v if (!directed) { x = new WeightedEdge(adj[u].thisVertex, adj[v].head, weight); adj[v].head = x; } } e++;

/*Clase interna de los bordes ponderados en las listas de adyacencia. Listas de adyacencia son simplemente enlazada*/ protected static class WeightedEdge extends Edge{ //el peso del borde private double weight; /**Creamos el nuevo peso * v el vertice adjacente * successor borde sucesor a este * wgt el nuevo peso del borde*/ public WeightedEdge(Vertex v, Edge successor, double wgt){ super(v, successor); weight = wgt; }

32

public void setWeight(double wgt){ weight = wgt; } public double getWeight(){ return weight; } } /** Devuelve un iterador que itera a travs de las aristas incidentes ponderada en un vrtice dado. Cada arista incidente se indica mediante el correspondiente vrtice adyacente. "u" es el vrtice cuyo aristas incidentes son devueltos por el iterador*/ public Iterator edgeIterator(Vertex u){ return new EdgeIterator(u.getIndex()); } public Iterator edgeIterator(int u){ return new EdgeIterator(u); } /*Devuelve un iterador, de WeightedEdgeIterator tipo (de modo que la persona que llama no tiene que convertir el resultado), que recorre las aristas incidentes ponderada en un vrtice dado. Cada arista incidente se indica mediante el correspondiente vrtice adyacente. */ public WeightedEdgeIterator weightedEdgeIterator(Vertex u){ return weightedEdgeIterator(u.getIndex()); } public WeightedEdgeIterator weightedEdgeIterator(int u){ return new EdgeIterator(u); } /*CLASE INTERNA */ public class EdgeIterator extends AdjacencyListGraph.EdgeIterator implements WeightedEdgeIterator{ /*Inicia una iteracin a travs de las aristas incidentes ponderada en un vrtice dado.*/ public EdgeIterator(int v){ super(v); } /*Devuelve el peso de la orilla devuelto por la llamada ms reciente a la siguiente*/ public double getWeight(){ return ((WeightedEdge) current).getWeight(); } public void setWeight(double weight){ ((WeightedEdge) current).setWeight(weight); }

33

/*Crea y devuelve una WeightedAdjacencyListGraph vaco, sin bordes, dado el nmero de vrtices y un booleano que indica si el grafo es dirigido.*/ protected AdjacencyListGraph makeEmptyGraph(int cardV, boolean directed) { return new WeightedAdjacencyListGraph(cardV, directed); } /*Devuelve la representacion de un grafo ponderado */ public String toString() { String result = ""; Iterator vertexIter = vertexIterator(); while (vertexIter.hasNext()) { Vertex u = (Vertex) vertexIter.next(); result += u + ":\n"; WeightedEdgeIterator edgeIter = weightedEdgeIterator(u); while (edgeIter.hasNext()) { Vertex v = (Vertex) edgeIter.next(); double w = edgeIter.getWeight(); result += " " + v + ", weight = " + w + "\n"; }

} }

} return result;

Clase WeightedEdgeIterator:
package algoritmojohnson; import java.util.Iterator; /* @author Alfredo Parra y Carlos San Juan */ public interface WeightedEdgeIterator extends Iterator{ /*Devuelve el peso de la orilla devuelto por la llamada ms reciente a la siguiente.*/ public double getWeight(); public void setWeight(double weight); }

34

PRUEBAS DEL ALGORITMO


Por motivos de espacio, solo realizaremos una prueba para mostrar cmo trabaja nuestro algoritmo, ya que el resultado entregado es un poco extenso, pero el grfico ser con las 5 pruebas que se piden, a continuacin los grafos que utilizamos en el programa y la solucin de este, adems de las 5 pruebas realizadas donde analizaremos el tiempo.

1.-

2.-

4.-

5.-

35

Ejecucin de nuestro Algoritmo de Johnson:


PRIMER GRAFO: a (index = 0): e (index = 4), weight = -4.0 c (index = 2), weight = 8.0 b (index = 1), weight = 3.0 b (index = 1): d (index = 3), weight = 1.0 e (index = 4), weight = 7.0 c (index = 2): b (index = 1), weight = 4.0 d (index = 3): a (index = 0), weight = 2.0 c (index = 2), weight = -5.0 e (index = 4): d (index = 3), weight = 6.0

**** Uso de Johnson 1 *** Grafo con nodo nuevo 's': a (index = 0): b (index = 1), weight = 3.0 c (index = 2), weight = 8.0 e (index = 4), weight = -4.0 b (index = 1): e (index = 4), weight = 7.0 d (index = 3), weight = 1.0 c (index = 2): b (index = 1), weight = 4.0 d (index = 3): c (index = 2), weight = -5.0 a (index = 0), weight = 2.0 e (index = 4): d (index = 3), weight = 6.0 s (index = 5): e (index = 4), weight = 0.0 d (index = 3), weight = 0.0 c (index = 2), weight = 0.0 b (index = 1), weight = 0.0 a (index = 0), weight = 0.0 Muestra los nuevos pesos h(v) 0.0 -1.0 -5.0 0.0 -4.0 0.0 Grafo con pesos recalculados: w(u, v) + h(u) h(v) a (index = 0): b (index = 1), weight = 4.0 c (index = 2), weight = 13.0

36

e (index = 4), weight = 0.0 b (index = 1): e (index = 4), weight = 10.0 d (index = 3), weight = 0.0 c (index = 2): b (index = 1), weight = 0.0 d (index = 3): c (index = 2), weight = 0.0 a (index = 0), weight = 2.0 e (index = 4): d (index = 3), weight = 2.0 s (index = 5): e (index = 4), weight = 4.0 d (index = 3), weight = 0.0 c (index = 2), weight = 5.0 b (index = 1), weight = 1.0 a (index = 0), weight = 0.0 Ejecucin Dijkstra: Desde: a (index = 0) Recorrido ms corto: a->e->d->c->b Hacia: a (index = 0)d = 0.0, pi = (null) Hacia: b (index = 1)d = 1.0, pi = c Hacia: c (index = 2)d = -3.0, pi = d Hacia: d (index = 3)d = 2.0, pi = e Hacia: e (index = 4)d = -4.0, pi = a Desde: b (index = 1) Recorrido mas corto: b->d->c->a->e Hacia: a (index = 0)d = 3.0, pi = d Hacia: b (index = 1)d = 0.0, pi = (null) Hacia: c (index = 2)d = -4.0, pi = d Hacia: d (index = 3)d = 1.0, pi = b Hacia: e (index = 4)d = -1.0, pi = a Desde: c (index = 2) Recorrido mas corto: c->b->d->a->e Hacia: a (index = 0)d = 7.0, pi = d Hacia: b (index = 1)d = 4.0, pi = c Hacia: c (index = 2)d = 0.0, pi = (null) Hacia: d (index = 3)d = 5.0, pi = b Hacia: e (index = 4)d = 3.0, pi = a Desde: d (index = 3) Recorrido ms corto: d->c->b->a->e Hacia: a (index = 0)d = 2.0, pi = d Hacia: b (index = 1)d = -1.0, pi = c Hacia: c (index = 2)d = -5.0, pi = d Hacia: d (index = 3)d = 0.0, pi = (null) Hacia: e (index = 4)d = -2.0, pi = a Desde: e (index = 4) Recorrido ms corto: e->d->c->b->a Hacia: a (index = 0)d = 8.0, pi = d

37

Hacia: b (index = 1)d = 5.0, pi = c Hacia: c (index = 2)d = 1.0, pi = d Hacia: d (index = 3)d = 6.0, pi = e Hacia: e (index = 4)d = 0.0, pi = (null)

** FIN JOHNSON 1** tiempo de ejecucin 1: 73 miliseg

SEGUND GRAFO (1) (index = 0): (2) (index = 1): (3) (index = 2), weight = 2.0 (1) (index = 0), weight = 1.0 (3) (index = 2): (2) (index = 1), weight = 1.0 (1) (index = 0), weight = 4.0 (4) (index = 3): (5) (index = 4), weight = 4.0 (2) (index = 1), weight = 8.0 (5) (index = 4): (4) (index = 3), weight = 2.0 (3) (index = 2), weight = 2.0 **** Uso de Johnson 2*** Grafo con nodo nuevo 's': (1) (index = 0): (2) (index = 1): (1) (index = 0), weight = 1.0 (3) (index = 2), weight = 2.0 (3) (index = 2): (1) (index = 0), weight = 4.0 (2) (index = 1), weight = 1.0 (4) (index = 3): (2) (index = 1), weight = 8.0 (5) (index = 4), weight = 4.0 (5) (index = 4): (3) (index = 2), weight = 2.0 (4) (index = 3), weight = 2.0 s (index = 5): (5) (index = 4), weight = 0.0 (4) (index = 3), weight = 0.0 (3) (index = 2), weight = 0.0 (2) (index = 1), weight = 0.0 (1) (index = 0), weight = 0.0 Muestra los nuevos pesos h(v) 0.0 0.0

38

0.0 0.0 0.0 0.0 Grafo con pesos recalculados: w(u, v) + h(u) h(v) (1) (index = 0): (2) (index = 1): (1) (index = 0), weight = 1.0 (3) (index = 2), weight = 2.0 (3) (index = 2): (1) (index = 0), weight = 4.0 (2) (index = 1), weight = 1.0 (4) (index = 3): (2) (index = 1), weight = 8.0 (5) (index = 4), weight = 4.0 (5) (index = 4): (3) (index = 2), weight = 2.0 (4) (index = 3), weight = 2.0 s (index = 5): (5) (index = 4), weight = 0.0 (4) (index = 3), weight = 0.0 (3) (index = 2), weight = 0.0 (2) (index = 1), weight = 0.0 (1) (index = 0), weight = 0.0 Ejecucin Dijkstra: Desde: (1) (index = 0) Recorrido ms corto: (1)->s->(5)->(4)->(3) Hacia: (1) (index = 0)d = 0.0, pi = (null) Hacia: (2) (index = 1)d = Infinity, pi = (null) Hacia: (3) (index = 2)d = Infinity, pi = (null) Hacia: (4) (index = 3)d = Infinity, pi = (null) Hacia: (5) (index = 4)d = Infinity, pi = (null) Desde: (2) (index = 1) Recorrido ms corto: (2)->(1)->(3)->(4)->(5) Hacia: (1) (index = 0)d = 1.0, pi = (2) Hacia: (2) (index = 1)d = 0.0, pi = (null) Hacia: (3) (index = 2)d = 2.0, pi = (2) Hacia: (4) (index = 3)d = Infinity, pi = (null) Hacia: (5) (index = 4)d = Infinity, pi = (null) Desde: (3) (index = 2) Recorrido ms corto: (3)->(2)->(1)->(4)->s Hacia: (1) (index = 0)d = 2.0, pi = (2) Hacia: (2) (index = 1)d = 1.0, pi = (3) Hacia: (3) (index = 2)d = 0.0, pi = (null) Hacia: (4) (index = 3)d = Infinity, pi = (null) Hacia: (5) (index = 4)d = Infinity, pi = (null) Desde: (4) (index = 3) Recorrido ms corto: (4)->(5)->(3)->(2)->(1) Hacia: (1) (index = 0)d = 8.0, pi = (2)

39

Hacia: (2) (index = 1)d = 7.0, pi = (3) Hacia: (3) (index = 2)d = 6.0, pi = (5) Hacia: (4) (index = 3)d = 0.0, pi = (null) Hacia: (5) (index = 4)d = 4.0, pi = (4) Desde: (5) (index = 4) Recorrido ms corto: (5)->(3)->(4)->(2)->(1) Hacia: (1) (index = 0)d = 4.0, pi = (2) Hacia: (2) (index = 1)d = 3.0, pi = (3) Hacia: (3) (index = 2)d = 2.0, pi = (5) Hacia: (4) (index = 3)d = 2.0, pi = (5) Hacia: (5) (index = 4)d = 0.0, pi = (null)

** FIN JOHNSON 2** Tiempo de ejecucin 2: 28 miliseg

TERCERA PRUEBA (0) (index = 0): (2) (index = 2), weight = 13.0 (1) (index = 1), weight = 16.0 (1) (index = 1): (3) (index = 3), weight = 12.0 (2) (index = 2), weight = 10.0 (2) (index = 2): (4) (index = 4), weight = 14.0 (1) (index = 1), weight = 4.0 (3) (index = 3): (5) (index = 5), weight = 20.0 (2) (index = 2), weight = 9.0 (4) (index = 4): (5) (index = 5), weight = 4.0 (3) (index = 3), weight = 7.0 (5) (index = 5):

**** Uso de Johnson 3 *** Grafo con nodo nuevo 's': (0) (index = 0): (1) (index = 1), weight = 16.0 (2) (index = 2), weight = 13.0 (1) (index = 1): (2) (index = 2), weight = 10.0 (3) (index = 3), weight = 12.0 (2) (index = 2): (1) (index = 1), weight = 4.0 (4) (index = 4), weight = 14.0 (3) (index = 3): (2) (index = 2), weight = 9.0 (5) (index = 5), weight = 20.0

40

(4) (index = 4): (3) (index = 3), weight = 7.0 (5) (index = 5), weight = 4.0 (5) (index = 5): s (index = 6): (5) (index = 5), weight = 0.0 (4) (index = 4), weight = 0.0 (3) (index = 3), weight = 0.0 (2) (index = 2), weight = 0.0 (1) (index = 1), weight = 0.0 (0) (index = 0), weight = 0.0 Muestra los nuevos pesos h(v) 0.0 0.0 0.0 0.0 0.0 0.0 0.0 Grafo con pesos recalculados: w(u, v) + h(u) h(v) (0) (index = 0): (1) (index = 1), weight = 16.0 (2) (index = 2), weight = 13.0 (1) (index = 1): (2) (index = 2), weight = 10.0 (3) (index = 3), weight = 12.0 (2) (index = 2): (1) (index = 1), weight = 4.0 (4) (index = 4), weight = 14.0 (3) (index = 3): (2) (index = 2), weight = 9.0 (5) (index = 5), weight = 20.0 (4) (index = 4): (3) (index = 3), weight = 7.0 (5) (index = 5), weight = 4.0 (5) (index = 5): s (index = 6): (5) (index = 5), weight = 0.0 (4) (index = 4), weight = 0.0 (3) (index = 3), weight = 0.0 (2) (index = 2), weight = 0.0 (1) (index = 1), weight = 0.0 (0) (index = 0), weight = 0.0 Execution Dijkstra: Desde: (0) (index = 0) Recorrido ms corto: (0)->(2)->(1)->(4)->(3)->(5) Hacia: (0) (index = 0)d = 0.0, pi = (null) Hacia: (1) (index = 1)d = 16.0, pi = (0) Hacia: (2) (index = 2)d = 13.0, pi = (0) Hacia: (3) (index = 3)d = 28.0, pi = (1)

41

Hacia: (4) (index = 4)d = 27.0, pi = (2) Hacia: (5) (index = 5)d = 31.0, pi = (4) Desde: (1) (index = 1) Recorrido ms corto: (1)->(2)->(3)->(4)->(5)->s Hacia: (0) (index = 0)d = Infinity, pi = (null) Hacia: (1) (index = 1)d = 0.0, pi = (null) Hacia: (2) (index = 2)d = 10.0, pi = (1) Hacia: (3) (index = 3)d = 12.0, pi = (1) Hacia: (4) (index = 4)d = 24.0, pi = (2) Hacia: (5) (index = 5)d = 28.0, pi = (4) Desde: (2) (index = 2) Recorrido ms corto: (2)->(1)->(4)->(3)->(5)->(0) Hacia: (0) (index = 0)d = Infinity, pi = (null) Hacia: (1) (index = 1)d = 4.0, pi = (2) Hacia: (2) (index = 2)d = 0.0, pi = (null) Hacia: (3) (index = 3)d = 16.0, pi = (1) Hacia: (4) (index = 4)d = 14.0, pi = (2) Hacia: (5) (index = 5)d = 18.0, pi = (4) Desde: (3) (index = 3) Recorrido ms corto: (3)->(2)->(1)->(5)->(4)->s Hacia: (0) (index = 0)d = Infinity, pi = (null) Hacia: (1) (index = 1)d = 13.0, pi = (2) Hacia: (2) (index = 2)d = 9.0, pi = (3) Hacia: (3) (index = 3)d = 0.0, pi = (null) Hacia: (4) (index = 4)d = 23.0, pi = (2) Hacia: (5) (index = 5)d = 20.0, pi = (3) Desde: (4) (index = 4) Recorrido ms corto: (4)->(5)->(3)->(2)->(1)->(0) Hacia: (0) (index = 0)d = Infinity, pi = (null) Hacia: (1) (index = 1)d = 20.0, pi = (2) Hacia: (2) (index = 2)d = 16.0, pi = (3) Hacia: (3) (index = 3)d = 7.0, pi = (4) Hacia: (4) (index = 4)d = 0.0, pi = (null) Hacia: (5) (index = 5)d = 4.0, pi = (4) Desde: (5) (index = 5) Recorrido ms corto: (5)->s->(2)->(4)->(3)->(0) Hacia: (0) (index = 0)d = Infinity, pi = (null) Hacia: (1) (index = 1)d = Infinity, pi = (null) Hacia: (2) (index = 2)d = Infinity, pi = (null) Hacia: (3) (index = 3)d = Infinity, pi = (null) Hacia: (4) (index = 4)d = Infinity, pi = (null) Hacia: (5) (index = 5)d = 0.0, pi = (null) d = 20.0, pi = (2) ** FIN JOHNSON 3** tiempo de ejecucin grafo 3: 33 miliseg

CUARTA PRUEBA (0) (index = 0):

42

(2) (index = 2), weight = 13.0 (1) (index = 1), weight = 16.0 (1) (index = 1): (3) (index = 3), weight = 12.0 (2) (index = 2), weight = 10.0 (2) (index = 2): (4) (index = 4), weight = 14.0 (1) (index = 1), weight = 4.0 (3) (index = 3): (5) (index = 5), weight = 20.0 (2) (index = 2), weight = 9.0 (4) (index = 4): (5) (index = 5), weight = 4.0 (3) (index = 3), weight = 7.0 (5) (index = 5):

**** Uso de Johnson 4*** Grafo con nodo nuevo 's': (W) (index = 0): (Z) (index = 3), weight = 2.0 (X) (index = 1): (Y) (index = 2), weight = 3.0 (W) (index = 0), weight = 6.0 (Y) (index = 2): (W) (index = 0), weight = 4.0 (Z) (index = 3), weight = 5.0 (Z) (index = 3): (Y) (index = 2), weight = 3.0 (X) (index = 1), weight = -7.0 s (index = 4): (Z) (index = 3), weight = 0.0 (Y) (index = 2), weight = 0.0 (X) (index = 1), weight = 0.0 (W) (index = 0), weight = 0.0 Muestra los nuevos pesos h(v) -1.0 -7.0 -4.0 0.0 0.0 Grafo con pesos recalculados: w(u, v) + h(u) h(v) (W) (index = 0): (Z) (index = 3), weight = 1.0 (X) (index = 1): (Y) (index = 2), weight = 0.0 (W) (index = 0), weight = 0.0 (Y) (index = 2): (W) (index = 0), weight = 1.0 (Z) (index = 3), weight = 1.0 (Z) (index = 3): (Y) (index = 2), weight = 7.0

43

(X) (index = 1), weight = 0.0 s (index = 4): (Z) (index = 3), weight = 0.0 (Y) (index = 2), weight = 4.0 (X) (index = 1), weight = 7.0 (W) (index = 0), weight = 1.0 Ejecucin Dijkstra: Desde: (W) (index = 0) Recorrido ms corto: (W)->(Z)->(X)->(Y) Hacia: (W) (index = 0)d = 0.0, pi = (null) Hacia: (X) (index = 1)d = -5.0, pi = (Z) Hacia: (Y) (index = 2)d = -2.0, pi = (X) Hacia: (Z) (index = 3)d = 2.0, pi = (W) Desde: (X) (index = 1) Recorrido ms corto: (X)->(Y)->(W)->(Z) Hacia: (W) (index = 0)d = 6.0, pi = (X) Hacia: (X) (index = 1)d = 0.0, pi = (null) Hacia: (Y) (index = 2)d = 3.0, pi = (X) Hacia: (Z) (index = 3)d = 8.0, pi = (Y) Desde: (Y) (index = 2) Recorrido ms corto: (Y)->(W)->(Z)->(X) Hacia: (W) (index = 0)d = 4.0, pi = (Y) Hacia: (X) (index = 1)d = -2.0, pi = (Z) Hacia: (Y) (index = 2)d = 0.0, pi = (null) Hacia: (Z) (index = 3)d = 5.0, pi = (Y) Desde: (Z) (index = 3) Recorrido ms corto: (Z)->(X)->(Y)->(W) Hacia: (W) (index = 0)d = -1.0, pi = (X) Hacia: (X) (index = 1)d = -7.0, pi = (Z) Hacia: (Y) (index = 2)d = -4.0, pi = (X) Hacia: (Z) (index = 3)d = 0.0, pi = (null)

** FIN JOHNSON 4** tiempo de ejecucin 4: 21 miliseg

QUINTA PRUEBA (A) (index = 0): (E) (index = 4), weight = 2.0 (B) (index = 1): (C) (index = 2), weight = 1.0 (A) (index = 0), weight = 1.0 (C) (index = 2): (D) (index = 3), weight = 3.0 (D) (index = 3): (E) (index = 4), weight = -1.0

44

(E) (index = 4): (B) (index = 1), weight = -2.0 (F) (index = 5): (E) (index = 4), weight = -1.0 (A) (index = 0), weight = -4.0 (G) (index = 6): (F) (index = 5), weight = 1.0 (H) (index = 7): (G) (index = 6), weight = 1.0 (A) (index = 0), weight = 10.0

**** Uso de Johnson 5 *** Grafo con nodo nuevo 's': (A) (index = 0): (E) (index = 4), weight = 2.0 (B) (index = 1): (A) (index = 0), weight = 1.0 (C) (index = 2), weight = 1.0 (C) (index = 2): (D) (index = 3), weight = 3.0 (D) (index = 3): (E) (index = 4), weight = -1.0 (E) (index = 4): (B) (index = 1), weight = -2.0 (F) (index = 5): (A) (index = 0), weight = -4.0 (E) (index = 4), weight = -1.0 (G) (index = 6): (F) (index = 5), weight = 1.0 (H) (index = 7): (A) (index = 0), weight = 10.0 (G) (index = 6), weight = 1.0 s (index = 8): (H) (index = 7), weight = 0.0 (G) (index = 6), weight = 0.0 (F) (index = 5), weight = 0.0 (E) (index = 4), weight = 0.0 (D) (index = 3), weight = 0.0 (C) (index = 2), weight = 0.0 (B) (index = 1), weight = 0.0 (A) (index = 0), weight = 0.0 Muestra los nuevos pesos h(v) -4.0 -4.0 -3.0 0.0 -2.0 0.0 0.0 0.0 0.0 Grafo con pesos recalculados: w(u, v) + h(u) h(v)

45

(A) (index = 0): (E) (index = 4), weight = 0.0 (B) (index = 1): (A) (index = 0), weight = 1.0 (C) (index = 2), weight = 0.0 (C) (index = 2): (D) (index = 3), weight = 0.0 (D) (index = 3): (E) (index = 4), weight = 1.0 (E) (index = 4): (B) (index = 1), weight = 0.0 (F) (index = 5): (A) (index = 0), weight = 0.0 (E) (index = 4), weight = 1.0 (G) (index = 6): (F) (index = 5), weight = 1.0 (H) (index = 7): (A) (index = 0), weight = 14.0 (G) (index = 6), weight = 1.0 s (index = 8): (H) (index = 7), weight = 0.0 (G) (index = 6), weight = 0.0 (F) (index = 5), weight = 0.0 (E) (index = 4), weight = 2.0 (D) (index = 3), weight = 0.0 (C) (index = 2), weight = 3.0 (B) (index = 1), weight = 4.0 (A) (index = 0), weight = 4.0 Ejecucin Dijkstra: Desde: (A) (index = 0) Recorrido ms corto: (A)->(E)->(B)->(C)->(D)->s->(H)->(G) Hacia: (A) (index = 0)d = 0.0, pi = (null) Hacia: (B) (index = 1)d = 0.0, pi = (E) Hacia: (C) (index = 2)d = 1.0, pi = (B) Hacia: (D) (index = 3)d = 4.0, pi = (C) Hacia: (E) (index = 4)d = 2.0, pi = (A) Hacia: (F) (index = 5)d = Infinity, pi = (null) Hacia: (G) (index = 6)d = Infinity, pi = (null) Hacia: (H) (index = 7)d = Infinity, pi = (null) Desde: (B) (index = 1) Recorrido ms corto: (B)->(C)->(D)->(A)->(E)->(G)->s->(H) Hacia: (A) (index = 0)d = 1.0, pi = (B) Hacia: (B) (index = 1)d = 0.0, pi = (null) Hacia: (C) (index = 2)d = 1.0, pi = (B) Hacia: (D) (index = 3)d = 4.0, pi = (C) Hacia: (E) (index = 4)d = 3.0, pi = (D) Hacia: (F) (index = 5)d = Infinity, pi = (null) Hacia: (G) (index = 6)d = Infinity, pi = (null) Hacia: (H) (index = 7)d = Infinity, pi = (null) Desde: (C) (index = 2) Recorrido ms corto: (C)->(D)->(E)->(B)->(A)->s->(H)->(F)

46

Hacia: (A) (index = 0)d = 1.0, pi = (B) Hacia: (B) (index = 1)d = 0.0, pi = (E) Hacia: (C) (index = 2)d = 0.0, pi = (null) Hacia: (D) (index = 3)d = 3.0, pi = (C) Hacia: (E) (index = 4)d = 2.0, pi = (D) Hacia: (F) (index = 5)d = Infinity, pi = (null) Hacia: (G) (index = 6)d = Infinity, pi = (null) Hacia: (H) (index = 7)d = Infinity, pi = (null) Desde: (D) (index = 3) Recorrido ms corto: (D)->(E)->(B)->(C)->(A)->(H)->s->(F) Hacia: (A) (index = 0)d = -2.0, pi = (B) Hacia: (B) (index = 1)d = -3.0, pi = (E) Hacia: (C) (index = 2)d = -2.0, pi = (B) Hacia: (D) (index = 3)d = 0.0, pi = (null) Hacia: (E) (index = 4)d = -1.0, pi = (D) Hacia: (F) (index = 5)d = Infinity, pi = (null) Hacia: (G) (index = 6)d = Infinity, pi = (null) Hacia: (H) (index = 7)d = Infinity, pi = (null) Desde: (E) (index = 4) Recorrido ms corto: (E)->(B)->(C)->(D)->(A)->s->(H)->(G) Hacia: (A) (index = 0)d = -1.0, pi = (B) Hacia: (B) (index = 1)d = -2.0, pi = (E) Hacia: (C) (index = 2)d = -1.0, pi = (B) Hacia: (D) (index = 3)d = 2.0, pi = (C) Hacia: (E) (index = 4)d = 0.0, pi = (null) Hacia: (F) (index = 5)d = Infinity, pi = (null) Hacia: (G) (index = 6)d = Infinity, pi = (null) Hacia: (H) (index = 7)d = Infinity, pi = (null) Desde: (F) (index = 5) Recorrido ms corto: (F)->(A)->(E)->(B)->(C)->(D)->(G)->s Hacia: (A) (index = 0)d = -4.0, pi = (F) Hacia: (B) (index = 1)d = -4.0, pi = (E) Hacia: (C) (index = 2)d = -3.0, pi = (B) Hacia: (D) (index = 3)d = 0.0, pi = (C) Hacia: (E) (index = 4)d = -2.0, pi = (A) Hacia: (F) (index = 5)d = 0.0, pi = (null) Hacia: (G) (index = 6)d = Infinity, pi = (null) Hacia: (H) (index = 7)d = Infinity, pi = (null) Desde: (G) (index = 6) Recorrido ms corto: (G)->(F)->(A)->(E)->(B)->(C)->(D)->(H) Hacia: (A) (index = 0)d = -3.0, pi = (F) Hacia: (B) (index = 1)d = -3.0, pi = (E) Hacia: (C) (index = 2)d = -2.0, pi = (B) Hacia: (D) (index = 3)d = 1.0, pi = (C) Hacia: (E) (index = 4)d = -1.0, pi = (A) Hacia: (F) (index = 5)d = 1.0, pi = (G) Hacia: (G) (index = 6)d = 0.0, pi = (null) Hacia: (H) (index = 7)d = Infinity, pi = (null) Desde: (H) (index = 7) Recorrido ms corto: (H)->(G)->(F)->(A)->(E)->(B)->(C)->(D)

47

Hacia: (A) (index = 0)d = -2.0, pi = (F) Hacia: (B) (index = 1)d = -2.0, pi = (E) Hacia: (C) (index = 2)d = -1.0, pi = (B) Hacia: (D) (index = 3)d = 2.0, pi = (C) Hacia: (E) (index = 4)d = 0.0, pi = (A) Hacia: (F) (index = 5)d = 2.0, pi = (G) Hacia: (G) (index = 6)d = 1.0, pi = (H) Hacia: (H) (index = 7)d = 0.0, pi = (null)

** FIN JOHNSON 5** tiempo de ejecucin 5: 26 miliseg

Resultados de las ejecuciones:


miliseg t1 t2 t3 t4 t5
120 105 90 75 60 45 30 15 0 t1 Grafo 1 t2 Grafo 2 t3 Grafo 3 t4 Grafo 4 Grafo 5 t5

Grafo 1 73 76 74 67 104

Grafo 2 28 14 21 30 34

Grafo 3 33 33 25 22 43

Grafo 4 21 26 34 18 13

Grafo 5 26 49 32 69 51

48

Anlisis del Algoritmo:


: = , = , = () Se busca encontrar el camino ms corto entre todos los pares en ( ) . Para grafos dispersos, es asintticamente ms rpido que sea repetido la cuadratura del matrices o el algoritmo de Floyd-Warshall. El algoritmo o bien devuelve una matriz de la ruta ms corta de pesos para todos los pares de vrtices o informes que el grafo de entrada contiene un ciclo negativo de peso. Algoritmo de Johnson utiliza como subrutinas, tanto Dijkstra y el algoritmo de Bellman-Ford. Algoritmo de Johnson utiliza la tcnica de ponderacin, que funciona usando todos los pesos de las aristas en una grafo = ( , ) son positivos, podemos encontrar ms corto rutas entre todos los pares de vrtices mediante la ejecucin de algoritmo de Dijkstra, una vez de cada vrtice, con el Heap-Fibonacci y la cola de min-prioridad, el tiempo de ejecucin de este todos los pares de algoritmo es ( ) Si tiene pesos negativos en los bordes, pero no ciclos negativos, simplemente se calcula un nuevo conjunto de pesos para las aristas no negativas, que nos permite utilizar el mismo mtodo. El nuevo conjunto de pesos de las aristas y debe satisfacer dos propiedades importantes: 1. Para todos los pares de vrtices , , un camino es un camino ms corto usado desde para utilizando la funcin de peso si y slo si es tambin un camino ms corto desde hasta utilizando la funcin de peso . 2. Para todos los bordes ( , ), el nuevo peso y ( , ) no es negativo.

En nuestro grafo numero 1 ( ( , ), = , = ) vemos que hay bordes con pesos negativos, por lo tanto lo primero que debe hacer nuestro algoritmo es verificar que ni existan ciclos negativos para luego crear un vrtice nuevo para poder redirigirse al resto de los vrtices y usar el algoritmo de Bellman-Ford donde ( ) se calcula ( , ), para as poder cambiar los pesos de las aristas. Una vez realizados los cambios teniendo un grafo al cual se le puede aplicar Dijkstra al vrtice 1, ( , ) ( , ), para obtener los caminos ms cortos. Si calculamos tendramos: ( )= ( ) ( , )= = ( ) ( ) ( , )= ( )= = Aplicamos Dijkstra al vrtice 2, al vrtice 3, al vrtice 4 y al 5 y termina la aplicacin del algoritmo de Johnson.

49

Conclusin
Al desarrollar este algoritmo nos hemos dado cuenta de lo importante que son los grafos y la gran incidencia que tienen en nuestra vida cotidiana y laboral, ya que en la bsqueda de ejemplos vimos los muchos usos que se les dan. Eso en trminos globales, pero si nos enfocamos ms en el problema podemos deducir varias cosas interesantes, entre ellas los diferentes tiempos que se demora un programa para resolver un mismo algoritmo, si bien son escazas diferencias, nos ensean que la computacin no es exacta como las matemticas, si bien se pueden estimar los tiempos mediante frmulas y clculos, hay varias cosas que pueden influir. Por ejemplo el procesador del computador, ya que los tiempos varan de un computado a otro. Por otra parte descubrimos un nuevo algoritmo, que no habamos escuchado anteriormente y que gracias a este pudimos introducirnos en otros dos grandes algoritmos como lo son el Dijkstra y el algoritmo de Bellman-Ford, los funcionamientos de esto y como juntos resuelven ms problemas. Para finalizar podemos decir que el algoritmo de Johnson es muy til ya que resuelve una parte importante de grafos complicados y que para nosotros es fundamental tener una herramienta como esta.

50

Vous aimerez peut-être aussi