19.05.2013 Views

Algoritmos e Estruturas de Dados I

Algoritmos e Estruturas de Dados I

Algoritmos e Estruturas de Dados I

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

<strong>Algoritmos</strong> e <strong>Estruturas</strong> <strong>de</strong> <strong>Dados</strong> I<br />

Projeto <strong>de</strong> Implementação<br />

Comparação Empirica dos<br />

<strong>Algoritmos</strong> <strong>de</strong> Or<strong>de</strong>nação<br />

(Data <strong>de</strong> entrega 08/05)


Projeto proposto pelo<br />

Prof. André Balan


Objetivo<br />

● Realizar um estudo empírico do consumo <strong>de</strong><br />

tempo dos algoritmos <strong>de</strong> or<strong>de</strong>nação vistos em<br />

classe.


● Pouco eficientes:<br />

– BubbleSort<br />

– InsertionSort<br />

– SelectionSort<br />

● Mais eficientes:<br />

– QuickSort<br />

– HeapSort<br />

– MergeSort<br />

<strong>Algoritmos</strong>


O Módulo <strong>de</strong> Or<strong>de</strong>nação<br />

● Criar um “Módulo <strong>de</strong> Or<strong>de</strong>nação”<br />

– Interface: or<strong>de</strong>nacao.h<br />

– Implementação: or<strong>de</strong>nacao.c<br />

● A interface será dada a seguir, e você não po<strong>de</strong>rá<br />

mudá-la<br />

● Você <strong>de</strong>verá <strong>de</strong>finir as funções <strong>de</strong>claradas na<br />

