Proyecto I:Representación de Grafos en el Computador CI2693-Algoritmos y Estructuras de Datos 3 1 Definición del Problema El objetivo de este proyecto es lograr que se familiarice con las operaciones básicas de los TADs Grafo No Dirigido y Grafo Dirigido. Para ello se desea que implemente los TADs usando el lenguaje de programación Java y luego desarrolle una pequeña aplicación que permita probar los TADs. Los TADs implementados serán utilizados en el proyecto final, por lo que se debe garantizar su correcto funcionamiento. Para la implementación se creará una clase abstracta llamada Grafo que contendrá las operaciones y estructuras de datos asociados a un grafo, sea dirigido o a no. Los grafos podrán tener lados múltiples y bucles. La clase Grafo tendrá dos clases concretas derivadas que llamaremos GrafoDirigido y GrafoNoDirigido. En esta entrega se debe representar el TAD utilizando una matriz de adyacencia. La estructura de datos debe implementarse siguiendo las siguientes restricciones: • El TAD debe utilizar dos estructuras. La primera estructura es una colección donde se puede acceder la información de cada uno de los nodos a partir de su identificador en orden constante. La segunda estructura es una matriz cuadrada donde cada entrada Aij corresponderá a una lista de lados entre los nodos i y j (Ver figura 1). • El tipo Vertice será una clase concreta que poseerá al menos un campo de tipo String que identica únivocamente a cada vértice, un entero que identifica la fila correspondiente en la matriz, y otro campo real que permite representar un peso asociado al vértice. • El tipo Lado es una clase abstracta que puede asumir como valores tuplas de la forma ≤ id, prop ≥ donde id es un String que identica únivocamente la arista mientras que prop es una instancia de una clase apropiada (posiblemente una tupla) donde se pueden guardar las propiedades asociadas al lado. • El tipo Arista es una clase concreta derivada de la clase Lado, asociada a un grafo no dirigido. • El tipo Arco es una clase concreta derivada de la clase Lado, asociada a un grafo dirigido, por lo que debe indicar la orientación del mismo. El TAD Grafo debe incorporar al menos los siguientes operadores 123 : • CrearGraf o : N ada → Graf o Semántica: CrearGraf o() crea un Grafo vacı́o. • CrearGraf o : Archivo → Graf o Semántica: CrearGraf o(a) crea un grafo a partir del nombre de un archivo de texto. • AgregarV ertice : Graf o × V ertice → Graf o Semántica: AgregarV ertice(G, v) agrega el vértice v al grafo G previamente creado. • EliminarV ertice : Graf o × id(V ertice) → Graf o Semántica: EliminarV ertice(G, idV ertice) elimina el vértice identificado por idV ertice del grafo G. • V ertices : Graf o → ListadeV ertices Semántica: V ertices(G) obtiene el conjunto de vértices del grafo G. 1 Vertice, Lado y Arco se refieren a instancias de las clases respectivas es una colección iterable 3 id(Vertice),id(Lado) se refieren a los string que identifican univocamente el objeto 2 Lista 1 Figure 1: Representación con Matriz de Incidencia • Lados : Graf o → ListadeLados Semántica: Lados(G) obtiene el conjunto de lados del grafo G. • Grado : Graf o × id(V ertice) → Entero Semántica: Graf o(G, idV ertice) calcula el grado del vértice identificado por idV ertice en el grafo G. • Adyacentes : Graf o × id(V ertice) → ListadeV ertice Semántica: Adyacentes(G, idV ertice) obtiene el conjunto de vértices adyacentes al vértice identicado por idV ertice en el grafo G. • Incidentes : Graf o × id(V ertice) → ListadeLado Semántica: Incidentes(G, idV ertice) obtiene el conjunto de lados a incidentes en el vértice identificado por idV ertice en el grafo G. La clase concreta GrafoNoDirigido tendrá los operadores adicionales: • AgregarArista : Graf o × Arista → Graf o Semántica: AgregarArista(G, a) agrega la arista a al grafo G previamente creado. • EliminarArista : Graf o × id(Arista) → Graf o Semántica: EliminarArista(G, idArista) elimina la arista identificada cada por idArista del grafo G. La clase concreta GrafoDirigido tendrá los operadores adicionales: • AgregarArco : Graf o × Arco → Graf o Semántica: AgregarArco(G, a) agrega el arco a al grafo G. • EliminarArco : Graf o × id(Arista) → Graf o Semántica: EliminarArco(G, idArista) elimina el arco identificado por idArista del grafo G. • GradoInterior : Graf o × id(V ertice) → Entero Semántica: GradoInterior(G, idV ertice) calcula el grado interior del vértice identificado por idV ertice en el grafo G. • GradoExterior : Graf o × id(V ertice) → Entero Semántica: GradoExterior(G, idV ertice) calcula el grado exterior del vértice identificado por idV ertice en el grafo G. 2 • Sucesores : Graf o × id(V ertice) → ListadeV ertice Semántica: Sucesores(G, idV ertice) calcula el conjunto de vértices sucesores del vértice identificado por idV ertice en el grafo G. • P redecesores : Graf o × id(V ertice) → ListadeV ertice Semántica: P redecesores(G, idV ertice) calcula el conjunto de vértices predecesores del vértice identificado por idV ertice en el grafo e G. Recuerde verificar las cotas teóricas de cada operación para implementar cada una de la manera más eficiente posible. Para verificar el funcionamiento de la implementación del TAD Grafo, deberá desarrollar una pequeña aplicación que permita, por medio de un menú de texto acceder a todas las funciones del TAD. Además se debe proveer un medio que permita visualizar en texto cada grafo creado en cualquier momento. Adicionalmente, debe escribir una rutina que permita leer un grafo desde un archivo y cargarlo a la lista de grafos disponibles en memoria, ası́ como la selección de alguno de los grafos leı́dos para trabajar con él. 2 Archivo de Entrada El archivo de texto tendrá el siguiente formato: • La primera lı́nea contendrá la cadena ’d’ o ’n’ para indicar si es un grafo dirigido o no. • La segunda lı́nea contendrá un número entero n que indica el número de vértices. • La tercera lı́nea contendrá un número entero m que indica el número de lados. • Seguirán n lı́neas, cada una definiendo un vértice. Cada linea contiene un String que corresponde a su identificador y un real que corresponde a su peso, separadas por un espacio en blanco. • Seguirán m lı́neas, cada una definidiendo un lado. Cada linea contiene dos Strings que corresponden a los identificadores de los vertices sobre los que se creará el lado4 , y un doble que representa el peso del lado. Todos los valores estarán separados por espacios en blanco. 3 Entrega Para el dı́a miercoles de la semana 4 a las 1:30pm usted deberá entregar en clase un sobre cerrado debidamente identificado con nombre, carnet y profesor de laboratorio. Dentro del sobre deberán estar incluido: • Listados (documentados) de los fuentes del TAD Grafo y la aplicación de prueba • Un CD debidamente identificado, libre de virus y defectos fı́sicos cuyos únicos directorios sean bin/ (conteniendo los .class), src/ (conteniendo los .java) doc/ (conteniendo la documentación generada con javadoc). • Un informe que describa el proyecto y su implementación. En la página del curso podrá encontrar la información de estructura y formato para el mismo. Además, cada grupo deberá enviar un correo a su profesor de práctica donde este un zip con el codigo del proyecto. No se aceptan proyectos por correo que no tengan un respaldo impreso. 4 Criterios de Corrección Se corregirá la ejecución y la calidad del código. Toda entrega que no pueda ser compilada sin errores tendrá CERO en la ejecución. Se corregirá la correcta implementación del TAD y el uso correcto de las facilidades del lenguaje Java. Todas las operaciones debe ser implementadas en función de las cotas óptimas que se revisaron en la teorı́a. En caso de alguna decisión particular de diseño la misma debe estar explicada y justificada en el informe. 4 En el caso de los digrafos el primer vertice es el origen 3