Estructuras de datos: Proyecto 2 28 de mayo de 2013 Instrucciones Enviar las soluciones por email a los ayudantes, con copia a la profesora. Plazo de entrega: 16 de junio (durante todo el día). Se debe incluir: Todos los archivos java. Documentación en HTML para las clases e interfaces, usando la herramienta javadocs (para las preguntas de programación) Un informe donde se detallan las respuestas a cada pregunta, con sus respectivo desarrollo y conclusiones. (No incluir código en el informe) Se debe indicar claramente, para las pregunta de programación, el nombre de los archivos con el código y la manera de ejecutar. El informe debe estar en formato PDF. 1. PR-QuadTree Hasta el momento, todas las estructuras de datos que hemos visto están diseñadas para realizar búsqueda sobre claves unidimensionales. No obstante, existen diversas estructuras de datos que permiten búsquedas sobre claves bidimensionales (incluso n-dimensionales). Un ejemplo de estas estructuras es el PR-QuadTree, una de las versiones de la estructura QuadTree[1] Para realizar búsquedas bidimensionales, se deben entender otros conceptos. Imagine un mapa o plano en el cual están marcadas distintas cuidades. Cada ciudad puede ser determinada de manera unívoca a través de sus coordenadas (x,y). De esta manera, las búsqueda, inserciones, eliminaciones, etc deben considerar esta clase bidimensional y no sólo una de sus componentes. El PR-QuadTree tiene por objetivo representar en poco espacio puntos en el plano, en especial, zonas en las cuales se pueden encontrar muchos puntos contiguos o muchos espacios en blanco. Cada nodo de este árbol se tiene 5 componentes: Una lista de 4 enlaces a nodos, uno por cada cuadrante. Un entero que representa la coordenada x. Un entero que representa la coordenada y. 1
Figura 1: Plano con puntos. Un campo para almacenar información extra acerca del punto (el nombre de la ciudad, por ejemplo). Un campo que representa el tipo de nodo, el cual puede tomar los valores blanco, negro o gris. Si un nodo es blanco, indica que el cuadrante que representa no contiene puntos, por otro lado, si es negro, indica que el cuadrante que representa está compuesto únicamente por puntos. Finalmente, un nodo gris indica que en su cuadrante hay tanto espacios vacíos como puntos. Antes de dar más detalles, miremos el siguiente ejemplo. Imagine que tiene el plano de la Figura 1, donde cada punto puede representar cualquier cosa ubicada en el plano, ya seas ciudades, cajas, etc. Inicialmente tomamos todo el plano como un solo cuadrante. En este caso, ya que el plano está compuesto por puntos y zonas sin puntos, lo podemos representar como un nodo gris, como se aprecia en la Figura 2. El siguiente paso, una vez que representamos el plano como un punto (obteniendo la raíz del árbol), es dividir nuestro plano en 4 cuadrantes, enumerando cada uno de ellos de manera conveniente. La manera de realizar la división es dividiendo el plano en 4 cuadrantes de igual tamaño. A su vez, se analiza cómo está compuesto cada uno de los 4 cuadrantes, clasificándolos como nodos blancos, grises o negros. Estos 4 nuevos nodos corresponden a los 4 hijos del nodo en el paso previo. El resultado se puede apreciar en la Figura 3 Recursivamente se aplican los mismos pasos a cada cuadrante. Si nos centramos en el primer cuadrante del paso anterior, veremos que al dividirlo en 4 nuevos cuadrantes, obtenemos 2 de ellos compuestos exclusivamente por zonas sin puntos. Por esta razón, estos cuadrantes serán representados como nodos blancos en el PR-QuadTree. Una vez llegado a este punto, no es necesario seguir 2
Figura 2: Primer nivel. Figura 3: Segundo nivel. 3
Figura 4: Tercer nivel. dividiendo este cuadrante. Lo mismo ocurre para nodos negros. En otra palabras, sólo los nodos grises deben seguir dividiéndose. Se puede apreciar el resultado de este paso en la Figura 4. Debido a que en el paso anterior todavía existen nodos grises, se aplican los mismos pasos recursivamente a cada cuadrante gris. Al hacer esto, se obtiene el plano subdividido de la Figura 5 y el árbol de la Figura 6. Como se puede apreciar, todas las hojas del PR-QuadTree son blancas o negras y todos los nodos internos son grises. Nótese que este versión de QuadTree puede ser fácilmente extendida a una que soporte en cada coordenada (x,y) más de un punto, añadiendo una lista que almacene los puntos que comparten la misma coordenada. Otro punto importante a considerar es lo que anteriormente se llamo enumeración conveniente de los cuadrantes. Esta enumeración (asginación de un nombre) es importante, ya que el primer cuadrante será representado por el nodo de más a la izquierda en el nivel correspondiente, el cuarto cuadrante será el nodo de más a la derecha en ese mismo nivel y los otros dos cuadrantes seguirán ese orden creciente. Es por ello que, una vez acordado la enumeración, esta se debe mantener para todas las operaciones sobre el árbol. Pseudo-códigos de las operaciones básicas sobre el PR-QuadTree se pueden encontrar en [1]. Para este proyecto se pedirá implementar los siguientes métodos sobre el PR-QuadTree: Inserción de un nuevo punto p en las coordenadas (x,y). Eliminación de un punto p en las coordenadas (x,y). Cantidad de puntos en una región del plano, tomando como centro un punto p (coordenadas (x,y)) y una distancia d. Representación como plano (imagen) del PR-QuadTree. Inserción de un nuevo punto en el cuadrante con mayor cantidad de espacios vacíos. Para esto, imagine que le piden proponer la ubicación de una nueva ciudad a construir, de manera tal que la distribución de las ciudades sea lo más homogénea posible. 4
Figura 5: Última división recursiva. Figura 6: Cuarto nivel y final. 5
Figura 7: Región en el plano con centro (2,4) y distancia 2. Un ejemplo del punto 3, cantidad de puntos en una región, sería por ejemplo: Cuántos puntos hay en la región con centro (2,4) y distancia 2? La representación de dicha área se puede ver en la Figura 7 y su respuesta es 4. Consideraciones: Tome en consideración lo siguiente: Para efectos de evaluación, sólo se considerarán potencias de 2 como dimensiones del plano. Las coordenadas comenzarán desde 0. Su implementación debe tomar como entrada un plano con puntos en formato texto, para la construcción inicial del PR-QuadTree. Dicho formato será el siguiente: La primera línea contendrá el tamaño del plano. Sólo se trabajará con planos cuadrados. Sólo se representarán los puntos en el plano, no los espacios sin contenido. Cada línea del archivo de entrada representará a un único punto. Cada punto tendrá el formato: cord-x,cord-y,info. Por ejemplo, el plano de la Figura 1 sería representado de la siguiente manera (en un archivo.txt): 8 0,0,punto 1 4,1,punto 2 1,2,punto 3 6,2,punto 4 4,4,punto 5 5,4,punto 6 4,5,punto 7 5,5,punto 8 7,5,punto 9 6
1,6,punto 10 6,7,punto 11 Nota: Como punto de inicio para dibujar el plano, en java, pueden seguir los siguientes enlaces: http://www.youtube.com/watch?v=aqly7sv8wwa http://todojava.awardspace.com/ejemplos-java.html?desc=figuras http://graficos-12.blogspot.com/ Forma de evaluar: La evaluación de esta parte del proyecto será de la siguiente manera: Se probarán al menos 3 planos distintos, con el formato descrito anteriormente, se aplicarán algunas operaciones, como inserción de nuevos puntos y/o eliminación de ellos y se revisará la imagen resultante de aplicar todos esos cambios. Además se realizarán algunas consultas del tipo cantidad de nodos en un región. 2. Contador de caracateres En esta parte del proyecto, se pide implementar un contador de caracteres. Las características que deberá cumplir este contador son: Trabajará usando caracteres ascii 1. No confundir con el ascii extendido, aunque deben pensar la implementación de la manera más genérica posible. Este contador no deberá discriminar entre mayúsculas y minúsculas para el caso de las letras. Por ejemplo, la letra A será considerada como la misma que a. El contador deberá ser implementado usando tablas hash. Como entrada, el contador deberá recibir un archivo de texto y como salida, deberá entregar una lista impresa con todas los caracteres presentes en el archivo. Nota: Deden considerar que hay caracteres en ascii que no son imprimibles, pero al ser parte del ascii, deben ser considerados de igual manera, como es el caso de \n o \r. Por ejemplo, si el archivo de entrada fuese como la Figura 8, la respuesta debería ser la siguiente: \n: 69!: 1024 (espacio): 1856 : 52 $: 1015 1 http://es.wikipedia.org/wiki/ascii 7
: 104 +: 1 -: 7,: 38 /: 3.: 47 3: 1 7: 1 ;: 43?: 12 =: 4 <: 22?: 42 >: 37 : 55 c: 51 d: 12 f: 9 i: 2 h: 12 l: 1 p: 3 r: 2 z: 7 Para poder evaluar de manera más simple la correctitud de la implementación, se adjuntará un script en python que cuenta caracteres, retornando la frecuencia de cada uno. Para su ejecución, bastará con correr por consola: python characterscounter.py <input text> Forma de evaluar: Esta sección se evaluará de la siguiente manera: Se tendrán al menos 3 archivos compuestos de caracteres ascii, los cuales serán la entrada del contador que se pide implementar. Luego, se comparará la lista resultante con la entregada por el script en python. Si ambas son iguales, para todos los archivos, se considerará que el contador está correcto. Referencias [1] Samet, Hanan, The design and analysis of spatial data structures. Addison- Wesley Longman Publishing Co., Inc., 1990. Pages 92-103. URL: http://cdn.preterhuman.net/texts/math/data_structure_and_ Algorithms/TheDesignAndAnalysisOfSpatialDataStructures-HananSamet. pdf 8
Figura 8: Imagen ascii. 9