La descarga está en progreso. Por favor, espere

La descarga está en progreso. Por favor, espere

Tema 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.

Presentaciones similares


Presentación del tema: "Tema 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."— Transcripción de la presentación:

1 Tema 5 Grafos.

2 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 SEVILL A MADRI D MALAGA BARCELONA MELILL A BILBAO

3 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 ALBACETE MADRID 251 ZAPE ZIPI es-hermano-de BCN MAD IB2458 El Buscón Quevedo autor-de novela ejemplo

4 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 e d f g XU V W Y a c b e d f g

5 Más terminología Camino, bucle y ciclo: : camino simple de longitud 4. : camino de longitud 5. : no es un camino. : camino, bucle y ciclo a b c d e Grafo no dirigido a b c d e Grafo dirigido : camino simple de longitud 1. : camino de longitud 3. : no es un camino. : camino, bucle y ciclo Grafo simple/multigrafo Grafos etiquetados/ponderados

6 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 **/ }

7 Implementación de Grafos: Matriz de Adyacencias

8 Matriz de adyacencias Tabla 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.

9 Ejemplos a b c d e abcde a01000 b00000 c10010 d11000 e01011 a b c d e abcde a01110 b10001 c10010 d10100 e01000 Grafo dirigido Grafo no dirigido matriz simétrica

10 Representación en matriz de adyacencias Los vértices se representan mediante índices. a b c d e Vértices:abcde Índices:01234 Matriz de adyacencias se implementa como un array 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

11 Clase GrafoMA en JAVA Grafos simples, dirigidos o no dirigidos, no etiquetados public class GrafoMA implements Grafo { private boolean dirigido; private int maxNodos; private int numVertices; private 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.

12 Insertar aristas La 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]; }

13 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.

14 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

15 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

16 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 abcde a01000 b00000 c10010 d11000 e01011 Grado de entrada (a)= 2 Grado de salida (a) = 1

17 Grado de salida y entrada de un vértice (II) public int gradoIn(int x) { int gIn = 0; for (int i=0; i

18 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

19 Método que comprueba si un grafo es dirigido Para 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

20 Listas de Adyacencias

21 Lista de adyacencias En 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 array 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.

22 Ejemplo null

23 Representación en lista de adyacencias Los vértices se representan mediante índices. a b c d e Vértices:abcde Índices:01234 Lista de adyacencias se implementa como un array 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 del TAD ListaOrdenada.

24 Clase Lista public class Lista { public int dato; public Lista sig; public Lista () { dato = 0; sig = null; } public interface Lista_ord { boolean estaVacia () ; Lista copiar(); void insertar (int x) ; void eliminarElemento (int x); int obtenerClave (); NodoLista obtenerInicio(); void avanzar (); boolean busqueda (int x); }

25 Clase GrafoLA en JAVA Grafos simples, dirigidos o no dirigidos, no etiquetados public class GrafoLA implements Grafo { private boolean dirigido; private int maxNodos; private int numVertices; private 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.

26 Insertar aristas La 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 ) { 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); }

27 Eliminar aristas La 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].eliminarElemento(j); if (!dirigido) listaAdy[j].eliminarElemento(i); }

28 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

29 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) = 1 b null a b c d e a d ab be b

30 Grado de salida y entrada de un vértice (II) public int gradoIn(int v) { int gIn = 0; for (int i=0; i

31 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 salida Tamañ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

32 Método que comprueba si un grafo es dirigido En 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

33 Imprimir la lista de adyacencias public 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

34 Recorridos de Grafos En profundidad En anchura

35 Recorrido del Grafo Un grafo puede ser recorrido en profundidad o en amplitud. Aspectos que hay que considerar (comparado con el recorrido de árboles): Puesto que un árbol es un grafo orientado sin circuitos, al avanzar en el recorrido no cabe la posibilidad de que se vuelva a visitar un vértice ya visitado. En el recorrido de un grafo sí cabe la posibilidad de al avanzar visitar un vértice ya visitado. Partiendo de la raíz de un árbol se pueden visitar todos los vértices, mientras que en un grafo se puede dar la posibilidad de que no se alcancen todos los vértices desde un vértice. Habría que comenzar el recorrido en otro vértice para poder alcanzar todos los vértices.

36 Recorrido en profundidad (I) Preferencia a visitar a los vértices conectados con el último visitado. Recorrido en profundidad: Parte recursiva que recorre parcialmente un subgrafo a partir de un vértice de inicio Parte no recursiva que se encarga de relanzar el proceso en cada vértice no visitado. Vector de valores lógicos para marcar los vértices visitados. Se utilizan los índices de los vértices para iniciar y marcar el proceso de recorrido.

37 Se toma como vértice inicial 1, v1 visitado (el conjunto de vértices adyacentes a v1 es 2,3) Se toma vértice 2: v2 visitado (el conjunto de vértices adyacentes a v2 es 3,4) Se toma vértice 3 v3 visitado (el conjunto de vértices adyacentes a v3 es 1) //v1 ya está visitado por lo que se termina el recorrido en profundidad a partir de v3 Se toma el vértice 4 v4 visitado (el conjunto de vértices adyacentes a v4 es 3) //v3 ya está visitado por lo que se termina el recorrido en profundidad a partir del v4. No es posible alcanzar más vértices desde v1, de manera que hay que seleccionar un nuevo vértice desde el que recomenzar la exploración en profundidad. Se toma el vértice 5: v5 visitado (el conjunto de vértices adyacentes a v5 es 4) //v4 ya está visitado de manera que se termina el recorrido en profundidad a partir del vértice 5 Recorrido en profundidad (II)

38 Recorrido en profundidad (III) public void recorrerProfundidad (Grafo g, int v, boolean[] visitados) { visitados[v] = true; //se marca el vértice v como visitado System.out.println(v); //se examinan los vértices adyacentes a v para continuar el recorrido for (int i=0; i

39 Recorrido en amplitud Se elige un vértice no visitado v como punto de partida Se pasa a visitar cada uno de sus vértices adyacentes Se continúa visitando los adyacentes a estos últimos y así sucesivamente hasta que no se puedan alcanzar más vértices. Si queda algún vértice sin visitar, se selecciona y se vuelve a relanzar el proceso. Es necesario utilizar una estructura de datos cola: En la cola se van almacenando los vértices a medida que se llega a ellos. Los vértices se marcan en la cola como visitados Son tratados cuando se extraen de la cola al tiempo que se introducen en la cola los adyacentes al vértice tratado

40 public static void amplitud (Grafo g) throws ColaVacia { Cola cola = new Cola(); boolean visitados[] = new boolean[g.obtenerNumVertices()]; int v; //vértice actual for (int i=0;i


Descargar ppt "Tema 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."

Presentaciones similares


Anuncios Google