You are on page 1of 18

Estructuras de Datos y Algoritmos I CAPITULO 7: GRAFOS 7.1 Definiciones Grafo modelo para representar relaciones entre elementos de un conjunto.

o. Grafo: (V, E), V es un conjunto de vrtices o nodos, con una relacin entre ellos; E es un conjunto de pares (u,v), u,v V , llamados aristas o arcos. Grafo dirigido: la relacin sobre V no es simtrica. Arista par ordenado (u,v). Grafo no dirigido la relacin sobre V s es simtrica. Arista par no ordenado {u,v}, u,v V y u v.

Grafo dirigido G(V , E). V = {1,2,3,4,5,6} E = {(1,2),(1,4),(2,5),(3,5),(3,6),(4,2),(5,4), (6,6)}

Grafo no dirigido G(V , E). V = {1,2,3,4,5} E = {{1,2},{1,5},{2,3},{2,4},{2,5}, (5,4),(6,6)}

Camino desde u V a v V : secuencia v1, v2, . . . , vk tal que u = v1, v = vk, y (vi1,vi) E, para i =2, . . . ,k. Ej: camino desde 3 a 2 <3,5,4,2>.

Longitud de un camino: nmero de arcos del camino.

Estructuras de Datos y Algoritmos I Camino simple: camino en el que todos sus vrtices, excepto, tal vez, el primero y el ltimo, son distintos. Ciclo: camino simple v1, v2, . . . , vk tal que v1 = vk. Ej: <2,5,4,2> es un ciclo de longitud 3.

Bucle: ciclo de longitud 1. Grafo acclico: grafo sin ciclos. Grado de un nodo: nmero de arcos que inciden en l. Grado de un grafo: mximo grado de sus vrtices. v es alcanzable desde u, si existe un camino de u a v. Un grafo no dirigido es conexo si existe un camino desde cualquier vrtice a cualquier otro. Un grafo dirigido con esta propiedad se denomina fuertemente conexo.

Si un grafo dirigido no es fuertemente conexo, pero el grafo subyacente (sin sentido en los arcos) es conexo, el grafo es dbilmente conexo. Grafo ponderado o etiquetado: cada arco, o cada vrtice, o los dos, tienen asociada una etiqueta.

Estructuras de Datos y Algoritmos I

7.2 Representacin de grafos

7.2.1 Listas de Adyacencia G = (V, E): vector de tamao |V |. Posicin i puntero a una lista enlazada de elementos (lista de adyacencia). Los elementos de la lista son los vrtices adyacentes a i

Si G es dirigido, la suma de las longitudes de las listas de adyacencia ser |E|. Si G es no dirigido, la suma de las longitudes de las listas de adyacencia ser 2|E|. Costo espacial, sea dirigido o no: O(|V | + |E|). Utilidad: Representacin apropiada para grafos con |E| menor que |V |2. Es econmico en el almacenamiento de grafos no densos (dispersos). Desventaja: si se quiere comprobar si una arista (u,v) pertenece a E buscar v en la lista de adyacencia de u. Costo O(Grado(G)) O(|V |). El acceso es ms lento.

Estructuras de Datos y Algoritmos I

Representacin extensible a grafos ponderados. El peso de (u,v) se almacena en el nodo de v de la lista de adyacencia de u.

Definicin de tipos en C (grafos ponderados): #define MAXVERT . . . typedef struct vertice{ int nodo, peso; struct vertice *sig; }vert_ady; typedef struct{ int talla; vert_ady *ady[MAXVERT]; }grafo;

Estructuras de Datos y Algoritmos I 7.2.2 Matriz de Adyacencia G = (V, E): matriz A de dimensin |V | |V |. 1 si (i, j ) E Valor aij de la matriz: a ij = 0 en cualquier otro caso

Utilidad: Representacin es til para grafos con nmero de vrtices pequeo, o grafos densos (|E| |V | |V |). Es conveniente para algoritmos que requieran saber rpidamente si un determinado arco existe (ya que hay acceso directo). Comprobar si una arista (u,v) pertenece a E consultar posicin A[u][v]. Costo O (1). Desventaja: Requiere gran cantidad de almacenamiento, siempre de orden O (|V |2), aunque el grafo no tenga muchos arcos. Representacin grafos ponderados: El peso de (i,j) se almacena en A[i, j]. w(i, j ) si (i, j ) E aij = 0 en cualquier otro caso

