johnson juan

50
Facultad Ciencias Empresariales. Escuela de Ingeniería Civil Informática. Chillan. Tarea de Análisis y Diseños de Algoritmos. ALGORITMO DE JOHNSON” Integrantes: Alfredo Parra Urrea. Carlos San Juan Contreras. Profesor: Pablo Sáez González. Fecha: 12-octubre-2011

Upload: alfredo-parra-urrea

Post on 07-Oct-2014

159 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Johnson juan

Facultad Ciencias Empresariales.

Escuela de Ingeniería Civil Informática.

Chillan.

Tarea de Análisis y Diseños de Algoritmos.

“ALGORITMO DE

JOHNSON”

Integrantes: Alfredo Parra Urrea.

Carlos San Juan Contreras.

Profesor: Pablo Sáez González.

Fecha: 12-octubre-2011

Page 2: Johnson juan

2

Page 3: Johnson juan

3

Introducción

En el análisis de algoritmos muchas veces nos encontramos con problemas

difíciles de resolver o simplemente no hallamos las herramientas adecuadas para

poder desarrollar dichos inconvenientes. Entre los grandes problemas que nos

podemos topar, están los grafos, ya que son difíciles de analizar, producto de sus

múltiples 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 diseñar algoritmos que nos permitan evaluar y analizar los diferentes

grafos, para así tener la mejor solución de forma más rápida. Existen varias

herramientas para grafos específicos, encontramos los algoritmos de DIJKSTRA

que es un algoritmo usado para encontrar los caminos mínimos de un grafo

dirigido ponderado de “N” nodos no aislados, donde sea “x” el nodo inicial, un

vector “D” de tamaño “N” guardará el final del algoritmo las distancia desde “x” al

resto de los nodos. También 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 cómo realizo su

algoritmo.

Page 4: Johnson juan

