Grafos..

Slides:



Advertisements
Presentaciones similares
Arreglos Unidimensionales y Bidimensionales ESTRUCTURAS DE DATOS I
Advertisements

5. Estructuras no lineales estáticas y dinámicas
PRACTICO N° 6 GRAFOS año: 2012.
GRAFOS ESTRUCTURAS DE DATOS.
Teoría de Grafos I semestre 2009 UNIVERSIDAD NACIONAL DE INGENIERIA
Unidad 5 Listas Enlazadas Bibliografía: Algoritmos y Estructuras de datos de Aguilar y Martinez. Unidad 9 Autor: Ing Rolando Simon Titiosky.
Listas enlazadas c++ Prof. Franklin Cedeño.
Programación II Listas
Estructuras de datos y algoritmos
Utilización de un TAD Arbol.
MATEMÁTICAS DISCRETAS.
Tema 5 Grafos..
Tema 5 Grafos. Implementación (I)..
Árboles binarios. Algoritmos básicos
Tema 1. Introducción a la programación (Lenguaje java).
Tratamiento de listas en Java
Tema 5 Grafos. Recorridos..
Tema 4 Árboles. Árbol sobre matriz.
Abstracción de Datos La abstracción es un recurso fundamental en la programación orientada a objetos y está además fuertemente ligado a reusabilidad.
Implementación de Listas
Oscar Bedoya. Edificio 331, 2º piso, E.I.S.C. Estructuras de datos y algoritmos.
L ISTAS E NLAZADAS No son mas que un conjunto o lista de objetos que a diferencia de los vectores, estas poseen la capacidad de crecer o decrecer. Por.
Slide 7-1 Copyright © 2003 Pearson Education, Inc. Figure: Estructuras de datos.
Diplomado en Informática Aplicada
Estructuras dinámicas de datos, TAD Lista, parte 2
Tema 6: Clases Antonio J. Sierra.
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.
AED I. Estructuras de Datos.
GRAFOS HUGO ARAYA CARRASCO.
Igor Santos Grueiro. Ahora tenemos datos y datos …
Teoría de Grafos.
1 Algoritmos Elementales de Grafos Agustín J. González ELO-320: Estructura de Datos Y Algoritmos 1er.Sem
PROGRAMACIÓN PARALELA EN ALGORITMOS SOBRE GRAFOS
Material de apoyo Unidad 4 Estructura de datos
Grafos. Un Grafo G es un par de conjuntos (V, E), donde V es un conjunto no vacío de elementos llamados vértices o nodos y E es un conjunto formado por.
Teoria de grafos.-clase 4
C++ LISTAS C++ 11/04/2017 Ing. Edgar Ruiz Lizama.
ESTRUCTURAS DE DATOS I Conocer, comprender y analizar algunos de los principales tipos de estructuras de datos.
Estructura de Datos y Algoritmos
ESTRUCTURA DE DATOS EN JAVA
Clase 10: Estructuras de datos y arreglos.
Grafo Juan Ramón Pérez Pérez Prácticas EDI - © Juan Ramón Pérez1.
METODOLOGÍA DE LA PROGRAMACIÓN
ARBOLES ESTRUCTURAS DE DATOS.
Árboles Binarios Estructuras de Datos.
LISTA DOBLEMENTE ENLAZADA
Estructuras de datos para Grafos
s t a c b d Grafos.
Sentencias de repetición
Agustín J. González ELO-320: Estructura de Datos Y Algoritmos
Algoritmos y Estructura de Datos
Vectores y Matrices.
Cecilia Laborde González
Estructura de datos I CIS - UABJB.
Estructuras de datos Fundamentos de análisis y diseño de algoritmos.
UNIDAD 2 Grafos Árboles abarcadores mínimos Caminos más cortos.
Capitulo 4 Arreglos o Arrays Unidimensionales Bidimensionales Strings
Entrada y Salida ES.leerChar (); ES.leerEntero (); ES.leerEnteroLargo (); ES.leerFloat (); ES.leerDouble (); System.out.print System.out.println.
Listas. Utilización de un TAD Lista. Interfaz del TAD LISTA public interface Lista { void crearNodo (); /*Crea un nuevo nodo en el TadLista*/ int devolverClave.
M.C. Meliza Contreras González
LE, EI, Profesor Ramón Castro Liceaga UNIVERSIDAD LATINA (UNILA) V. GESTIÓN DE TIPOS Y GENERACIÓN DE CÓDIGOS.
Listas Dinámicas.
INTRODUCCIÓN A LA PROGRAMACIÓN ORIENTADA A OBJETOS Arreglo.
1 ListaUna Lista se define como una serie de N elementos E 1, E 2,..., E N, ordenados de manera consecutiva, es decir, el elemento E k (que se denomina.
Las interfaces Predicate y Function Versión Unidad Didáctica 17 Fundamentos de Programación Departamento de Lenguajes y Sistemas Informáticos.
Programación en Java Introducción a Java. Reseña histórica Surge en 1991 por Sun Microsystems Desarrollado para electrodomésticos Se buscaba un código.
UNIVERSIDAD TECNOLÓGICA DE PANAMÁ Facultad de Ingeniería de Sistemas Computacionales Programa de Lic. en Informática Educativa Computación.
Lenguaje de Programación II Prof. Rafael Montenegro B. Carrera: T.S.U en Informática Periodo: 2014-I.
2. Arreglos e invariantes. Arreglos Un arreglo es una coleccion ordenada de elementos del mismo tipo – Tipos de datos primitivos (int, …) – Referencias.
Programación en Java Introducción a Java. Reseña histórica Surge en 1991 por Sun Microsystems Desarrollado para electrodomésticos Se buscaba un código.
Transcripción de la presentación:

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 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. BILBAO 606 BARCELONA OVIEDO 395 622 445 538 MADRID 437 531 ALICANTE 1006 SEVILLA 534 207 221 MALAGA MELILLA

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

Incidencia, Adyacencia y Grado X U V W Y a c b e d f g 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 X U V W Y a c b e d f g

Más terminología Camino, bucle y ciclo: Grafo dirigido <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 Grafo dirigido <a,b>: camino simple de longitud 1. <e,d,a,b>: camino de longitud 3. <a,c,d>: no es un camino.

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

Implementación de Grafos: Matriz de Adyacencias

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.

Ejemplos Grafo no dirigido Grafo dirigido matriz simétrica a b c d e a 1 a b c d e 1 matriz simétrica

Representación en matriz de adyacencias Los vértices se representan mediante índices. a b c d e Vé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

Clase GrafoMA en JAVA public class GrafoMA implements Grafo { boolean dirigido; int maxNodos; int numVertices; boolean matrizAdy[ ][ ]; } Grafos simples, dirigidos o no dirigidos, no etiquetados Dos constructores: grafo vacío y grafo de tamaño n. public GrafoMA (boolean d) { maxNodos = numVertices = 0; dirigido = d; } public GrafoMA (int n, boolean d) { maxNodos = n; numVertices = 0; matrizAdy = new boolean[n][n];

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]; }

Eliminar aristas La eliminación de una arista (i, j) en la matriz supone asignar a la celda correspondiente el valor false. public void eliminarArista (int i, int j) { matrizAdy [i] [j] = false; if (!dirigido) matrizAdy [j] [i] = false; }

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

Insertar vértices Método que inserta n vértices en la tabla si existe espacio para ellos: 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;

Grado de salida y entrada de un vértice (I) b c d e 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 1 Grado de salida (a) = 1 Grado de entrada (a)= 2

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; }

