1
Tema 10- Grafos
Duración: 2 semanas aprox. Índice general:
1. Relaciones entre los Datos de una Colección 2. Conceptos básicos sobre Grafos
3. Representación de un Grafo: Matriz y Listas de Adyacencia
4. Implementación de un Grafo en Java: las clases
Arista,Verticey Grafo
5. Recorrido de un Grafo: ampliación de la clase Grafo
6. Caminos Mínimos en un Grafo sin y con Pesos (Dijkstra): la clase Java CaminosDelGrafo
Objetivos:
9 Estudio de la Representación de una Relación Binaria entre los Datos de una Colección mediante la estructura Grafo y algunas de sus aplicaciones más significativas. Ello permitirá recapitular y ampliar conceptos y estructuras que se han estudiado a lo largo del curso, como:
la ventaja de re-utilizar el Software que presenta la POO, al estudiar las posibles Representaciones de un Grafo (Modelos Diccionario y Lista Con Punto de Interés ) y la implementación de las operaciones de Recorrido y cálculo de caminos mínimos sobre él (Modelos Cola y Cola de Prioridad)
las características de las Representaciones Lineal, Jerárquica y No Lineal de los Datos de una Colección para, respectivamente, su Acceso Secuencial, su Recorrido en Profundidad y Anchura y la Búsqueda Dinámica
9 Implementación en Java de un Grafo, que supondrá el diseño de las clases Arista,Vertice,Grafoy CaminosDelGrafo (ubicadas en el paquete grafosde estructurasDeDatos)
3
Bibliografía básica:
9 Weiss, M.A. Estructuras de datos en Java. Adisson-Wesley, 2000.
• Capítulo 14, para conceptos sobre Grafos y Grafos Dirigidos • Capítulo 22, apartado 22.2.3 para el algoritmo de Dijkstra con
Montículos de Emparejamiento
9 Aho A.V., Hopcroft J.E., Ullman J.E. Estructuras de datos y
Algoritmos. Addison-Wesley, 1988. Capítulo 6 para conceptos sobre Grafos y Grafos Dirigidos
Sea un Colección cuyos Datos son: • ciudades
• aeropuertos
• computadores de una red • puntos del plano de una ciudad Queremos modelar
• rutas entre ciudades • rutas aéreas
• envío de correo electrónico • recorridos turísticos
• carreteras • vuelos • enlaces • calles
Relaciones entre los Datos de la Colección
1) Representación Lineal 2) Representación Jerárquica
35
5 Una RelaciónRsobre un ConjuntoSse define como un Conjunto de Pares(a, b): a, b∈ S
¾si (a, b)∈Rse escribe a R by denota que aestá Relacionado
con b
¾indica si cada Par de Datos del Conjunto están o no Relacionados
Relación Binaria entre los
Datos de la Colección 3) Grafo cuyos Vérticesse Relacionan vía Aristas
35
10
Relaciones entre los Datos de la Colección
6
9
Grafos Dirigidos y no Dirigidos
9
Grafos Etiquetados
9
Relaciones de Incidencia y Adyacencia
9
Caminos
7
Conceptos básicos sobre Grafos:
Grafos Dirigidos (Digrafos)
Un Grafo Dirigido (gd) es un Par G = (V,E)
9 V es un conjunto finito de Vértices (o Nodos o Puntos) 9 E es un conjunto de Aristas (o Arcos) dirigidas
Arista: Par ordenado de Vértices(u,v): u →v
1 2 3
5 6
4
Conceptos básicos sobre Grafos:
Grafos no Dirigidos (Grafos)
Un Grafo no Dirigido (gnd) es un Par G = (V,E) 9 V es un conjunto finito de Vértices
9 E es un conjunto de Aristas no Dirigidas
Arista: Par no ordenado de Vértices(u,v) = (v,u), u≠v : u v
1 2 3
5 6
9
Conceptos básicos sobre Grafos:
Grafos Etiquetados
9Un Grafo Etiquetado es un grafo G = (V,E) sobre el que se define una función f: E → A, dónde A es un conjunto cuyas componentes se llaman Etiquetas
NOTA: la función de etiquetado se puede definir también sobre V,el conjunto de Vértices
9Un Grafo Ponderado es un Grafo Etiquetado (sus Aristas) con números Reales (A ≡ ℜ)
Ejemplos:discútase la necesidad de etiquetar/ponderar los Grafos asociados a las aplicaciones reseñadas en el primer punto del tema
10
Conceptos básicos sobre Grafos:
Relaciones de Incidencia
Sea G = (V,E) un Grafo Dirigido. Si (u,v)∈E, decimos que Incide desdeu(sale de ..) e Incide env(llega a ..)
1 2 3
5 6
4
Sea G = (V,E) un Grafo no Dirigido. Si (u,v)∈E, decimos que Incide sobreuy v
1 2 3
5 6
11
1 2 3
5 6
4
Sea G = (V,E) un Grafo. Si (u,v)∈E, decimos que el Vértice ves Adyacente al Vérticeu
En un Grafo no Dirigido la relación es simétrica
1 2 3
5 6
4
Conceptos básicos sobre Grafos:
Relaciones de Adyacencia
Conceptos básicos sobre Grafos:
Grado de un Vértice
1 2 3
5 6
4
El Grado de un Vértice en un Grafo no Dirigido es el número de Aristas que Inciden sobre él
El Grado de un Vértice en un Grafo Dirigido es la suma de: • el número de Aristas que salen de él (Grado de Salida) • el número de Aristas que entran en él (Grado de Entrada)
1 2 3
5 6
4
13
1 2 3
5 6
4
El Grado de un Grafo es el de su Vértice de máximo Grado
Conceptos básicos sobre Grafos:
Grado de un Grafo
14
Conceptos básicos sobre Grafos:
Caminos
9 Un Camino de longitud k desdeua u’en un grafo G=(V,E) es una secuencia de Vértices〈v0,v1,..,vk〉 tal que:
•
vo= uy vk= u’• ∀ i : 1..k : (vi-1,vi) ∈E
• la longitud k del Camino es el número de Aristas
• la longitud del Camino con Pesos es la suma de los Pesos de las Aristas que forman el Camino
9 Si hay un CaminoPdesde u hasta u’, decimos que u’es alcanzable desde u vía P
1 2 3
5 6
15
Conceptos básicos sobre Grafos:
Caminos Simples y Ciclos
9 Un Camino es Simple si todos sus Vértices son distintos 9 En un Grafo Dirigido un Camino〈v0,v1,..,vk〉forma un Ciclo si:
•vo= vk
• el Camino contiene al menos una Arista
9 El Ciclo es Simple si todos sus Vértices son distintos 9 Un Bucle es un Camino de longitud1
9 Un Grafo Dirigido es Acíclico si no contiene Ciclos (GDA)
1 2 3
5 6
4
9 En un Grafo no Dirigido un Camino〈v0,v1,..,vk〉 forma un Ciclo si: •vo= vk
• si todos los vison distintos
9 Un Grafo no Dirigido es Acíclico si no contiene Ciclos
1 2 3
5 6
4
Conceptos básicos sobre Grafos:
Caminos Simples y Ciclos
Ejemplo:sea G = (V,E) un Grafo Dirigido con Pesos V={v0,v1, v2, v3, v4, v5, v6}, 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) } Se pide: 1.- |V| y |E|
2.- Vértices adyacentes a cada vi 3.- Grado de cada vi y del Grafo
4.- Caminos desde v0 al resto de Vértices, su longitud con y sin Pesos 5.- Vértices alcanzables desde v0
6.- Caminos mínimos desde v0 al resto de Vértices 7.- ¿Tiene ciclos? 18 0 1 2 3 4 5 0 1 2 3 4 5
Representación de un Grafo:
Matriz de Adyacencia
0 1 2 4 5 3 false false false false false false false true false false false false false false false false false false false false false truefalse false false false false true true
false false false true
Un Grafo G=(V,E) se representa con una Matriz de|V|x|V| boolean:
si (u,v) ∈ E, G[u,v] = true; sino G[u,v] = false
true true true true 9Memoria: O(|V|2)
19 0 1 2 3 4 5 0 1 2 3 4 5 true false false false false
true false false false false true true 0 1 2 4 5 3 true true true true false flase false false false false false false false false false false false false false false false false false false
Un Grafo G=(V,E) se representa con una Matriz de|V|x|V| boolean:
si (u,v) ∈ E, G[u,v] = true, sino G[u,v] = false
Representación de un Grafo:
Matriz de Adyacencia
0 1 2
4 5
3
Un Grafo G=(V,E) se representa con un arrayde|V|Listas de Vértices:G[v], v ∈ V, es una Lista de los Vértices Adyacentes a v 9 Memoria: O(|V|+|E|)
9Tiempo de acceso: O(Grado de G)
X 1 |X 1 | 3 | 4 |X 4 |X 3 |X 2 |X 0 | 0 1 2 3 4 5
Representaciones de un Grafo:
Listas de Adyacencia
21
Ejemplo propuesto:
representar los
siguientes Grafos
22
0 1 2
4 5
3
GrafoV0representa un Grafo
•de Vértices sin Etiquetar, i.e. de tipo int •de Aristas sin Pesos, i.e. Pares de int
mediante Listas de Adyacencia (arrayde|V|Listas de Vértices)
Implementación de un Grafo en Java:
la clase GrafoV0
X 1 |X 1 | 3 | 4 |X 4 |X 3 |X 2 |X 0 | 0 1 2 3 4 523 package grafos;
import modelos.*; import lineales.*; public class GrafoV0 {
/**Representa un Grafo Básico mediante Listas de Adyacencia
*i.e. como unarrayde|V|Listas Con PI de Integer */
protected ListaConPI elArray[]; public GrafoV0(intnumVertices){...}
publicvoidinsertarArista(intorigen, intdestino){...} public String toString(){...}
}
Implementación de un Grafo en Java:
la clase GrafoV0
package grafos;
import modelos.*; import lineales.*; public class GrafoV0 {
protected ListaConPI elArray[]; public GrafoV0(intnumVertices){ }
publicvoidinsertarArista(intorigen, intdestino){
}
public String toString() {
}
elArray = newListaConPI[numVertices];
for ( int i=0; i numVertices; i++ )elArray[i] = newLEIListaConPI();
La clase GrafoV0
elArray[origen].inicio();
elArray[origen].insertar(newInteger(destino)); String res = “”;
for ( int i = 0; i < elArray.length; i++ )
if ( elArray[i].esVacia())res += “Vértice ”+i+“ sin Adyacentes”;
elseres += “Vértice ”+i+“ con Adyacentes”+elArray[i].toString();
Ejemplo propuesto:
escríbase un programa cuya salida sea
la que se muestra a continuación y dibújese el Grafo leído.
Indique el número de Vértices del Grafo: 6
Grafo inicializado:
Vértice 0 sin Adyacentes Vértice 1 sin Adyacentes Vértice 2 sin Adyacentes Vértice 3 sin Adyacentes Vértice 4 sin Adyacentes Vértice 5 sin Adyacentes
Introduzca Arista (Par de Vértices separados por blancos): 0 1 0 4 1 0 1 4 2 5 4 0 4 1 5 2 Grafo construido:
Vértice 0 con Adyacentes 4 1 Vértice 1 con Adyacentes 4 0 Vértice 2 con Adyacentes 5 Vértice 3 sin Adyacentes Vértice 4 con Adyacentes 1 0 Vértice 5 con Adyacentes 2
0 1 2 4 5 3 26 0 1 2 4 5 3
GrafoV1representa un Grafo
• de Vértices sin Etiquetar, i.e. de tipo int
• de Aristas con Pesos, Tripletes de int(origen, destino, coste) mediante Listas de Adyacencia (arrayde|V|Listas de Vértices)
7 7 7 3 3 3 8 2 (1,3)|X (1,2)| (3,8)| (4,7)|X (4,7)|X (3,3)|X (2,7)|X (0,7)| X 0 1 2 3 4 5
Implementación de un Grafo Ponderado en
Java: la clase GrafoV1
27
La clase Java Arista
package grafos; class Arista {
intdestino; intcoste;
Arista(intd, intc){ destino = d; coste = c;}
public String toString(){ returndestino + “(”+ coste+ “)”; } }
package grafos;
import modelos.*; import lineales.*; public class GrafoV1 {
protected ListaConPI elArray[]; public GrafoV1(intnumVertices){...}
publicvoidinsertarArista(intorigen, intdestino, intcoste){
}
public String toString(){...} }
La clase GrafoV1
elArray[origen].inicio();
29
Grafo representa un Grafo
• de Vértices con Etiquetas, i.e. Pares (etiqueta, nº vértice)
• de Aristas con Pesos, i.e. Tripletes de int
mediante Listas de Adyacencia ( arrayde |V|Vértices)
7 7 7 3 3 3 8 2 v2 v5 v0 v1 v3 v4 (v0, ) (v1, ) (v2,x) (v3, ) (v4, ) (v5, ) (1,3)|X (1,2)| (3,8)| (4,7)|X (4,7)|X (3,3)|X (2,7)|X (0,7)| 0 1 2 3 4 5
Implementación de un Grafo Ponderado
con Vértices Etiquetados en Java:
la clase Grafo
La clase Java Vertice
package grafos;
import modelos.*; import lineales.*; class Vertice {
String nombre; int codigo; ListaConPI listaAdy;
Vertice(String n){ this(n, -1);} Vertice(String n, int c){
nombre = n; codigo = c; listaAdy = newLEIListaConPI(); }
}
¿ Cómoobtener codigode un Vértice a partir de su nombre ?
Al insertar un Vértice en un Grafo se actualiza unDiccionario de Vértices con una nueva Entradatal que suclave== nombrey sucodigo== ordenInsercionVertice
31
Ejemplo:
inserción de una Arista, Par de Vértices, en
Grafo
D C 10 Diccionario de Vértice’s
...
....
D Vértice 0: D, ¿? buscar(D) Grafo (vacío)|V| = 0Ejemplo:
inserción de una Arista, Par de Vértices, en
Grafo
D C 10 Diccionario de Vértice’s
...
....
D D, ¿? buscar(D) ElementoNoEncontrado 0 Vértice 0: Grafo (vacío)|V| = 033
Ejemplo:
inserción de una Arista, Par de Vértices, en
Grafo
D C 10 Diccionario de Vértice’s
...
....
D, 0 D, 0 insertar((D, 0)) Vértice 1: 0 D Grafo |V| = 01 34Ejemplo:
inserción de una Arista, Par de Vértices, en
Grafo
D C 10 Diccionario de Vértice’s
...
....
C C, ¿? buscar(C) ElementoNoEncontrado 1 Vértice 2: D, 0 0 D Grafo |V| = 135
Ejemplo:
inserción de una Arista, Par de Vértices, en
Grafo
D C 10 Diccionario de Vértice’s
...
....
C, 1 insertar((C, 1)) Vértice 2: D, 0 0 D Grafo |V| = 1 C, 1 2 1 C 10 10Ejemplo:
inserción de una Arista, Par de Vértices, en
Grafo
D B 23 Diccionario de Vértice’s
...
....
D, 0 0 D Grafo |V| = 2 C, 1 1 C 10 D D, ¿? buscar(D) ElementoDuplicado 0 Vértice 3:37 package grafos;
import modelos.*; import excepciones.*; import lineales.*; import noLineales.*; public class Grafo {
protected Vertice elArray[]; public Grafo(intnumVertices){...}
publicvoidinsertarArista(String nO, String nD, intcoste){...} public String toString(){...}
protected Diccionario dicVertices; protectedint ordenInsercionVertice;
public intinsertarVertice(String nO){...} }
La clase Grafo
public Grafo(intnumVertices){
}
public String toString() {
}
public voidinsertarArista(String nO, String nD, intcoste){
}
39 public intinsertarVertice(String nombreVertice) {
intres = -1;
Vertice v = newVertice(nombreVertice);
try {res = ((Vertice)dicVertices.buscar(v)).codigo; } catch(ElementoNoEncontrado e){
res = v.codigo = ordenInsercionVertice;
try {dicVertices.insertar(v); }catch(ElementoDuplicado ed){;}
elArray[res] = v; ordenInsercionVertice++; } returnres; }
La clase Grafo
Ejemplo propuesto:
definir el método
toString
en
Grafo
de
forma que se muestren siempre los Vértices mediante sus
etiquetas, y no con la representación numérica interna
41 9 Método constructor para crear un Grafo a partir de la
información de Aristas/Vértices leída desde un fichero
9 Método para consultar el número total de Aristas de un Grafo 9 Método para consultar el Grado de un Vértice dado de un Grafo
(Grado de Salida si el Grafo es Dirigido)
9 Método para consultar el Grado de un Grafo (Grado de Salida si el Grafo es Dirigido)
9 Método para consultar si un Grafo está Vacío
9 Método para consultar si una Arista dada pertenece a un Grafo