4

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 vértice agregado a esta gráfica. */

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) {

Page 5: Johnson juan

5

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 vértice de adyacencia, cuya lista es esto. */ public Vertex thisVertex;

/** El primer borde en la lista de adyacencia de este vértice.*/

Page 6: Johnson juan

6

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 vértice.

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 vértice devuelto por la llamada más reciente

Inicialmente, su valor es -1.*/ protected int lastVisited;

/** Inicia una iteración a través de los vértices */

public VertexIterator() { lastVisited = -1;

}

/*verifica si hay el iterator tiene más vertices */

public boolean hasNext() { return lastVisited < adj.length - 1;

}

/** Devuelve el siguiente vértice en la iteración.*/

public Object next() { return adj[++lastVisited].thisVertex;

}

Page 7: Johnson juan

7

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 vértice dado.*/

public class EdgeIterator implements Iterator { /*retorna el borde de la llamada más reciente*/

protected Edge current;

/*El índice del vértice cuyos bordes este iterador recorre.*/ protected int index;

/*Inicia una iteración a través de las aristas

incidentes en un vértice dado.

donde v es un indice*/ public EdgeIterator(int v) {

index = v; current = null;

}

/*verifica si hay más vertices */

public boolean hasNext() { if (current == null) {

return adj[index].head != null;

} else { return current.next != null;

} }

/*Devuelve el siguiente borde de la iteración*/

public Object next() {

if (current == null) { current = adj[index].head;

} else { current = current.next;

}

return current.vertex;

}

/*en caso de errores

Page 8: Johnson juan

8

*/

public void remove() {

throw new UnsupportedOperationException(); }

}

/** retorna el numero de vertices*/

public int getCardV() { return adj.length;

}

/*retorna el número de bordes */ public int getCardE() {

return e;

}

/*verifica si el grafo es o no dirigido*/ public boolean isDirected() {

return directed;

}

/** Crea y devuelve un gráfico que utiliza el mismo conjunto de * vértices en la gráfica. El gráfico creado no tiene bordes*/

public AdjacencyListGraph useSameVertices() { // inicializa un grafo vacio.

AdjacencyListGraph newGraph = makeEmptyGraph(adj.length, directed);

//Ahora agregue cada vértice 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 número de vértices 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*/ //imprime las iteraciones public String toString() {

String result = "";

Iterator vertexIter = vertexIterator(); while (vertexIter.hasNext()) {

Vertex u = (Vertex) vertexIter.next(); result += u + ":\n";

Iterator edgeIter = edgeIterator(u);

Page 9: Johnson juan

9

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 asignación SpInfo pero no la asignación de los ShortestPathInfo, objetos

referenciado por la matriz de initializeSingleSource

theGraph para encontrar los caminos más cortos.

*/ public BellmanFord(WeightedAdjacencyListGraph theGraph){

super(theGraph);

}

/*Calcula una sola fuente de rutas más cortas desde un origen determinado Vértice, el llenado de los pesos y sus predecesores del tipo SpInfo.

También establece la variable de instancia NoNegWeightCycle adecuada,

para no encotrar ciclos negativos.

"s" La origen vértice. */

public void computeShortestPaths(Vertex s) { initializeSingleSource(s);

int cardV = g.getCardV();

// Ejecutar a través 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();

Page 10: Johnson juan

10

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

}

} }

// Un pase más 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 asignación SpInfo pero no la asignación de los ShortestPathInfo, objetos

referenciado por la matriz de initializeSingleSource

theGraph para encontrar los caminos más cortos.

*/ public Dijkstra(WeightedAdjacencyListGraph theGraph) {

super(theGraph);

}

/*Calcular una sola fuente rutas más cortas desde un origen determinado vértice, llenando en los pesos y los predecesores de la matriz

*/ public void computeShortestPaths(Vertex s) {

initializeSingleSource(s);

Vector recorrido=new Vector(1,1);

Page 11: Johnson juan

11

//crear una cola de prioridad minima minPriorityQueue

MinPriorityQueue q = new MinHeapPriorityQueue();

/*La información que estamos manteniendo para

cada vértice es un objeto DijkstraInfo. Tenemos que establecer el theVertex y manejar los campos.

Mediante la inserción 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 vértice de la cola con la llave más pequeña. 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 más corta de estimación ha cambiado,

//por lo que actualizar la cola de priorityMin. q.decreaseKey(vInfo.handle,new Double(vInfo.getEstimate()));

}

} recorrido.add(u.getName());

}

//se imprime el camino for(int i=0;i<cardV-2;i++) System.out.print(recorrido.elementAt(i)+"->");

System.out.print(recorrido.elementAt(cardV-2)+"\n\n"); }

/*retorna nuevo DijkstraInfo*/ protected ShortestPathInfo newShortestPathInfo(){

return new DijkstraInfo(); }

Page 12: Johnson juan

12

/*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 vértice de este objeto a la de otro.

vértice es menor; 0 si las claves son iguales, un entero positivo si la clave del vértice 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();

/compara elementos public int compareTo(Object e);/

Page 13: Johnson juan

13

/*Clase interna para definir los métodos estáticos de ayuda.*/

public static class Helper { /**

* Compara un DynamicSetElement a otro * Objeto. Si el otro objeto es también un * DynamicSetElement, las llaves de ambos se comparan. * Si el otro objeto no es un DynamicSetElement, pero la aplicación 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 { /*

Añade un vértice a la grafo. Teniendo en cuenta el nombre del vértice, 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 */

Page 14: Johnson juan

14

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 vértice 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 gráfica. El borde es especificado por un par de índices de vértice. */

public void addEdge(int u, int v);

/*Devuelve un iterador que itera ppasando por todos los

vértices del grafo.*/ public Iterator vertexIterator();

/*Devuelve un iterador que recorre las aristas incidentes en un vértice dado. Cada arista incidente se indica mediante el

correspondiente vértice adyacente.*/ public Iterator edgeIterator(Vertex u);

/* Devuelve un iterador que recorre las aristas incidentes en un vértice dado.

Cada arista incidente se indica mediante el

correspondiente vértice adyacente.*/ public Iterator edgeIterator(int u);

/*Retorna el número de vertices */

public int getCardV();

/*retorna el número 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;

/*tamaño del arreglo*/ protected int heapSize;

/*Restaura la propiedad del montículo. Asume que en el momento de la llamada, la propiedad del HEAP tiene en todas partes,

Page 15: Johnson juan

15

con la posible excepción de una posición 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 máx-heap, el elemento más grande, y por un montón de minutos,

Page 16: Johnson juan

16

el elemento más pequeño.*/

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 método está dentro de una clase anidada dentro del //HEAP, debe haber un montón 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 montón.

Para ser utilizado por las subclases MinHeapPriorityQueue y MaxHeapPriorityQueue.*/

protected static class Handle implements Comparable{

/* Índice en la matriz HEAP*/ protected int index;

/*Información almacenada */

protected DynamicSetElement info;

/*Inicializacion de Handle*/

protected Handle(int index, DynamicSetElement info){ this.index = index;

this.info = info;

Page 17: Johnson juan

17

}

/*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

más corto de u a v, donde u y v son los índices de vértice, junto con el

predecesor de v en un camino más corto desde u. Puede consultar esta información llamando a los métodos de la

clase ShortestPathInfo. */ private ShortestPathInfo[][] spInfo;

/*Inicializa las variables de instancia, a excepción de la asignación de

los objetos acutal ShortestPathInfo en spInfo.*/

public Johnson(WeightedAdjacencyListGraph theGraph) { g = theGraph;

noNegWeightCycle = true;

int n = g.getCardV();

spInfo = new ShortestPathInfo[n][n]; }

Page 18: Johnson juan

18

/*se verifica si hay ciclos negativos*/

public boolean hasNoNegativeWeightCycle(){ return noNegWeightCycle;

}

/*Devuelve una referencia al objeto ShortestPathInfo para un determinado

par de vértices.*/ 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 más 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 vértice

adicional y bordes 0-peso desde el vértice adicional a todos los otros vértices. El vértice extra "s" es V0, pero aquí vamos a

hacer que el índice disponible. Los objetos vértice en G será

compartida con Gprime. Por lo que s se encuentra en el índice disponible siguiente, todos los vértices 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"

/ y los conecta a todos con peso cero System.out.println(gPrime);/

Page 19: Johnson juan

19

//Ejecutar el algoritmo de Bellman-Ford en Gprime de la fuente.

BellmanFord bf = new BellmanFord(gPrime); bf.computeShortestPaths(s);

if (bf.hasNoNegativeWeightCycle()) { /*El gráfico no contiene un ciclo negativo de peso, por lo que

puede proceder. Calcular los valores de h para todos los vértices

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 vértice de G

//en el gráfico 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();

Page 20: Johnson juan

20

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);

Page 21: Johnson juan

21

//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);

tomado Grafo del Libro de Cormen System.out.println("PRIMER GRAFO:");// /mostramos el grafo System.out.println(graph);/

//comienza el algoritmo System.out.println("\n**** Uso de Johnson 1 ***"); //iniciamos el tiempo para luego calcular la demora

long time=System.currentTimeMillis(); //creamos un grafo de jonhoson Johnson jon=new Johnson(graph);

//busca las rutas más cortas entre los vertices

jon.computeShortestPaths(); System.out.println("\n\n\t ** FIN JOHNSON 1**\n");

/calculamos el tiempo final tfinal=System.currentTimeMillis()-time;/ 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);

Page 22: Johnson juan

22

graph2.addEdge(a4,a5,4);

//muestra el grafo

System.out.println(graph2); //inicia el cálculo de johnson

System.out.println("**** Uso de Johnson 2***\n"); inicializa el tiempo time=System.currentTimeMillis();//

/se inicializa el grafo Johnson jon2=new Johnson(graph2);/

se calcula los caminos más cortos jon2.computeShortestPaths();// 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

/LuckyPuck Cormen System.out.println("\n\n\tTERCERA PRUEBA \n");/

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

Page 23: Johnson juan

23

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);

Page 24: Johnson juan

24

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 excepción de

una posición 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)

Page 25: Johnson juan

25

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 método 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 dinámico, puesto en la cola de prioridad minima*/ public Object insert(DynamicSetElement x)

{

// Si la matriz aún 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 //tamaño 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;

Page 26: Johnson juan

26

heapSize++;

//Burbuja hasta la pila. bubbleUp(heapSize-1);

//devuelve el handle

return handle;

}

/*Devuelve el elemento más pequeño 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 más pequeño en la cola de prioridad min.

Con el fin de la "manija" del elemento volvió a ser elegible para la recolección de basura, el usuario de la MinPriorityQueue debe incluir en

los datos de un satélite 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 más pequeño. DynamicSetElement min = ((Handle) array[0]).info;

//Mueva el último elemento de la pila a la raíz, y claro //la referencia en su posición 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; // all done

}

/* 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();

Page 27: Johnson juan

27

// seleccionar nueva clave handle.info.setKey(newKey);

// restaurar la propiedad min-heap bubbleUp(handle.index);

}

/*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 dinámico, puesto en la cola de prioridad min.*/

public Object insert(DynamicSetElement x);

/*Devuelve el elemento más pequeño en la cola "min-priority" sin la eliminación del elemento.*/

public DynamicSetElement minimum();

public DynamicSetElement extractMin();

/*Quita y devuelve el elemento más pequeño 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 vértice.*/

private Vertex pi;

Page 28: Johnson juan

28

/* Inicializa el cálculo de ruta más corta hasta el infinito

y el predecesor de nulo. */

public ShortestPathInfo(){ d = Double.POSITIVE_INFINITY;

pi = null; }

/*Establece la estimación de la ruta más corta.*/ public void setEstimate(double newEstimate) {

d = newEstimate; }

/*Devuelve el cálculo de ruta más 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;

} }

Page 29: Johnson juan

29

Clase SingleSourceShortestPaths:

package algoritmojohnson;

abstract public class SingleSourceShortestPaths{

/*El gráfico que se está calculando una sola ruta de los caminos más cortos. */

protected WeightedAdjacencyListGraph g;

//verifica si el grafo es dirigido

protected boolean noNegWeightCycle;

/* El resultado de ejecutar el algoritmo para la ruta más corta. Cada objeto de esta matriz corresponde a un vértice de la gráfica, y puede

consultar sus respuestas llamando a los métodos de la

clase ShortestPathInfo.*/ private ShortestPathInfo[] spInfo;

/*Establece las variables de instancia, incluida la asignación de la matriz

spInfo pero no la asignación de los objetos ShortestPathInfo referencia

a la matriz.*/ protected SingleSourceShortestPaths(WeightedAdjacencyListGraph theGraph) {

g = theGraph; noNegWeightCycle = true; //no han encontrado todavía una

spInfo = new ShortestPathInfo[g.getCardV()]; }

/*Calcula una sola fuente de rutas más cortas desde un origen determinado vértice, el llenado de los pesos y los predecesores de la matriz spInfo. */

abstract public void computeShortestPaths(Vertex s);

/*inicializa la ruta más 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 más corta*/

Page 30: Johnson juan

30

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 vértice aún no cuenta con un índice, es decir,

el índice se desconoce. */

public static final int UNKNOWN_INDEX = -1;

/* Índice de este vértice de su gráfica, de 0 a cardV-1. */ private int index;

/*Nombre del vertice */ private String name;

/*Crea un vértice cuyo índice se desconoce.*/

public Vertex(String name) { index = UNKNOWN_INDEX;

this.name = name;

}

/*Crea un vértice cuyo índice y nombre se conoce.*/ public Vertex(int index, String name){

this.index = index;

this.name = name; }

/*modifica el indice */

Page 31: Johnson juan

31

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();

}

/**

Page 32: Johnson juan

32

Agrega un margen ponderado de este gráfico. 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;

}

Page 33: Johnson juan

33

public void setWeight(double wgt){

weight = wgt;

} public double getWeight(){

return weight; }

}

/**

Devuelve un iterador que itera a través de las aristas incidentes ponderada en un vértice dado. Cada arista incidente se indica

mediante el correspondiente vértice adyacente. "u" es el vértice 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 vértice dado. Cada arista incidente se indica mediante el correspondiente vértice 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 iteración a través de las aristas incidentes ponderada en un vértice dado.*/

public EdgeIterator(int v){ super(v);

}

/*Devuelve el peso de la orilla devuelto por la llamada más reciente a

la siguiente*/ public double getWeight(){

return ((WeightedEdge) current).getWeight(); }

public void setWeight(double weight){ ((WeightedEdge) current).setWeight(weight);

} }

Page 34: Johnson juan

34

/*Crea y devuelve una WeightedAdjacencyListGraph vacío, sin bordes, dado el

número de vértices 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 más

reciente a la siguiente.*/

public double getWeight();

public void setWeight(double weight); }

Page 35: Johnson juan

35

PRUEBAS DEL ALGORITMO

Por motivos de espacio, solo realizaremos una prueba para mostrar cómo trabaja nuestro algoritmo, ya que el resultado entregado es un poco extenso, pero el gráfico será con las 5 pruebas que se piden, a continuación los grafos que utilizamos en el programa y la solución de este, además de las 5 pruebas realizadas donde analizaremos el tiempo.

1.- 2.-

4.- 5.-

Page 36: Johnson juan

36

Ejecución 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

Page 37: Johnson juan

37

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 Ejecución Dijkstra: Desde: a (index = 0) Recorrido más 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 más 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 más corto: e->d->c->b->a Hacia: a (index = 0)d = 8.0, pi = d

Page 38: Johnson juan

38

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 ejecución 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

Page 39: Johnson juan

39

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 Ejecución Dijkstra: Desde: (1) (index = 0) Recorrido más 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 más 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 más 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 más corto: (4)->(5)->(3)->(2)->(1) Hacia: (1) (index = 0)d = 8.0, pi = (2)

Page 40: Johnson juan

40

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 más 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 ejecución 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

Page 41: Johnson juan

41

(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 más 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)

Page 42: Johnson juan

42

Hacia: (4) (index = 4)d = 27.0, pi = (2) Hacia: (5) (index = 5)d = 31.0, pi = (4) Desde: (1) (index = 1) Recorrido más 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 más 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 más 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 más 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 más 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 ejecución grafo 3: 33 miliseg CUARTA PRUEBA (0) (index = 0):

Page 43: Johnson juan

43

(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

Page 44: Johnson juan

44

(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 Ejecución Dijkstra: Desde: (W) (index = 0) Recorrido más 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 más 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 más 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 más 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 ejecución 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

Page 45: Johnson juan

45

(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)

Page 46: Johnson juan

46

(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 Ejecución Dijkstra: Desde: (A) (index = 0) Recorrido más 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 más 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 más corto: (C)->(D)->(E)->(B)->(A)->s->(H)->(F)

Page 47: Johnson juan

47

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 más 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 más 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 más 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 más 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 más corto: (H)->(G)->(F)->(A)->(E)->(B)->(C)->(D)

Page 48: Johnson juan

48

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 ejecución 5: 26 miliseg

Resultados de las ejecuciones:

miliseg Grafo 1 Grafo 2 Grafo 3 Grafo 4 Grafo 5

t1 73 28 33 21 26

t2 76 14 33 26 49

t3 74 21 25 34 32

t4 67 30 22 18 69

t5 104 34 43 13 51

0

15

30

45

60

75

90

105

120

t1 t2 t3 t4 t5

Grafo 1 Grafo 2 Grafo 3 Grafo 4 Grafo 5

Page 49: Johnson juan

49

Análisis del Algoritmo:

𝑷𝒂𝒓𝒂 𝒈𝒓𝒂𝒇𝒐𝒔 𝒔𝒆 𝒖𝒔𝒂 𝒍𝒂 𝒎𝒂𝒚𝒐𝒓𝒊𝒕𝒂𝒓𝒊𝒂𝒎𝒆𝒏𝒕𝒆 𝒆𝒔𝒕𝒂 𝒔𝒊𝒎𝒃𝒐𝒍𝒐𝒈í𝒂: 𝑮𝒓𝒂𝒇𝒐 = 𝑮, 𝑽𝒆𝒓𝒕𝒊𝒄𝒆𝒔 = 𝑽, 𝑩𝒐𝒓𝒅𝒆𝒔 = 𝑬 (𝑬𝒅𝒈𝒆)

Se busca encontrar el camino más corto entre todos los

pares en ( ) . Para grafos dispersos, es asintóticamente más rápido que sea repetido la cuadratura del matrices o el algoritmo de Floyd-Warshall. El algoritmo o bien devuelve una matriz de la ruta más corta de pesos para todos los pares de vértices 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 técnica de ponderación, que

funciona usando todos los pesos de las aristas en una grafo = ( , ) son positivos, podemos encontrar más corto rutas entre todos los pares de vértices mediante la ejecución de algoritmo de Dijkstra, una vez de cada vértice, con el Heap-Fibonacci y la cola de min-prioridad, el tiempo de ejecución 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

método. El nuevo conjunto de pesos de las aristas y debe satisfacer dos propiedades importantes:

1. Para todos los pares de vértices , , un camino es un camino más corto usado desde para utilizando la función de peso si y sólo si es también un camino más corto desde hasta utilizando la función 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 vértice nuevo para poder redirigirse al resto de los vértices 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 vértice 1, ( , ) ( , ), para obtener los caminos más cortos. Si calculamos tendríamos:

( ) = ( ) ( , ) = = ( ) = ( ) ( , ) = ( ) =

Aplicamos Dijkstra al vértice 2, al vértice 3, al vértice 4 y al 5 y termina la aplicación del algoritmo de Johnson.

Page 50: Johnson juan

50

Conclusión 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 búsqueda de ejemplos vimos los muchos usos que se les dan. Eso en términos globales, pero si nos enfocamos más 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 enseñan que la computación no es exacta como las matemáticas, si bien se pueden estimar los tiempos mediante fórmulas y cálculos, hay varias cosas que pueden influir. Por ejemplo el procesador del computador, ya que los tiempos varían de un computado a otro.

Por otra parte descubrimos un nuevo algoritmo, que no habíamos 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 más 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.