Estructuras de Datos y Algoritmos I

Definicin de tipos en C: #define MAXVERT . . . typedef struct{ int talla; int A[MAXVERT][MAXVERT]; }grafo;

Implementacin de funciones

Ejemplo 1: Funcin que entrega el primer nodo adyacente al nodo n. int Primero(int n) { int i; for(i=0;i<MAXVERT;i++) if(A[n][i]) return i; return -1; } Ejemplo 2: Entrega nodo siguiente que sigue a i; int Siguiente(int n, int i) { int j; for(j=i+1;j<MAXVERT;j++) if(A[n][j]) return j; return -1; }

Estructuras de Datos y Algoritmos I 7.3 Recorrido de los Grafos

La idea es partir de un nodo y recorrer en forma sistemtica los distintos nodos del grafo. Existen dos tipos de recorridos utilizados: Recorrido en profundidad (depth first). Recorrido en amplitud (breadth first).

7.3.1 Recorrido en Profundidad

Generalizacin del orden previo (preorden) de un rbol. Estrategia: Partir de un vrtice determinado v. Cuando se visita un nuevo vrtice, explorar cada camino que salga de l. Hasta que no se ha finalizado de explorar uno de los caminos no se comienza con el siguiente. Un camino deja de explorarse cuando lleva a un vrtice ya visitado. Si existan vrtices no alcanzables desde v el recorrido queda incompleto: seleccionar alguno como nuevo vrtice de partida, y repetir el proceso. Esquema recursivo: dado G = (V, E) 1. Marcar todos los vrtices como no visitados. 2. Escoger vrtice u como punto de partida. 3. Marcar u como visitado. 4. v adyacente a u, (u,v) E, si v no ha sido visitado, repetir recursivamente (3) y (4) para v. Finalizar cuando se hayan visitado todos los nodos alcanzables desde u. Si desde u no fueran alcanzables todos los nodos del grafo: volver a (2), escoger un nuevo vrtice de partida v no visitado, y repetir el proceso hasta que se hayan recorrido todos los vrtices. Usar un vector color (talla |V|) para indicar si u ha sido visitado color[u] = AMARILLO) o no (color[u]=BLANCO): Algoritmo Recorrido en profundidad (G) { para cada vrtice u V color[u] = BLANCO 7

Estructuras de Datos y Algoritmos I fin para para cada vrtice u V si (color[u] = BLANCO) Visita nodo(u) fin para } Algoritmo Visita nodo(u){ color[u] = AMARILLO para cada vrtice v V adyacente a u si (color[v] = BLANCO) Visita nodo(v) fin para } Ejemplo: Para el siguiente grafo, muestre el recorrido en profundidad.

Recorrido en Profundidad: 1, 4, 6, 7, 3, 5, 2

Costo Temporal G = (V, E) se representa mediante listas de adyacencia. Visita nodo se aplica nicamente sobre vrtices no visitados slo una vez sobre cada vrtice. Visita nodo depende del nmero de vrtices adyacentes que tenga u (longitud de la lista de adyacencia). Costo de todas las llamadas a Visita nodo:

xV

ady (v ) = O( E )

Aadir costo asociado a los bucles de Recorrido en profundidad: O(|V |). costo del recorrido en profundidad es O(|V | + |E|).

Estructuras de Datos y Algoritmos I 7.3.2 Recorrido en Anchura

Generalizacin del recorrido por niveles de un rbol. Estrategia: Partir de algn vrtice u, visitar u y, despus, visitar cada uno de los vrtices adyacentes a u. Repetir el proceso para cada nodo adyacente a u, siguiendo el orden en que fueron visitados. Costo: O(|V | + |E|).

Esquema: 1. Se visita el nodo inicial n, marcndolo como visitado. 2. Luego se visitan, todos los nodos adyacentes m, no visitado, del nodo inicial. 3. Despus se visitan todos los nodos adyacentes, no visitados, de los nodos ya recorridos, en el orden de visita. Para mantener el orden de visita es conveniente usar una cola: Algoritmo Recorrido en Anchura (Grafo G, nodo n){ boolean visitado [MAXVERT]= FALSE; cola Q; nodo m; anular(Q); visitado[n]=TRUE; enqueue(n,Q); while(EsVacia(Q)){ n=Frente(Q); dequeue (Q); Para todo nodo m adyacente de n, no visitado{ visitado[m]=TRUE; enqueue(m,Q); } } }

