7. GRAFOS Se consideran los árboles como una generalización del concepto de lista porque permiten que un elemento tenga más de un sucesor. Los grafos aparecen como una extensión del concepto de árbol, ya que en este tipo de estructura cada elemento puede tener, además de más de un sucesor, varios elementos predecesores. Esta propiedad hace a los grafos la estructura más adecuada para representar situaciones donde la relación entre los elementos cambia según el contexto. El origen de la palabra grafo es griego y significa "trazar". Un grafo es con frecuencia la respuesta a problemas de la vida cotidiana. Algunos ejemplos podrían ser: un gráfico de una serie de tareas a realizar indicando su secuenciación (un organigrama), grafos matemáticos representando las relaciones binarias, una red de carreteras o de tránsito, la red de enlaces ferroviarios o aéreos, la red eléctrica de una ciudad, sistemas de telecomunicaciones, circuitos impresos o redes de computadores. En muchos casos un problema es conveniente representarlo gráficamente como un conjunto de puntos (nodos o vértices) conectados por líneas (arcos) según los requerimientos. Hoy en día es rara la disciplina científica o humanística que no utilice la teoría de grafos. se puede citar la sicología en dinámica de grupos, la sociología en los sociogramas, la física teórica que emplea los diagramas de Feynmann, donde se presenta mediante líneas las partículas elementales, en programación lineal e investigación operativa el estudio de flujo en redes, los cambios de variables en Figura 7.1 Ejemplo de un grafo. el cálculo diferencial,... Los grafos son estructuras de datos dinámicas no-lineales, utilizadas comúnmente en el análisis de redes, en diseño de circuitos eléctricos, en estrategias de mercados, cartografía, mapas conceptuales, matemática, planificación de procesos y muchas áreas del conocimiento. 82 Definición. Un grafo lineal (o simplemente un grafo), es una dupla G=(V,E), donde V={v1, v2, v3, ..., vn} es un conjunto de vértices, y E={e1, e2, e3, ..., en} es un conjunto de arcos. Los vértices contendrán información referente a objetos, mientras que los arcos establecen dependencia entre los objetos a los que relaciona directamente. Un arco queda determinado por los vértices a los que une. Cada arco ej esta identificado con un par de vértices (vi, vi+1). Ejemplo. En la figura 7.1 el arco e7 o V3V4 es enlace entre V3 y V4; el arco e6 o V2V4 es enlace entre V2 y V4. Notese que la definición no inhibe que un par de vértices tengan asociados dos o más arcos diferentes e7 y e10, en este caso se dice que los arcos son paralelos. El arco e9 en la figura 7.1 es llamado loop. Si se desea representar mediante un grafo la red de vuelos de una compañía aérea entre diferentes ciudades, tendríamos el siguiente grafo G = {V, A}; V = {Bogotá, Neiva, Cali, Medellín}; A = {(Bogotá, Neiva), (Bogotá, Medellín), (Neiva, Medellín), (Cali, Medellín)}. Figura 7.2 Puentes de Konigsberg. Un grafo G es un conjunto en el que hay definida una relación binaria, G=(V,R) tal que V es un conjunto de objetos a los que se denominan vértices o nodos y R ⊆ 0VxV es una relación cuyos elementos se denominan arcos o enlaces. Dados x, y en V, puede ocurrir que: * (x,y) ∈ 0R, en cuyo caso se dirá que x e y están unidos mediante un arco. * (x,y) _ 0R, en cuyo caso se dirá que no lo están. La más común representación de un grafo es por medio de una figura o diagrama en la cual los vértices se representan por puntos o círculos y los arcos por un segmento de línea. Un grafo se usa para representar situaciones físicas envolviendo objetos discretos y relaciones entre ellos. Se usan en ingeniería, en física, en ciencias biológicas y sociales, en lingüística y numerosas áreas. Problema del puente KONIGSBERG Es el mejor ejemplo de teoría de grafos, fue solucionado por Leonard Euler (1707-1783) en 1736. Dos islas C y B se hallan en el río Pregel en Konigsberg (la capital del este de Prusia, pero llamada Kaliningrad en el oeste de Rusia soviética) fueron conectadas la una a la otra y a las orillas por siete puentes (figura 7.2). El problema es iniciar en cualquiera de las áreas A, B, C o D y caminar por cada Luis Carlos Torres Soler Estructuras de Datos uno de los siete puentes exactamente una vez, y retornar al punto de partida. 83 Figura 7.3 Diagrama de los puentes de Konigsberg. La figura 7.3 indica el diagrama respectivo. Se han considerado las áreas de la figura 7.2 como nodos en la figura 7.3, mientras que los puentes se representan por arcos o enlaces entre los nodos. Problema de servicios Hay 3 casas C1, C2, C3 cada una conectada con los tres servicios: Agua (A), Gas (G) y Electricidad (E). Es posible hacer las conexiones sin sobreponer ninguna línea? Figura 7.4 Grafo del problema de los servicios. La figura 7.4 muestra como este problema puede ser representado por un grafo. Los conductos son mostrados como arcos, mientras que las casas y los servicios se muestran como nodos. Problema de la red eléctrica Las propiedades de una red eléctrica son funciones de solamente dos factores: 1. La naturaleza y valor de los elementos que forman la red, tales como resistencias, inductores, transistores. 2. La manera como esos elementos se conectan, esto es, la topología de la red. Puesto que hay pocos tipos diferentes de elementos eléctricos, la variación en la red son principalmente vistos en la variación de la topología. Así, el análisis de la red eléctrica y la síntesis son principalmente el estudio de la topología de red. Problema de asientos Nueve miembros de un club se reúnen cada día a almorzar en una mesa redonda. Ellos deciden sentarse de tal manera que cada miembro tenga diferentes vecinos cada día. Cuándo vuelven a tener un mismo ordenamiento? Esta situación se representa en el grafo de la figura 7.5. Facultad de Ingeniería 84 Pueden verse dos posibles ordenamientos 1 2 3 4 5 6 7 8 9 y 1 3 5 2 7 4 9 6 8 1. Demuéstrese que hay sólo otros dos ordenamientos 1 5 7 3 9 2 8 4 6 1 y 1 7 9 5 8 3 6 2 4 1. En general, para n personas el número posible de ordenamientos es: (n-1)/2 si n es impar y (n-2)/2 si n es par. Figura 7.5 Grafo del problema generalizado de los asientos. De aquí se podría deducir que un grafo es básicamente un objeto geométrico basado en un conjunto de puntos (vértices) y un conjunto de líneas que unen cada par de puntos (vértices). Por otro lado, debido a su generalidad y a la gran diversidad de formas que pueden usarse, resulta complejo tratar con todas las ideas relacionadas con un grafo. Definición. Un grafo que no tiene arcos loop's, ni arcos paralelos se llama grafo simple. Definición. Un arco es incidente en un vértice, si una de sus puntas llega a ese vértice. En la figura 7.1, e2 y e1, son incidentes del vértice v1. Dos arcos no paralelos se dicen son adyacentes si son incidentes en un vértice común, por ejemplo, e2 y e8, son adyacentes en la figura 7.1. En algunos casos es necesario imponer un sentido a los enlaces, por ejemplo, al representar la red vial de una ciudad con sus inevitables orientaciones, así que, el estudio de los grafos podría dividirse en dos grandes bloques; grafos dirigidos y grafos no dirigidos, pueden ser considerados un caso particular de los anteriores. Definición. Un grafo dirigido o digrafo, es aquel grafo en el que sus arcos tienen una orientación1. Un grafo dirigido es simétrico si para todo arco (x,y) ∈ 0A también aparece el arco (y,x) ∈ 0A y es antisimétrico si dado un arco (x,y) ∈ 0A implica que (y,x) _ 0A. Proposición. En un grafo simple el número máximo de arcos que puede contener es de n(n-1)/2, donde n es el número de vértices del grafo. En un grafo dirigido el número máximo de arcos es n(n-1). 1 Un ejemplo de grafo dirigido lo constituye la red de aguas de una ciudad ya que cada tubería sólo admite que el agua la recorra en un único sentido, por el contrario, la red de carreteras de un país representa en general un grafo no dirigido, puesto que una misma carretera puede ser recorrida en ambos sentidos. Luis Carlos Torres Soler Estructuras de Datos 85 Se prueba por inducción. Sea n=1 (un nodo), luego el número de arcos sería: 1(1-1)/2=0. Sea n=2 (dos nodos), el número de arcos es: 2(2-1)/2=1. Sea n=3 (tres nodos), el número de arcos es: 3(3-1)/2=3. Se considera que n=k es válido, es decir, arcos=k(k-1)/2 Sea n=k+1, arcos= (k+1)((k+1)-1)/2 = (k+1)k/2 Es decir, se cumple la condición. Figura 7.6 Ejemplo de un grafo. Proposición. A todo grafo no dirigido se puede asociar un grafo denominado dual construido de la siguiente forma: G (V, A) ------> G' (V', A' ) Donde A' se construye de la siguiente forma: si e1,e2 ∈ A son adyacentes => (e1,e2) ∈ A' con e1,e2 ∈ V; en definitiva, para construir un grafo dual se cambian vértices por arcos y viceversa. Definición. Si un grafo dispone de todos los posibles arcos entre sus vértices entonces se denomina completo. Definición. Dos vértices que son extremos de un arco se denominan adyacentes. Un grafo puede tener diferentes diagramas. El grafo es determinado por la incidencia de los arcos y los vértices (figura 7.6).2 Figura 7.7 Diagramas o figuras de un grafo. 2 En un grafo, algunos arcos pueden mostrar intersección para un punto que no representa un vértice, debe Facultad de Ingeniería 86 Un grafo también es llamado un lineal complejo, 1-complejo, o unidimensional complejo. Un vértice es referenciado como un nodo, una juncion, un punto, 0-celda, 0-simple. Términos usados para un arco son: línea, 1-celda, 1-simple. Figura 7.9 Diagramas de grafos infinitos. Figura 7.10 Grafos regulares. En ciertos casos es necesario asociar información a los arcos del grafo. Esto se logra mediante una etiqueta que contenga información útil, como el nombre, peso, coste o un valor de cualquier tipo de datos dado. En este caso se habla de grafos etiquetados. La etiqueta podría significar el tiempo que se tarda el vuelo entre dos ciudades o indicar cuáles son los parámetros de entrada y de salida en la llamada a un subprograma. Un grafo no etiquetado es un grafo donde los arcos no tienen etiquetas. En el caso del grafo que representa el sentido del tráfico se pueden etiquetar los arcos con el nombre de las calles. Tanto a los arcos como a los vértices se les puede asociar información. Grafos finitos e infinitos En la definición de un grafo, ni el conjunto de vértices V, ni el conjunto de arcos E, necesitan ser finitos, en muchas aplicaciones y en la teoría esos conjuntos son finitos. Un grafo con un número de vértices y arcos finito, es llamado grafo finito, de otra forma es infinito. Definición. El número de arcos incidentes en un vértice vk (un loop se cuenta dos veces) es llamado el grado G(vk), del vértice vk. En la figura 7.1, G(v1)=3. El grado de un vértice es en algunas veces también referido como valencia. Considerando un grafo G con m arcos e1, e2, ..., em y n vértices v1, v2, ..., vn. Dado que cada arco contribuye con 2 grados, la suma de los grados de todos los vértices en G es dos veces el número de arcos, esto es ΣG(vi) = 2m Teorema 1. El número de vértices de grado impar en un grafo es siempre par. mejorarse el diagrama. Luis Carlos Torres Soler Estructuras de Datos Dem. Considerando los vértices con grados par e impar por separado, se tiene que: 87 ΣG(vi) = ΣG(vj) + ΣG(vl) (1) con l impares, j pares Puesto que el lado izquierdo de (1) es par y el primer elemento de la suma en (1) es par, el segundo elemento debe ser también par, es decir: ΣG(vl) = 2m1 (2) Como en (2), cada g(vl) es impar, el total de términos de la suma debe ser par para que la suma sea par. Un grafo en la cual todos los vértices tienen igual grado se llama grafo regular. Vértices aislados, pendientes y grafo nulo Un vértice que no tiene arcos de incidencia es llamado vértice aislado. En otras palabras, un vértice aislado tienen grado cero. Un vértice con grado 1 se llama vértice pendiente o vértice final. Dos arcos adyacentes se dicen están en serie si el vértice en común es de grado 2. Figura 7.11 Diagramas de grafos. En la definición de grafo G=(V,E), es posible que el conjunto E de arcos sea vacío, en tal caso, se dice, es un grafo nulo3. En otras palabras, todo vértice en un grafo nulo es un vértice aislado. El conjunto V de vértices nunca puede ser vacío, si lo es, no hay grafo. En otras palabras, un grafo debe tener al menos un vértice. Definición. Dos grafos son equivalentes (isomorfos) si tienen idéntico funcionamiento y similares propiedades. Dos grafos G y G' se dicen son isomorfos si hay una correspondencia uno-uno entre sus vértices, entre sus arcos, y tal que las relaciones de incidencia se preservan. En otras palabras, supongamos que el arco ai es incidente en los vértices vi1 y vi2 en G; entonces, el correspondiente arco ai en G' debe ser 3 El número de elementos de V se denomina orden del grafo, un grafo nulo es un grafo de orden cero. Facultad de Ingeniería incidente en los vértices vi1' y vi2' que corresponden a vi1 y vi2 respectivamente. 88 En los grafos de la figura 7.11 existe la correspondencia: a4 ~ v1 x6 ~ e6 a3 ~ v2 x2 ~ e5 Figura 7.12 Diagramas de grafos isomorfos. a5 ~ v5 x1 ~ e3 a1 ~ v4 x4 ~ e4 a2 ~ v3 x5 ~ e1 x3 ~ e2 Excepto los nombres de los vértices y arcos, grafos isomorfos, son el mismo grafo. (figura 7.12) Subgrafos Un grafo H, se dice que es un subgrafo de G, si todos los vértices y todos los arcos de H están en G y cada arco de H tiene el mismo vértice final en H como en G. Obviamente al considerar un subgrafo, el grafo original no debe ser alterado al identificar los vértices o adicionando nuevos arcos o vértices. Las siguientes observaciones pueden ser hechas inmediatamente: 1. Todo grafo es así mismo un subgrafo. 2. Un subgrafo K de un subgrafo H de G, es a la vez un subgrafo de G. 3. Un vértice en un grafo G es un subgrafo de G. 4. Un arco en G, con sus vértices, es un subgrafo de G. Definición. Dos subgrafos G1 y G2 de un grafo G, se dicen disjuntos en arcos, si G1 y G2 no tienen arcos en común. Similarmente, si dos subgrafos no tienen vértices comunes se dicen son disjuntos en vértices. Si no tienen ni vértices, ni arcos comunes, se dicen son disjuntos. Camino y circuito Se define cadena como una secuencia alternada de vértices y arcos empezando y finalizando con vértice y tal que cada arco es incidente con el vértice precedente y siguiente. Luis Carlos Torres Soler Estructuras de Datos 89 Ningún arco puede aparecer más de una vez en la cadena. (un vértice, sin embargo, puede aparecer más de una vez). El conjunto de vértices y arcos constituyendo la cadena es un subgrafo claramente. Los vértices con los cuales inicia y termina la cadena son llamados vértices terminales. Si una cadena inicia y termina en el mismo vértice, es cerrada, es un bucle o simplemente ciclo. Una cadena en la cual ningún vértice aparece más de una vez es llamado camino. El número de arcos en el camino, indica la longitud del camino. Una cadena cerrada en la cual ningún vértice (excepto el inicial y final) aparecen más de una vez se llama circuito. Un nodo N se dice alcanzable desde un nodo M, si y sólo si, existe un camino desde M hasta N. Más formalmente, un nodo N se dice alcanzable desde un nodo M si: 1) N y M son el mismo nodo. 2) N es alcanzable desde algún nodo que sea sucesor de M. Para cada nodo de un grafo existe un conjunto de nodos alcanzables desde ese nodo, denominado conjunto alcanzable. Un nodo N se dice directamente alcanzable desde un nodo M, si y sólo si, son adyacentes y N es el sucesor de M. Definición. Un grafo se dice conexo si desde cualquier vértice puede llegarse a todos los demás. Se llama componente conexa a un conjunto de vértices de un grafo tal que entre cada par de vértices hay al menos un camino y si se añade algún otro vértice esta condición deja de verificarse. Matemáticamente se puede ver que la conexión es una relación de equivalencia que descompone a V en clases de equivalencia, cada uno de los subgrafos a los que da lugar cada una de esas clases de equivalencia constituiría una componente conexa4. Definición. Un digrafo se dice fuertemente conexo si desde cualquier vértice puede llegarse a todos los demás. Definición. Un grafo o digrafo se dice que es débilmente conexo, si por lo menos existe un vértice desde el cual no puede llegarse a los demás. Definición. Un grafo es disconexo si por lo menos existe un punto aislado o existe un conjunto de vértices a los cuales no puede visitarse nunca. 4 Un grafo se dice conexo, si sólo existe una componente conexa que coincide con todo el grafo. Facultad de Ingeniería 90 Teorema. Un grafo G es disconexo, si y sólo si, su conjunto de vértices V puede ser particionado en dos conjuntos no vacíos V1 y V2, tal que no existe arco alguno ex en G cuyos vértices a1 y a2, se de que a1 este en V1 y a2 en V2. Un grafo conexo acíclico no dirigido es un árbol libre. Un árbol libre puede convertirse en un árbol general si se elige cualquier nodo deseado como raíz y se orienta el cada arco desde él. Los árboles libres tienen dos propiedades interesantes: Figura 7.13 Grafo y su matriz de adyacencia. 1. Todo árbol libre con n nodos tiene exactamente n-1 arcos. 2. Si se agrega cualquier arco a un árbol libre, se genera un ciclo. Definición. Un grafo se dice que es un grafo de Euler si existe un camino cerrado que recorre todos los arcos del grafo. Es decir, se pueden visitar todos los vértices (cuantas veces sea necesario), recorriendo una sola vez los arcos. Definición. Un grafo se dice que es un grafo de Hamilton si existe un circuito que recorra todos vértices del grafo. Es decir, se visitan todos los vértices una única vez. Definición. Un grafo se dice que es completo si cada vértice tiene un grado igual a n-1, donde n es el número de vértices que componen el grafo. Se denomina grado de entrada de un vértice x al número de arcos incidentes en él, se denota ge(x). Se denomina grado de salida de un vértice x al número de arcos adyacentes a él, se denota gs(x). Para grafos no dirigidos tanto el grado de entrada como el de salida coinciden y se habla simplemente de grado y lo notamos por g(x). Búsqueda de caminos mínimos en grafos Supongamos que se tiene un grafo dirigido sencillo etiquetado G = {V, A} de grado n, V ={1,..., n} y Luis Carlos Torres Soler Estructuras de Datos con etiquetas en los arcos no negativas. 91 Búsqueda entre un vértice y todos los demás vértices del grafo. Se plantea el problema: dado un vértice, determinar el camino de costo mínimo de ese vértice a todos los demás vértices de V. Para resolver el problema se aplica un algoritmo debido a Dijkstra que esencialmente parte de un conjunto S de vértices (S ⊂ V) cuya distancia más corta desde el origen es conocida y en cada paso se agrega un nuevo vértice vi a S cuya distancia a su vez desde el origen siga siendo la más corta posible. Si la suposición hecha de que las etiquetas son siempre no negativas se cumple, puede comprobarse que siempre es posible encontrar un camino más corto desde el origen y un vértice v que sólo pase a través de los vértices de S (camino "inherente"). Si se utiliza además un vector D donde se almacena las longitudes de los caminos inherentes más cortos a cada vértice, una vez que S incluya a todos los vértices, todos los caminos son inherentes de forma que D contendrá la distancia más corta del origen a cada vértice. Notación: * * * Origen = vértice 1 (obviamente esto no es una condición) Sea S un vector de n componentes representando el conjunto de vértices cuya distancia más corta desde el origen ya es conocida. D es un vector de n componentes donde D[i] indica en cada paso la distancia más corta entre el origen y el vértice i: a. Por el camino directo si existe el arco (i,j). b. A través de los vértices de S (de los que se conoce su distancia más corta al origen). Al final D contendrá el costo del camino mínimo entre el origen y cada vértice. * * C es la matriz de costos del grafo. C [1,i] representa el costo del arco (1,i). Si el arco no existe, se le asigna un valor fuera de rango ( ∝ ) P es un vector de dimensión n a través del cual se reconstruirá el camino más corto del origen al resto de los vértices. Así P[i] contiene el vértice inmediato anterior a i en el camino más corto. Inicialmente es evidente que S = {1} y D[i] = C[1,i] con P[i]=1 Facultad de Ingeniería 92 Figura 7.15 Grafo para el ejemplo. Con estas premisas el algoritmo de Dijkstra se puede esquematizar así: Algoritmo Dijkstra() 1. S = {1} 2. Para (i = 2; i<=n; i++) { D[i] = C[I,i] P[i] = 1 } 3. MQ (S ≠ V) { elegir w ∈ V-S / D[w] sea mínimo S= S U {w} PC (vértice v∈ V-S) SI (D[v] > D[w] + C[w, v]) { D[v] = D[w] + C[w, v] P[v] = w } } Un ejemplo del algoritmo. Sea que se desea encontrar el camino mínimo del vértice 1 al resto en el grafo de la figura 7.15: En principio: * * * S= {1} D[2]=60; D[3]=10; D[4]=100; D[5]= ∞ P[i]=1 _ i Iteración 1: V -S = {2,3,4,5}, w =3 -> S = {1,3} -> V -S = {2,4,5} D[2] = min(D[2], D[3] + C[3,2]) = min(60, 50) = 50 -> P[2] = 3 D[4] = min(D[4], D[3] + C[3,4]) = min(100, 40) = 40 -> P[4] = 3 D[5] = min(D[5], D[3] + C[3,5]) = min ( ∞ , ∞ )= ∞ Luis Carlos Torres Soler Estructuras de Datos Así D[2]=50; D[4]=40; D[5]= ∞ ; P[2]=3; P[4]=3; P[5]= 1 93 Iteración 2: V -S = {2,4,5}, w = 4 -> S = {1,3,4} -> V- S = {2,5} D[2] = min(D[2], D[4] + C[4,2]) = min(50, ∞ ) = 50 -> P[2]=3 D[5] = min(D[5], D[4] + C[4,5]) = min( ∞ ,60) = 60 -> P[5]=4 Así D[2]=50; D[5]=60; p[2]=3; P[5]=4 Iteración 3: V -S = {2,5}, w = 2 -> S = {1,3,4,2} -> V- S = {5} D[5] = min(D[5], D[2] + C[2,5]) = min(60, 58) = 58 -> P[5]=2 Así D[5]=58; P[5]=2 Finalmente w = 5 -> S = {1,3,4,2,5} -> FIN DEL ALGORlTMO Para reconstruir el camino más corto del origen a cada vértice, se asignan los predecesores en orden inverso. Por ejemplo, si se quiere conocer el camino desde el origen al vértice S, se tiene que: P[5]=2-+ P[2]=3-+P[3]=1 siendo por tanto el camino (1,3,2,5) con costo 58. Aunque la implementación de este algoritmo es simple al realizarla con base a una matriz de adyacencia, en la práctica se utiliza normalmente una implementación con base a listas de adyacencia. La razón de esta elección es que en la primera la eficiencia es O(n2) para cualquier grafo; sin embargo, la mayoría de los grafos encontrados en la práctica tiene un número de arcos bastante pequeño (grafos que pueden denominarse dispersos o no densos) y por tanto el uso de listas de adyacencia se presenta como una solución más eficiente. Para conseguir una mejor eficiencia en la implementación del algoritmo de Dijkstra se ha echado mano de una estructura de datos formada por un APO que tiene como etiqueta los vértices del grafo y como clave el coste de ir desde el vértice inicial en el problema a ese vértice de tal forma que obtener el vértice con mínimo coste sería O(log n). Búsqueda entre cada par de vértices del grafo. En lugar de buscar los caminos mínimos de un vértice a los demás podemos plantear, buscar el camino más corto entre cualquier par de vértices, es decir, dado un grafo dirigido etiquetado G = {V, A} en el que las etiquetas son no negativas encontrar el camino de longitud más corta entre dos vértices cualesquiera de ese grafo. Podría pensarse, para resolver el problema, en aplicar el algoritmo de Dijkstra n veces, una por vértice, pero en lugar de eso, se aplica un nuevo algoritmo creado por Floyd que va encontrando los caminos de forma iterativa. Notación: * * V = {1, ..., n} conjunto de vértices. A es una matriz de tamaño n x n en la que se calculará en cada Aij la longitud más corta del Facultad de Ingeniería 94 * * camino que va de i a j. P es una matriz de tamaño n x n que se utiliza para recuperar los caminos más cortos. C es una matriz de dimensión n x n conteniendo los costos de los arcos. Si no existe arco de un vértice i a otro j el correspondiente valor C[i,j]=? Inicialmente A[i,j] = {C[i,j] si i≠j, 0 si i=j}. A continuación se itera sobre A n veces de forma que tras hacer la iteración k, A[i,j] tiene un valor correspondiente a la longitud más pequeña de cualquier camino de i a j que no pase por un vértice de índice mayor que k, es decir, cualquier vértice intermedio entre i y j (extremos del camino) ha de ser menor o igual que k. Por tanto, en cada iteración k se usará la siguiente fórmula: Ak[i,j] = min(Ak-1[i,j] ,Ak-1[i,k] +Ak-1l[k,j])3, es decir, cada Ak[i,j] se obtiene comparando Ak-1[i,j], el coste de ir de i a j sin pasar por k o cualquier vértice de índice mayor, con Ak-1[i,k] +Ak-1[k,j], el costo de ir primero de i a k y después de k a j sin pasar por un vértice de índice mayor que k de forma que si el paso por el vértice k produce un camino i más corto que el indicado por Ak-1[i,j], se elige ese coste para Ak[i,j]. Así mismo, cada iteración P[i,j] contendrá el vértice k que permitió al algoritmo de Floyd encontrar el valor más pequeño de A[i,j]. Inicialmente P[i,j]=0, puesto que inicialmente el camino más corto de i a j es el propio arco. Algoritmo Floyd() 1. Para (i = 1; i <= n; i++) Para (j = 1; j <=n ; j++) { A[i,j]= C[i,j] P[i,j]= 0 } 2. Para (i = 1; i <= n; i++) A[i,i]= 0 3. Para (k = 1; k <= n; k++) Para (i = 1; i <= n; i++) Para (j = l; j <=n ; j++) SI ((i≠j) && (A[i,k]+A[k,j] < A[i,j])) { A[i,j]= A[i, k]+A[k,j] P[i,j]= k } Luis Carlos Torres Soler 95 Estructuras de Datos Veamos un ejemplo con el grafo de la figura 7.16. 07* 5* 0 0 0 0 0 * 0 2 * _6 0 0 0 0 _0 A0 = 5 * 0 * * P0 = 0 0 0 0 0 ** 30 8 0 0 0 0 0 * * 7 * _0 0 0 0 0 _0 07* 5* 0 0 0 0 0 + 0 2 _* 6 0 0 0 0 _0 A1 = 5 [12] 0 [10] * P1 = 0 [1] 0 [1] 0 +* 3 0* 0 0 0 0 0 +* 7 * 0 0 0 0 0 _0 Figura 7.16 Grafo para el ejemplo. Facultad de Ingeniería A2 = A3 = 0 7 [9] 5 [13] 0 0 [2] 0 2 + 0 _2 * 6 0 0 0 0 _0 5 12 0 10 18 P1 = 0 1 0 1 [2] + * 3 0 _* 0 0 0 0 0 +* 7 * 0 0 0 0 0 _0 0 7 9 5 [13] 0 0 2 0 2 [7] 0 2 [12] 6 3 0 0 3 _0 P1 = 5 12 0 10 18 0 10 12 [8] [15] 3 0 _ [21] [3] [3] 0 0 [3] [12] [19] 7 [17] 0 [3] [3] 0 _ [3] 0 0 7 [8] 5 13 0 0 [4] 0 2 7 0 2 12 6 3 0 0 3 _0 A4 = 5 12 0 10 18 P1 = 96 0 10 12 8 15 3 0 _ 21 3 30 0 3 12 19 7 17 0 3 3 0 3 _0 0 7 8 5 13 0 0 4 0 2 7 0 2 _12 6 3 0 0 3 _0 A5 = 5 12 0 10 18 P1 = 0 1 0 1 2 8 15 3 0 21 3 30 0 3 12 19 7 17 0 3 3 0 3 _0 A5=A4 con lo que el algoritmo termina. Con el objeto de recuperar los caminos de cualquier vértice i a cualquier otro j puede usarse el siguiente algoritmo: Algoritmo recuperar_camino (i, j de tipo vértice) Luis Carlos Torres Soler Estructuras de Datos 1. k= P[i,j] 2. SI (k≠ 0) { recuperar_camino (i, k) escribir (k) recuperar_camino (k, j) } 97 Por ejemplo, el camino más corto entre los vértices 2 y 4 se determinaría llamando a: recuperar-camino (2,4) k = 3 -> recuperar-camino (2,3) -> 0 [3] recuperar-camino (3,4) -> k = 1 -> recuperar-camino (3,1) -> 0 [1] recuperar-camino (1,4) -> 0 con la que el camino es (2,3,1,4) con costo 12. Existen diversas representaciones de naturaleza muy diferente que resultan adecuadas para manejar un grafo, y en la mayoría de los casos no se puede decir que una sea mejor que otra siempre ya que cada una puede resultar más adecuada dependiendo del problema concreto al que se desea aplicar, así, si existe una representación que es peor que otra para todas las operaciones excepto una es posible que aún así nos decantemos por la primera porque precisamente esa operación es la única en la que tenemos especial interés en que se realice de forma eficiente. Matriz de adyacencia La matriz de adyacencia, es una matriz en que cada elemento M(i,j), se le asigna un 1 si el vértice i es adyacente del vértice j, y un 0 en caso contrario. Las filas y las columnas de la matriz son los vértices del grafo5. Matriz de incidencia La matriz de incidencia, es una matriz en que cada elemento M(i,j), representa la relación incidencia que existe entre el arco i y el vértice j, se le asigna un 1 si el arco i incide en el vértice j, y un 0 en caso contrario (es la matriz de adyacencia para digrafos). La principal desventaja de la matriz de adyacencia es la cantidad de elementos que quedan desaprovechados si el grafo a representar dispone de gran cantidad de vértices y pocos arcos; los algoritmos que tengan que inspeccionar la totalidad de la matriz deberán acceder a n2-n elementos, siendo n el número de vértices del grafo. 5 En el caso de digrafos, la adyacencia se expresa desde o hacia. Facultad de Ingeniería 98 Figura 7.17 Digrafo y su matriz de incidencia. Si el grafo es etiquetado, entonces, tanto bi,j como bi,j representan al coste o valor asociado al arco (i,j) y se suelen denominar matrices de coste. Si el arco (i,j) no pertenece a A entonces se asigna bi,j o bi,j un valor que no puede ser utilizado como una etiqueta valida. La principal ventaja de la matriz de adyacencia es que el orden de eficiencia de las operaciones de obtención de etiqueta de un arco o ver si dos vértices están conectados son independientes del número de vértices y de arcos, por el contrario, existen dos grandes inconvenientes: * * Es una representación orientada hacia grafos que no modifica el número de sus vértices ya que una matriz no permite que se le o supriman filas o columnas. Se puede producir un gran derroche de memoria en grafos poco densos (con gran número de vértices y escaso número de arcos). Operaciones en grafos Como en el caso de muchas entidades matemáticas, es conveniente considerar un gran grafo como la combinación de uno o más subgrafos y derivar sus propiedades de ellos. Sean los grafos G1=(V1,A1) y G2=(V2,A2) G = G1 ∪ G2 = (V1 ∪ V2, A1 ∪ A2) G = G1 ∩ G2 = (V1 ∩ V2, A1 ∩ A2) Si G1 y G2, son disjuntos-arcos, entonces G1 ∩ G2 = grafo nulo. Si G1 y G2, son disjuntos-vértices, entonces G1 ∩ G2 es vacío. Un grafo G se dice que puede ser descompuesto en dos subgrafos g1 y g2 si, g1 ∪ g2 = G y, g1 ∩ g2 = grafo nulo. Definición. Un árbol es un grafo conexo sin circuitos. Teorema. Un árbol con n vértices tiene n-1 arcos. Luis Carlos Torres Soler Estructuras de Datos 99 En 1987, Arthur Cayley descubrió árboles mientras contaba el número de isomeros estructurales de hidrocarburos saturados CkH2k+2. Se usa un grafo conexo para representar la molécula CkH2k+2. correspondiendo a su valencia química, un carbono puede ser representado por un vértice de grado 4 y el hidrógeno por un vértice de grado 1. El número total de vértices en tal grafo es n=3k+2, y el número de arcos es 1/2(suma de grados)=1/2(4k+2k+2)=3k+1. Así el problema de conteo de isomeros estructurales de un hidrocarburo es contar árboles. La primera pregunta de Cayley; ¿Cuál es el número de diferentes árboles que se pueden construir con n distintos vértices? Teorema. El número de árboles marcados con n vértices (n>=2) es nn-2. Cubo unitario y su grafo Figura 7.18 Diagrama de Q1, Q2 y Q3. Considérese un conjunto de m variables x1, x2, ..., xm. Cada xi puede tomar los valores 0 o 1. Por tanto se pueden formar 2m distintas m-tuplas. Cada una de esas m-tuplas puede ser representada por un vértice de un cubo unitario m-dimensional. Los arcos y vértices de un m-dimensional cubo unitario forman un grafo con 2m vértices. Cada vértice es marcado con una secuencia binaria distinta de m-bits tal que dos vértices son adyacentes, si y solamente si, ellos difieren en exactamente un bit. Tal grafo es llamado un m-cubo y es designado por Qm. Algunas propiedades de un m-cubo Qm 1. Hay exactamente m distintas marcas que difieren en una posición. Por tanto cada vértice en Qm es de grado m. Así Qm es un grafo regular de n=2m vértices y m*2m-1 arcos. 2. La distancia d(vi,vj) entre dos vértices vi y vj, en un m-cubo, es igual al número de posiciones en que los labels de vi y vj difieren. 3. La máxima distancia posible entre dos vértices en un m-cubo es m. Facultad de Ingeniería