Incidencia de un vértice y tamaño del grafo 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 incidencia (int i) { if (!dirigido) return gradoIn (i); else return gradoIn (i) + gradoOut (i); } 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; }

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 < numVertices; i++) for (int j = 0; j < numVertices; j++) if (matrizAdy [i] [j] != matrizAdy [j] [i]) dir = false; return dir; }

Implementación de Grafos: Lista de Adyacencias

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

Ejemplo 1 2 3 4 null

Representación en lista de adyacencias Los vértices se representan mediante índices. a b c d e Vé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.

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);

Clase GrafoLA en JAVA public class GrafoLA implements Grafo { boolean dirigido; int maxNodos; int numVertices; Lista listaAdy [ ]; } Grafos simples, dirigidos o no dirigidos, no etiquetados Dos constructores: grafo vacío y grafo de tamaño n. public GrafoLA (boolean d) { maxNodos = numVertices = 0; dirigido = d; } public GrafoLA (int n, boolean d) { maxNodos = n; numVertices = 0; listaAdy = new Lista [n];

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 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); }

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].eliminar (j); if (!dirigido) listaAdy[j].eliminar (i); }

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;

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 b null a c d e Grado de salida (a) = 1 Grado de entrada (a)= 2

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;

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 < 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;

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 < numVertices; i++) for (int j = 0; j < numVertices; j++){ if (listaAdy [i].busqueda (j) != listaAdy [j].busqueda (i)) dir = false; } return dir;

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 < 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");