Estructuras de Datos y Algoritmos I Ejemplo: Para el siguiente grafo muestre el recorrido en anchura.

Recorrido en anchura: 1,2,4,5,6,3,7

7.4 El problema del Camino Mnimo

Suponemos: Un grafo dirigido G=(V,E) con E un conjunto de arcos y V un conjunto de vrtices. Una distancia definida entre los nodos que viene dada por una matriz L[1..n,1..n]>=0. Se trata de hallar la distancia de los caminos mnimos desde un nodo raz a todos los dems. La solucin de este problema conduce al Algoritmo de Dijkstra, del que las principales caractersticas son las siguientes:

7.4.1 Algoritmo de Dijkstra

Llamamos S al conjunto de los nodos elegidos. S contendr los nodos cuya distancia desde el origen es mnima.

Inicialmente, S slo contiene el origen y cuando finalice el algoritmo, S cotendr todos los nodos del grafo.

En cada etapa se elegir aquel nodo cuya distancia al origen sea menor, para ponerlo en S.

10

Estructuras de Datos y Algoritmos I Diremos que un camino del origen a otro nodo es especial si todos los nodos intermedios estn en S. En cada etapa del algoritmo se emplea un vector D que contiene la longitud del camino especial ms corto a cada nodo del grafo, de manera que en cada etapa, como aadimos un vrtice nuevo a S, todos los valores de D[V] se actualizan. Para la actualizacin vemos si con el nuevo vrtice introducido en S podemos llegar al vrtice v por un camino de longitud ms corta que el que haba. Si es posible, se actualiza D[V]; FUNCION DIJKSTRA c={2,3,,N} para i=2 hasta n hacer D[i]=L[1,i]; i=2, N P[i]=1; Repetir N-2 veces v=algn elemento de C que minimice D[v] c=c-(v) para cada w c hacer si D[w]>D[v]+L[v,w] entonces D[w]=D[v]+l[v,w] P[w]=v Devolver D; FIN FUNCION

Donde P es un vector que nos permite conocer por donde pasa cada camino de longitud mnima desde el origen. El algoritmo consume un tiempo en O(n2) en el peor caso. El algoritmo puede extenderse fcilmente para que de la distancia entre todos los pares de vrtices: O(n3). La hiptesis de que las distancias sean no negativas es esencial. Si hay alguna distancia negativa el algoritmo no funciona correctamente.

11

Estructuras de Datos y Algoritmos I Ejemplo: Dado el siguiente grafo, calcule el camino mnimo desde el nodo 1 a todo el resto de los nodos, a travs del algoritmo Dijkstra. 1 5 20 6 10 5 S {1} {1,6} {1,6,5} {1,6,5,2} {1,6,5,2,4} {1,6,5,2,4,3} Q v 10 5 20 1 0,4 2 5 5 2 10 3

40

{1,2,3,4,5,6} {2,3,4,5,6} {2,3,4,5} {2,3,4} {3,4} {3} 1 6 5 2 4 3

, ,25,6 25,6

,40,1 40,1 40,1 40,1 35,4

, , ,1
30,5 30,5

,10,1 10,1

,5,1

Nodo Origen 1 1 1 1 1 1

Nodo Destino 1 2 3 4 5 6

Camino 1,6,2 1,5,4,3 1,5,4 1,5 1,6

Costo 0 25 35 30 10 5

7.4.2 Algoritmo Floyd - Warshall

El problema que intenta resolver este algoritmo es el de encontrar el camino ms corto entre todos los pares de nodos o vrtices de un grafo. Esto es semejante a construir una tabla con todas las distancias mnimas entre pares de ciudades de un mapa, indicando adems la ruta a seguir para ir de la primera ciudad a la segunda. Este es uno de los problemas ms interesantes que se pueden resolver con algoritmos de grafos.

12

