UNIVERSIDADE FEDERAL DO RIO GRANDE DO SUL INSTITUTO DE INFORMÁTICA Simulador didático de testes de algoritmos de ordenação Nomes: Bruno Silva Guedes (159033) Matheus de Carvalho Proença (160184) Turma: C Professor: José Valdeni de Lima INF 01124 – Classificação e Pesquisa de Dados Porto Alegre, Julho de 2008 1. Resumo O aprendizado e a compreensão de como funcionam os algoritmos básicos de classificação de dados é fundamental para o estudante da área da Computação. Este projeto oferece a futuros alunos uma ferramenta que auxilie e facilite este aprendizado. O projeto consiste na criação e elaboração de um software que permite ao aluno analisar e comparar o funcionamento e o desempenho de oito algoritmos clássicos de ordenamento. 2. Introdução O projeto implementado em nosso trabalho é um software, de fácil uso e com várias ferramentas, que permite ao aluno modelar e analisar o comportamento de algoritmos de ordenação em diversas situações. A idéia é que o usuário possa manipular, por exemplo, a quantidade de dados a ser ordenado e o intervalo das chaves (supondo que sejam valores inteiros). Além disso, o usuário deverá comparar os diversos algoritmos de classificação por desempenho em relação a tempo, número de comparações, número de trocas, etc. Implementamos os seguintes algoritmos de ordenação: Bubble Sort, Selection Sort, Insertion Sort, Heap Sort, Merge Sort, Quick Sort, Counting Sort e Radix Sort. Note que podemos dividir os algoritmos em 3 “classes”, conforme sua complexidade temporal: - Algoritmos de tempo de execução O(n²) – Bubble, Selection e Insertion - Algoritmos de tempo de execução O(lg n) – Heap, Merge e Quick - Algoritmos de tempo de execução O(n) – Counting e Radix. Exibiremos gráficos mostrando diversas características dos algoritmos de ordenação dependendo do número de chaves (número de comparações, número de trocas, tempo de execução, etc). 3. Implementação Primeiramente, implementamos os oito algoritmos de classificação na linguagem C++. Para verificação de erros e pela linguagem, era mais fácil implementar os algoritmos em C++ primeiro e convertê-los para Java em seguida. Para elaborar os oito algoritmos, fizemos uso do conhecimento adquirido ao longo das aulas e com auxílio de livros e de sites da Internet. Bubble Sort, Selection Sort, Insertion Sort, Counting Sort e Quick Sort possuem implementação trivial. Não tivemos nenhum problema com eles. Com o Radix Sort, era preciso utilizar um método estável para classificar o vetor segundo um dígito qualquer do número. Para isso, usamos Selection Sort. Para retornar o dígito de um número, foi preciso desenvolver uma função que retornasse um dígito d de um certo número n. Essa função teve que ser desenvolvida do zero, e nos custou algum tempo até que a acertassemos. O Merge Sort e o Heap Sort apresentavam problemas devido à recursão. Foi demorado para obter um algoritmo consistente, isto é, que funcionasse em todos os casos. Para obter a solução ideal, tivemos que recorrer a alguns livros e sites das Referências do projeto. A conversão dos algoritmos de C++ para Java não é difícil. O que foi difícil foi criar uma classe em Java que interpretasse os valores recebidos dos arquivos de classificação para os gráficos que queriamos plotar. Para isso, foi necessário criar uma classe que abstraísse ao máximo a implementação dos gráficos. Ela acabou sendo usada tanto para a análise de ordenação quanto para o relatório. Também houve dificuldades em manipular as janelas graficamente com Java, por que os gráficos eram gerados em janelas separadas pelo JFreeChart. Conseguimos manipular a geração das janelas e fazer com que o fechamento de uma não encerrasse o programa. A interface gráfica foi de fácil aplicação, graças aos poderosos recursos do NetBeans IDE 6.1. Por causa dessa ferramenta, foi possível implementar inúmeras funcionalidades extras ao nosso programa. 4. Utilizando o Programa 4.1. Especificações Algumas limitações são naturalmente impostas ao programa, principalmente no que se refere ao tempo de execução dos algoritmos de ordenação. As seguintes especificações são fixadas: BUBBLE SORT e RADIX SORT Resolução máxima: 50 Número máximo de chaves: 5000 INSERTION SORT e SELECTION SORT Resolução máxima: 100 Número máximo de chaves: 5000 QUICK SORT, MERGE SORT, HEAP SORT e COUNTING SORT Resolução máxima: 1000 Número máximo de chaves: 50000 Nota-se que, apesar do algoritmo Radix Sort ter um desempenho teoricamente igual a O(n), ele depende do desempenho do vetor de ordenação a cada passada. Na prática, ele tem desempenho pior que o Bubble Sort, por ser um Selection Sort multiplicado por uma constante (igual ao número de dígitos do maior elemento). 4.2. Modo de Análise (adaptado da Ajuda do programa) A análise de ordenação permite ao usuário comparar, de forma gráfica, a performance dos diversos algoritmos de classificação ao longo do tempo, por número de trocas ou por número de comparações. O usuário deve selecionar os algoritmos de ordenação desejados na caixa de seleção. Ele também pode escolher o número de chaves desejadas e o intervalo no qual estas chaves variam (sempre números inteiros positivos). No campo Resolução, deve ser informado quantas vezes o programa deve calcular os pares ordenados correspondentes a cada algoritmo. Para algoritmos de ordem O(n²) como o Bubble Sort, se este número for muito grande, o programa poderá demorar para executar estes cálculos. Para os casos dos gráficos "ideais" (O(n²), O(n lg n) e O(n)), o gráfico pode ser multiplicado por uma constante para que seja possível visualizar a aproximação dos gráficos ideais com os gráficos dos algoritmos. Para isso, é possível informar no campo correspondente do gráfico ideal uma constante POSITIVA diferente de 1 (tal como 2 para duplicar a amplitude do gráfico ou 0.5 para reduzir a amplitude à metade). Por fim, há ainda a opção Exibir, que define qual será o eixo das ordenadas (o eixo das abscissas é fixo como sendo o número de chaves). As opções são tempo de execução, número de trocas e número de comparações. 4.3. Relatório (adaptado da Ajuda do programa) O relatório serve para obter dados relativos a uma análise textual do desempenho dos algoritmos. Para executar a análise por relatório, basta selecionar os métodos de organização desejados e também quais grandezas deverão ser exibidas. Esta simulação pode demorar vários minutos, pois são executadas medidas com até dez mil chaves. Os resultados serão exibidos na Janela de Relatório. O último relatório pode ser acessado a partir de Ferramentas -> Exibir último relatório (ou pelo atalho F3). 5. Material do Software Todo o material do software está disponível no seguinte endereço: www.inf.ufrgs.br/~bsguedes/simulador/ Neste endereço, estão disponíveis: 5.1. Dados do Grupo 5.2. Documentação 5.3. Executável do Software 5.4. Slides do PowerPoint 5.5. Código Fonte 5.6. Ferramentas de Desenvolvimento 5.7. Referências Bibliográficas 6. Referências Bibliográficas Livros consultados: Azeredo, P.A. Métodos de Classificação de Dados e análise de suas complexidades. Rio de Janeiro, Campus, 1996. Santos, C.L.; Azeredo, P.A. Tabelas: organização e pesquisa. Porto Alegre, Sagra-Luzzatto, 2001. Horstmann, C.S. Big Java 2nd edition. Hoboken, John Wiley & Sons, 2006. Drozdek, A. Estruturas de Dados e Algoritmos em C++. São Paulo, Thomson Learning, 2002. Websites: JFreeChart: www.jfree.org/jfreechart/ Docs Java API: http://java.sun.com/j2se/1.5.0/docs/api/ Wikipedia – Merge Sort: http://en.wikipedia.org/wiki/Merge_sort Wikipedia – Heap Sort: http://en.wikipedia.org/wiki/Heapsort