algoritmos y estructuras de datos iii

Anuncio
OBJETIVOS
] Definiciones formales de grafo y conceptos relacionados
] Estructuras de datos para representar grafos
] Algoritmos para resolver diferentes variantes del problema de
encontrar el camino mínimo sobre un grafo
] Algoritmos para resolver el problema de encontrar el árbol de
extensión de coste mínimo sobre un grafo
Tema 9: GRAFOS
Primera Parte
Estructuras de Datos y Algoritmos
Curso 2002/03
Grafos. EDA. Curso 2002/03
ÍNDICE
]
]
]
]
]
]
BIBLIOGRAFÍA
1. Introducción
2. Conceptos Básicos
3. Implementación de grafos
4. Recorridos de grafos
5. Búsqueda del camino con peso mínimo: algoritmo de Dijkstra
6. Otros problemas de caminos en GAD
\ Ordenación topológica
\ Búsqueda de caminos mínimos
] 7. Problema de obtención de árboles de extensión sobre grafos
no dirigidos
\ Algoritmos de Prim y Kruskal
Grafos. EDA. Curso 2002/03
2
Básica:
] Weiss, M.A. Estructuras de datos en Java. Adisson-Wesley, 2000.
\ Capítulos 14 y 23
Otros:
] T.H. Cormen, C.E. Leiserson, R.L. Rivest. Introduction to Algorithms. MIT
Press, 1990.
\ Capítulos 5 y 23.
] Aho A.V., Hopcroft J.E., Ullman J.E. Estructuras de datos y Algoritmos.
Addison-Wesley, 1988.
\ Capítulos 6 y 7.
3
Grafos. EDA. Curso 2002/03
4
CONCEPTOS BÁSICOS
1. INTRODUCCIÓN
] Un grafo permite representar relaciones binarias entre los
elementos de un conjunto.
Ejemplos:
]
]
]
]
]
]
]
•Rutas de transporte
•Envío de correo electrónico
25
18
35
30
21
49
Grafos dirigidos y no dirigidos
Grafos etiquetados
Relaciones de incidencia y adyacencia
Caminos
Subgrafos
Conectividad
Árboles y Grafos
25
23
39
Grafos. EDA. Curso 2002/03
Grafos. EDA. Curso 2002/03
5
Grafos Dirigidos (DiGrafos)
Grafos no dirigidos
] Un grafo dirigido (g.d.) es un par G=(V,E)
] Un grafo no dirigido (G.N.D) es un par G=(V,E)
\ V es un conjunto finito de vértices (nodos)
\ E es un conjunto de arcos (o aristas). Un arco es un par
ordenado(u,v) con u,v∈V
1
4
2
5
3
V={1,2,3,4,5,6}
6
E={(1,2),(2,2),(2,4),(2,5),(4,1),
(4,5),(5,4),(6,3)}
Grafos. EDA. Curso 2002/03
6
\ V es un conjunto finito de vértices (nodos)
\ E es un conjunto de arcos (aristas). Un arco es un par NO ordenado
(u,v) con u,v∈V, u≠v
1
2
3
V={1,2,3,4,5,6}
E={(1,2),(1,5),(2,5),(3,6)}
4
7
5
6
Grafos. EDA. Curso 2002/03
8
Grafos Etiquetados
Relaciones de Incidencia y Adyacencia
] Un 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.
] Un grafo ponderado (o con pesos o costes) es un grafo
etiquetado con números reales (A≡ℜ)
Grafos. EDA. Curso 2002/03
Ejemplo: vértice 2
1
2
3
4
5
6
Grafos. EDA. Curso 2002/03
9
Relaciones de Incidencia y Adyacencia (cont.)
10
Relaciones de Incidencia y Adyacencia (cont.)
] Sea G=(V,E) un grafo no dirigido. Si (u,v)∈E, decimos que incide
sobre u y v.
]
] Sea G=(V,E) un grafo dirigido. Si (u,v)∈E, decimos que incide
desde u (sale de..) e incide en v (llega a..).
Ejemplo: vértice 2
] Sea G=(V,E) un grafo. Si (u,v)∈E, decimos que el vértice v es
adyacente al u.
\ La relación es simétrica en grafos no dirigidos
2 es adyacente a 1
1 NO es adyacente a 2
2 es adyacente a 1
1 es adyacente a 2
1
2
3
1
2
3
1
2
3
4
5
6
4
5
6
4
5
6
Grafos. EDA. Curso 2002/03
11
Grafos. EDA. Curso 2002/03
12
Relaciones de Incidencia y Adyacencia (cont.)
] Llamaremos grado de un vértice en un g.n.d. al nº de arcos que
inciden sobre él.
1
2
3
4
5
6
13
Relaciones de Incidencia y Adyacencia (cont.)
2
3
4
5
6
1
2
3
4
5
6
Grafos. EDA. Curso 2002/03
14
Caminos
] Un camino de longitud k desde u a u’ en un grafo G=(V,E) es
una secuencia de vértices ⟨v0,v1,..,vk⟩ tal que vo=u y vk=u’ y
∀i:1..k:(vi-1,vi)∈E. La longitud del camino es el número de arcos.
] La longitud del camino con pesos es la suma d elos costes de las
aristas que forman el camino
] Si hay un camino P desde u hasta u’, decimos que u’ es
alcanzable desde u via P.
] El grado de un grafo es el del vértice de máximo grado.
1
] El grado de un vértice en un g.d. es el nº de arcos que salen de
él (grado de salida) más el nº de arcos que entran (grado de
entrada).
Grado de entrada del 2=2, Grado de salida del 2 =3
Grado de 2=5
El grado de 2 es 2
Grafos. EDA. Curso 2002/03
Relaciones de Incidencia y Adyacencia (cont.)
El grado de este grafo es 5
Grafos. EDA. Curso 2002/03
15
Grafos. EDA. Curso 2002/03
16
Caminos (cont.)
Caminos (cont.)
] Un camino es simple si todos sus vértices son distintos.
] En un g.d. un camino <v0,v1,..,vk> forma un ciclo si v0=vk y el
camino contiene al menos un arco.
\ El ciclo es simple si los vértices son distintos
\ Un bucle es un ciclo de longitud 1
1
2
3
4
5
6
1
2
3
4
5
6
<1,2,5,4> es un camino simple de longitud 3
<2,5,4,5> no es un camino simple
Grafos. EDA. Curso 2002/03
<1,2,5,4> es un ciclo
Grafos. EDA. Curso 2002/03
17
Caminos (cont.)
18
Ejercicio
]
] En un g.n.d. un camino <v0,v1,..,vk> forma un ciclo si v0=vk y
los vi son distintos.
] Un grafo sin ciclos diremos que es acíclico (GDA)
Sea G = (V,E) un Grafo dirigido con pesos
V={v0,v1, v2, v3, v4, v6, 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 y su longitud con pesos
5.- Vértices alcanzables desde v0
6.- Caminos mínimos desde v0 al resto de Vértices
7.- ¿Tiene ciclos?
Grafos. EDA. Curso 2002/03
19
Grafos. EDA. Curso 2002/03
20
Subgrafos
Conectividad de un grafo
] Un grafo G’=(V’,E’) es un subgrafo de G=(V,E) si V’⊆V y E’⊆E.
] Dado un conjunto V’⊆V, el subgrafo de G inducido por V’ es
] Un g.n.d. es conexo si cualquier par de vértices están
conectados por un camino. Las componentes conexas de un
grafo son las clases de equivalencia en V definidas por la
relación “es alcanzable desde..”
G’=(V’,E’):E’={(u,v)∈E:u,v∈V’}
Ejemplo: subgrafo inducido por {1,2,3,6}
1
2
3
4
5
6
1
2
1
2
3
4
5
6
3
6
Grafos. EDA. Curso 2002/03
Grafos. EDA. Curso 2002/03
21
22
Árboles
Conectividad de un grafo (cont.)
] Un g.d. es fuertemente conexo si cualquier vértice es
alcanzable desde cualquier otro. Las componentes
fuertemente conexas de un grafo son las clases de
equivalencia en V definidas por la relación “son mutuamente
] Un bosque es un grafo acíclico no dirigido.
] Un grafo acíclico, no dirigido y conexo es un árbol (libre).
(libre)
alcanzables”
1
2
3
4
5
6
(a) Árbol
Grafos. EDA. Curso 2002/03
23
(b) Bosque
(c) Grafo
Grafos. EDA. Curso 2002/03
24
Árboles
Árboles con raíz
] Un Árbol con raíz es un árbol con un vértice distinguido
denominado raíz.
] Teorema: Sea G=(V,E) un g.n.d. Las siguientes afirmaciones
son equivalentes:
\ G es un árbol (libre)
\ Cualquier par de vértices en G están conectados por un único camino
simple
\ G es conexo y |E|=|V|-1
\ G es acíclico pero si añadimos un arco a E, el grafo resultante
contiene un ciclo
7
3
8
Dem. Pág. 91-93 [Cormen,90]
6
10
12
5
4
11
2
1
9
Grafos. EDA. Curso 2002/03
25
Árbol de recubrimiento de un gnd
4
a
11
8
h
7
8
7
c
2
i
4
g
d
] Listas de Adyacencia:
Adyacencia Un grafo G=(V,E) se representa como un vector
de listas de vértices indexado por vértices. G[v] es una lista de los vértices
emergentes y/o incidentes de/a v∈V.
\ Memoria: O(|V|+|E|)
\ Tiempo de acceso: O(Grado(G))
] Matriz de Adyacencias:
Adyacencias Un grafo G=(V,E) se representa como una
9
e
14
f
26
2. REPRESENTACIÓN DE GRAFOS
] Un árbol de recubrimiento del grafo G=(V,E) es un árbol libre
T=(V’,E’) tal que V’=V y E’ ⊆E
] Ejemplo:
b
Grafos. EDA. Curso 2002/03
matriz indexada por vértices de booleanos. La componente G[u,v] es true si
(u,v)∈E, sino G[u,v]=false.
\ Memoria: O(|V|2)
\ Tiempo de acceso: O(1)
Peso total=37
10
Grafos. EDA. Curso 2002/03
27
Grafos. EDA. Curso 2002/03
28
Ejemplos
Implementación de grafos
] Basada en listas de adyacencia:
\ Implementación básica:
[ Grafos sin pesos
[ Vértices numerados desde 0 hasta |V|-1
\ Implementación de grafos ponderados
[ La clase Arista
\ Los vértices no están numerados desde 0 hasta |V|-1
[ Utilización de un diccionario (tabla hash)
[ La clase Vertice
Grafos. EDA. Curso 2002/03
Grafos. EDA. Curso 2002/03
29
Implementación básica
Programa de prueba
public class Grafo {
private static final int TAMANYO_INICIAL=10;
private Lista tabla [];
private int numVertices;
public Grafo() {
numVertices=0; tabla=new Lista[TAMANYO_INICIAL];
}
public void insArista (int orig, int dest) {
if (tabla[orig]==null) tabla[orig]=new Lista();
tabla[orig].insertar(new Integer(dest));
}
public String toString() {
String s="";
for (int i=0; i<TAMANYO_INICIAL; i++)
if (tabla[i]!=null) s+="Or:"+i+"Ady="+tabla[i].toString()+"\n";
return s;
}
}
Grafos. EDA. Curso 2002/03
30
31
public class pruebaGrafo {
public static void main (String args[]) {
BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
Grafo GM=new Grafo();
System.out.println("Escribe pares de vértices separados por blancos:");
try {
String linea=in.readLine();
while (linea.length()!=0){
StringTokenizer st=new StringTokenizer(linea);
int orig=Integer.parseInt(st.nextToken());
int dest=Integer.parseInt(st.nextToken());
GM.insArista(orig,dest);
linea=in.readLine();
}
}catch (IOException e) {}
System.out.println("Grafo leído:");
System.out.println(GM.toString());
}
}
Grafos. EDA. Curso 2002/03
32
Ejemplo de ejecución
Ejercicio 1
] Definir los siguientes métodos en la clase Grafo:
Escribe pares de vértices separados por blancos:
1
1
2
3
3
4
5
6
\ Método constructor para crear el grafo a partir de la información de
arcos leída desde un fichero
\ Método para consultar el número total de arcos de un grafo
\ Método para consultar el grado de un vértice dado (grado de salida si el
grafo es dirigido)
\ Método para consultar el grado del grafo (grado de salida si el grafo es
dirigido)
\ Método para comprobar si el grafo está vacío
\ Método para comprobar si un determinado arco pertenece al grafo
2
4
5
5
6
2
4
6
Grafo leído:
Orig:1
Orig:2
Orig:3
Orig:4
Orig:5
Orig:6
Ady=
Ady=
Ady=
Ady=
Ady=
Ady=
4 2
5
6 5
2
4
6
Grafos. EDA. Curso 2002/03
Grafos. EDA. Curso 2002/03
33
Implementación de un grafo ponderado
La clase Arista
public class Grafo {
private static final int TAMANYO_INICIAL=10;
private Lista tabla [];
private int numVertices;
public Grafo() {
numVertices=0; tabla=new Lista[TAMANYO_INICIAL];
}
public void insArista (int orig, int dest, int coste) {
if (tabla[orig]==null) tabla[orig]=new Lista();
tabla[orig].insertar(new Arista(dest,coste));
}
public String toString() {
String s="";
for (int i=0; i<TAMANYO_INICIAL; i++)
if (tabla[i]!=null) s+="Or:"+i+"Ady="+tabla[i].toString()+"\n";
return s;
}
}
Grafos. EDA. Curso 2002/03
34
35
public class Arista {
// atributos: el vértice destino y el coste del arco
private int dest;
private int coste;
public Arista(int v, int c) {
dest=v;coste=c;
}
public String toString(){
return dest+“ ("+coste+")";
}
}
Grafos. EDA. Curso 2002/03
36
Implementación de grafos en Java
Los nombres de los vértices...
] En general, los vértices tendrán nombres asociados,
típicamente cadenas de caracteres:
] La clase Grafo
] La clase Arista
] La clase Vértice
Grafo
Es un
vector
de...
\ Se mantendrá una tabla hash con la codificación de cada vértice
\ Los códigos se asignan internamente con valores entre 0 y el número de
vértices menos 1, conforme se va leyendo el grafo
Vértices
Tiene
una
lista
de...
Grafos. EDA. Curso 2002/03
Ejemplo:
D C 10
A B 12
D B 23
A D 87
E D 43
B E 11
C A 19
Aristas
DICCIONARIO
D
0
C
1
A
2
B
3
E
4
Grafos. EDA. Curso 2002/03
37
La implementación del diccionario
38
La clase Vertice
class ElementoHash implements Hashable {
public class Vertice {
String nombre; //el nombre del vértice
Lista ady; // la lista de vértices adyacentes (aristas)
String nombre;
int codigo;
public ElementoHash (String nom) {
nombre=nom;
}
public int hash () {
return ExploracionTablaCuadratica.hash(nombre);
}
public boolean equals (Object x) {
return nombre.equals( ((ElementoHash)x).nombre );
}
public Vertice(String v) {
nombre=v;
ady=new Lista();
}
public String toString() {
return ady.toString();
}
}
}
Grafos. EDA. Curso 2002/03
39
Grafos. EDA. Curso 2002/03
40
La clase Grafo
El método constructor de Grafo
public class Grafo {
private
private
private
private
public Grafo() {
numVertices=0;
static final int TAMANYO_INICIAL=10;
Vertice tabla [];
int numVertices;
TablaHash diccio;
tabla=new Vertice[TAMANYO_INICIAL];
diccio=new ExploracionTablaCuadratica();
}
public Grafo() { ... }
public insArista (String orig,String dest,int cost) { ... }
public String toString() { ... }
}
Grafos. EDA. Curso 2002/03
Grafos. EDA. Curso 2002/03
41
La operación insArista
42
La codificación de los vértices
private int insNodo (String nomVertice) {
ElementoHash aux = new ElementoHash(nomVertice);
ElementoHash res;
try {
res= (ElementoHash) diccio.buscar(aux);
return res.codigo; //Si ya está en el diccionario devolvemos su código
}catch (ElementoNoEncontrado e) {
public void insArista (String orig, String dest, int cost) {
int codOrig=insNodo(orig);
int codDest=insNodo(dest);
Lista aux=tabla[codOrig].ady;
aux.insertar(new Arista(codDest,cost));
}
// Si no está, la añadimos al diccionario e incrementamos numVertices
// Si fuera necesario se duplica la tabla de vértices
aux.codigo=numVertices;
diccio.insertar(aux);
if (numVertices==tabla.length)
duplicarvectorTabla();
tabla[numVertices]=new Vertice(aux.nombre);
return numVertices++;
}
}
Grafos. EDA. Curso 2002/03
43
Grafos. EDA. Curso 2002/03
44
Ejercicio 3: 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
Ejercicio 2
] Repetir el ejercicio número 1 sobre la implementación completa
de grafo (usando el diccionario)
public String toString() {
String elGrafo =“”;
for (int i=0;i<=numVertices;i++) {
elGrafo+=“Vértice: ”+tabla[i].nombre+“ con Adyacentes”;
Lista adyacentesAI = tabla[i].ady;
adyacentesAI.inicio();
while ( !adyacentesAI.esFin()) {
Arista actual = (Arista)adyacentesAI.recupera();
int
numActual = actual.dest;
String nombreActual = tabla[numActual].nombre;
elGrafo+=“ (”+nombreActual+“, ”+actual.coste+“), ”; }
elGrafo+=“\n”;
return elGrafo;
Grafos. EDA. Curso 2002/03
45
}
}
Grafos. EDA. Curso 2002/03
46
Descargar