interface no arquivo or<strong>de</strong>nacao.c (que <strong>de</strong>verá<br />

incluir a interface, ou seja, <strong>de</strong>verá fazer<br />

#inclu<strong>de</strong> "or<strong>de</strong>nacao.h")


#ifn<strong>de</strong>f _ORDENACAO_H<br />

#<strong>de</strong>fine _ORDENACAO_H<br />

Interface<br />

void bubble_sort(int *v, int n);<br />

void insertion_sort(int *v, int n);<br />

void selection_sort(int *v, int n);<br />

void quick_sort(int *v, int n);<br />

void merge_sort(int *v, int n);<br />

void heap_sort(int *v, int n);<br />

#endif


Detalhes <strong>de</strong> Implementação<br />

● Todas as funções recebem um vetor v <strong>de</strong> inteiros<br />

(passado sob forma <strong>de</strong> ponteiro) e o número<br />

n <strong>de</strong> elementos <strong>de</strong>sse vetor.<br />

● Em sala, <strong>de</strong>finimos as funções quick_sort e<br />

merge_sort recebendo três parâmetros como<br />

(int *v, int p, int r).<br />

● Para po<strong>de</strong>r implementá-las do modo como foi<br />

pedido, você po<strong>de</strong>rá <strong>de</strong>finir novas funções<br />

<strong>de</strong>ntro <strong>de</strong> or<strong>de</strong>nacao.c (que não serão visíveis<br />

fora <strong>de</strong>sse arquivo e que só po<strong>de</strong>rão ser<br />

chamadas <strong>de</strong> <strong>de</strong>ntro <strong>de</strong> or<strong>de</strong>nacao.c).


Metodologia<br />

● Após criar o Módulo <strong>de</strong> Or<strong>de</strong>nação, criar um<br />

programa para realizar o estudo empírico dos<br />

métodos <strong>de</strong> or<strong>de</strong>nação implementados.<br />

● Cada algoritmo <strong>de</strong> or<strong>de</strong>nação <strong>de</strong>verá ser testado<br />

com vetores <strong>de</strong> elementos do tipo int,<br />

dos seguintes tamanhos:<br />

● 10.000<br />

● 30.000<br />

● 90.000<br />

● 270.000<br />

● 810.000<br />

● 2.430.000<br />

● 7.290.000<br />

● 21.870.000<br />

● 65.610.000


Gerando vetores aleatórios<br />

● Os vetores são compostos por números inteiros,<br />

com distribuição uniforme, gerados com a<br />

função rand() da biblioteca stdlib.h<br />

– v[i] = rand();<br />

– /* gera um inteiro entre 0 e 2.147.483.647 */<br />

● Para cada tamanho <strong>de</strong> vetor, o programa <strong>de</strong>ve<br />

rodar cada método <strong>de</strong> or<strong>de</strong>nação com 6<br />

sequências aleatórias diferentes:<br />

● (6 algoritmos) x (9 tamanhos) x (6 sequências) =<br />

324 or<strong>de</strong>nações


Garantindo comparação justa<br />

● Atenção: em cada “rodada” <strong>de</strong> or<strong>de</strong>nações,<br />

todos os algoritmos <strong>de</strong>vem or<strong>de</strong>nar a mesma<br />

sequência aleatória para que a comparação<br />

seja justa.<br />

● Como gerar a mesma sequência aleatória em<br />

tempos diferentes?


Garantindo comparação justa<br />

● Na verda<strong>de</strong>, os computadores geram números<br />

pseudoaleatórios.<br />

● Toda função que cria números pseudoaleatórios,<br />

cria uma sequência <strong>de</strong> números a partir<br />

<strong>de</strong> uma semente (seed).<br />

● Se as sementes usadas para a geração <strong>de</strong><br />

duas seqüências são iguais, as seqüências<br />

geradas serão iguais.


Gerando a mesma seqüência<br />

● Asssim, para criarmos duas sequências pseudoaleatórias<br />

idênticas em tempos diferentes,<br />

basta <strong>de</strong>finirmos a mesma semente (seed)<br />

para as duas sequências:<br />

// criamos uma sequência<br />

srand(seed);<br />

for (i = 0; i < n; i ++) v[i] = rand();<br />

// criamos uma sequência idêntica à anterior<br />

srand(seed);<br />

for (i = 0; i < n; i ++) v[i] = rand();


Sementes para cada seqüência<br />

● Neste trabalho, você <strong>de</strong>ve criar 6 sequências<br />

pseudoaleatórias. Para isso, você <strong>de</strong>verá utilizar<br />

as seguintes seeds:<br />

– seed[0] = 4<br />

– seed[1] = 81<br />

– seed[2] = 151<br />

– seed[3] = 1601<br />

– seed[4] = 2307<br />

– seed[5] = 4207


Metodologia (cont.)<br />

● Além disso, o programa também <strong>de</strong>ve realizar<br />

uma rodada <strong>de</strong> or<strong>de</strong>nações com uma sequência<br />

<strong>de</strong> 50.000 itens or<strong>de</strong>nados inversamente.<br />

● Atenção, o QuickSort po<strong>de</strong> falhar ao processar<br />

gran<strong>de</strong>s sequências: stack overflow!<br />

● Para que o QuickSort não estoure a pilha <strong>de</strong><br />

execução, use o particiona aleatorizado!


Metodologia (cont.)<br />

● Para cada or<strong>de</strong>nação o programa <strong>de</strong>ve medir:<br />

– o tempo total em milissegundos<br />

● Cada par (método, tamanho) terá 6 medições<br />

<strong>de</strong> tempo (uma para cada seqüência pseudoaleatória<br />

daquele tamanho)


Medindo o tempo <strong>de</strong>corrido<br />

● Como medir o tempo <strong>de</strong> uma or<strong>de</strong>nação?<br />

// Não se esqueça <strong>de</strong> incluir a biblioteca time.h<br />

#inclu<strong>de</strong> <br />

int inicio, final;<br />

int tempo_ms;<br />

start = (int) clock();<br />

// chamada da função <strong>de</strong> or<strong>de</strong>nação<br />

final = (int) clock();<br />

tempo_ms = ((final - inicio) * 1000 / CLOCKS_PER_SEC);<br />

printf("%d", tempo_ms);


Metodologia (cont.)<br />

● Após <strong>de</strong>senvolver o programa, chegou a hora<br />

<strong>de</strong> colocar pra rodar e ir dormir.<br />

● Deixe apenas o seu programa rodar. Não faça<br />

nada no computador enquanto o experimento<br />

estiver rodando (não mexa nem o mouse).<br />

● O programa <strong>de</strong>ve lhe retornar todos os dados<br />

necessários para você realizar o estudo empírico.


Resultados<br />

● Com todos os dados obtidos, você <strong>de</strong>ve elaborar<br />

um relatório contendo<br />

– gráficos que permitam uma comparação fácil e<br />

rápida entre os métodos<br />

– análise dos gráficos<br />

● Em um único gráfico, coloque várias curvas<br />

<strong>de</strong> tempo, uma para cada método. Cada ponto<br />

das curvas <strong>de</strong> tempo, é uma média aritmética<br />

<strong>de</strong> 6 medidas <strong>de</strong> tempo, uma para cada<br />

sequência aleatória.


Resultados<br />

● Muito provavelmente, os métodos ineficientes<br />

irão <strong>de</strong>sbalancear as comparações.<br />

● Sendo assim, você <strong>de</strong>ve <strong>de</strong>cidir se estes métodos<br />

<strong>de</strong>vem ser colocados em gráficos separados.<br />

● Você po<strong>de</strong> <strong>de</strong>cidir também, um timeout para<br />

cada experimento (vamos combinar 20 min)<br />

para que não <strong>de</strong>more a vida inteira para rodar<br />

o projeto todo.


Resultados<br />

● Se algum método exce<strong>de</strong>u 20min quando ao<br />

tentar or<strong>de</strong>nar um vetor <strong>de</strong> um certo tamanho,<br />

você não precisa rodar o experimento com<br />

outros vetores <strong>de</strong>sse tamanho ou maiores!<br />

● Para cada par (método, tamanho) que não foi<br />

rodado por completo, estimar o quanto ele<br />

<strong>de</strong>moraria para rodar e justificar sua estimativa.


Análise<br />

● O relatório <strong>de</strong>ve conter uma seção <strong>de</strong> análise,<br />

on<strong>de</strong> você <strong>de</strong>ve discutir os resultados obtidos<br />

empíricamente com as análise <strong>de</strong> complexida<strong>de</strong><br />

dos algotirmos vistas em aula.<br />

● Consulte a bibliografia indicada no site para<br />

tirar suas dúvidas.<br />

● Trabalho em duplas ou individual.


Entrega<br />

Todo o código fonte e o relatório em pdf<br />

(entregar no TIDIA até o dia 08/05)<br />

● Turma do matutino: fazer em C<br />

● Tidia matutino: BC1424-AED1-matutino<br />

● Turma do noturno: fazer em C ou C++<br />

● Tidia noturno: AED1-2012-1


Bom trabalho!

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!