Estructuras de Datos y Algoritmos I Existen varias soluciones a este problema y los algoritmos a aplicar dependen tambin de la existencia de arcos con pesos o costos negativos en el grafo. En el caso de no existir pesos negativos, sera posible ejecutar V veces el Algoritmo de Dijkstra para el clculo del camino mnimo, donde V es el nmero de vrtices o nodos del grafo. Esto conllevara un tiempo de ejecucin de O(n3) (aunque se puede reducir). El algoritmo de Floyd-Warshall ('All-Pairs-Shortest-Path' - Todos los caminos mnimos) ideado por Floyd en 1962 basndose en un teorema de Warshall tambin de 1962, usa la metodologa de Programacin Dinmica para resolver el problema. ste puede resolver el problema con pesos negativos y tiempos de ejecucin iguales a O(n3); sin embargo, para ciclos de peso negativo el algoritmo tiene problemas. Implementacin del Algoritmo de Floyd

Supongamos que tenemos los nodos de un grafo G = (V,E) numerados entre 1 y |V |. Sea dkij la distancia mnima entre el nodo i y el nodo j, con todos los nodos intermedios en el conjunto {1, . . . , k}. Podemos escribir una expresin recursiva para dkij:

A nosotros nos interesar calcular d|V |ij , y es posible hacerlo de la siguiente manera: FUNCION FLOYD-WARSHALL (Grafo W) n=Filas[W]; para i=1 hasta n hacer para j=1 hasta n hacer
0 d ij = wij ;

fin para fin para para k=1 hasta n hacer

13

Estructuras de Datos y Algoritmos I para i=1 hasta n hacer para j=1 hasta n hacer
k k 1 k 1 k 1 d ij = mn{d ij , d ik + d kj };

fin para fin para fin para FIN FUNCION

7.5 El problema del rbol Generador Minimal

Se trata de encontrar el rbol generador minimal de un grafo, es decir, el rbol generador de mnima longitud.

Suponemos un grafo conexo G=(V,A) sobre el que hay definida una matriz de pesos L(i,j) >=0. Se desea encontrar un rbol T A, tal que todos los nodos permanezcan conectados cuando solo se usen aristas de T, siendo la suma de los pesos de sus aristas mnimas. Al grafo (V,T) se le llama rbol Generador Minimal del grafo G.

Algunas aplicaciones a este problema son el diseo de redes fsicas; telfonos, elctricas, hidrulicas, TV por cable, computadores, carreteras, etc.

La solucin del problema es a travs de la listas de arista, donde a partir de ellas puede darse una lista de candidatos o no a solucin. Una solucin ser un conjunto de aristas que forme un AGM. La condicin de factibilidad es que la arista que se vaya a incluir no forme un ciclo con las ya incluidas. El criterio de seleccin ser escoger en cada momento la arista de mnimo peso. El objetivo es que la suma de los pesos de las aristas en el rbol sea mnima. Propiedad del AGM

Sea G=(V,A) un grafo no dirigido y conexo donde cada arista tiene una longitud conocida. Sea U V un subconjunto propio ( lo que significa que U no puede coincidir con V) de los nodos de G. Si (u,v) es una arista tal que u U y v V-U y, adems, es la

14

Estructuras de Datos y Algoritmos I arista del grafo que verifica esa condicin con el menor peso, entonces existe un AGM T que incluye a (u,v).

7.5.1 Algoritmo de Kruskal

Ordenar las aristas de forma creciente de costo. Repetir o Coger la arista ms corta. o Borrar la arista de E. o Aceptar la arista si no forma un ciclo en el rbol parcial. Rechazarla en caso contrario, hasta que tengamos V 1 aristas correctas.

Si nuestro grafo tiene n vrtices y a aristas, el tiempo de este algoritmo es O(a log n). Implementacin del Algoritmo de Kruskal FUNCION KRUSKAL (G:GRAFO): Conjunto de aristas. Ordenar las aristas por longitudes crecientes N= V T= Inicializar N conjuntos (1 elemento cada conjunto) Repetir

{U ,V } =arista ms corta an no considerada


Conjunto U= BUSCA(U) Conjunto V= BUSCA(V) Si Conjunto U Conjunto V ENTONCES UNIR(Conjunto U,Conjunto V) T=T ({U,V}) Hasta que T = N 1 DEVOLVER(T) FIN FUNCION

