A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

Métodos de Ordenação Desempenho, Método de Shell, Quicksort.

Apresentações semelhantes


Apresentação em tema: "Métodos de Ordenação Desempenho, Método de Shell, Quicksort."— Transcrição da apresentação:

1 Métodos de Ordenação Desempenho, Método de Shell, Quicksort

2 Análise de Desempenho A análise de desempenho visa determinar uma função (f) que permita computar o tempo gasto por um algoritmo. F é função do tamanho da entrada do algoritmo

3 Exemplo Determinar a função de desempenho da função troca vetores: void trocavetores(int a[],int b[], int n) { int i; for(i=0;i

4 Desempenho 1.Atribuir custo às operações usadas no algoritmo: void trocavetores(int a[],int b[], int n) { int i; n for(i=0;i

5 Desempenho Considerar só as operações relevantes para o desempenho. Operações podem ser desprezadas se forem insiginificantes com relação as operações relevantes: void trocavetores(int a[],int b[], int n) { int i,x,y; n for(i=0;i

6 Desempenho Um loop dentro de outro void leMatrizQuadrada(int m[MAX][MAX], int n, FILE *arq){ int i,j; n for(i=0;i

7 Desempenho Em algoritmos de ordenação f é determinada em função do tamanho do vetor As operações relevantes são as comparações e trocas

8 Desempenho método da seleção algoritmo seleção (int a[], int n){ L1 Para i da primeira posição até a penúltima faca 0 mínimo = i L2 para j da posição seguinte a i até a ultima posição faça 1 se (a[j] < a[mínimo] minimo =j; fim para 1 troca(a[mínimo],a[i]); fim para fim algoritmo L1 = n-1 L2 = (n-1) + (n-2) = n*(n-1)/2 F(n) = (n*(n-1)/2)*1 + (n-1)*1 F(n) = n*(n-1)/2 + (n-1)

9 Desempenho Método da Inserção Algoritmo insercao(int A[], int n) (n-1) para j do segundo elemento até o último faça x = A[j]; i=j-1; (???) enquanto (i >= 0 e A[i] > x) faça A[i+1]=A[i]; i = i-1; fim enquanto A[i+1]=x; fim para fim algoritmo 1

10 Desempenho Método da Inserção Em algoritmo como o método da inserção (devido ao loop mais interno) o desempenho não depende somente do tamanho da entrada, depende também do formato da entrada. Neste caso o formato é: o vetor já está ordenado, está parcialmente ordenado, invertido, formato aleatório. Nestes casos temos que considerar: –O melhor caso –O pior caso –O caso médio

11 Desempenho Método da Inserção Calculando o custo do loop mais interno. C i é o custo deste loop na i-ésima interação do loop mais externo: –Melhor caso: C i (n) = 1, –Pior caso: C i (n) = i, –Caso Médio: C i (n) = 1 / i * ( i) = (i+1)/2 Ex: i = 2, = ½ *(1+2), 50% de chance haver uma interação e 50% de chance de haver duas interações.

12 Desempenho Método da Inserção F(n) = C 2 + C C n Calculando o valor de f, temos que considerar os 3 casos: –Melhor Caso: f(n) = ( ) = n-1 –Pior caso: f(n) = ( n) = n 2 /2 + n/2 –1 –Caso médio: f(n) = ½ ( n +1) = n 2 /4 + 3n/4 -1

13 Desempenho Método da Bolha algoritmo bolha ( int a[],int n) L1 Para i do ultimo elemento até o segundo faça L2 para j do segundo elemento até i faça 1 se (a[j-1]>a[j]) 1 troca(&a[j-1],&a[j]); } Melhor caso: f(n) = n 2 /2 Pior caso: f(n) = 2 n 2 Caso médio: f(n) = 5n 2 /2 Observação: Vejam a implementação do bolha em Assembly em Não é fácil programar em C?

14 Exercício Obter as expressões do pior, melhor e caso médio para o método da bolha.

15 Método de Shell (Shell Sort) Método inventado por Shell. Consiste em aplicar o método de inserção em elementos não adjacentes do vetor. Algoritmo: –Inicialmente, é determinada uma distância d. –Todos os elementos localizados no vetor separados por uma distância d são ordenados. –A cada iteração a distância d é reduzida de acordo com alguma seqüência. –Na ultima iteração esta distância é reduzida a 1. Este passo corresponde ao método de inserção original.

16 Método de Shell Exemplo: –Vetor: [35,28,16,07,12,08,04] - –Seqüência de Distâncias: - {3,1} está ordenado, 7 é comparado {07,35} está ordenado, 4 é comparado {04,07,35} está ordenado está ordenado, 12 é comparado {12,28} está ordenado está ordenado, 35 é comparado {08,16} está ordenado Passo 2 : d =1 equivalente ao método da inserção

17 Método de Shell Algoritmo shell(int A[], int n, int d) para j de d até o último elemento faça x = A[j]; i=j-d; enquanto (i >= 0 e A[i] > x) faça A[i+d]=A[i]; i = i-d; fim enquanto A[i+d]=x; fim para fim algoritmo Quando d = 1 equivale ao algoritmo de inserção: Algoritmo insercao(int A[], int n) para j do segundo elemento até o último faça x = A[j]; i=j-1; enquanto (i >= 0 e A[i] > x) faça A[i+1]=A[i]; i = i-1; fim enquanto A[i+1]=x; fim para fim algoritmo

18 Método de Shell O algoritmo ordena os elementos separados uma distância d. A distância d é dada por uma seqüência decrescente. Para cada valor de d chamamos o algoritmo shell Exemplo: shellSort1(int a[], int n) { int d[2] = {3,1}; int p,nd =2; for (p=0;p

19 Método de Shell A seqüência {3,1} pode não ter eficiência para grandes vetores. Não existe uma seqüência ideal. Donald Knuth mostrou empiricamente que a seqüência ( 1, 4, 13, 40, 121, 364, ) apresenta eficiência 20 % maior que outras seqüências.

20 Método de Shell Implementação da seqüência de Knuth: #define MAX xxxxx // tamanho máximo do vetor void shellsort2(int a[],int n) { int i,p=0, d[MAX/9]; if((n/9)<1){ // trata vetores < 9 p =1; d[0]=1; } else { // gera sequencia de knuth no vetor d for (i=1;i<=n/9;i=3*i+1) { d[p] =i; p++; } for (i=p-1;i>=0;i--) { // executa shell printf("%d \n", d[i]); shell(a,n,d[i]); }

21 Método Quicksort (QS) Baseado na estratégia Dividir para conquistar. Algoritmo: 1.Inicialmente, o vetor a[0..n-1] é subdividido em dois vetores – a[0..p] e a [ p+1.. r] não vazios – cada elemento de a[0..p] é menor ou igual a cada elemento de a[p+1..n-1]. –A[p] é chamado pivô da iteração. –O valor de p é escolhido arbitrariamente. Um escolha trivial é o pivô central p = (esq + dir)/2 2.Os dois subvetores a[0..p] e a[p+1..n-1] são ordenados por chamadas recursivas do QS. Ou seja, repete-se o passo 1 para cada um dos subvetores, recursivamente.

22 Método Quicksort A operação que divide os elementos do vetor entre maiores e menores que o pivô é chamada de particionamento. Exemplo: a = { 12, 7, 3, 2, 10, 1, 0}, n =7, n-1 = 6 particiona (a,0,6) - escolhe o pivô: q = (0+6)/2=3 a[q] = 2 troca 12 com 0 troca 7 com 1 troca 2 com 3 O vetor ficou: {0,1,2,3,10,7,12} Repete o particionamento para a[0..2] e a[3..6]

23 Método Quicksort a[0..2] = {0,1,2} Particiona(a,0,2) pivô = 1 Não há trocas a[3..6] = {3,10,7,12} Particiona(a,3,6) pivô = q= (3+6)/2 = 4 a[4] = 10 Troca 10 com o 7 No final o vetor está ordenado: {0,1,2,3,7,10,12}

24 Método Quicksort void particiona(int a[], int esq,int dir, int *pi, int *pj) { int x, i,j; i = esq; j = dir; x = a[(i+j)/2]; // obtém o pivô desta partição faça { procuro por a[i] do lado esquerdo menor que o pivô procuro por um a[j] do lado direito maior que o pivô } se i e j não se cruzarem eu encontrei elementos para trocar troca(a[i],a[j]); avanço o i para depois do elemento trocado avanço o j para antes do elemento trocado } enquanto(i< j); retorno o i e o j para servirem de limites para as novas partições }

25 Método quicksort void particiona(int a[], int esq,int dir, int *pi, int *pj) { int x,i,j; i = esq; j = dir; x = a[(i+j)/2]; // obtem o pivo desta particao faça { // procuro a[i] > x a esquerda enquanto((x > a[i]) && (i

26 Método quicksort ordenaQS(int a[], int esq, int dir) { int i,j; particiona(a, esq,dir, &i,&j) se (esqi) ordenaQS(a,i,dir) } quicksort(int a[],int n) { ordenaQS(a,0,n-1) }

27 Método quicksort Desempenho: –Melhor caso: n log( n ) –Caso médio: n log( n ) –Pior caso: n 2 Pesquisa sobre o desempenho do Quicksort, Fonte – livro referência - Nivio Ziviani – Projeto de algoritmos –http://www.google.com


Carregar ppt "Métodos de Ordenação Desempenho, Método de Shell, Quicksort."

Apresentações semelhantes


Anúncios Google