UNIVERSIDAD TECNOLÓGICA DE PANAMÁ FACULTAD DE INGENIERÍA DE SISTEMAS COMPUTACIONALES DEPARTAMENTO DE COMPUTACIÓN Y SIMULACIÓN DE SISTEMAS ESTRUCTURA DE DATOS II PROYECTO FINAL CAMINO MAS CORTO ENTRE DOS CAPITALES DE EUROPA APLICACIÓN DE GRAFO GRUPO: 1IL122 PROFESORA CRISPINA RAMOS INTEGRANTES SANCHEZ ERNESTO 9-743-681 MORENO GERARDO 8-940-408 II SEMESTRE 2019 FECHA 13 DE DICIEMBRE DEL 2019 INTRODUCCIÓN .................................................................................................................. 3 1. Objetivos del trabajo ....................................................................................................... 4 2. Contenido ........................................................................................................................ 4 2.1. Modelado de la situación. ........................................................................................ 4 2.1.1. Estructura de Datos Utilizada. .............................................................................. 4 2.1.2. Funciones Utilizadas. ........................................................................................... 7 2.1.2.1. Funciones para crear un grafo ........................................................................ 7 2.1.2.2. . Funciones para crear una cola de prioridad Funciones para crear una cola de prioridad. ..................................................................................................................... 8 2.1.2.3. Función para el cálculo de camino mínimo ................................................... 8 2.1.2.4. Esquema de la estructura Representada. ...................................................... 10 3. Formatos ........................................................................................................................ 11 3.1. Datos de Entrada. ................................................................................................... 11 3.1.1. variables utilizadas.......................................................................................... 11 3.1.2. Datos de Prueba .............................................................................................. 11 3.1.3. Casos considerados ......................................................................................... 12 4. Referencia...................................................................................................................... 13 2 INTRODUCCIÓN El origen de la palabra grafo es griego y su significado etimológico es "trazar". aparece con gran frecuencia como respuesta a problemas de la vida cotidiana, algunos ejemplos podrían ser los siguientes: un gráfico de una serie de tareas a realizar indicando su secuenciación (un organigrama), grafos matemáticos que representan las relaciones binarias, una red de carreteras, la red de enlaces ferroviarios o aéreos o la red eléctrica de una ciudad. En cada caso es conveniente representar gráficamente el problema dibujando un grafo como un conjunto de puntos (nodos o vértices) con líneas conectándolos (arcos). De aquí se podría deducir que un grafo es básicamente un objeto geométrico, aunque en realidad sea un objeto combinatorio, es decir, un conjunto de puntos y un conjunto de líneas tomado de entre el conjunto de líneas que une cada par de vértices. Por otro lado, debido a su generalidad y a la gran diversidad de formas que pueden usarse, resulta complejo tratar con todas las ideas relacionadas con un grafo. Para facilitar el estudio de este tipo de dato, a continuación, se realizará un estudio de la teoría de grafos desde el punto de vista de las ciencias de la computación, considerando que dicha teoría es compleja y amplia, aquí sólo se realizará una introducción a la misma, describiéndose el grafo como un tipo de dato y mostrándose los problemas típicos y los algoritmos que permiten solucionarlos usando un ordenador. Los grafos son estructuras de datos no lineales que tienen una naturaleza generalmente dinámica, u estudio podría dividirse en dos grandes bloques; grafos dirigidos y grafos no dirigidos (pueden ser considerados un caso particular de los anteriores). Un ejemplo de grafo dirigido lo constituye la red de aguas de una ciudad ya que cada tubería sólo admite que el agua la recorra en un único sentido, por el contrario, la red de carreteras de un país representa en general un grafo no dirigido, puesto que una misma carretera puede ser recorrida en ambos sentidos. No obstante, podemos dar unas definiciones generales para ambos tipos. 3 1. Objetivos del trabajo 2. Contenido 2.1. Modelado de la situación. Europa consta de n capitales, de cada uno de sus estados, cada par de ciudades está conectada o no por vía aérea. En caso de estar co nectadas (se entiende por Vuelo directo) se sabe las millas de la conexión no tiene por qué ser bidireccionales, así pude haber vuel os Viena-Roma y no Roma-Viena. Escribe un programa que represente la estructura expuesta y resuel va el problema: Disponemos de una cantidad de dinero D, deseamos realizar un viaje entre dos capitales, C1-C2, y queremos información sobre la ruta m ás corta que se ajuste a nuestro bolsillo. Se modelo la problemática para resolver el problema de la ruta de menor distancia con el dinero que se cuenta a partir de un grafo dirigido, debido a que los tiene la propiedad de Las nociones de camino, camino simple y ciclo se aplican en los grafos dirigidos igual que en los grafos no dirigidos excepto que la dirección de cada arista de un camino (ciclo) debe coincidir con la dirección del camino (ciclo). Que es lo que se quiere para resolver la problemática 2.1.1. Estructura de Datos Utilizada. Lista de adyacencia para representar un grafo Una lista de adyacencia representa un grafo como una matriz de lista vinculada. El índice de la matriz representa un vértice y cada elemento en su lista vinculada representa los otros vértices que forman un borde con el vértice. Representación de la lista de adyacencia A continuación, se muestra un gráfico y su representación de lista de adyacencia equivalente. 4 Una lista de adyacencia es eficiente en términos de almacenamiento porque solo necesitamos almacenar los valores para los bordes. Para un gráfico escaso con millones de vértices y bordes, esto puede significar mucho espacio ahorrado. Estructura de lista de adyacencia La lista de adyacencia más simple necesita una estructura de datos de nodo para almacenar un vértice y una estructura de datos de gráfico para organizar los nodos. Nos mantenemos cerca de la definición básica de gráfico: una colección de vértices y aristas {V, E}. Para simplificar, utilizamos un gráfico sin etiquetar en lugar de uno etiquetado, es decir, los vértices se identifican por sus índices 0,1,2,3. Veamos las estructuras de datos en juego aquí. // Una estructura para representar un nodo en la lista de // adyacencia typedef struct { int nVertices; int nPeso; float fCostoVuelo; } st_Arista; a. La estructura st_Arista contiene: Contiene el identificador de la arista Contiene la distancia de el vértice nVertices nPeso fCostoVuelo Almacena el costo del vuelo 5 b. La estructura st_Vertice contiene: // Una estructura para representar LAS ARISTA S con sus datos carecteristicos: typedef struct { st_Arista **sVertice; int nNumDeVertice; int nTamDevertice; int dist; float fCosto; int prev; int nVisitado; } st_Vertice; Contiene el identificador de la arista como una especie de vector Contiene la distancia de el vértice **sVertice nNumDeVertice nTamDevertice Almacena el costo del vuelo dist Distancia acumulada fCosto Costo acumulado prev Arista previa nVisitado Fue visitado 1 ó 0 c. La estructura st_Grafo contiene: //Una estructura para representar un gráfico . Un gráfico es una matriz de listas de adyac encia. typedef struct { st_Vertice **sListaAdy; int nNumDeAristas; int nNumDeEnlases; } st_Grafo; 6 **sListaAdy Contiene arista el identificador de la nNumDeAristas Contiene la distancia de el vértice nNumDeEnlases Almacena el costo del vuelo 2.1.2. Funciones Utilizadas. Se pueden dividir en tres bloques: • Funciones para crear un grafo. • Funciones para crear una cola de prioridad se implementó con un montón binario. • Función para el cálculo de camino mínimo. 2.1.2.1. Funciones para crear un grafo a. Agregar un Vértice al grafo add_Vertice(st_Grafo *, int ) Agregara un nuevo vértice en la posición de inicio o capital fuente, solo si la posición no se a agregado anteriormente Inicializa la lista de adyacencia (esto se realizará una vez) nVertices nPeso fCostoVuelo Se llevará una cuenta de los vértices agregados. b. Agrega una arista add_Arista(st_Grafo *, int, int, int, float) Crea una arista con los valores con el identificado, peso y costo de vuelo. Agregara tanto la fuente como el destino a una lista de adyacencia. nVertices fuente c. nPeso fCostoVuelo CrearGrafo(st_Grafo *) Función que está dedicada a la creación del grafo void CrearGrafo(st_Grafo *g) { add_Arista(g, 'a', 'b', 20, 100.8); add_Arista(g, 'a', 'c', 100, 1200.6); add_Arista(g, 'a', 'f', 60, 560.3); add_Arista(g, 'b', 'c', 90, 720.9); add_Arista(g, 'b', 'd', 13, 110.4); add_Arista(g, 'c', 'd', 11, 320.1); add_Arista(g, 'c', 'f', 24, 910.8); add_Arista(g, 'd', 'e', 59, 670.6); add_Arista(g, 'e', 'f', 14, 410.1); } 7 2.1.2.2. Funciones para crear una cola de prioridad Funciones para crear una cola de prioridad. a. st_Monton *Crear_Monton(int ) Initialization de un mouton st_Monton *Crear_Monton(int n) { st_Monton *h = (st_Monton *)calloc(1, sizeof(st_Monton *)); h->nDato = (int *)calloc(n + 1, sizeof(int)); h->prio = (int *)calloc(n + 1, sizeof(int)); h->index = (int *)calloc(n, sizeof(int)); return h; } b. push_Monton(st_Monton *, int , int ) Función para ingresar un valor en el montón void push_Monton(st_Monton *h, int v, int p) { int i = h->index[v] == 0 ? ++h->nLarg : h->index[v]; int j = i / 2; while (i > 1) { if (h->prio[j] < p) break; h->nDato[i] = h->nDato[j]; h->prio[i] = h->prio[j]; h->index[h->nDato[i]] = i; i = j; j = j / 2; } h->nDato[i] = v; h->prio[i] = p; h->index[v] = i; } c. 2.1.2.3. pop_Monton(st_Monton *) Saca el elemento de el montón y lo devuelve Función para el cálculo de camino mínimo a. dijkstra(st_Grafo *, int , int ) Esta función inicializa las distancias, con un ciclo for la cantidad de aristas, a un numero muy grande, los previos y los visitados a ceros 8 Seguido creara un Montón y ingresando la capital fuente y la distancia infinita Recorrerá la ruta mas optima siendo esta la de menor distancia y acumulara si y solo si la suma del peso es menor al infinito y de paso se acumula el costo del vuelo. if (!u->nVisitado && v->dist + e->nPeso <= u->dist) { u->prev = i; u->dist = v->dist + e->nPeso; u->fCosto = v->fCosto + e->fCostoVuelo; push_Monton(h, e->nVertices, u->dist); } b. print_Patron(st_Grafo *, int , float, int , int ) Función que imprimirá un patrón de residiendo como partida la capital fuente y el monto que el usuario ingreso como valor tope el cual será usado como condición, al hacer que solo imprima el patrón con un valor acumulado de dinero menor o igual a este. c. printGrafo(st_Grafo *g, int x, int y) Función que recorrerá el grafo e imprimirá, tanto la lista de adyacencia con letras y las rutas que recorre en formato de países para visualizar el usuario. d. IngresoMonto(st_Grafo *g) Solo es una función utilitaria para visualizar y capturar el monto con el que cuenta el usuario para realizar el vuelo. 9 2.1.2.4. Esquema de la estructura Representada. b c d Figura 3: Representación del problema en grafo Francia Portugal Alemania Andorra Italia Ucrania Figura 4: Representación del problema en grafo modo Capitales de Países 10 . ‘f’ ‘e’ ‘f’ 14 mi ‘d’ ‘e’ 59 mi ‘d’ 13 mi ‘b’ ‘c’ 90 mi ‘a’ ‘b’ 20 mi ‘c’ 410.1 $ 670.6 $ ‘f’ 24mi 910.8 $ 720.9 $ ‘d’ 13 mi 110.4 $ 100.8 $ ‘c’ 100 mi 1200.6 $ 110.4 & ‘f’ 60 mi Figura 5: Representación del problema en lista de adyacencia. 3. Formatos 3.1. Datos de Entrada. 3.1.1. variables utilizadas float monto Monto ingresado por el usuario para ir de una capital a otra. char fuente Capital fuente char destino Capital destino st_Grafo *g grafo Char path Almacenara el recorrido como un string Char paises Contiene los países de Europa st_Monton *h Variable de montón 3.1.2. Datos de Prueba 'a', 'a', 'a', 'b', 'b', 'c', 'c', 'd', 'e', 'b', 'c', 'f', 'c', 'd', 'd', 'f', 'e', 'f', 20, 100.8 100, 1200.6 60, 560.3 90, 720.9 13, 110.4 11, 320.1 24, 910.8 59, 670.6 14, 410.1 11 560.3 $ 3.1.3. Casos considerados Francia Portugal Alemania Andorra Italia Ucrania Figura 6: Representación del problema en grafo modo Capitales de Países con sus longitudes y costo de vuelo. 12 4. Referencia. Título del Adjacency List (With Code in C, C++, Java and Python) articulo Sitio programiz.com web URL: https://www.programiz.com/dsa/graph-adjacency-list Título Dijkstra’s Algorithm for Adjacency List Representation | Greedy Algo-8 del GeeksforGeeks articulo Sitio . GeeksforGeeks.com web https://www.geeksforgeeks.org/dijkstras-algorithm-for-adjacency-list-representationURL: greedy-algo-8/ Título del GRAFOS articulo Sitio . decsai.ugr.es web URL: http://decsai.ugr.es/~jfv/ed1/c++/cdrom4/paginaWeb/grafos.htm Título del Estructura de datos en C++ articulo Sitio studylib web URL: https://studylib.es/doc/7869244/estructura-de-datos-en-c-- 13