Title: A'E'D'1
1Tema 5. Grafos.
- 5.1. Introducción, notación y definiciones.
- 5.2. Representación de grafos.
- 5.3. Recorridos sobre grafos.
- 5.4. Árboles de expansión mínimos.
- 5.5. Problemas de caminos mínimos.
- 5.6. Algoritmos sobre grafos dirigidos.
- 5.7. Algoritmos sobre grafos no dirigidos.
- 5.8. Otros problemas con grafos.
-
25.1. Ejemplos de grafos.
- Ejemplo Grafo de carreteras entre ciudades.
35.1. Ejemplos de grafos.
- Ejemplo Grafo de carreteras entre ciudades.
- Problemas
- Cuál es el camino más corto de Murcia a Badajoz?
- Existen caminos entre todos los pares de
ciudades? - Cuál es la ciudad más lejana a Barcelona?
- Cuál es la ciudad más céntrica?
- Cuántos caminos distintos existen de Sevilla a
Zaragoza? - Cómo hacer un tour entre todas las ciudades en
el menor tiempo posible?
45.1. Ejemplos de grafos.
- Ejemplo Grafo de transiciones de un AFD.
55.1. Ejemplos de grafos.
- Ejemplo Grafo de transiciones de un AFD.
- Problemas
- La expresión a b b a b a b b b a, es una
expresión válida del lenguaje? - Cuál es la expresión válida más corta?
- Transformar el grafo en una expresión regular y
viceversa.
65.1. Ejemplos de grafos.
- Ejemplo Grafo asociado a un dibujo de líneas.
Escena
75.1. Ejemplos de grafos.
- Ejemplo Grafo de asociado a un dibujo de líneas.
- Problemas
- Cuántos grupos hay en la escena?
- Qué objetos están visibles en la escena y en qué
posiciones? - Qué correspondencia hay entre puntos del modelo
y de la escena observada? - Qué objetos son isomorfos?
85.1. Introducción y definiciones.
- Un grafo G es una tupla G (V, A), donde V es un
conjunto no vacío de vértices o nodos y A es un
conjunto de aristas o arcos. - Cada arista es un par (v, w), donde v, w ? V.
- Tipos de grafos
- Grafo no dirigido.Las aristas no están
ordenadas (v, w) (w, v) - Grafos dirigidos (o digrafos).Las aristas son
pares ordenadosltv, wgt ? ltw, vgt - ltv, wgt ? w cabeza de la arista, v cola.
95.1. Terminología de grafos.
- Nodos adyacentes a un nodo v todos los nodos
unidos a v mediante una arista. - En grafos dirigidos
- Nodos adyacentes a v todos los w con ltv, wgt ? A.
- Nodos adyacentes de v todos los u con ltu, vgt ?
A. - Un grafo está etiquetado si cada arista tiene
asociada una etiqueta o valor de cierto tipo. - Grafo con pesos grafo etiquetado con valores
numéricos. - Grafo etiquetado G (V, A, W), con W A ?
TipoEtiq
105.1. Terminología de grafos.
- Camino de un vértice w1 a wq es una secuencia
w1, w2, ..., wq ? V, tal que todas las aristas
(w1, w2), (w2, w3), ..., (wq-1, wq) ? A. - Longitud de un camino número de aristas del
camino nº de nodos -1. - Camino simple aquel en el que todos los vértices
son distintos (excepto el primero y el último que
pueden ser iguales). - Ciclo es un camino en el cual el primer y el
último vértice son iguales. En grafos no
dirigidos las aristas deben ser diferentes. - Se llama ciclo simple si el camino es simple.
115.1. Terminología de grafos.
- Un subgrafo de G(V, A) es un grafo G(V, A)
tal que V?V y A?A. - Dados dos vértices v, w, se dice que están
conectados si existe un camino de v a w. - Un grafo es conexo (o conectado) si hay un camino
entre cualquier par de vértices. - Si es un grafo dirigido, se llama fuertemente
conexo. - Un componente (fuertemente) conexo de un grafo G
es un subgrafo maximal (fuertemente) conexo.
125.1. Terminología de grafos.
- Un grafo es completo si existe una arista entre
cualquier par de vértices. - Para n nodos, cuántas aristas tendrá un grafo
completo (dirigido o no dirigido)? - Grado de un vértice v número de arcos que
inciden en él. - Para grafos dirigidos
- Grado de entrada de v nº de aristas con ltx, vgt
- Grado de salida de v nº de aristas con ltv, xgt
135.1. Operaciones elementales con grafos.
- Crear un grafo vacío (o con n vértices).
- Insertar un nodo o una arista.
- Eliminar un nodo o arista.
- Consultar si existe una arista (obtener la
etiqueta). - Iteradores sobre las aristas de un nodo
- para todo nodo w adyacente a v hacer
- acción sobre w
- para todo nodo w adyacente de v hacer
- acción sobre w
Mucho menos frecuente
145.2. Representación de grafos.
- Representación de grafos
- Representación del conjunto de nodos, V.
- Representación del conjunto de aristas, A.
- Ojo las aristas son relaciones muchos a muchos
entre nodos...
155.2. Representación de grafos.
- Representación del conjunto de aristas, A.
- Mediante matrices de adyacencia.
- Mediante listas de adyacencia.
165.2. Matrices de adyacencia.
- tipo GrafoNoEtiq array 1..n, 1..n de
booleano - Sea M de tipo GrafoNoEtiq, G (V, A).
- Mv, w cierto ? (v, w) ? A
- Grafo no dirigido ? Matriz simétrica Mi, j
Mj, i. - Resultado se desperdicia la mitad de la memoria.
175.2. Matrices de adyacencia.
- Grafos etiquetados
- tipo GrafoEtiqE array 1..n, 1..n de E
- El tipo E tiene un valor NULO, para el caso de no
existir arista.
- Cómo serían los iteradores para todo adyacente
a, y adyacente de? Y contar número de aristas? - Cuánto es el tiempo de ejecución?
185.2. Matrices de adyacencia.
- Uso de memoria
- k2 bytes/etiqueta
- Memoria usada k2n2
- Ventajas
- Representación y operaciones muy sencillas.
- Eficiente para el acceso a una arista dada.
- Inconvenientes
- El número de nodos del grafo no puede cambiar.
- Si hay muchos nodos y pocas aristas (altltn2) se
desperdicia mucha memoria (matriz escasa).
195.2. Listas de adyacencia.
- tipo Nodo entero (1..n)
- tipo GrafoNoEtiq array 1..n de ListaNodo
- Sea R de tipo GrafoNoEtiq, G (V, A).
- La lista Rv contiene los w tal que (v, w) ? A.
- Grafo no dirigido ? Las aristas están repetidas.
- Resultado también se desperdicia memoria.
205.2. Listas de adyacencia.
- Grafos etiquetados
- tipo GrafoEtiqE array 1..n de ListaNodo,E
- Cómo serían los iteradores para todo adyacente
a, y adyacente de? Y contar número de aristas? - Cuánto es el orden de complejidad? Se suponen n
nodos y a aristas.
215.2. Listas de adyacencia.
- Uso de memoria
- k1 bytes/puntero, k2 bytes/etiqueta o nodo
- Memoria usada k1(na) 2k2a
- Con matrices de adyacencia k2n2
- Cuál usa menos memoria?
- Ventajas
- Más adecuada cuando altltn2.
- Inconvenientes
- Representación más compleja.
- Es ineficiente para encontrar las aristas que
llegan a un nodo.
225.2. Listas múltiples de adyacencia.
- Alternativa Usar estructuras de listas
múltiples. - Lista de arcosde salida.
- Lista de arcosde entrada
registros de aristas
array de nodos
c
a
1
2
b
sig_ent valor sig_sal
3
lista_ent lista_sal
235.3. Recorridos sobre grafos.
- Idea similar al recorrido en un árbol.
- Se parte de un nodo dado y se visitan los
vértices del grafo de manera ordenada y
sistemática, moviéndose por las aristas. - Tipos de recorridos
- Búsqueda primero en profundidad. Equivalente a un
recorrido en preorden de un árbol. - Búsqueda primero en amplitud o anchura.
Equivalente a recorrer un árbol por niveles. - Los recorridos son una herramienta útil para
resolver muchos problemas sobre grafos.
245.3. Recorridos sobre grafos.
- El recorrido puede ser tanto para grafos
dirigidos como no dirigidos. - Es necesario llevar una cuenta de los nodos
visitados y no visitados. - var
- marca array 1, ..., n de (visitado,
noVisitado) - operación BorraMarcas
- para i 1, ..., n hacer
- marcai noVisitado
255.3. Búsqueda primero en profundidad.
operación bpp (v nodo) marcav
visitado para cada nodo w adyacente a v hacer
si marcaw noVisitado entonces bpp(w) f
inpara operación BúsquedaPrimeroEnProfundidad Bo
rraMarcas para v 1, ..., n hacer si
marcav noVisitado entonces bpp(v) finpara
265.3. Búsqueda primero en profundidad.
- El recorrido no es único depende del nodo
inicial y del orden de visita de los adyacentes. - El orden de visita de unos nodos a partir de
otros puede ser visto como un árbol árbol de
expansión en profundidad asociado al grafo. - Si aparecen varios árboles bosque de expansión
en profundidad. - Ejemplo.Grafonodirigido.
275.3. Búsqueda primero en profundidad.
- Bosque de expansión en profundidad
4
1
7º
1º
2º
2
5
8º
Arcos del árbol
7
6º
3º
6
9
9º
3
8
5º
4º
Arcos no del árbol
- Arcos no del árbol si marcav noVisitado ...
? se detectan cuando la condición es falsa.
285.3. Búsqueda primero en profundidad.
Bosque de expansión
b
2º
a
1º
Arco de retroceso
c
3º
Arco de cruce
Arco de avance
d
4º
e
5º
- Cuánto es el tiempo de ejecución de la BPP?
- Imposible predecir las llamadas en cada
ejecución. - Solución medir el trabajo total realizado.
295.3. Búsqueda primero en anchura (o amplitud).
- Búsqueda en anchura empezando en un nodo v
- Primero se visita v.
- Luego se visitan todos sus adyacentes.
- Luego los adyacentes de estos y así
sucesivamente. - El algoritmo utiliza una cola de vértices.
- Operaciones básicas
- Sacar un elemento de la cola.
- Añadir a la cola sus adyacentes no visitados.
- operación BúsquedaPrimeroEnAnchura
- BorraMarcas
- para v 1, ..., n hacer
- si marcav noVisitado entonces
- bpa(v)
305.3. Búsqueda primero en anchura (o amplitud).
- operación bpa (v Nodo)
- var C ColaNodo
- x, y Nodo
- marcav visitado
- InsertaCola (v, C)
- mientras NOT EsVacíaCola (C) hacer
- x FrenteCola (C)
- SuprimirCola (C)
- para cada nodo y adyacente a x hacer
- si marcay noVisitado entonces
- marcay visitado
- InsertaCola (y, C)
- finsi
- finpara
- finmientras
315.3. Búsqueda primero en anchura (o amplitud).
- Ejemplo.Grafo nodirigido.
- Bosque de expansión en anchura.
1
1º
4
7º
2
3
2º
3º
8º
9º
5
9
6
4º
7
5º
Arcos de cruce
8
6º
325.3. Búsqueda primero en anchura (o amplitud).
Bosque de expansión
b
2º
a
1º
4º
c
e
3º
d
5º
- Cuál es el tiempo de ejecución de la BPA?
- Cómo comprobar si un arco es de avance, cruce,
etc.? - Solución Construir el bosque explícitamente.
335.3. Recorridos sobre grafos.
- Construcción explícita del bosque de expansión
Usamos una estructura de punteros al padre. - marca array 1, ..., n de entero
- marcav vale -1 si v no está visitado
- 0 si está visitado y es raíz de un árbol
- En otro caso indicará cuál es el padre de v
- Modificar BorraMarcas, bpp y bpa, para construir
el bosque de expansión. - Arco de avance ltv, wgt w es descendiente de v en
uno de los árboles del bosque. - Arco de retroceso ltv, wgt v es descendiente de w.
- Arco de cruce ltv, wgt si no se cumple ninguna de
las anteriores.
345.3. Ejemplos de aplicación de los recorridos.
- Problema 1 Encontrar los componentes conexos de
un grafo no dirigido. - Problema 2 Prueba de aciclicidad. Dado un grafo
(dirigido o no dirigido) comprobar si tiene algún
ciclo o no.
355.3. Ejemplos de aplicación de los recorridos.
- Prueba de aciclicidad.
- Grafo no dirigido. Hacer una BPP (o BPA). Existe
algún ciclo si y sólo si aparece algún arco que
no es del árbol de expansión. - Grafo dirigido. Hacer una BPP (o BPA). Existe un
ciclo si y sólo si aparece algún arco de
retroceso. - Orden de complejidad de la prueba de aciclicidad
igual que los recorridos. - Con matrices de adyacencia O(n2).
- Con listas de adyacencia O(an).
365.4. Árboles de expansión mínimos.
- Definición Un árbol de expansión de un grafo
G(V, A) no dirigido y conexo es un
subgrafoG(V, A) conexo y sin ciclos. - Ejemplo los árboles de expansión en profundidad
y en anchura de un grafo. - En grafos con pesos, el coste del árbol de
expansión es la suma de los costes de las
aristas. - Problema del árbol de expansión de coste mínimo
- Dado un grafo ponderado no dirigido, encontrar
el árbol de expansión de menor coste.
375.4. Árboles de expansión mínimos.
2
3
2
6
1
3
4
5
5
6
- Problema conectar todos los ordenadores con el
menor coste total. - Solución algoritmos clásicos de Prim y Kruskal.
385.4. Algoritmo de Prim.
- Esquema
- Empezar en un vértice cualquiera v. El árbol
consta inicialmente sólo del nodo v. - Del resto de vértices, buscar el que esté más
próximo a v (es decir, con la arista (v, w) de
coste mínimo). Añadir w y la arista (v, w) al
árbol. - Buscar el vértice más próximo a cualquiera de
estos dos. Añadir ese vértice y la arista al
árbol de expansión. - Repetir sucesivamente hasta haber añadido los n
vértices.
395.4. Algoritmo de Prim.
- La solución se construye poco a poco, empezando
con una solución vacía. - Implícitamente, el algoritmo maneja los
conjuntos - V Vértices del grafo.
- U Vértices añadidos a la solución.
- V-U Vértices que quedan por añadir.
- Cómo implementar eficientemente la búsqueda
encontrar el vértice de V-U más próximo a alguno
de los de U?
405.4. Algoritmo de Prim.
- Para calcular el siguiente vértice a coger se
usan dos arrays - MAS_CERCANO Para cada vértice de V-U indica el
vértice de U que se encuentra más próximo. - MENOR_COSTO Indica el costo de la arista más
cercana (almacenada en el array anterior). - Estructura del algoritmo de Prim
- Inicialmente U1 ? MAS_CERCANOv 1.
MENOR_COSTOv C1, v - Suponemos que Cv, w (Matriz de costes)
contiene el coste de la arista (v, w) - Buscar el valor v, con valor MENOR_COSTO mínimo.
Asignarle un valor muy grande (para no volver a
cogerlo). - Recalcular los valores MAS_CERCANO y MENOR_COSTO
de los demás nodos. Para cada w, comprobar si
Cv, w es menor que MENOR_COSTOw. - Repetir los dos puntos anteriores hasta que se
hayan añadido los n vértices.
415.4. Algoritmo de Prim.
- Resultados del algoritmo
- Árbol de expansión las aristas serán los pares
(i, MAS_CERCANOi), para i 2, ..., n. - Costo del árbol de expansión Suma de los
MENOR_COSTOi, para i 2, ..., n (antes de
asignarles un valor grande). - Ejemplo. Mostrar la ejecución del algoritmo de
Prim para el siguiente grafo no dirigido.
5
1
1
4
4
1
1
6
5
2
2
5
3
5
3
4
4
2
2
6
6
6
3
3
6
5
5
- Cuál es el orden de complejidad del algoritmo?
425.4. Algoritmo de Kruskal.
- Dado un grafo ponderado G(V, A), el algoritmo
parte de un grafo G (V, Ø). Cada nodo es una
componente conexa en sí misma. - En cada paso de ejecución se elige la arista de
menor costo de A. - Si une dos nodos que pertenecen a distintas
componentes conexas entonces se añade al árbol de
expansión G. - En otro caso no se coge, ya que formaría un ciclo
en G. - Acabar cuando G sea conexo cuando tengamos n-1
aristas.
435.4. Algoritmo de Kruskal.
- Estructura del algoritmo de Kruskal
- Sea T de tipo Conjunto de aristas, el lugar donde
se guardarán las aristas del árbol de expansión.
Asignar Ø a T. - Mientras T contenga menos de n-1 aristas hacer
- Elegir la arista (v, w) de A con menor costo. Las
aristas deben estar ordenadas por coste. - Borrar (v, w) de A (para no volver a cogerla).
- Si v, w están en distintos componentes conexos
entonces añadir (v, w) a T. En otro caso,
descartar (v, w). Necesitamos operaciones para
saber si dos nodos están en la misma componente
conexa y para unir componentes.
445.4. Algoritmo de Kruskal.
5
1
1
4
1
4
4
1
1
6
5
2
2
5
3
3
5
3
4
4
2
2
2
6
6
6
6
3
6
3
5
5
5
- Relación dos nodos pertenecen a una componente
conexa es una relación binaria de equivalencia ?
podemos usar la estructura de representación para
relaciones de equivalencia (con operaciones
Inicia, Encuentra y Unión). - Cuál es el orden de complejidad del algoritmo?
455.5. Problemas de caminos mínimos.
- Definición Dado un grafo ponderado G (V, A)
(dirigido o no) y un camino w1, w2, ..., wq en G,
el costo del camino será la suma de los costos
asociados a las aristas (w1, w2), ..., (wq-1,
wq). - Si el grafo es no ponderado, normalmente el costo
se asocia con la longitud del camino. - Problema de los caminos más cortos por un origen
- Encontrar los caminos más cortos entre un nodo
origen dado a todos los demás nodos.
465.5. Algoritmo de Dijkstra.
- Supongamos un grafo ponderado G (con pesos ? 0) y
un nodo origen v. - El algoritmo trabaja con dos conjuntos
- S conjunto de nodos escogidos, para los cuales
se conoce el camino de distancia mínima al
origen. - C conjunto de nodos candidatos, pendientes de
calcular el camino mínimo. Conocemos los caminos
mínimos al origen pasando por nodos de S. - En cada paso coger del conjunto de candidatos el
nodo con distancia mínima al origen. Recalcular
los caminos de los demás candidatos pasando por
el nodo cogido. - Un camino especial del origen a otro nodo
cualquiera es un camino que sólo pasa por nodos
ya escogidos. - Supongamos que el nodo origen es el 1.
475.5. Algoritmo de Dijkstra.
- En un array D2, ..., N se guarda la longitud
del camino especial más corto a cada vértice.
Cuando todos los nodos estén en S, todos los
caminos son especiales y D contiene las
distancias mínimas al origen. - En otro array P2, ..., N se almacena el camino
por el que pasa cada nodo v. El camino de 1 a v
pasa por Pv. - Inicialmente D contendrá los caminos directos de
1 a los restantes nodos, es decir d1, x. Si no
existe la arista (1, x) el costo será ?.
- P contendrá el valor 1 (el camino es directo). S
contendrá sólo el nodo 1. - Buscar el nodo v de CV-S con mínimo valor de D.
Añadir v a S. Para el resto de nodos comprobar si
el camino al origen es más corto pasando por el
nodo v - si Dvdv, w lt Dw
- Dw Dv dv, w
- Pw v
-
485.5. Algoritmo de Dijkstra.
para i 2, ..., N Si FALSO Di d1,
i Pi 1 para i 1, ..., N-1 v vértice
con Dv mínimo y SvFALSO Sv
VERDADERO para cada nodo w adyacente a v
si SwFALSO si Dvdv, wltDw
Dw DvCv, w Pw
v
Operación ImprimeCamino (ventero) si v ! 1
ImprimirCamino(Pv) escribir v
495.5. Algoritmo de Dijkstra.
2
1
2
4
1
10
3
2
4
3
2
5
8
4
5
6
6
7
1
505.5. Algoritmo de Dijkstra, complejidad.
- Matrices de adyacencia
- Inicialización O(n).
- Ejecutar n-1 veces
- Buscar el elemento con Dv mínimo y Sv falso
O(n). - Actualizar los valores de los nodos candidatos
O(n). - En total tenemos O(n2).
- Listas de adyacencia
- Inicialización O(n).
- La actualización de los candidatos se limita a
los nodos que son adyacentes a v. En total la
actualización se hace O(a) veces. - La búsqueda del elemento sigue requiriendo O(n)
pasos, por lo que el orden total sería O(n2). - Modificación usar una estructura ordenada para
guardar los nodos candidatos (por ejemplo un
árbol binario). La búsqueda requiere O(log n) en
cada paso, en total O(nlog n). Además, en la
actualización un nodo podría cambiar de posición
en el árbol, luego requiere O(alog n). - En total, requiere O((an)log n).
- Esta modificación será adecuada cuando altltn2.
515.5. Caminos mínimos entre todos los vértices.
- Aplicando el algoritmo de Dijkstra n veces O(n3)
ó O((an)nlog n). - Algoritmo de Floyd
- Utiliza una matriz de adyacencia Dv, w, que
será la matriz de costos. - Inicialmente Dv, w contendrá los costos de las
aristas Cv, w. - En cada paso k, en la posición Dv, w estará la
longitud del camino óptimo que contiene nodos
sólo de los k primeros. - Al final del algoritmo, D almacenará los costos
de los caminos mínimos. - En el paso k, el nodo k actúa de pivote.
Calcular, para cada camino de v a w, si es más
corto pasando por k. - Dki, j min (Dk-1i, j, Dk-1i, k Dk-1k,
j), para todo i?j. - Dki, k min (Dk-1i, k, Dk-1i, k Dk-1k,
k) ? la fila y la columna k no varían en el paso
k, luego sólo necesitamos una matriz D.
525.5. Algoritmo de Floyd.
- operación Floyd (C array 1..N, 1..N de entero)
- var
- k, i, j entero
- D array 1..N, 1..N de entero
- para i 1, ..., N
- para j 1, ..., N
- Di, j Ci, j
- para k 1, ..., N k es el pivote
- para i 1, ..., N
- para j 1, ..., N
- Di, j min (Di, j, Di, k Dk, j)
- Tenemos los costos de los caminos mínimos, cómo
saber cuáles son los caminos?
8
2
1
2
3
2
3
5
535.5. Algoritmo de Floyd.
- Igual que en Dijkstra, una matriz P de NxN
almacena el camino. Pi, j0 si el camino es
directo. En otro caso, el camino de i a j pasa
por Pi, j. - si Di, k Dk, j lt Di, j
- Di, j Di, k Dk, j
- Pi, j k
- Para escribir el camino
- operación Camino (i, j integer)
- k Pi, j
- si k! 0
- Camino (i, k)
- escribir k
- Camino (k, j)
- Cuál es el orden de complejidad del algoritmo de
Floyd?
545.5. Cierre transitivo.
- Dada una matriz de adyacencia M de un grafo
dirigido, obtener una matriz A de valores
booleanos en la que Ai, j indica si existe o no
un camino de i a j. - Algoritmo de Warshall
- Es parecido al algoritmo de Floyd. En lugar de
enteros (costos) trabajamos con booleanos (existe
arista o no). - Inicialmente AM. En cada paso k Ai, j Ai,
j or (Ai, k and Ak, j).
555.6. Algoritmos sobre grafos dirigidos.
- Componentes fuertemente conexos
- Un componente conexo de un grafo G es un subgrafo
conexo (y maximal) de G. Es decir, contiene un
conjunto de vértices para los cuales existen
caminos entre cualquier par de nodos (v, w) y
(w,v). - Ejemplo. Grafo G no dirigido.
- Cálculo de componentes conexos en grafos no
dirigidos Realizar un recorrido en profundidad.
Cada árbol generado es un componente conexo. - Si el grafo es dirigido, entonces hablamos de
componentes fuertemente conexos. - En grafos dirigidos no es suficiente con realizar
una búsqueda primero en profundidad.
Componente conexo 2
Componente conexo 1
565.6. Componentes fuertemente conexos.
- Algoritmo para encontrar los componentes
fuertemente conexos de un grafo dirigido G. - 1. Realizar la búsqueda en profundidad de G,
numerando los vértices en el orden de terminación
de las llamadas recursivas (al final de bpp). - 2. Construir un nuevo grafo dirigido GR
invirtiendo las direcciones de los arcos. Para
todo ltv, wgt ? A(G), ltw, vgt ? A(GR). - 3. Realizar una búsqueda en profundidad en GR
partiendo del nodo con numeración más alta. Si en
el recorrido no se visitan todos los nodos,
iniciar la búsqueda en profundidad a partir del
nodo no visitado con numeración más alta. - 4. Cada árbol del bosque abarcador resultante es
un componente fuertemente conexo de G. - Ejemplo.
B
D
A
E
C
575.6. Componentes fuertemente conexos.
B
D
A
5
A
E
B
4
A
C
D
C
3
B
E
C
E
2
D
1
- Podemos representar las relaciones entre
componentes mediante un grafo reducido. - Grafo reducido de un grafo dirigido G es un
grafo dirigido en el que cada nodo representa un
componente fuertemente conexo de G, y existirá
una arista entre un nodo y otro si existe una
arista entre algunos de los nodos de los
componentes conexos de G correspondientes.
A, B, C
D, E
585.6. Grafos dirigidos acíclicos.
- Definición un grafo dirigido acíclico (GDA) es
un grafo dirigido y sin ciclos. - Ejemplos estructura de directorios (con
posibilidad de enlaces simbólicos),
representación de expresiones aritméticas (con
subexpresiones comunes), prerrequisitos para
realizar un curso, grafo de actividades para
planificación de tareas. - (AB)(DD(AB))
- Representación de órdenes parciales. Un orden
parcial en un conjunto S es una relación binaria
que cumple - Para cualquier elemento a de S, (a R a) es falso.
- Para cualquier a, b, c de S, si (a R b) y (b R c)
entonces (a R c). - Ejemplo. La relación de inclusión propia entre
conjuntos (?).
Paredes (4)
Techo (2)
Cimientos (3)
inicio
Jardín (2)
Fachada (2)
D
B
A
Comprar ventanas (5)
final
595.6. Ordenación topológica en grafos dirigidos
acíclicos.
- Recorrido en orden topológico es un tipo de
recorrido aplicable solamente a GDAs. Un vértice
sólo se visita después de haber sido visitados
todos sus predecesores en el grafo. - Este recorrido da lugar a una ordenación
topológica a cada nodo se le asigna un número
num_top(v), tal que si existe una arista lti, jgt
entonces num_top(i) lt num_top(j). En general
puede existir más de un orden válido. - Ejemplos
- El orden Cimientos, Paredes, Techo, Jardín,
Comprar ventanas, Fachada, es una posible
ordenación topológica del grafo de tareas. - En una expresión aritmética, el orden topológico
a la inversa, es el orden para evaluar el
resultado total de la expresión.
605.6. Ordenación topológica en grafos dirigidos
acíclicos.
- Implementación del recorrido en orden topológico.
- 1. Calcular los grados de entrada de todos los
nodos. - 2. Buscar un nodo v con grado de entrada 0 (es
decir sin predecesores, si no hay ninguno es
porque existe un ciclo). Marcarlo como visitado. - 3. Para todos los nodos adyacentes a v,
decrementar en 1 su grado de entrada. - 4. Repetir los pasos 2 y 3 hasta haber visitado
todos los nodos.
615.6. Algoritmos sobre grafos dirigidos.
- Grafos dirigidos acíclicos
operación OrdenTopológico(G grafo var num_top
array 1..N de enteros) var C Cola(nodo)
contador entero v, w nodo Anula
(C) contador 1 para cada nodo v si
GradoEntv 0 InsertaCola(v, C) mientras NO
EsVacíaCola(C) v FrenteCola(C)
SuprimirCola(C) num_topv contador
contador contador 1 para cada w
adyacente a v GradoEntw
GradoEntw-1 si GradoEntw 0
InsertaCola(v, C)
- Cuál es el orden de complejidad del algoritmo,
con matrices y listas de adyacencia?
625.6. Flujo máximo en redes.
- Supongamos un grafo dirigido G(V, A) con pesos
en las aristas. El peso de una arista C(v, w)
representa el número máximo de unidades que
pueden fluir desde el nodo v al w. - Por ejemplo C(v, w) puede ser la cantidad máxima
de agua que puede ir por una tubería que comunica
v con w, o el número de coches máximo que cabe en
una calle. - Problema de flujo máximo.
- Dado un nodo origen s y un nodo destino t en un
grafo dirigido con pesos, encontrar la cantidad
máxima de flujo que puede pasar de s a t.
2
2
b
b
d
d
2
2
3
3
4
s
1
s
t
1
t
0
3
3
3
2
2
2
c
a
c
a
- La suma de entradas para cada nodo interior debe
ser igual a la suma de salidas. - Los valores de flujo en cada arista no pueden
superar los valores máximos.
635.6. Flujo máximo en redes.
- Algoritmo para calcular el flujo máximo.
- 1. Inicializar un grafo de flujo Gf con los
mismos nodos y aristas de G, pero con pesos 0.
Este grafo guardará el resultado del algoritmo. - 2. Buscar un camino en G, desde s hasta t (camino
creciente). Sea m el valor mínimo de los costes
de las aristas por las que pasa el camino (por
este camino pueden fluir hasta m unidades de
flujo). - 3. Para cada arista (v, w) del camino, añadir al
costo de la arista correspon-diente en Gf el
valor m Cfv, w Cfv, w m. - 4. Decrementar el valor m en cada arista (v, w)
del camino, en el grafo G. Si la arista toma el
valor 0, eliminarla de G. - 5. Volver al paso 2 mientras sigan existiendo
caminos entre s y t en G. - Ejemplos
- Caso 1 (s, b, d, t) con m2 (s, a, c, t) con
m2 (s, a, d, t) con m1. FIN - Caso 2 (s, a, d, t) con m3. FIN
- El algoritmo no garantiza una solución óptima.
645.6. Flujo máximo en redes.
- Solución en el paso 4 añadir una arista ltw, vgt a
G con costo m (para permitir deshacer los
caminos).
655.7. Algoritmos en grafos no dirigidos.
- Puntos de articulación
- Definición un punto de articulación de un grafo
no dirigido G es un nodo v tal que cuando es
eliminado de G (junto con las aristas incidentes
en él) se divide un componente conexo del grafo
original en dos o más componentes conexos. - Ejemplo. Si el grafo representa una red de
ordenadores, un punto de articulación será un
nodo que si no funciona, hará que otros
ordenadores de la red queden incomunicados.
665.7. Componentes biconexos.
- Definición un grafo no dirigido se dice que es
biconexo si no tiene puntos de articulación. - Definición un grafo G tiene conectividad k si la
eliminación de k-1 nodos (con sus aristas) no
desconecta el grafo. - Un grafo es biconexo si y sólo si tiene
conectividad 2 o más. - El cálculo de los puntos de articulación se basa
en un recorrido en profundidad.
675.7. Algoritmos para localizar los puntos de
articulación.
- 1. Realizar una búsqueda primero en profundidad,
numerando los nodos en el orden en que son
recorridos. En el array numero_bpp1..N
guardamos el orden de cada nodo. - 2. En los puntos de terminación de las llamadas
recursivas de bpp (orden posterior) calcular los
valores bajov para cada nodo, según la fórmula - bajov mínimo (numero_bppv,
- numero_bppz tal que exista un arco de
retroceso (z, v), - bajo y para todo y hijo de v en el árbol
generado) - 3. La raíz es un punto de articulación si y sólo
si tiene dos o más hijos en el árbol abarcador en
profundidad. - 4. Un nodo v, distinto de la raíz, es un punto de
articulación si y sólo si tiene algún hijo w en
el árbol tal que bajow ? numero_bppv.
685.7. Puntos de articulación.
n_bppa 1 bajoa 1
a
n_bppb 2 bajob 1
n_bppc 5 bajoc 5
b
c
n_bppf 6 bajof 5
n_bppd 3 bajod 1
d
f
n_bppg 7 bajog 5
n_bppe 4 bajoe 1
e
g
- a es la raíz y tiene dos hijos ? a es un punto
de articulación - c tiene un hijo f tal que bajof5 ? n_bppc5
? c es un punto de articulación - bajov indica el menor valor de bpp alcanzable
desde v hasta algún descendiente y luego a través
de un arco de retroceso. - Si se cumple la condición del punto 4 (bajow ?
numero_bppv, para algún hijo w de v), si
eliminamos v entonces w y sus descendientes no
pueden alcanzar los nodos antecesores de v.
695.7. Circuitos de Euler.
- Un grafo no dirigido representa un dibujo de
líneas. Cada nodo del grafo representa un punto
del dibujo y una arista entre dos nodos indica
que existe una línea entre los dos puntos
correspondientes.
- Es posible dibujar estas figuras con un
bolígrafo, pintando cada línea una sola vez, sin
levantar el bolígrafo y acabando donde se empezó? - Circuito de Euler es un ciclo (no necesariamente
simple) que visita todas las aristas exactamente
una vez.
705.7. Circuitos de Euler.
- Condiciones necesarias para que exista un
circuito de Euler - El grafo debe ser conexo.
- Todos los nodos deben tener grado (número de
aristas) par, ya que el camino entra y sale de
los nodos. - Estas condiciones necesarias son también
suficientes. - Algoritmo para encontrar un circuito de Euler en
un grafo G, partiendo de un nodo v. - 1. Buscar un ciclo en G empezando por v (por
ejemplo con una búsqueda en profundidad). Puede
que no todas las aristas hayan sido visitadas. - 2. Si quedan aristas por visitar, seleccionar el
primer nodo w del ciclo anterior que tenga una
arista sin visitar. Buscar un ciclo partiendo de
w que pase por aristas no visitadas. - 3. Unir el ciclo del paso 1 con el obtenido en el
paso 2. Repetir sucesivamente los pasos 2 y 3
hasta que no queden aristas por visitar.
715.7. Circuitos de Euler.
1
- Ejemplo.
- Paso 1. Ciclo (1, 2, 5, 7, 6, 3, 1)
- Paso 2. Ciclo (2, 3, 4, 2)
- Paso 3. Ciclo (1, 2, 3, 4, 2, 5, 7, 6, 3, 1)
- Paso 2. Ciclo (4, 5, 6, 4)
-
- Paso 3. Ciclo (1, 2, 3, 4, 5, 6, 4, 2, 5, 7, 6,
3, 1)
3
2
4
6
5
1
7
3
2
4
6
5
1
3
7
2
4
6
5
1
7
3
2
4
6
5
7
725.8. Otros problemas con grafos.
- Problemas NP, de los que no se conocen algoritmos
eficientes para solucionarlos. - La solución se basa normalmente en una búsqueda
exhaustiva en el espacio de soluciones,
produciéndose explosión combinatoria. - Se puede encontrar solución aproximada por medio
de algoritmos heurísticos. - A partir de la solución inicial se puede realizar
una búsqueda local para intentar mejorar la
solución.
735.8. Problema del ciclo hamiltoniano.
- Dado un grafo no dirigido G, un ciclo
hamiltoniano es un ciclo simple que visita todos
los vértices. - Problema del ciclo hamiltoniano.
- Determinar si un grafo no dirigido dado tiene un
ciclo hamiltoniano. - Aunque el problema es muy parecido al del
circuito de Euler, no se conoce ningún algoritmo
para resolverlo en tiempo polinomial.
745.8. Problema del viajante.
- Dado un grafo no dirigido, completo y ponderado G
(V, A), encontrar un ciclo simple de costo
mínimo.
- Ejemplos Un repartidor de determinadas
mercancías tiene encargos en varias ciudades.
Qué ruta debe seguir para que el costo de
desplazamiento sea mínimo? - El problema del viajante es un problema
NP-completo, con un orden de complejidad
exponencial. No existe una solución polinómica. - Podemos aplicar heurísticas, obteniendo
soluciones aproximadas, no necesariamente óptimas.
755.8. Coloración de grafos.
- Un grafo no dirigido G representa elementos, y
una arista (v, w) representa una incompatibilidad
entre los elementos v y w. - La coloración de un grafo consiste en la
asignación de un color (o etiqueta) a cada nodo,
de forma que dos nodos incompatibles no tengan el
mismo color. - Problema de coloración de grafos
- Realizar una coloración del grafo utilizando un
número mínimo de colores. - Ejemplo. Un grafo se emplea para representar
trayectorias (en una intersec-ción de calles) e
incompatibilidades entre ellas. El objetivo es
diseñar un sistema de semáforos con un número
mínimo de estados. Cada estado será un color
resultante del algoritmo de coloración.
E
D
C
A
B
765.8. Isomorfismo de grafos.
- Comparación de grafos Dados dos grafos G(Vg,
Ag) y F(VF, AF), determinar si son iguales o no. - La comparación se puede realizar fácilmente,
comprobando si se cumple que Vg VF y Ag AF. - Isomorfismo de grafos Dos grafos G(Vg, Ag) y
F(VF, AF) se dice que son isomorfos si existe
una asignación de los nodos de Vg con los nodos
de VF tal que se respetan las aristas.
- El isomorfismo de grafos es también un problema
NP-completo, la solución consistiría básicamente
en comprobar todas las posibles asignaciones.