grafos.. grafos un grafo se define como un par g = (v, a), donde v es un conjunto finito no vacío...

33
Grafos.

Upload: paula-prado-guzman

Post on 02-Feb-2016

221 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Grafos.. Grafos Un grafo se define como un par G = (V, A), donde V es un conjunto finito no vacío de vértices A es un conjunto de pares de vértices de

Grafos.

Page 2: Grafos.. Grafos Un grafo se define como un par G = (V, A), donde V es un conjunto finito no vacío de vértices A es un conjunto de pares de vértices de

Grafos Un grafo se define como un par G = (V, A), donde

V es un conjunto finito no vacío de vértices A es un conjunto de pares de vértices de V, es decir, las

aristas. Ejemplo:

Los vértices representan ciudades y almacenan el nombre de la ciudad

Las aristas representan la ruta y la distancia kilométrica entre las ciudades que unen.

ALICANTE

OVIEDO

SEVILLA

MADRID

MALAGA

BARCELONA

MELILLA

BILBAO

622

606

1006

534

221

207

531

445395

437

538

Page 3: Grafos.. Grafos Un grafo se define como un par G = (V, A), donde V es un conjunto finito no vacío de vértices A es un conjunto de pares de vértices de

Tipos de Grafos Según el tipo de arista:

Arista dirigida: par ordenado de vértices (u,v)

El primer vértice u es el origen de la arista

El segundo vértice v es el término (o vértice final).

(u, v) ≠ (v, u). Arista no dirigida: par no ordenado

de vértices (u, v) (u, v) = (v, u).

SE DEFINEN: Grafos dirigidos (todas las aristas son

dirigidas) Expresan relaciones asimétricas y de

jerarquía Grafos no dirigidos (todas las aristas

son no dirigidas) Expresan relaciones simétricas y de

colaboración

ALBACETEMADRID 251

ZAPEZIPIes-hermano-de

BCNMADIB2458

“El Buscón”

Quevedo autor-de

novela

ejemplo

Page 4: Grafos.. Grafos Un grafo se define como un par G = (V, A), donde V es un conjunto finito no vacío de vértices A es un conjunto de pares de vértices de

Incidencia, Adyacencia y Grado Incidencia: La arista (u,v) es incidente con

los vértices u y con v). De forma que: Aristas a, d, y b son incidentes en V

Adyacencia: Dos vértices u y v son adyacentes si existe la arista (u, v) o (v, u).

Grado de un vértice: Determinado por el número de vértices adyacentes al nodo. Grado de X = 3

Si el grafo es dirigido: Grado de salida: número de vértices

adyacentes desde el nodo. Grado de salida de W = 0 Grado de salida de Y = 2

Grado de entrada: número de vértices adyacentes al nodo.

Grado de entrada de W = 4 Grado de entrada de Y = 0

XU

V

W

Y

a

c

b

ed

f

g

XU

V

W

Y

a

c

b

ed

f

g

Page 5: Grafos.. Grafos Un grafo se define como un par G = (V, A), donde V es un conjunto finito no vacío de vértices A es un conjunto de pares de vértices de

Más terminologíaCamino, bucle y ciclo:

<a,b,e,d,c>: camino simple de longitud 4.<a,c,d,a,b,e>: camino de longitud 5.<a,e>: no es un camino.<e,e>: camino, bucle y ciclo

a b

c d

e

Grafo no dirigido

a b

c d

e

Grafo dirigido

<a,b>: camino simple de longitud 1.<e,d,a,b>: camino de longitud 3.<a,c,d>: no es un camino.<e,e>: camino, bucle y ciclo

Page 6: Grafos.. Grafos Un grafo se define como un par G = (V, A), donde V es un conjunto finito no vacío de vértices A es un conjunto de pares de vértices de

Interfaz de Grafo

