Grafos y caminos Dra. Laura Cruz Reyes Instituto Tecnológico de Ciudad Madero México Definiciones Laura Cruz Reyes Grafos y Caminos El Grafo como una relación • Hablando intuitivamente, un grafo es un conjunto de nodos unidos por un conjunto de líneas o flechas. • Existen muchos problemas de la vida real que pueden ser modelados matemáticamente con grafos. Los nodos son entes de procesamiento o estructuras que contienen algún tipo de información y las líneas o flechas son conexiones o relaciones entre estos entes. Laura Cruz Reyes Grafos y Caminos El Grafo como una relación Problema: ¿Cómo detectar al líder de un grupo? Laura Cruz Reyes Grafos y Caminos El Grafo como una relación • Relación de preferencia entre colegas: Laura Clarita Chelita Arquim. Laura Cruz Reyes Grafos y Caminos El Grafo como una relación • Relación de preferencia entre colegas, indicando el grado de preferencia (1‐10): 9 Laura Clarita 8 8 10 Arquim. Laura Cruz Reyes Grafos y Caminos Chelita El Grafo como una relación • Problema: Dadas cinco ciudades (A..D) que están separadas por un río y conectadas por puentes ¿Será posible ir a todas las ciudades, pasando por los puentes una sola vez? puente Laura Cruz Reyes Grafos y Caminos El Grafo como una relación • Relación entre ciudades (A..D) que están separadas por un río y conectadas por puentes: puente Laura Cruz Reyes Grafos y Caminos El Grafo como una relación • Problema: ¿Será posible ir a todas las ciudades, pasando por los puentes una sola vez, con el menor costo posible? puente Laura Cruz Reyes Grafos y Caminos El Grafo como una relación • Relación entre ciudades (A..D) que están separadas por un río y conectadas por puentes, indicando costo de acceso: 15 10 30 35 10 30 puente Laura Cruz Reyes 8 Grafos y Caminos Conceptos básicos • Un grafo G = (V, E) es una estructura que consiste en un conjunto finito V de elementos llamados vértices o nodos (en inglés vertex) y un conjunto E de pares llamados arcos o aristas (en ingés edges) • En un grafo dirigido o digrafo, cada arco es un par ordenado. • En un grafo no‐dirigido, los arcos están formados por pares de nodos no ordenados. • A un grafo también se le denomina red cuando los nodos o aristas tienen valores numéricos. Laura Cruz Reyes Grafos y Caminos Conceptos básicos Grafo Dirigido 1 2 3 G = (V, E) V = {1, 2, 3, 4, 5, 6} E = {(1,2), (2,2), (2,4), (2,5), 4 5 6 (4,1), (4,5), (5,4), (6,3)} (2, 2) es un ciclo Grafo No Dirigido 1 2 3 5 6 G = (V, E) V = {1, 2, 3, 4, 5, 6} E = {{1,2}, {1,5}, {2,5}, {3,6}} Laura Cruz Reyes Grafos y Caminos 4 Conceptos básicos Grafo Dirigido 1 4 Laura Cruz Reyes Subgrafo Dirigido 2 3 5 6 1 Grafos y Caminos 2 3 6 Conceptos básicos Relación de adyacencia A: • Dos vértices son adyacentes si existe una arista que los conecte. • Sea u y v elementos de V, entonces uAw (que se lee “u es adyacente a w” si y solo si vw está en E. En grafos no dirigidos, la relación A es simétrica (es decir, wAv si y sólo si vAw). Laura Cruz Reyes Grafos y Caminos Conceptos básicos Camino en un grafo • Un camino o trayectoria es una sucesión de vértices con la propiedad de que cada vértice es adyacente al siguiente. • Un camino o trayectoria de v a w es una sucesión de vértices v0, v1, v2, …, vk‐1, vk, tal que v=v0 y vk=w • La longitud del camino sin peso, es el número de aristas en el camino y es igual a k. • La longitud del camino con pesos, es la suma de los costos de las aristas en el camino. • Un vértice es alcanzable desde v si existe un camino de v a w. • Un camino simple es un camino tal que v0…vk son todos distintos. • El camino mínimo entre dos vértices u y w es el camino de menor longitud. Laura Cruz Reyes Grafos y Caminos Conceptos básicos Ciclo en un grafo • Ciclo, circuito o lazo, es un camino no vacío que inicia y termina en el mismo vértice. • En un grafo no dirigido, si una arista aparece más de una vez, aparece con la misma orientación. Laura Cruz Reyes Grafos y Caminos Conceptos básicos Ciclo en un grafo • Un ciclo hamiltoniano es un circuito (sucesión de aristas adyacentes tal que el último vértice visitado es adyacente al primero) que visita todos los vértices del grafo una sola vez. Ciclos Hamiltonianos Laura Cruz Reyes No Hamiltoniano Grafos y Caminos Conceptos básicos Ciclo en un grafo • En grafos dirigidos con pesos en sus aristas , se sabe que el ciclo hamiltoniano de menor costo, es a su vez también la solución al problema clásico del agente viajero (TSP, Traveling Salesman Problem). Laura Cruz Reyes Grafos y Caminos Conceptos básicos Ciclo en un grafo • Un ciclo euleriano es una circuito que recorre todas las aristas de un grafo conexo, pasando una y sólo una vez por cada arco. Para que exista un ciclo euleriano en un grafo, todos los vértices tienen que tener grado par. Ciclo Euleriano Laura Cruz Reyes No Euleriano Grafos y Caminos Conceptos básicos Grafos sin ciclos • Un grafo es acíclico si no tiene ciclos. • Es común usar la abreviatura DAG para referirse a un grafo acíclico dirigido (por sus siglas en inglés). 1 2 DAG 3 Laura Cruz Reyes Grafos y Caminos 4 Conceptos básicos Grafos sin ciclos • Un grafo acíclico no dirigido se denomina bosque no dirigido. Si el grafo también esta completamente conectado, es un árbol no dirigido. bosque no dirigido Laura Cruz Reyes Árbol no dirigido Grafos y Caminos Conceptos básicos Grafo denso vs. disperso • Cuando la mayoría de los vértices están presentes, tenemos que |E|=Θ (|V|2). A este tipo de grafo se le denomina denso porque tiene un número elevado de aristas. • Cuando la mayoría de los vértices no están presentes el grafo es disperso, por tanto |E|=Θ (|V|) Laura Cruz Reyes Grafos y Caminos Representación de grafos Laura Cruz Reyes Grafos y Caminos Representación formal mediante conjuntos V0 4 Grafo 2 V1 1 3 V2 Vértices V3 V4 2 2 5 G=(V,E) 10 4 8 V5 V={V0,V1,V2,V3,V4,V5,V6} 6 V6 Aristas 1 E= (V0,V1,2),(V0,V3,1),(V1,V3,3),(V1,V4,10) (V3,V4,2),(V3,V6,4),(V3,V5,8),(V3,V2,2) (V2,V0,4),(V2,V5,5),(V4,V6,6),(V6,V5,1) (Origen, destino, Costo) Laura Cruz Reyes Grafos y Caminos Representación computacional mediante matriz de adyacencia (para grafos densos) 0 1 2 3 4 5 6 ∞ 2 ∞ 1 ∞ ∞ ∞ 1 ∞ ∞ ∞ 3 10 ∞ ∞ 4 ∞ ∞ ∞ 5 ∞ ∞ ∞ ∞ 2 ∞ 2 8 4 4 ∞ ∞ ∞ ∞ ∞ ∞ 6 5 ∞ ∞ ∞ ∞ ∞ ∞ ∞ 6 ∞ ∞ ∞ ∞ ∞ 1 ∞ 0 2 3 4 2 V0 1 V2 1 V1 3 2 V3 V4 2 4 8 5 V5 6 V6 1 Las aristas inexistentes se pueden representar mediante un INFINITO lógico Grafos y Caminos Laura Cruz Reyes 10 Representación computacional mediante matriz de adyacencia • Complejidad temporal – Inserción: Θ(1) – Borrado: Θ(1) – Consultas: Θ(1) – Inicialización: Θ(|V|2) • Complejidad espacial – Θ(|V|2) Laura Cruz Reyes Grafos y Caminos lista i Representación computacional mediante lista de adyacencia 0 1(2) 3(1) 1 4(10) 3(3) 2 0(4) 5(5) 3 4(2) 6(4) 4 6(6) 5(8) 5 6 2(2) 4 1 5(1) Los nodos en la lista i representan los vértices adyacentes a i y el costo de la arista correspondiente Laura Cruz Reyes 2 V0 V2 1 V1 10 3 2 V3 V4 2 4 8 5 V5 V6 1 Grafos y Caminos 6 Representación computacional mediante lista de adyacencia • Complejidad temporal – Inserción: Θ(1) – Borrado: Θ(|V|2)* – Consultas: Θ(|V|2)* • Complejidad espacial – Θ(|E|)+ Θ(|V|) *En el peor caso, la lista i podría contener a todos los vértices del grafo Laura Cruz Reyes Grafos y Caminos Problema: Distancia mínima entre vértices Algoritmos para determinar la distancia mínima entre vértices Los siguientes algoritmos determinan los caminos más cortos desde un punto de origen hasta todos los vértices . • • • • Camino mínimo sin peso Camino mínimo con pesos positivos Camino mínimo con pesos negativos Ordenación topológica Laura Cruz Reyes Grafos y Caminos Estructura de datos para el problema de distancia mínima entre vértices Laura Cruz Reyes Grafos y Caminos En la mayoría del as aplicaciones de la vida real los vértices tienen nombres, en vez de estar denotados por números consecutivos. La forma de transformarlos es proporcionar un diccionario en el que le asigna a cada nombre de vértice un numero interno en el rango de 0 a |V|‐1 . Los números internos se van asignando según se va leyendo el grafo . Entrada Tabla es la tabla del grafo D C 10 A B 12 D B 23 A D 87 E D 43 B E 11 C A 19 A 19 12 87 C 0 10 1 76 0 C 2(19) 2 0 ‐1 A 0(87),3(12) 3 12 2 B 4(11) 4 23 3 E 0(43) nombre posicion B 23 D Laura Cruz Reyes dist prev nombre adj 66 4 D 3(23),1(10) 11 D(0) C(1) A(2) B(3) E(4) E 43 Grafos y Caminos MapaVertices es el diccionario Tabla es la tabla del grafo dist: longitud del camino mas corto desde el vértice de comienzo hasta este vértice .Este valor es calculado por el algoritmo de búsqueda del camino mínimo. prev: el vértice anterior en el camino mas corto a este vértice. Se utiliza para construir cada camino mínimo. nombre: el nombre correspondiente a este vértice. Se fija cuando el vértice se coloca en el diccionario y no lo cambia nunca .Ninguno de los algoritmos de búsqueda del camino mínimo lo utilizara .Solo se utiliza al imprimir el camino final . adj: una lista de vértices adyacentes .se crea al leer el grafo .ninguno de los algoritmos de búsqueda del camino mínimo modificara dichas listas Laura Cruz Reyes Grafos y Caminos MapaVertices es el diccionario nombre: El nombre real del vértice posicion: El número asignado en forma consecutiva Laura Cruz Reyes Grafos y Caminos Problema del camino mínimo sin pesos Laura Cruz Reyes Grafos y Caminos PROBLEMA DEL CAMINO SIN PESOS MÍNIMO CON UN ÚNICO ORIGEN Encontrar el camino más corto (medido por el número de aristas) desde el vértice origen O a cualquier otro vértice. Laura Cruz Reyes Grafos y Caminos V0 V2 V1 V3 V5 V6 Nodo origen= O = V2 Laura Cruz Reyes V4 Grafos y Caminos Camino más corto de O a v2 V0 V1 0 V2 V3 V5 Laura Cruz Reyes V4 V6 Grafos y Caminos Camino mínimo=1 1 V0 V1 0 V2 V3 V5 V6 1 Laura Cruz Reyes V4 Grafos y Caminos Camino mínimo=2 1 2 V0 V1 0 V2 V3 2 V5 V6 1 Laura Cruz Reyes V4 Grafos y Caminos Camino mínimo=3 1 2 V0 V1 0 3 V2 V3 V4 2 3 V5 V6 1 Laura Cruz Reyes Grafos y Caminos Fundamento • Sea Di el camino mas corto desde O hasta i, entonces las condiciones iniciales son: D0=0 Di=∞ para i≠0 • Sea v el vértice actual con un camino Dv • Sea w el vértice adyacente a V con un camino Dw • Si el vértice w no ha sido visitado, entonces aporta un paso a la ruta más corta hacia él. Si Dw== ∞ : Dw= Dv + 1 Laura Cruz Reyes Grafos y Caminos Fundamento Dv Vértice actual Dw=Dv+1 V W Vertice adyacente Si Dw==∞ 0 O Laura Cruz Reyes Grafos y Caminos Fundamento • Dado que la búsqueda es en amplitud, si el vértice w ya ha sido visitado, entonces la nueva ruta hacia él no será la más corta. Si Dw ≠ ∞ : Dw= Dw Laura Cruz Reyes Grafos y Caminos Estructura de datos • La pila es una estructura apropiada para la busqueda en profundidad. • La cola es una estructura apropiada para la búsqueda en amplitud. • Usando una búsqueda en amplitud, los niveles de la búsqueda corresponden a la distancia mínima del origen a cualquier vértice. Laura Cruz Reyes Grafos y Caminos Algoritmo caminoSinPeso ( nodoInicio, tabla) { tabla es un grafo de adyacencia v, w son nodos; q es una cola de nodos; tabla.dist = ∞; tabla[ nodoInicio ].dist = 0; q.inserta( nodoInicio ); while( !q.esVacia( ) ) { v = q.borra( ); p = tabla[ v ].adj; for (p.inicio( ); p.existe( ); p.siguiente( ) ) { w = (p.recupera( )).dest; if( tabla[ w ].dist == ∞ ) { tabla[ w ].dist = table[ v ].dist + 1; tabla[ w ].prev = v; q.inserta(w ); } } } } Laura Cruz Reyes Grafos y Caminos Vértice actual Vértice adyacente V0 Vértice procesado V1 0 V2 V3 V5 V4 V6 Lista vértices adyacentes a Vértice actual Cola de vértices en los que se ha calculado su costo V2 V2 Laura Cruz Reyes Grafos y Caminos V0 V5 V0 1 V1 0 V2 V3 V5 V4 V6 Lista vértices adyacentes a Vértice actual Cola de vértices en los que se ha calculado su costo V2 V2 V0 Laura Cruz Reyes Grafos y Caminos V0 V5 V0 1 V1 0 V2 V3 V5 V4 V6 1 Lista vértices adyacentes a Vértice actual Cola de vértices en los que se ha calculado su costo V2 V0 Laura Cruz Reyes V2 V5 Grafos y Caminos V0 V5 V0 1 V1 0 V2 V3 V5 V4 V6 1 Lista vértices adyacentes a Vértice actual Cola de vértices en los que se ha calculado su costo V2 V0 Laura Cruz Reyes V2 V5 Grafos y Caminos V0 V5 V0 1 V1 0 V2 V3 V5 V4 V6 1 Lista vértices adyacentes a Vértice actual Cola de vértices en los que se ha calculado su costo V2 V0 Laura Cruz Reyes V0 V5 Grafos y Caminos V1 V3 V0 1 V1 2 0 V2 V3 V5 V4 V6 1 Lista vértices adyacentes a Vértice actual Cola de vértices en los que se ha calculado su costo V2 V0 Laura Cruz Reyes V5 V0 V1 Grafos y Caminos V1 V3 V0 1 V1 2 0 V2 V3 2 V5 V4 V6 1 Lista vértices adyacentes a Vértice actual Cola de vértices en los que se ha calculado su costo V2 V0 Laura Cruz Reyes V5 V1 V0 V3 Grafos y Caminos V1 V3 V0 1 V1 2 0 V2 V3 2 V5 V4 V6 1 Lista vértices adyacentes a Vértice actual Cola de vértices en los que se ha calculado su costo V2 V0 Laura Cruz Reyes V5 V1 V0 V3 Grafos y Caminos V1 V3 V0 1 V1 2 0 V2 V3 2 V5 V4 V6 1 Lista vértices adyacentes a Vértice actual Cola de vértices en los que se ha calculado su costo V2 V0 Laura Cruz Reyes V5 V1 V5 V3 Grafos y Caminos No adyacentes V0 1 V1 2 0 V2 V3 2 V5 V4 V6 1 Lista vértices adyacentes a Vértice actual Cola de vértices en los que se ha calculado su costo V2 V0 Laura Cruz Reyes V5 V1 V1 V3 Grafos y Caminos V3 V4 V0 1 V1 2 0 V2 V3 2 V5 V4 V6 1 Lista vértices adyacentes a Vértice actual Cola de vértices en los que se ha calculado su costo V2 V0 Laura Cruz Reyes V5 V1 V1 V3 Grafos y Caminos V3 V4 V0 1 V1 2 0 V2 V3 2 V5 V4 3 V6 1 Lista vértices adyacentes a Vértice actual Cola de vértices en los que se ha calculado su costo V2 V0 Laura Cruz Reyes V5 V1 V3 V4 Grafos y Caminos V1 V3 V4 V0 1 V1 2 0 V2 V3 2 V5 V4 3 V6 1 Lista vértices adyacentes a Vértice actual Cola de vértices en los que se ha calculado su costo V2 V0 Laura Cruz Reyes V5 V1 V3 V4 Grafos y Caminos V1 V3 V4 V0 1 V1 2 0 V2 V3 2 V5 V4 3 V6 1 Lista vértices adyacentes a Vértice actual Cola de vértices en los que se ha calculado su costo V2 V0 Laura Cruz Reyes V5 V1 V3 V4 Grafos y Caminos V3 V4 V5 V6 V0 1 V1 2 0 V2 V3 2 V5 V4 3 V6 1 Lista vértices adyacentes a Vértice actual Cola de vértices en los que se ha calculado su costo V2 V0 Laura Cruz Reyes V5 V1 V3 V4 Grafos y Caminos V3 V4 V5 V6 V0 1 V1 2 0 V2 V3 V5 2 V4 V6 1 3 Lista vértices adyacentes a Vértice actual Cola de vértices en los que se ha calculado su costo V2 V0 Laura Cruz Reyes V5 V1 3 V3 V4 Grafos y Caminos V3 V4 V5 V6 V0 1 V1 2 0 V2 V3 2 V5 V4 V6 1 3 Lista vértices adyacentes a Vértice actual Cola de vértices en los que se ha calculado su costo V2 V0 Laura Cruz Reyes V5 V1 3 V3 V4 V6 Grafos y Caminos V3 V4 V5 V6 V0 1 V1 2 0 V2 V3 2 V5 V4 V6 1 3 Lista vértices adyacentes a Vértice actual Cola de vértices en los que se ha calculado su costo V2 V0 Laura Cruz Reyes V5 V1 3 V3 V4 V6 Grafos y Caminos V3 V4 V5 V6 V0 1 V1 2 0 V2 V3 2 V5 V6 1 V0 Laura Cruz Reyes V5 V1 3 Lista vértices adyacentes a Vértice actual Cola de vértices en los que se ha calculado su costo V2 V4 3 V3 V4 V6 Grafos y Caminos V4 V6 V0 1 V1 2 0 V2 V3 2 V5 V6 1 V0 Laura Cruz Reyes V5 V1 3 Lista vértices adyacentes a Vértice actual Cola de vértices en los que se ha calculado su costo V2 V4 3 V3 V4 V6 Grafos y Caminos V4 V6 V0 1 V1 2 0 V2 V3 2 V5 V6 1 V0 Laura Cruz Reyes V5 V1 3 Lista vértices adyacentes a Vértice actual Cola de vértices en los que se ha calculado su costo V2 V4 3 V3 V4 V6 Grafos y Caminos V4 V6 V0 1 V1 2 0 V2 V3 2 V5 V6 1 V0 Laura Cruz Reyes V5 V1 3 Lista vértices adyacentes a Vértice actual Cola de vértices en los que se ha calculado su costo V2 V4 3 V3 V4 V6 Grafos y Caminos V6 V5 V0 1 V1 2 0 V2 V3 2 V5 V6 1 V0 Laura Cruz Reyes V5 V1 3 Lista vértices adyacentes a Vértice actual Cola de vértices en los que se ha calculado su costo V2 V4 3 V3 V4 V6 Grafos y Caminos V6 V5 V0 1 V1 2 0 V2 V3 2 V5 V6 1 V0 Laura Cruz Reyes V5 V1 3 Lista vértices adyacentes a Vértice actual Cola de vértices en los que se ha calculado su costo V2 V4 3 V3 V4 V6 Grafos y Caminos V6 V5 V0 1 V1 2 0 V2 V3 2 V5 V6 1 Cola de vértices en los que se ha calculado su costo V2 V0 Laura Cruz Reyes V5 V1 V3 V4 V4 V6 Grafos y Caminos 3 3 Implementación de Algoritmos de Solución del Problema: Distancia mínima entre vértices En la mayoría del as aplicaciones de la vida real los vértices tienen nombres, en vez de estar denotados por números consecutivos. La forma de transformarlos es proporcionar un diccionario en el que le asigna a cada nombre de vértice un numero interno en el rango de 0 a |V|‐1 . Los números internos se van asignando según se va leyendo el grafo . Entrada Table es la tabla del grafo D C 10 A B 12 D B 23 A D 87 E D 43 B E 11 C A 19 A 19 12 87 C 0 10 adj 3(23),1(10) 1 76 0 C 2(19) 2 0 ‐1 A 0(87),3(12) 3 12 2 B 4(11) 4 23 3 E 0(43) name rank B 23 D Laura Cruz Reyes dist prev name 66 4 D 11 D(0) C(1) A(2) B(3) E(4) E 43 Grafos y Caminos VertexMap es el diccionario Table es la tabla del grafo dist: longitud del camino mas corto desde el vértice de comienzo hasta este vértice .Este valor es calculado por el algoritmo de búsqueda del camino mínimo. prev: el vértice anterior en el camino mas corto a este vértice. Se utiliza para construir cada camino mínimo. name: el nombre correspondiente a este vértice. Se fija cuando el vértice se coloca en el diccionario y no lo cambia nunca .Ninguno de los algoritmos de búsqueda del camino mínimo lo utilizara .Solo se utiliza al imprimir el camino final . adj: una lista de vértices adyacentes .se crea al leer el grafo .ninguno de los algoritmos de búsqueda del camino mínimo modificara dichas listas Laura Cruz Reyes Grafos y Caminos VertexMap es el diccionario name: El nombre real del vértice rank: El número asignado en forma consecutiva Laura Cruz Reyes Grafos y Caminos Elementos del Grafo Aristas y Vértices Clase ARISTA class Edge { // First vertex in edge is implicit public int dest; // Second vertex in edge public int cost; // Edge cost public Edge( int d, int c ) { dest = d; cost = c; } } Laura Cruz Reyes Grafos y Caminos Clase VERTICE class Vertex { String name; // The real name List adj; // The adjacency list int dist; int prev; int scratch; // Cost (after running algorithm) // Previous vertex on shortest path // Extra variable for use in algorithm Vertex( String nm ) { name = nm; // Share name in hash table adj = new LinkedList( ); // Make a new list } } Laura Cruz Reyes Grafos y Caminos Elemento del Diccionario Elemento de la tabla Hash Objeto VertexMap QuadraticProbingTable <extends> ProbingHashTable <implements> HashTable private static final int DEFAULT_TABLE_SIZE = 11; protected HashEntry [ ] array; // The array of elements Hashable element; // the element HashItem <implements > Hashable public String name; /* The real name */ public int rank; /* The assigned number */ boolean isActive; // false is deleted private int currentSize; // The number of occupied cells Laura Cruz Reyes Grafos y Caminos Diagrama de Clases Laura Cruz Reyes Grafos y Caminos Declaración del tipo de interfaz private HashTable vertexMap; // Gets internal number ....... Definición del tipo de implementación vertexMap = new QuadraticProbingTable( ); Laura Cruz Reyes Grafos y Caminos public interface HashTable { // Insert into the hash table void insert( Hashable x ); // Remove x from the hash table. void remove( Hashable x ) throws ItemNotFound; // Find an item x in the hash table. Hashable find( Hashable x ) throws ItemNotFound; //Make the hash table logically empty. void makeEmpty( ); } Laura Cruz Reyes Grafos y Caminos public class QuadraticProbingTable extends ProbingHashTable { /** * Method that performs quadratic probing resolution. * @param x the item to search for. * @return the position where the search terminates. */ protected final int findPos( Hashable x ) { int collisionNum = 0; int currentPos = x.hash( array.length ); while( array[ currentPos ] != null && !array[ currentPos ].element.equals( x ) ) { currentPos += 2 * ++collisionNum - 1; // Compute ith probe if( currentPos >= array.length ) // Implement the mod currentPos -= array.length; } return currentPos; } } Laura Cruz Reyes Grafos y Caminos public abstract class ProbingHashTable implements HashTable { private static final int DEFAULT_TABLE_SIZE = 11; protected HashEntry [ ] array; // The array of elements private int currentSize; // The number of occupied cells // Find the position in the hash table for a new or existent element protected abstract int findPos( Hashable x ); ……. } Laura Cruz Reyes Grafos y Caminos class HashEntry { Hashable element; // the element boolean isActive; // false is deleted public HashEntry( Hashable e ) { this( e, true ); } public HashEntry( Hashable e, boolean i ) { element = e; isActive = i; } } Laura Cruz Reyes Grafos y Caminos public abstract class ProbingHashTable implements HashTable { …….. public ProbingHashTable( ) { // Construct the hash table allocateArray( DEFAULT_TABLE_SIZE ); makeEmpty( ); } …….. } Laura Cruz Reyes Grafos y Caminos // A hash function for String objects. public final static int hash( String key, int tableSize ) { int hashVal = 0; for( int i = 0; i < key.length( ); i++ ) hashVal = 37 * hashVal + key.charAt( i ); hashVal %= tableSize; if( hashVal < 0 ) hashVal += tableSize; return hashVal; } Laura Cruz Reyes Grafos y Caminos //Insert into the hash table //If the item is already present, then replace it with the new item. //if hash table is full, create a new double-sized table public final void insert( Hashable x ) // x is the item to insert { int currentPos = findPos( x ); array[ currentPos ] = new HashEntry( x, true ); if( ++currentSize < array.length / 2 ) return; …… // REHASHING CODE: table is full } Laura Cruz Reyes Grafos y Caminos // Remove x from the hash table. Otherwise, throw an exception public final void remove( Hashable x ) throws ItemNotFound { int currentPos = findPos( x ); assertFound( currentPos, "ProbingHashTable remove" ); array[ currentPos ].isActive = false; } Laura Cruz Reyes Grafos y Caminos // Find an item in the hash table. Otherwise, throw an exception public final Hashable find( Hashable x ) throws ItemNotFound { int currentPos = findPos( x ); assertFound( currentPos, "ProbingHashTable find" ); return array[ currentPos ].element; } Laura Cruz Reyes Grafos y Caminos public final void makeEmpty( ) { currentSize = 0; for( int i = 0; i < array.length; i++ ) array[ i ] = null; } Laura Cruz Reyes Grafos y Caminos class HashItem implements Hashable { public String name; /* The real name */ public int rank; /* The assigned number */ public HashItem( ) { this( null ); } public HashItem( String nm ) { name = nm; } public int hash( int tableSize ) { return ProbingHashTable.hash( name, tableSize ); } public boolean equals( Object rhs ) { return name.equals( ((HashItem) rhs).name ); } } Laura Cruz Reyes Grafos y Caminos package Supporting; /** * Protocol for Hashable objects. * @author Mark Allen Weiss */ public interface Hashable { /** * Compute a hash function for this object. * @param tableSize the hash table size. * @return (deterministically) a number between * 0 and tableSize-1, distributed equitably. */ int hash( int tableSize ); } Laura Cruz Reyes Grafos y Caminos VertexMap Array element // Hashable class // HashItem implements Hashable name // vertex name rank //consecutive vertex number isactive element name isactive rank ** específico de la aplicación ** para cualquier aplicación DEFAULT_TABLE_SIZE //Table size currentSize // The number of occupied cells Laura Cruz Reyes Grafos y Caminos Grafo Lista Adyacencia Diccionario Clase GRAFO /** * Graph class: evaluate shortest paths. */ public class Graph { private static final int INIT_TABLE_SIZE = 50; private static final int NULL_VERTEX = -1; private static final int INFINITY = 2147483647 / 3; private HashTable vertexMap; private Vertex [ ] table; private int numVertices; Laura Cruz Reyes Grafos y Caminos // Gets internal # // The table array // Current # vertices read Clase GRAFO /** * Graph class: evaluate shortest paths. */ public class Graph { public Graph( ) { numVertices = 0; //Lista de Adyacencia table = new Vertex[ INIT_TABLE_SIZE ]; //Diccionario vertexMap = new QuadraticProbingTable( ); } Laura Cruz Reyes Grafos y Caminos /** * Add the edge ( source, dest, cost ) to the graph. */ public void addEdge( String source, String dest, int cost ) { addInternalEdge( addNode( source ), addNode( dest ), cost ); } Laura Cruz Reyes Grafos y Caminos public boolean processRequest( BufferedReader in ) { String sourceName, destName; HashItem source = new HashItem( ); HashItem dest = new HashItem( ); try { System.out.println( "Enter start node:" ); if( ( sourceName = in.readLine( ) ) == null ) return false; System.out.println( "Enter destination node:" ); if( ( destName = in.readLine( ) ) == null ) return false; } catch( IOException e ) { System.out.println( "Error: " + e return false; } . . . . . Laura Cruz Reyes Grafos y Caminos ); public boolean processRequest( BufferedReader in ) { . . . . . try { source.name = sourceName; source = (HashItem) ( vertexMap.find( source ) ); dest.name = destName; dest = (HashItem) ( vertexMap.find( dest ) ); unweighted( source.rank ); printPath( dest.rank ); if( dijkstra( source.rank ) ) printPath( dest.rank ); else System.out.println( "Dijkstra fails - neg edge" ); if( dijkstraPair( source.rank ) ) printPath( dest.rank ); else System.out.println( "Dijkstra fails - neg edge" ); if( negative( source.rank ) ) printPath( dest.rank ); else System.out.println( "Negative fails - neg cycle" ); if( acyclic( source.rank ) ) printPath( dest.rank ); else System.out.println( "Acyclic fails - cycle" ); } catch( ItemNotFound e ) { System.err.println( "Vertex not in graph" ); } return true; } Laura Cruz Reyes Grafos y Caminos Aplicación Main /** * A main routine that: * 1. Prompts for a file containing edges; * 2. Forms the graph; * 3. Repeatedly prompts for two vertices and * runs shortest path algorithms. * The data file is a sequence of lines of the format * source destination cost. */ Laura Cruz Reyes Grafos y Caminos public static void main( String [ ] args ) { // Get the file System.out.println( "Enter graph file:" ); BufferedReader in = new BufferedReader( new InputStreamReader( System.in ) ); FileReader fin; String fileName= ""; try { fileName = in.readLine( ); fin = new FileReader( fileName ); } catch( Exception e ) { System.err.println( e ); return; } BufferedReader graphFile = new BufferedReader( fin ); Graph g = new Graph( ); Laura Cruz Reyes Grafos y Caminos // Read the edges and insert try { String line; while( ( line = graphFile.readLine( ) ) != null ) { StringTokenizer st = new StringTokenizer( line ); try { if( st.countTokens( ) != 3 ) throw new Exception( ); String source = st.nextToken( ); String dest = st.nextToken( ); int cost = Integer.parseInt( st.nextToken( ) ); g.addEdge( source, dest, cost ); } catch( Exception e ) { System.err.println( "Error: " + line ); } } } Laura Cruz Reyes Grafos y Caminos catch( Exception e ) { System.err.println( "Error: " + e ); } while( g.processRequest( in ) ) ; } private static final int INIT_TABLE_SIZE = 50; private static final int NULL_VERTEX = -1; private static final int INFINITY = 2147483647 / 3; private HashTable vertexMap; private Vertex [ ] table; private int numVertices; Laura Cruz Reyes Grafos y Caminos // Gets internal # // The table array // Current # vertices read /** * Double the table array; usual stuff. */ private void doubleTableArray( ) { Vertex[ ] oldArray = table; table = new Vertex[ oldArray.length * 2 ]; for( int i = 0; i < oldArray.length; i++ ) table[ i ] = oldArray[ i ]; } Laura Cruz Reyes Grafos y Caminos /** * If vertexName is an already seen vertex, return its * internal number. Otherwise add it as a new vertex, * and return its new internal number. */ private int addNode( String vertexName ) { } Laura Cruz Reyes Grafos y Caminos private int addNode( String vertexName ) { HashItem hashV = new HashItem( vertexName ); HashItem result; try { result = (HashItem) vertexMap.find( hashV ); return result.rank; } catch( ItemNotFound e ) { // Newly seen vertex hashV.rank = numVertices; hashV.name = new String( vertexName ); vertexMap.insert( hashV ); if( numVertices == table.length ) doubleTableArray( ); table[ numVertices ] = new Vertex( hashV.name ); return numVertices++; } } Laura Cruz Reyes Grafos y Caminos public static void main( String [ ] args ) { // Get the file System.out.println( "Enter graph file:" ); BufferedReader in = new BufferedReader( new InputStreamReader( System.in ) ); FileReader fin; String fileName= ""; try { fileName = in.readLine( ); fin = new FileReader( fileName ); } catch( Exception e ) { System.err.println( e ); return; } Laura Cruz Reyes Grafos y Caminos BufferedReader graphFile = new BufferedReader( fin ); Graph g = new Graph( ); // Read the edges and insert try { String line; while( ( line = graphFile.readLine( ) ) != null ) { StringTokenizer st = new StringTokenizer( line ); try { if( st.countTokens( ) != 3 ) throw new Exception( ); String source = st.nextToken( ); String dest = st.nextToken( ); int cost = Integer.parseInt( st.nextToken( ) ); g.addEdge( source, dest, cost ); } catch( Exception e ) { System.err.println( "Error: " + line ); } } } catch( Exception e ) { System.err.println( "Error: " + e ); } while( g.processRequest( in ) ) ; } Laura Cruz Reyes Grafos y Caminos public void addEdge( String source, String dest, int cost ) { addInternalEdge( addNode( source ), addNode( dest ), cost ); } Laura Cruz Reyes Grafos y Caminos private int addNode( String vertexName ) { HashItem hashV = new HashItem( vertexName ); HashItem result; try { result = (HashItem) vertexMap.find( hashV ); return result.rank; } catch( ItemNotFound e ) { // Newly seen vertex hashV.rank = numVertices; hashV.name = new String( vertexName ); vertexMap.insert( hashV ); if( numVertices == table.length ) doubleTableArray( ); table[ numVertices ] = new Vertex( hashV.name ); return numVertices++; } } Laura Cruz Reyes Grafos y Caminos private void addInternalEdge( int source, int dest, int cost ) { ListItr p = new LinkedListItr( table[ source ].adj ); try { p.insert( new Edge( dest, cost ) ); } catch( ItemNotFound e ) { } // Cannot happen } class Edge { // First vertex in edge is implicit public int dest; // Second vertex in edge public int cost; // Edge cost public Edge( int d, int c ) { dest = d; cost = c; } } Laura Cruz Reyes Grafos y Caminos BufferedReader graphFile = new BufferedReader( fin ); Graph g = new Graph( ); // Read the edges and insert try { String line; while( ( line = graphFile.readLine( ) ) != null ) { StringTokenizer st = new StringTokenizer( line ); try { if( st.countTokens( ) != 3 ) throw new Exception( ); String source = st.nextToken( ); String dest = st.nextToken( ); int cost = Integer.parseInt( st.nextToken( ) ); g.addEdge( source, dest, cost ); } catch( Exception e ) { System.err.println( "Error: " + line ); } } } catch( Exception e ) { System.err.println( "Error: " + e ); } while( g.processRequest( in ) ) ; } Laura Cruz Reyes Grafos y Caminos public boolean processRequest( BufferedReader in ) { String sourceName, destName; HashItem source = new HashItem( ); HashItem dest = new HashItem( ); try { System.out.println( "Enter start node:" ); if( ( sourceName = in.readLine( ) ) == null ) return false; System.out.println( "Enter destination node:" ); if( ( destName = in.readLine( ) ) == null ) return false; } catch( IOException e ) { System.out.println( "Error: " + e ); return false; } Laura Cruz Reyes Grafos y Caminos try { source.name = sourceName; source = (HashItem) ( vertexMap.find( source ) ); dest.name = destName; dest = (HashItem) ( vertexMap.find( dest ) ); unweighted( source.rank ); printPath( dest.rank ); if( dijkstra( source.rank ) ) printPath( dest.rank ); else System.out.println( "Dijkstra fails - neg edge" ); if( dijkstraPair( source.rank ) ) printPath( dest.rank ); else System.out.println( "Dijkstra fails - neg edge" ); if( negative( source.rank ) ) printPath( dest.rank ); else System.out.println( "Negative fails - neg cycle" ); if( acyclic( source.rank ) ) printPath( dest.rank ); else System.out.println( "Acyclic fails - cycle" );} catch( ItemNotFound e ) { System.err.println( "Vertex not in graph" ); } return true; } Laura Cruz Reyes Grafos y Caminos Vértice Origen O private void unweighted( int startNode ) { int v, w; Queue q = new QueueAr( ); clearData( ); table[ startNode ].dist = 0; q.enqueue( new Integer( startNode ) ); try { while( !q.isEmpty( ) ) { v = ( (Integer) q.dequeue( ) ).intValue( ); ListItr p = new LinkedListItr( table[ v ].adj ); for( ; p.isInList( ); p.advance( ) ) { w = ( (Edge) p.retrieve( ) ).dest; if( table[ w ].dist == INFINITY ) { table[ w ].dist = table[ v ].dist + 1; table[ w ].prev = v; q.enqueue( new Integer( w ) ); } } } } catch( Underflow e ) { } // Cannot happen } Laura Cruz Reyes Grafos y Caminos private void unweighted( int startNode ) { int v, w; Queue q = new QueueAr( ); v=Vértice Actual w=Vértice Adyacente clearData( ); table[ startNode ].dist = 0; q.enqueue( new Integer( startNode ) ); try { while( !q.isEmpty( ) ) { v = ( (Integer) q.dequeue( ) ).intValue( ); ListItr p = new LinkedListItr( table[ v ].adj ); for( ; p.isInList( ); p.advance( ) ) { w = ( (Edge) p.retrieve( ) ).dest; if( table[ w ].dist == INFINITY ) { table[ w ].dist = table[ v ].dist + 1; table[ w ].prev = v; q.enqueue( new Integer( w ) ); } } } } catch( Underflow e ) { } // Cannot happen } Laura Cruz Reyes Grafos y Caminos private void unweighted( int startNode ) { int v, w; Queue q = new QueueAr( ); clearData( ); table[ startNode ].dist = 0; q.enqueue( new Integer( startNode ) ); D0=0 try { while( !q.isEmpty( ) ) { v = ( (Integer) q.dequeue( ) ).intValue( ); ListItr p = new LinkedListItr( table[ v ].adj ); for( ; p.isInList( ); p.advance( ) ) { w = ( (Edge) p.retrieve( ) ).dest; if( table[ w ].dist == INFINITY ) { table[ w ].dist = table[ v ].dist + 1; table[ w ].prev = v; q.enqueue( new Integer( w ) ); } } } } catch( Underflow e ) { } // Cannot happen } Laura Cruz Reyes Grafos y Caminos private void unweighted( int startNode ) { int v, w; Queue q = new QueueAr( ); clearData( ); table[ startNode ].dist = 0; q.enqueue( new Integer( startNode ) ); try { while( !q.isEmpty( ) ) { v = ( (Integer) q.dequeue( ) ).intValue( ); ListItr p = new LinkedListItr( table[ v ].adj ); for( ; p.isInList( ); p.advance( ) ) { w = ( (Edge) p.retrieve( ) ).dest; if( table[ w ].dist == INFINITY ) { table[ w ].dist = table[ v ].dist + 1; table[ w ].prev = v; q.enqueue( new Integer( w ) ); } } } } catch( Underflow e ) { } // Cannot happen } Laura Cruz Reyes Grafos y Caminos Insertar a la cola vértice origen private void unweighted( int startNode ) { int v, w; Queue q = new QueueAr( ); clearData( ); table[ startNode ].dist = 0; q.enqueue( new Integer( startNode ) ); try { while( !q.isEmpty( ) ) { v = ( (Integer) q.dequeue( ) ).intValue( ); ListItr p = new LinkedListItr( table[ v ].adj ); for( ; p.isInList( ); p.advance( ) ) { w = ( (Edge) p.retrieve( ) ).dest; if( table[ w ].dist == INFINITY ) { table[ w ].dist = table[ v ].dist + 1; table[ w ].prev = v; q.enqueue( new Integer( w ) ); } } } } catch( Underflow e ) { } // Cannot happen } Laura Cruz Reyes Grafos y Caminos Obtener vértice actual private void unweighted( int startNode ) { int v, w; Queue q = new QueueAr( ); clearData( ); table[ startNode ].dist = 0; q.enqueue( new Integer( startNode ) ); try { while( !q.isEmpty( ) ) { v = ( (Integer) q.dequeue( ) ).intValue( ); ListItr p = new LinkedListItr( table[ v ].adj ); for( ; p.isInList( ); p.advance( ) ) { w = ( (Edge) p.retrieve( ) ).dest; if( table[ w ].dist == INFINITY ) { table[ w ].dist = table[ v ].dist + 1; table[ w ].prev = v; q.enqueue( new Integer( w ) ); } } } } catch( Underflow e ) { } // Cannot happen } Laura Cruz Reyes Grafos y Caminos Añadir vértices adyacentes del vértice actual a una lista de adyacencia private void unweighted( int startNode ) { int v, w; Queue q = new QueueAr( ); clearData( ); table[ startNode ].dist = 0; q.enqueue( new Integer( startNode ) ); try { while( !q.isEmpty( ) ) { v = ( (Integer) q.dequeue( ) ).intValue( ); ListItr p = new LinkedListItr( table[ v ].adj ); for( ; p.isInList( ); p.advance( ) ) { w = ( (Edge) p.retrieve( ) ).dest; if( table[ w ].dist == INFINITY ) { table[ w ].dist = table[ v ].dist + 1; table[ w ].prev = v; q.enqueue( new Integer( w ) ); } } } } catch( Underflow e ) { } // Cannot happen } Laura Cruz Reyes Grafos y Caminos Si Dw=∞, es decir no se ha procesado private void unweighted( int startNode ) { int v, w; Queue q = new QueueAr( ); clearData( ); table[ startNode ].dist = 0; q.enqueue( new Integer( startNode ) ); try { while( !q.isEmpty( ) ) { v = ( (Integer) q.dequeue( ) ).intValue( ); ListItr p = new LinkedListItr( table[ v ].adj ); for( ; p.isInList( ); p.advance( ) ) { w = ( (Edge) p.retrieve( ) ).dest; if( table[ w ].dist == INFINITY ) { table[ w ].dist = table[ v ].dist + 1; table[ w ].prev = v; q.enqueue( new Integer( w ) ); } } } } catch( Underflow e ) { } // Cannot happen } Laura Cruz Reyes Grafos y Caminos Dw=Dv+1 private void unweighted( int startNode ) { int v, w; Queue q = new QueueAr( ); clearData( ); table[ startNode ].dist = 0; q.enqueue( new Integer( startNode ) ); try { while( !q.isEmpty( ) ) { v = ( (Integer) q.dequeue( ) ).intValue( ); ListItr p = new LinkedListItr( table[ v ].adj ); for( ; p.isInList( ); p.advance( ) ) { w = ( (Edge) p.retrieve( ) ).dest; if( table[ w ].dist == INFINITY ) { table[ w ].dist = table[ v ].dist + 1; table[ w ].prev = v; q.enqueue( new Integer( w ) ); } } } } catch( Underflow e ) { } // Cannot happen } Laura Cruz Reyes Grafos y Caminos Insertar Dw a la cola ( Vértice con costo mínimo calculado)