15

Estructuras de Datos y Algoritmos I Ejemplo: Dado el siguiente grafo. 2 2 1 4 1 4 4 4 7 3 6 3 5 3

Obtenga el rbol generador minimal a travs del algoritmo de Kruskal. Arista Peso Paso ini 1 2 3 4 5 6 7 (1,2) 1 Seleccin (1,2) (2,3) (4,5) (6,7) (1,4) (2,5) R (4,7) (2,3) 2 (4,5) 3 (6,7) 3 (1,4) 4 (2,5) 4 (4,7) 4 (3,5) 5

Componentes Conexas (N Conjuntos) {{1},{2},{3},{4},{5},{6},{7}} {{1,2},{3},{4},{5},{6},{7}} {{1,2,3},{4},{5},{6},{7}} {{1,2,3},{4,5},{6},{7}} {{1,2,3},{4,5},{6,7}} {{1,2,3,4,5},{6,7}} {{1,2,3,4,5},{6,7}} {1,2,3,4,5,6,7} 2 2 3

Conjunto T

{(1,2)} {(1,2),(2,3)} {(1,2),(2,3),(4,5)} {(1,2),(2,3),(4,5),(6,7)} {(1,2),(2,3),(4,5),(6,7),(1,4)} {(1,2),(2,3),(4,5),(6,7),(1,4)} {(1,2),(2,3),(4,5),(6,7),(1,4),(4,7)}

1 1 4 4 4 7 3 6 3 rbol Generador Minimal 5

16

Estructuras de Datos y Algoritmos I 7.5.2 Algoritmo de Prim

El Algoritmo de Prim es otro mtodo de resolver el problema del AGM que se basa en:

Construccin del algoritmo en funcin de la propiedad del AGM. En el algoritmo de Kruskal partamos de la seleccin de la arista ms corta que hubiera en la lista de aristas, lo que implica un crecimiento desordenado del AGM.

Para evitarlo, el algoritmo de Prim propone que el crecimiento del AGM sea ordenado. Para ellos aplica el algoritmo a partir de una raz, lo que no implica restriccin alguna.

La idea del algoritmo de Prim es la siguiente:

Se toma un conjunto U de nodos, que inicialmente contiene al nodo raz. Formamos el conjunto T de soluciones (aristas) En cada etapa del algoritmo busca la arista ms corta que conecta U con V-U, siendo V el conjunto de candidatos. Aade el vrtice obtenido al conjunto U y la arista obtenido a T. En cada instante, las aristas que estn en T constituyen en AGM para los nodos que estn en U. Esto lo hacemos hasta que U=n.

Implementacin del Algoritmo de Prim FUNCION PRIM (G=(V,A)) conjunto de aristas. (Inicializacin) T= (Contendr las aristas del AGM que buscamos). B=un miembro arbitrario de V mientras B <> N hacer BUSCAR e=(u,v) de longitud mnima tal que u B y v V-B (v no pertenece a B) T=T + e B=B + v DEVOLVER(T)

17

Estructuras de Datos y Algoritmos I Ejemplo: Dado el siguiente grafo:

2 2 1 4 1 4 4 4 7 3 6 3 5 3

Aplique el algoritmo de Prim, partiendo desde el nodo 1. Paso ini 1 2 3 4 5 6 Seleccin (1,2) (2,3) (1,4) (4,5) (4,7) (7,6) Conjunto B {1} {1,2} {1,2,3} {1,2,3,4} {1,2,3,4,5} {1,2,3,4,5,7} {1,2,3,4,5,6,7}=N Conjunto T

{(1,2)} {(1,2),(2,3)} {(1,2),(2,3),(1,4)} {(1,2),(2,3),(1,4),(4,5)} {(1,2),(2,3),(1,4),(4,5),(4,7)} {(1,2),(2,3),(1,4),(4,5),(4,7),(7,6)}

El algoritmo de Prim requiere un tiempo de O(n2), como el algoritmo de Kruskal tiene un O(a log n), siendo a el nmero de aristas del grafo y n el nmero de vrtices. Es conveniente emplear Kruskal para grafos pocos densos (pocas aristas) y si el grafo es muy denso emplear Prim.

18