public interface Grafo {public void insertaVertice( int n);/** Inserta un vértice en el grafo siempre que no se supere el número máximo de nodos permitidos **/public void eliminarVertice (int v);/** Elimina un vértice del grafo **/public void insertaArista (int i, int j);/** Inserta una arista entre los vértices i y j **/public void eliminarArista (int i, int j); /** Elimina la arista entre los vértices i y j **/public boolean esVacio (Grafo g);/** Devuelve true si el grafo no contiene ningún vértice **/public boolean existeArista (int i, int j);/** Devuelve true si existe una arista que una los vértices i y j. **/public int gradoIn (int i);/** Devuelve el grado de entrada del vértice i **/public int gradoOut (int i);/** Devuelve el grado de salida del vértice i **/public int incidencia (int i) /** Devuelve la incidencia del vértice i **/public int tamano();/** Devuelve el tamaño (número de aristas) del grafo **/public boolean esDirigido (Grafo g) ;/** Devuelve true si el grafo g es dirigido **/public void ponerMaxNodos (int n);/** Asigna el número máximo de nodos permitidos en el grafo**/public void ponerDirigido (boolean d);/** Determina si es un grafo dirigido o no dirigido **/

}

Page 7: Grafos.. Grafos Un grafo se define como un par G = (V, A), donde V es un conjunto finito no vacío de vértices A es un conjunto de pares de vértices de

Implementación de Grafos: Matriz de Adyacencias

Page 8: Grafos.. Grafos Un grafo se define como un par G = (V, A), donde V es un conjunto finito no vacío de vértices A es un conjunto de pares de vértices de

Matriz de adyacenciasTabla bidimensional que guarda las

adyacencias entre pares de vértices de un grafo.

Vértices: enteros en el conjunto {0,1,…,n-1}

Aristas: pares de tales enteros. Cada fila y cada columna representan un

vértice del grafo y cada posición representa una arista (o la ausencia de esta) cuyo vértice origen se encuentra en la fila y vértice final se encuentra en la columna.

Page 9: Grafos.. Grafos Un grafo se define como un par G = (V, A), donde V es un conjunto finito no vacío de vértices A es un conjunto de pares de vértices de

Ejemplos

a b

c d

e

a b c d e

a 0 1 0 0 0

b 0 0 0 0 0

c 1 0 0 1 0

d 1 1 0 0 0

e 0 1 0 1 1

a b

c d

e

a b c d e

a 0 1 1 1 0

b 1 0 0 0 1

c 1 0 0 1 0

d 1 0 1 0 0

e 0 1 0 0 0

Grafo dirigido Grafo no dirigido

matriz simétrica

Page 10: Grafos.. Grafos Un grafo se define como un par G = (V, A), donde V es un conjunto finito no vacío de vértices A es un conjunto de pares de vértices de

Representación en matriz de adyacenciasLos vértices se representan mediante índices.

a b

c d

eVértices: a b c d e

Índices: 0 1 2 3 4

Matriz de adyacencias se implementa como un vector A bidimensional de n x n donde:La celda [i, j] guarda información referente a la arista

(v, w) donde v es el vértice con índice i y w es el vértice con índice j.

Para grafos no etiquetados, las celdas guardan valores booleanos: true: existe la arista false: no existe la arista

Page 11: Grafos.. Grafos Un grafo se define como un par G = (V, A), donde V es un conjunto finito no vacío de vértices A es un conjunto de pares de vértices de

Clase GrafoMA en JAVAGrafos simples,

dirigidos o no dirigidos, no etiquetados

public class GrafoMA implements Grafo {boolean dirigido; int maxNodos; int numVertices; boolean matrizAdy[ ][ ];

}

public GrafoMA (boolean d) {maxNodos = numVertices = 0;dirigido = d;

}public GrafoMA (int n, boolean d) {

dirigido = d; maxNodos = n;numVertices = 0;matrizAdy = new boolean[n][n];}

}

Dos constructores: grafo vacío y grafo de tamaño n.

Page 12: Grafos.. Grafos Un grafo se define como un par G = (V, A), donde V es un conjunto finito no vacío de vértices A es un conjunto de pares de vértices de

Insertar aristasLa inserción de una arista (i, j) en la matriz

supone asignar a la celda correspondiente el valor true.En grafo dirigido:

las filas representan el vértice origen (i) las columnas representan el vértice destino (j)

