|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Nesta página você poderá acompanhar como foi o desenvolvimento do projeto que escolhemos:
Problema do Par mais Próximo no R²
Como este projeto foi feito em C, há alguns requisitos básicos para o funcionamento:
- GLUT/Mesa
- GTK e GDK
- Biblioteca GTK GLArea Arquivo para instalação
É possível entrar com os pontos do conjunto no formato arquivo texto, ou
através de cliques do mouse.
O formato do arquivo texto deve ser:
3 --------------------> Número de pontos do conjunto
5.36 -5----------------> Coordenadas (x,y) dos pontos, um por linha
0 -1.2
1 2.04
Maiores informações podem ser encontradas no menu Ajuda do programa executável.
Relatório do desenvolvimento:
O objetivo desse relatório é descrever as tomadas de decisões que tivemos que fazer durante o desenvolvimento do projeto de Geometria Computacional, intitulado Problema do Par mais Próximo, realizado no ano de 2000. (Data de criação [início] do projeto: 23/05/2000) 23/05/2000: Ao pensarmos melhor no problema e na interface que teria que ser feita com o usuário, decidimos alterar a biblioteca que usaríamos. Ao invés de se utilizar a Mesa/GLUT, precisaremos usar a GTK, pois esta contém intrinsicamente funções usadas para controle de janelas, botões e caixas de diálogo. Quanto ao problema de desenho, vimos que todas as funções que usaríamos no Mesa, possuem equivalentes no GTK, não alterando muito o que tinhamos planejado. Pelo que vimos, há uma biblioteca chamada GDK, que pode ser usada em conjunto com o GTK, usada para desenhos. 20/06/2000: Retomamos o projeto, ainda pensando nas estruturas que teremos que utilizar para desenvolvermos o Problema do Par mais Próximo. Precisaremos ter: Estrutura para guardar os n pontos do R² : Lista duplamente ligada: P ={0,...,n-1} (D1,p1,p2) = ParProximo(P): Se #elementos <= 3, use força bruta e devolva (Dmin,pmin1,pmin2). Caso contrário: /* Divisão, conquista e combinação */ 2 PRÉ-PROCESSAMENTOS: - Ordenação dos pontos segundo as x-coordenadas (em caso de empate, use como decisão a coordenada y). [O(n.logn)] Coloque o resultado em um vetor X. - Ordenação dos pontos segundo as y-coordenadas (em caso de empate, use como decisão a coordenada x). [O(n.logn)] Coloque o resultado em um vetor Y. ALGORITMO de Divisão e Conquista [O(n)] Dividir: * Pegue o elemento do meio em X e considere-o como mediana do conjunto, chame-o de med. * Tome Pl o conjunto {0,...,med} de pontos. * Tome Pr o conjunto {med+1,...,n-1} de pontos. Conquistar: Resolver recursivamente para os dois conjuntos. * (Dl,pl1,pl2) = ParProximo(Pl). * (Dr,pr1,pr2) = ParProximo(Pr). * onde: Dr = dist(pr1, pr2); * Dl = dist(pl1, pl2); Combinar: * D = min(Dl, Dr); * Calcula-se todos os pontos de Pl a uma dist. <= D da reta vertical dada pela mediana em X (reta: x = med). => Conj. Pl' * Calcula-se todos os pontos de Pr a uma dist. <= D da reta vertical dada pela mediana em X (reta: x = med). => Conj. Pr'. * Para cada ponto p em Pl' faça: Encontre os pontos em Pr' a uma dist. máxima D de p: Para isso, projete p em y: Percorra Pr' e tome apenas os pontos q cujo cálculo: |q.y - p.y| <= D. O número máximo de q será 6. Calcule a distância entre p e cada q. No final encontraremos um par (p3,q3) que deverá ser o que tem menor distância nessa faixa entre Pl' e Pr'. * Para determinar o par mais próximo, teremos que determinar quem é o mínimo entre Dl = dist(pl1, pl2), Dr = dist(pr1, pr2), Dm = dist(p3, q3). Chame-os de Dmin, pmin1, pmin2 RETORNE: (Dmin, pmin1,pmin2). 27/06/2000: Início da implementação propriamente dita: Começamos a desenvolver as estruturas para guardar os pontos e também o algoritmo de ordenação dos pontos segundo suas x-coordenadas. Escolhemos o Quicksort como algoritmo de ordenação, seguindo uma implementação dada no livro do Sedgewick (Algorithms in C), que se o vetor a ser ordenado for menor que uma certa constante M, não se chama o Quicksort recursivamente. No final, é feita uma ordenação InsertionSort que rearruma os termos que não foram ordenados. Mesmo com essa passagem do vetor por um Insertionsort, o custo da ordenação ainda é O(n.log n). O algoritmo ainda não está perfeito, caso haja pontos com mesma coordenada x. Ou seja, ainda não colocamos o desempate pela y-coordenada. 28/06/2000: O algoritmo para ordenar em relação à x-coordenada foi arrumado. Ou seja, agora também está funcionando quando há empate na coordenada x dos pontos analisados. Também foi pensado uma forma rápida de reaproveitar o código e poder usá-lo para ordenação em relação à y-coordenada sem muitas alterações. 29/06/2000: Foi implementado o algoritmo para ordenação através das y-coordenadas dos pontos. A idéia foi tentar reaproveitar ao máximo o código que já tinhamos feito para ordenar em relação à x-coordenada. Partindo desse princípio, foram necessários apenas alguns ajustes nas funções que eram responsáveis pela comparação das coordenadas de dois pontos, que eram passados como parâmetros. Sendo assim, à parte do projeto que corresponde ao pré-processamento, que é a ordenação dos pontos em termos das x-coordenadas e y-coordenadas, já está feito. Resta apenas testar para quantidades realmente grande de números (mais de 30 pontos, por exemplo). 04/07/2000: Retomamos o projeto. Nosso objetivo hoje é começar a implementar a parte interna do programa, ou seja, a parte responsável pela determinação do par de pontos mais próximo. Estávamos com dúvida quanto ao real uso de 2 vetores ordenados (um em relação à X e outro em relação em Y), mas pensamos um pouco mais e estamos quase certos que um só será necessário. Também pensamos quanto à função distância que será definida pelo usuário. Definimos que: - Precisa haver um arquivo cabeçalho, com nome: distancia.h que é o protótipo da função que incluiremos no programa principal. - O cabeçalho da função deve ser: double Distancia(double, double, double, double); onde cada double recebido como parâmetro é na verdade uma coordenada do ponto ao qual queremos calcular a distância. Por exemplo, a chamada: Distancia(-5.6, 4.2 8.0, 0.33) Calcula a distância entre os pontos do R²: (-5.6, 4.2) e (8.0, 0.33). - O arquivo que contém a implementação da função deve se chamar: distancia.c Implementamos mais algumas estruturas que usaremos para guardar os pontos mais próximos e sua distância, um vetor de Pontos, que é a coleção onde armazenaremos os pontos do problema. Além disso, escrevemos operações básicas que mexam com essas estruturas. 05/07/2000: Detalharemos uma estrutura que será muito usada: Estrutura ParProximo: valor double para a distância. vetor com 2 Pontos, que são os mais próximos. Na parte da manhã, a função para calcular a distância mínima, Parproximo, foi codificada seguindo o pseudo-código que foi escrito nesse relatório no dia 20/06. O código só foi compilado e corrigido no início da tarde. A função Parproximo, que é a parte principal do programa entre os pontos do conjunto está completada e, pelos testes realizados, parece estar funcionando corretamente, devolvendo a estrutura que corresponde ao verdadeiro par de pontos que minimiza a distância. Falta realizar mais testes, no sentido de comprovar a validade do programa desenvolvido. Próximos passos: Interface gráfica, que ainda estamos em dúvida se utilizaremos GLUT/Mesa3D ou GTK (com GDK) ou ainda os dois juntos. 06/07 - 03/08: A Rede Linux ficou por duas semanas inoperante, o que nos forçou a trabalharmos na rede IME e também em casa. Tivemos que estudar o GTK e o GDK para fazermos a interface, o que já nos consumiu um bom tempo. Gastamos cerca de uma semana e meia ajustando o código à interface. No dia 03/08 o projeto já estava concluído e apresentamos ao professor. |