Análise e Complexidade d Al de Algoritmos it Métodos de Ordenação - seleção e inserção - seleção e troca (bubble sort) - merge e quick i k sortt - radix - hashing Prof. Rodrigo Rocha [email protected] http://www.bolinhabolinha.com Onde Estamos Ementa • Revisão: Estrutura de dados;Crescimento de funções; Indução matemática e métodos matemáticos matemáticos. Medidas de complexidade, análise assintótica de limites de complexidades. Exemplos de análise de algoritmo iterativos e recursivos. Análise de desempenho de alguns algoritmos clássicos de busca e ordenação. Introdução aos principais paradigmas do projeto de algoritmos. Complexidade do Problema: Limites de Complexidade, Intratabilidade, Classes P, NP, problemas Np completos e NP-difíceis. 1 Introdução Atividade fundamental na computação Método de rearranjar um conjunto de dados em ordem crescente ou decrescente Métodos estudados: • • • • • • Seleção (Selection sort) Inserção (Insertion sort) Seleção e Troca (Bubble Sort) Intercalação (Merge Sort) Particionamento (troca) (QuickSort) Radix Ordenação Interna • Simples Adequados para pequenos arquivos O(n2) • Eficientes Arquivos maiores que requerem n(log n) Seleção - Selection Sort Um dos métodos mais simples Funcionamento • • • • Selecione o menor valor do vetor Troque com o item que está na 1. posição do vetor Repita esta operação para os n-1 itens restantes Depois repita para n-2, até restar apenas um elemento Animação ç • http://www.cs.pitt.edu/~kirk/cs1501/animations/Sort3.html 2 Seleção - Selection Sort Exemplo Seleção - Selection Sort Algortimo 3 Seleção - Selection Sort Complexidade • (números de troca) • Melhor caso entrada já ordenada O(n) • Pior caso entrada na ordem inversa O(n2) • Caso C médio édi O(n2) Inserção - Insertion Sort Dividir os valores a serem ordenados em: • coleção U de valores desordenados (a serem ordenados) • coleção S de valores ordenados Remover um a um os valores de U e inserí-los em S • Mantendo S ordenado Início: • U = conjunto desordenado de valores • S = vazio Termino: • U = vazio • S = conjunto ordenado de valores 4 Inserção - Insertion Sort Para ordenar n valores, no vetor A[0:n-1] • • • • Utilize A contendo subvetor S e U “lado-a-lado” S inicia no lado esquerdo de A U inicia no lado direito de A retire um valor V do final a esquerda de U criará um espaço entre S e U • mova todos os valores em S que forem maiores que V um espaço a direita • insira V no espaço remanescente em S Repetir até todos os valores em U estarem inseridos em S No final, S ocupa o mesmo espaço que A Inserção - Insertion Sort 5 Inserção - Insertion Sort Algoritmo Inserção - Insertion Sort Complexidade • Melhor caso entrada já ordenada O(n) • Pior caso entrada na ordem inversa O(n2) • Caso médio O(n2) 6 Inserção - Insertion Sort Animação na web • http://www http://www.cs.oswego.edu/~mohammad/classes/c cs oswego edu/ mohammad/classes/c sc241/samples/sort/Sort2-E.html • http://www.ece.unb.ca/brp/lib/java/insertionsort/ • http://www.oopweb.com/Algorithms/Documents/A nimatedAlgorithms/VolumeFrames.html Seleção e Troca - Bubble sort Funcionamento • Varrer o vetor V comparando os elementos adjascentes v[i], v[i+1] v[i 1] • Se v[i]>v[i+1] troque v[i] por v[i+1] • até nenhuma troca ser necessária Em cada passo • maior valor é empurrado para o fim • item(s) no final do vetor estão ordenados • menor valor é movido uma posição a menos no final 7 Seleção e Troca - Bubble sort Vetor A =18 26 3 9 34 5 21 14 6 Passo 1: A A A A A A A A A =(18 = 18 = 18 = 18 = 18 = 18 = 18 = 18 = 18 26) 3 9 34 5 21 14 6 (26 3) 9 34 5 21 14 6 3 (26 9) 34 5 21 14 6 3 9 (26 34) 5 21 14 6 3 9 26 (34 5) 21 14 6 3 9 26 5 (34 21) 14 6 3 9 26 5 21 ( (34 14) ) 6 3 9 26 5 21 14 (34 6) 3 9 26 5 21 14 6 | 34 ok troca troca ok troca troca troca troca Entre parênteses estão as comparações SubLista contém o último valor 34, e está ordenado Seleção e Troca - Bubble sort Passo 2: A A A A A A A A A = = = = = = = = = (18 3) 9 26 5 21 14 6 | 34 3 (18 9) 26 5 21 14 6 | 34 3 9 (18 26) 5 21 14 6 | 34 3 9 18 (26 5) 21 14 6 | 34 3 9 18 5 (26 21) 14 6 | 34 3 18 9 5 21 (26 14) 6 | 34 3 18 9 5 21 14 (26 6) | 34 3 18 9 5 21 14 6 (26 | 34) 3 18 9 5 21 14 6 | 26 34 troca troca ok troca troca troca troca ok subLista que contém os dois últimos valores 26 34 estão ordenados 8 Seleção e Troca - Bubble sort Passo 3: A A A A A A A A A = = = = = = = = = (3 18) 9 5 21 14 6 | 26 34 3 (18 9) 5 21 14 6 | 26 34 3 9 (18 5) 21 14 6 | 26 34 3 9 5 (18 21) 14 6 | 26 34 3 9 5 18 (21 14) 6 | 26 34 3 9 5 18 14 (21 6) | 26 34 3 9 5 18 14 6 (21 | 26) 34 3 9 5 18 14 6 21 | (26 34) 3 9 5 18 14 6 | 21 26 34 ok troca t troca ok troca troca ok ok subLista que contém os dois últimos valores 21 26 34 estão ordenados Depois do passo i, o último valor de i está ordenado Seleção e Troca - Bubble sort (Após) Passo 4: • A =3 5 9 14 6 | 18 21 26 34 (Após) Passo 5: • A =3 5 9 6 | 14 18 21 26 34 (Após) Passo 6: • A = 3 5 6 | 9 14 18 21 26 34 (Após) Passo 7: • A = 3 5 6 | 9 14 18 21 26 34 Terminado !!! nenhuma troca é necessária 9 Seleção e Troca - Buble Sort static void bubbleSort(int vet[]) { int passo,j,temp; p ,j, p; //contador dos passos de 1 até o tamanho do vetor for (passo=1;passo<vet.length;passo++) // passa por todos comparando o menor for (j=0;j<vet.length-passo;j++) if (vet[j]>vet[j+1]) { // troca os elementos temp = vet[j+1]; vet[j+1] = vet[j]; vet[j]=temp; } } Seleção e Troca - Bubble sort Número de comparações • Para 9 valores: 8 primeiro passo, 7 no segundo, 6 no terceiro, …. • 8+7+6+5+4+3+2+1 = 36 (comparações) • Para n valores: (n-1) primeiro passo, (n-2) segundo passo, … • (n-1) + (n-2) + …. + 1 = n * (n+1)/2 (comparações) • Número de comparações: n * (n+1)/2 = (n2 + n)/2 10 Seleção e Troca - Bubble sort Melhor Caso • vetor já ordenado • (n-1) comparações comparações, nenhuma troca Caso médio • metade do tempo • n(n+1)/4 proporcional a n2 Pior o Caso • vetor ordenado decrescente • uma troca por comparação • n(n+1)/2 = O(n2) Seleção e Troca - Bubble sort Animação na web • http://www.cs.oswego.edu/~mohammad/classes/c sc241/samples/sort/Sort2 E.html sc241/samples/sort/Sort2-E.html • http://www.ece.unb.ca/brp/lib/java/bubblesort/ • http://www.cosc.canterbury.ac.nz/people/mukund an/dsal/BSort.html /d l/BS t ht l 11 Merge sort Refinamento da estretégia de dividir para conquistar Para ordenar n valores em um vetor A[0:n-1], na ordem ascendente: 1. Dividir a seqüência A em duas metades, esquerda E e direita D 2. MergeSort a seqüência esquerda E 3. MergeSort a seqüência direira D • Unir as seqüências direita e esquerda em um resultado S • Utilizar recursividade para ordenar os dois lados • O “coração” do MergeSort é o passo de união Merge sort Passo de união • Assumimos duas seqüências ordenadas D e E • Para juntar os valores de D e E em uma nova seqüência ordenada S repetidamente 1. compare os valores iniciais de D e E 2. coloque o menor em S 3. (Se uma das seqüências estiver vazia, copiar os elementos restantes dentro de S • Resultado: S contém todos os elementos de D e E ordenados 12 Merge sort MergeSort A =18 26 3 9 34 5 21 14 6 Divide A: E = 18 26 3 9 e D =34 5 21 14 6 MergeSort E: Divide E: EE = 18 26 e ED =3 9 MergeSort EE: Divide EE: EEE = 18 e EED = 26 MergeSort EEE: ( já está ordenado) MergeSort EED: (já está ordenado) Merge 18 (EEE ordenado) e 26 (EED ordenado): Resultado: 18 26 MergeSort ED: ... Resultado: 3 9 Merge 18 26 (EE ordenado) e 3 9(ED ordenado): Resultado: 3 9 18 26 MergeSort D: ... Resultado: 5 6 14 21 34 Merge 3 9 18 26(E ordenado) e 5 6 14 21 34(D ordenado): Resultado: 3 5 6 9 14 18 21 26 34 Merge sort - exemplo 13 Merge sort - exemplo Merge sort - exemplo 14 Merge sort - exemplo Merge sort - exemplo 15 Merge Sort void mergesort(int a[ ], int low, int high) { if(low == high) return; int length = high-low+1; int pivot = (low+high) / 2; mergesort(a, low, pivot); mergesort(a pivot+1 mergesort(a, pivot+1, high); int working[ ] = new int[length]; for(int i = 0; i < length; i++) working[i] = a[low+i]; int m1 = 0; int m2 = pivot-low+1; for(int i = 0; i < length; i++) { if(m2 <= high-low) if(m1 <= pivot-low) if(working[m1] ( g[ ] > working[m2]) g[ ]) a[i+low] = working[m2++]; else a[i+low] = working[m1++]; else a[i+low] = working[m2++]; else a[i+low] = working[m1++]; } } Merge sort Estratégia • Dividir um vetor A de “n” elementos em duas metades (vetores) E[0:meio] e D[meio+1:n-1] • Combinar as metades ordenadas E e D unindo-as em um único resultado ordenado • Atenção requer um vetor adicional de tamanho igual ao que irá ser ordenado se somente o vetor original ocupa toda memória, merge sort não irá funcionar se você tem bastante espaço, merge sort é a melhor escolha Complexidade • Caso médio O(n log n) • Pior caso O(n log n) 16 Merge sort Animações na web • http://www.geocities.com/SiliconValley/Program/2 864/File/Merge1/mergesort.html • http://wwwcse.uta.edu/~holder/courses/cse2320/lectures/ap plets/sort1/mergesort_df.html Merge Sort 1-) Simular o processo do algoritmo de ordenação Merge Sort para o seguinte conjunto de valores: • 10,3,6,12,33,21,56,2,13,1 2-) Implementar o algoritmo de merge sort e testá-lo. 17 Quick sort QuickSort foi descoberto em 1962. Refinamento do algoritmo de dividir para conquistar Para ordenar n valores em um vetor A[0:n-1], na ordem ascendente: • 1. Particionar a seqüência A em direita D e esquerda E utilizando um valor de A como pivô • 2. QuickSort a porção esquerda E. • 3. QuickSort a porção direita D. Utilizar recursividade para ordenar os dois lados • Até uma seqüência de 1 elemento elemento, que está ordenada o “coração” do QuickSort é o passo de Particionar partir o vetor em dois sub vetores, tal que todos os elementos do primeiro sejam menores ou iguais a todos os elementos do segundo Particionamento dos dados Particionando • Para particionar os dados, dividimos em dois grupos • selecionamos um pivô podemos utilizar diversas técnicas (exemplo: meio do vetor) • percorro o vetor de baixo para cima até achar um valor que seja maior que o pivô • percorro o vetor de cima para baixo até achar um valor que seja menor que o pivô • troca troca-se se os dois elementos (aquele que não era menor que o pivô com aquele que não era maior que o pivô) • término = quando os percursos se cruzarem: dois grupos, um abaixo do pivô, com elementos menor que este outro acima do pivô, com elementos maiores que este 18 Quick sort - particionamento Quick sort - particionamento 19 Quick sort - particionamento Quick sort - particionamento 20 Quick sort - particionamento Exemplo 21 Quick sort Algoritmo void quicksort (int[] a, int lo, int hi) { // lo é o índice mais baixo, hi é o índice mais alto // da região do vetor que irá ser ordenada int i=lo, i=lo j=hi, j=hi h; int x=a[(lo+hi)/2]; // particionamento do { while (a[i]<x) i++; while (a[j]>x) j--; if (i<=j) { h=a[i]; a[i]=a[j]; a[j]=h; i++; j--; } } while (i<=j); // recursão if (lo<j) quicksort(a, lo, j); if (i<hi) quicksort(a, i, hi); } Quick sort Complexidade • melhor caso (a) cada particionamento produz duas partes de tamanhos iguais O(n log n) - log n cada metade • Caso médio O(n log n) • Pior Caso (c) Pivo é o maior ou menor valor da partição – Passo de particionamento separa n valores em “grupos” de um valor, e os grupos contém n-1 valores)O(n2) QuickSort é muito sensível a escolha do Pivo 22 Animações na web • http://www http://www.cs.oswego.edu/~mohammad/classes/c cs oswego edu/~mohammad/classes/c sc241/samples/sort/Sort2-E.html • http://wwwcse.uta.edu/~holder/courses/cse2320/lectures/ap t d / h ld / / 2320/l t / plets/quicksort/ Radix sort Rearranjar o vetor baseado na representação inteira dos dígitos individuais • • • • inteiros caracteres decimais (preparados) datas dois tipos • least significant digit (LSD) dígito menos significativo • most significant digit (MSD) dígito mais significativo 23 Radix sort Processo do LSD • • • Pegue o último digito mais significativo de cada chave Agrupe as chaves baseado no dígito, mantendo a ordem original g das chaves repita o processo para os outros dígitos mais significativos Exemplo • • Original, lista desordenada: 170, 45, 75, 90, 2, 24, 802, 66 Ordenando pelo último digito (unidade) • • Atenção: 2 está antes do 802, pois ele ocorre antes na lista original. Assim como o 170 e 90. Ordenando o próximo dígito (dezena) • 170 90 170, 90, 2 2, 802 802, 24 24, 45 45, 75 75, 66 2, 802, 24, 45, 66, 170, 75, 90 Ordenando pelo próximo dígito (centena) 2, 24, 45, 66, 75, 90, 170, 802 Radix sort Complexidade • temos n total de elementos m o valor máximo de um conjunto de elementos – exemplo sistemá decimal de 0 a 9, logo 10 digitos m=10 p é o número de iterações, depende da quantidade de dígitos, de 0 a 999 p=3 • O(m*p) e O(n*p) = O(p(n+m)) m e p são pequenos no caso de sistema decimal m=10 e p<=10 • O(n) 24 Radix sort Animações na web • http://wwwcse.uta.edu/ holder/courses/cse5311/lectures/ap cse.uta.edu/~holder/courses/cse5311/lectures/ap plets/radix/RadixSort.html • http://www.cse.iitk.ac.in/users/dsrkg/cs210/applet s/sortingII/radixSort/radixSort html s/sortingII/radixSort/radixSort.html • http://www.cs.umass.edu/~immerman/cs311/appl ets/vishal/RadixSort.html Exercícios Modifique o programa selection sort para sempre jogar o maior elemento para o final, ao invés do menor para o começo. A complexidade mudou? Justifique. Modifique o programa selection sort para ordenar de forma decrescente 25 Exercícios 1-) Considerando os vetores abaixo: a-) [ 10, 1, 9, 2, 8, 3 ] b-) [ 8,9,7,9,3,2,3,8,4,6 ] c-) [ 1,4,6,8,12,11 ] d-) [ 13,33,43,53,63 ] • Desenhe a seqüência de passos realizados para ordená-los, utilizando os métodos de busca insertion sort e bubble sort. • Qual a complexidade de cada ordenação para cada vetor? 2-) Se para cada comparação feita no algoritmo de ordenação bubble sort, você realiza-se uma busca seqüencial, com que complexidade ficaria este novo algoritmo? 3-) Se a busca implementada no exercício 2 fosse binária, a complexidade mudaria? Justifique. 4-) Um programador desconfiado, achou melhor implementar em cada iteração do insertion sort (no vetor parcialmente ordenado S), uma verificação, para isso, executa o procedimento de ordenação bubble sort na parte ordenada pelo insertion sort. Você acredita que foi uma boa escolha ? Justifique ? Exercícios 1-) Simular a ordenação por quick sort no seguinte conjunto de valores: • 7, 7 1, 1 3, 3 9, 9 8 8, 4, 4 2, 2 7 7, 4 4, 2 2, 3 3, 5 5. 2-) Implementar o algoritmo de quick sort e testá-lo. 26 Radix sort Exercício • Ordenar utilizando radix sort os seguintes conjuntos: a-) 0 45 93 38 74 39 32 72 14 92 5 91 66 1 2 3 4 5 6 7 8 9 Radix sort Exercício • Ordenar utilizando radix sort os seguintes conjuntos: b-) 111 0 1 12 2 11 3 1 33 4 22 5 112 6 2 96 7 55 8 14 66 9 27 Radix sort Exercício • c c-)) Como ficaria a implementação do Radix para ordenação de palavras? Dê um exemplo de ordenação de palavras com até 3 letras. Como ficou a complexidade, ela mudou ? Bibliografia Livro texto • • • ZIVIANI, Nivio. Projeto de Algoritmos : com implementação em Pascal e C.. 2ª ed. São Paulo: Pioneira Thomson Learning, 2004. p , VELOSO,, Paulo A. S.. Estrutura de Dados. 1ª ed. São Paulo: Campus, 1983. CORMEN, Thomas H. Algoritmos : teoria e prática. 1ª ed. Rio de Janeiro: CAMPUS, 2002. Complementar • SCHILDT, Herbert. C Completo e Total. 3ª ed. São Paulo: Pearson Education, 2005. • CELES, Waldemar; CERQUEIRA, Renato. Introdução a Estruturas de Dados : com técnicas de programação em C. 4ª ed. Rio de Janeiro: Elsevier, 2004 • WIRTH, Niklaus. Algoritmos e Estruturas de Dados. 1ª ed. Rio de Janeiro: LTC, 1989 • TENENBAUM, Aaron M; SOUZA, Tereza Cristina Félix de. Estruturas de Dados usando C. 1ª ed. São Paulo: Makron Books,1995. 28