En grafo no dirigido: La arista (i,j) es igual a la arista (j,i) (para que la matriz

mantenga la propiedad de la simetría.

public void insertaArista (int i, int j) {matrizAdy [i] [j] = true;if (!dirigido)

matrizAdy [j] [i] = matrizAdy [i] [j]; }

Page 13: Grafos.. Grafos Un grafo se define como un par G = (V, A), donde V es un conjunto finito no vacío de vértices A es un conjunto de pares de vértices de

Eliminar aristas

public void eliminarArista (int i, int j) {matrizAdy [i] [j] = false;if (!dirigido)

matrizAdy [j] [i] = false; }

La eliminación de una arista (i, j) en la matriz supone asignar a la celda correspondiente el valor false.

Page 14: Grafos.. Grafos Un grafo se define como un par G = (V, A), donde V es un conjunto finito no vacío de vértices A es un conjunto de pares de vértices de

Insertar vértices El tratamiento de los vértices implicaría

modificar el tamaño de la tabla (o modificar los índices en caso de querer eliminar un vértice):

Simplificación del método: No se permite añadir vértices si se supera el

tamaño máximo del grafo (valor del campo maxNodos).

Si el número de nodos es menor al tamaño máximo, se asigna el valor false a las celdas correspondientes y se actualiza el campo numVertices

Page 15: Grafos.. Grafos Un grafo se define como un par G = (V, A), donde V es un conjunto finito no vacío de vértices A es un conjunto de pares de vértices de

Insertar vértices

public void insertaVertice (int n) {if ( n > maxNodos - numVertices )

System.out.println ("Error, se supera el número de nodos máximo");else {

for (int i = 0; i < numVertices + n; i++) {for (int j = numVertices; j < numVertices + n; j++)

matrizAdy [i] [j] = matrizAdy [j] [i] = false;}

numVertices = numVertices + n;}

}

Método que inserta n vértices en la tabla si existe espacio para ellos:

Page 16: Grafos.. Grafos Un grafo se define como un par G = (V, A), donde V es un conjunto finito no vacío de vértices A es un conjunto de pares de vértices de

Grado de salida y entrada de un vértice (I)Grado de salida:

Dado que las filas representan los vértices origen, el grado de salida de un vértice i es el valor de la suma de la fila i.

Grado de entrada:Dado que las columnas

representan los vértices destino, el grado de entrada de un vértice j es el valor de la suma de la columna j.

a b

c d

e

a b c d e

a 0 1 0 0 0

b 0 0 0 0 0

c 1 0 0 1 0

d 1 1 0 0 0

e 0 1 0 1 1

Grado de entrada (a)= 2

Grado de salida (a) = 1

Page 17: Grafos.. Grafos Un grafo se define como un par G = (V, A), donde V es un conjunto finito no vacío de vértices A es un conjunto de pares de vértices de

Grado de salida y entrada de un vértice (II)public int gradoIn (int x) { int gIn = 0; for (int i = 0; i < numVertices; i++) //recorrido por filas

if (matrizAdy [i] [x]) //manteniendo la posición de la columna en [ x ] gIn++; return gIn;}

public int gradoOut (int x) { int gOut = 0; for (int j = 0; j < numVertices; j++) //recorrido por columnas

if (matrizAdy [x] [j]) // manteniendo la posición de la fila en [ x ] gOut++;

return gOut;}

Page 18: Grafos.. Grafos Un grafo se define como un par G = (V, A), donde V es un conjunto finito no vacío de vértices A es un conjunto de pares de vértices de

Incidencia de un vértice y tamaño del grafo

public int incidencia (int i) { if (!dirigido) return gradoIn (i); else return gradoIn (i) + gradoOut (i); }

Incidencia: Grafo no dirigido: la

incidencia de un vértice viene dada por su grado de entrada

Grafo dirigido: grado de entrada + grado de salida

Tamaño: Definido por el número

de aristas. Si el grafo es no dirigido, las aristas se cuentan dos veces, luego se ha de dividir entre dos el número de aristas contadas.

public int tamano () { int tm = 0; for (int I = 0; I < numVertices; i++) for (int j =0; j < numVertices; j++) if (matrizAdy [i] [j])

tm++; if (dirigido) return tm; else return tm/2;}

Page 19: Grafos.. Grafos Un grafo se define como un par G = (V, A), donde V es un conjunto finito no vacío de vértices A es un conjunto de pares de vértices de

Método que comprueba si un grafo es dirigidoPara comprobar si un grafo es dirigido o no,

basta con comprobar si se trata de una matriz simétrica, donde la posición [i, j] = [j, i].

public boolean esDirigido (Grafo g) { boolean dir = true; for (int I = 0; I < numVertices; i++)

for (int j = 0; j < numVertices; j++) if (matrizAdy [i] [j] != matrizAdy [j] [i])

dir = false; return dir;}

Page 20: Grafos.. Grafos Un grafo se define como un par G = (V, A), donde V es un conjunto finito no vacío de vértices A es un conjunto de pares de vértices de

Implementación de Grafos: Lista de Adyacencias

Page 21: Grafos.. Grafos Un grafo se define como un par G = (V, A), donde V es un conjunto finito no vacío de vértices A es un conjunto de pares de vértices de

Lista de adyacenciasEn una lista de adyacencias, a cada vértice i se le asocia

una lista enlazada con todos los vértices j adyacentes a i.

Sólo se reserva memoria para las aristas adyacentes a i. El grafo se representa por medio de un vector de n

componentes, (n = número de vértices del grafo) donde cada componente constituye la lista de adyacencias correspondiente a cada vértice del grafo.

Cada nodo de la lista consta de un campo indicando el vértice adyacente.

Si el grafo fuese etiquetado o valorado, habría que añadir un segundo campo para mostrar el valor de la etiqueta o el peso de la arista.

Page 22: Grafos.. Grafos Un grafo se define como un par G = (V, A), donde V es un conjunto finito no vacío de vértices A es un conjunto de pares de vértices de

Ejemplo

1

0 1

2 3

4

null0

1

2

3

4

0

null

3 null

0 1 null

3 4 null1

Page 23: Grafos.. Grafos Un grafo se define como un par G = (V, A), donde V es un conjunto finito no vacío de vértices A es un conjunto de pares de vértices de

Representación en lista de adyacenciasLos vértices se representan mediante índices.

a b

c d

eVértices: a b c d e

Índices: 0 1 2 3 4

Lista de adyacencias se implementa como un vector A de tamaño n:Cada componente i contiene la lista de nodos adyacentes

al vértice i. Cada nodo de la lista guarda información sobre índice del

vértice.Uso de una Lista Calificada Ordenada.

Page 24: Grafos.. Grafos Un grafo se define como un par G = (V, A), donde V es un conjunto finito no vacío de vértices A es un conjunto de pares de vértices de

Clases NodoLista y Lista

public class NodoLista {public int clave;public NodoLista sig;

}public class Lista {

public NodoLista inicio;}

Métodos utilizados:

void insertar (int x) ;void eliminar (int x);boolean busqueda (int x);

Page 25: Grafos.. Grafos Un grafo se define como un par G = (V, A), donde V es un conjunto finito no vacío de vértices A es un conjunto de pares de vértices de

Clase GrafoLA en JAVAGrafos simples,

dirigidos o no dirigidos, no etiquetados

public class GrafoLA implements Grafo {boolean dirigido; int maxNodos; int numVertices; Lista listaAdy [ ];

}

public GrafoLA (boolean d) {maxNodos = numVertices = 0;dirigido = d;

}public GrafoLA (int n, boolean d) {

dirigido = d; maxNodos = n;numVertices = 0;listaAdy = new Lista [n];

}

Dos constructores: grafo vacío y grafo de tamaño n.

Page 26: Grafos.. Grafos Un grafo se define como un par G = (V, A), donde V es un conjunto finito no vacío de vértices A es un conjunto de pares de vértices de

Insertar aristasLa inserción de una arista (i, j) en la lista de

adyacencias supone insertar un nodo con clave j en la lista con índice i.

Si el grafo es no dirigido: arista (i, j) = arista (j, i) Hay que insertar en la lista con índice j el nodo con clave i.

public void insertaArista (int i, int j) {if ( i >= numVertices ) System.out.println ("Error, no existe el vértice en el grafo");else {

listaAdy [i].insertar (j);if (!dirigido)

listaAdy [j].insertar (i);}

}

Page 27: Grafos.. Grafos Un grafo se define como un par G = (V, A), donde V es un conjunto finito no vacío de vértices A es un conjunto de pares de vértices de

Eliminar aristasLa eliminación de una arista (i, j) consiste en

eliminar el nodo con clave j de la lista con índice i. Si el grafo es no dirigido, habrá que eliminar el

nodo con clave i de la lista con índice j:

public void eliminaArista (int i, int j) {if (j >= numVertices)

System.out.println ("Error, no existe el vértice en el grafo");else {

listaAdy[i].eliminar (j);if (!dirigido)

listaAdy[j].eliminar (i);}

}

Page 28: Grafos.. Grafos Un grafo se define como un par G = (V, A), donde V es un conjunto finito no vacío de vértices A es un conjunto de pares de vértices de

Insertar vértices No se permite insertar vértices si se supera el límite de

vértices del grafo (valor del campo maxNodos). El método insertarVertices tiene como argumento un entero

que indica el número de vértices que se desea añadir al grafo. Si no se supera el número máximo de nodos del grafo, se

inicializan las n listas correspondientes a los vértices que se añaden al grafo

Se actualiza el campo numVertices del grafo.

public void insertaVertice (int n) { if ( n > maxNodos - numVertices ) System.out.println("Error, se supera el número de nodos máximo del grafo"); else { for (int i = numVertices; i < numVertices + n; i++) listaAdy [i] = new Lista (); } numVertices += n;}

Page 29: Grafos.. Grafos Un grafo se define como un par G = (V, A), donde V es un conjunto finito no vacío de vértices A es un conjunto de pares de vértices de

Grado de salida y entrada de un vértice (I)Grado de salida de v:

Número de elementos de la lista de adyacencia de v.Grado de entrada de v:

Número de veces que aparece v en las distintas listas de adyacencia.

a b

c d

e Grado de entrada (a)= 2

Grado de salida (a) = 1b nulla

b

c

d

e

a

null

d null

a b null

b e nullb

Page 30: Grafos.. Grafos Un grafo se define como un par G = (V, A), donde V es un conjunto finito no vacío de vértices A es un conjunto de pares de vértices de

Grado de salida y entrada de un vértice (II)

public int gradoIn (int v) { int gIn = 0; for (int i = 0; i < numVertices; i++)

if (i != v) if (listaAdy [i].busqueda (v)) gIn++; return gIn;

}

public int gradoOut (int i) { //contar los elementos de la lista int gOut = 0; NodoLista aux = listaAdy[i].inicio; while (aux != null){ gOut++; aux = aux.clave; } return gOut;}

Page 31: Grafos.. Grafos Un grafo se define como un par G = (V, A), donde V es un conjunto finito no vacío de vértices A es un conjunto de pares de vértices de

Incidencia de un vértice y tamaño del grafo public int incidencia (int i) {

if (!dirigido) return gradoIn (i); else return gradoIn (i) + gradoOut (i); }

Incidencia: Grafo no dirigido: incidencia

= grado de entrada Grafo dirigido: grado de

entrada + grado de salidaTamaño:

Definido por el número de aristas (i.e., número de nodos de las distintas listas).

Si el grafo es no dirigido, las aristas se cuentan dos veces, luego se ha de dividir entre dos el número de aristas contadas.

Uso del método auxiliar numElems.

public int tamanno () { int tm = 0; for (int i = 0; i < numVertices; i++) { tm += numElementos (listaAdy [i]); } if (!dirigido) tm = tm/2; return tm;}static int numElementos (Lista lista) { NodoLista aux = lista.inicio; int resul = 0; while (aux != null) { resul += 1; aux = aux.sig; } return resul;}

Page 32: Grafos.. Grafos Un grafo se define como un par G = (V, A), donde V es un conjunto finito no vacío de vértices A es un conjunto de pares de vértices de

Método que comprueba si un grafo es dirigidoEn un grafo dirigido: (i,j) ≠ (j,i)En un grafo no dirigido: (i,j)=(j,i). Para comprobar si se trata de un grafo dirigido, se

comprueba que, para cada par de vértices i,j, el vértice j se encuentra en la lista de adyacencias del vértice i; e igualmente que el vértice i se encuentra en la lista de adyacencias del vértice j.

public boolean esNoDirigido () { boolean dir = true; for (int i = 0; i < numVertices; i++) for (int j = 0; j < numVertices; j++){ if (listaAdy [i].busqueda (j) != listaAdy [j].busqueda (i)) dir = false; } return dir;}

Page 33: Grafos.. Grafos Un grafo se define como un par G = (V, A), donde V es un conjunto finito no vacío de vértices A es un conjunto de pares de vértices de

Imprimir la lista de adyacenciaspublic void imprimirGrafo () { System.out.println ("Tamaño máximo del grafo: " + maxNodos + "\n"); System.out.println ("El grafo contiene " + numVertices + " vértices: \n"); for (int i = 0; i < numVertices; i++) { System.out.print ("vértice " + i + ": "); escribir (listaAdy [i]); }}static void escribir (Lista lista) { NodoLista aux; aux = lista.inicio; while (aux != null) { System.out.print (aux.clave +", "); aux = aux.sig; } System.out.println ("FIN");}