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

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

Desempenho, Método de Shell, Quicksort

Apresentações semelhantes


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

1 Desempenho, Método de Shell, Quicksort
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 Determinar a função de desempenho da função troca vetores:
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<n;i++) troca(&a[x],&b[x]); }

4 Desempenho Atribuir custo às operações usadas no algoritmo:
void trocavetores(int a[],int b[], int n) { int i; n for(i=0;i<n;i++) 1 troca(&a[x],&b[x]); } 2. Considerar os loops multiplicando os custos: f(n) = n * 1

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<n;i++){ 0 x=a[i]; 0 y=b[i] 1 troca(&x,&y); 0 a[i]=x; 0 b[i]=y; } f(n) = n * 1

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<n;i++) { n for(j=0;j<n;j++) { 1 fscanf(arq,”%d”, &m[i][j]); } f(n) = n*n*1 = n2

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 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. Ci é o custo deste loop na i-ésima interação do loop mais externo: Melhor caso: Ci(n) = 1, Pior caso: Ci(n) = i, Caso Médio: Ci(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) = C2 + C Cn Calculando o valor de f, temos que considerar os 3 casos: Melhor Caso: f(n) = ( ) = n-1 Pior caso: f(n) = ( n) = n2/2 + n/2 –1 Caso médio: f(n) = ½ ( n +1) = n2/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) = n2/2 Pior caso: f(n) = 2 n2 Caso médio: f(n) = 5n2/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} 35 28 16 07 12 08 04 35 está ordenado, 7 é comparado {07,35} está ordenado, 4 é comparado {04,07,35} está ordenado 28 está ordenado, 12 é comparado {12,28} está ordenado 16 está ordenado, 35 é comparado {08,16} está ordenado Passo 2 : d =1 equivalente ao método da inserção

17 Método de Shell Quando d = 1 equivale ao algoritmo de inserção:
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<nd;p++) { shell(a,n,d[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 Implementação da seqüência de Knuth:
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 Baseado na estratégia Dividir para conquistar.
Método Quicksort (QS) Baseado na estratégia Dividir para conquistar. Algoritmo: 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 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<dir)) { i=i+1 } // procuro a[j] < x a direita enquanto ((x < a[j]) && (j>esq)){ j=j-1 // se i < = j então eu achei os valores para trocar se(i<=j) { troca(&a[i],&a[j]); i=i+1; j=j-1; } enquanto(i< j); // retorno os valores de i j *pi = i; *pj = j;

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

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


Carregar ppt "Desempenho, Método de Shell, Quicksort"

Apresentações semelhantes


Anúncios Google