trabalho de classificação e pesquisa
Post on 08-Apr-2018
220 Views
Preview:
TRANSCRIPT
-
8/7/2019 Trabalho de Classificao e pesquisa
1/8
-
8/7/2019 Trabalho de Classificao e pesquisa
2/8
Este algoritmo sugere por si prprio, alguns aperfeioamentos. No exemplo anterior,pode-se observar que os trs ltimos passos do algoritmo no afetaram a ordem dos elementos dovetor, pois estes j encontravam-se ordenados. Uma tcnica bvia para melhorar este algoritmoconsiste em manter uma indicao informando se houve ou no ocorrncia de uma permutao,
para determinar precocemente o trmino do algoritmo. Sendo assim, o algoritmo para ordenaobolha aperfeioado ficaria assim:
/* Rotina para ordenar um vetor de n elementos pelo mtodo Bolha aperfeioado */void BubbleSort2(int a[], int n) {
int i = 0; // Passos do algoritmo de ordenaoint j; // ndice do vetorint aux; // Varivel auxiliar para a permutao de elementosint trocou; // Indica se houve permutao em um passodo {trocou = FALSE;
for(j = 0; j < n-1-i; j++) {if(a[j] > a[j+1]) { // Se o elemento a esquerda for maior que o a direitaaux = a[j]; // Troca-se a posio destes elementosa[j] = a[j+1];a[j+1] = aux;trocou = TRUE; // sinaliza que houve uma troca
}}
} while(trocou && ++i < n-1);
}
Entretanto, mesmo esta melhoria pode ser por sua vez aperfeioada, guardando-se no asimples informao da ocorrncia de uma permutao, mas a posio (ndice) kdo vetor em queocorreu a ltima permutao realizada. Por exemplo, evidente que todos os pares de elementosadjacentes de ndice maior que k j se encontram na ordem desejada. Portanto, a partir destendice, o prosseguimento dos exames pode ser interrompido, ao invs de se prosseguir at olimite superior n i predeterminado. Entretanto, um programador cuidadoso percebe umaassimetria peculiar: uma nica bolha, colocada de modo incorreto na extremidade esquerda deum vetor, cujos demais elementos estejam ordenados ser posicionada corretamente em um nicopasso, mas um elemento incorretamente posicionado na extremidade direita ir deslocar-se deapenas uma posio por vez em direo a sua posio correta. Por exemplo, o vetor
94 06 12 18 42 44 55 67 ordenado pelo mtodo Bubblesortaperfeioado em um nico passo, mas o vetor
12 18 42 44 55 67 94 06
requer sete passos para a sua ordenao. Esta assimetria no natural sugere uma segundamelhoria: alterar a direo dos sucessivos passos de ordenao. O algoritmo resultante destaprtica se chama Shakesort(Ordenao por agitao).
Seu comportamento ilustrado a baixo, aplicando-se o algoritmo para as mesmas oitochaves que foram utilizadas o exemplo anterito.
-
8/7/2019 Trabalho de Classificao e pesquisa
3/8
Exemplo de aplicao do Shakesort.
/* Rotina para ordenar um vetor de n elementos pelo mtodo Shakesort */void ShakeSort(int a[], int n) {
int j; // ndice do vetorint k = 0; // Indica a posio da ltima permutaoint e = 0,d = n-1; // Limites esquerdo e direito do vetorint aux; // Varivel auxiliar para a permutao de elementosdo {
/* Varre o vetor da esquerda para a direita */
for(j = e; j < d; j++) {if(a[j] > a[j+1]) {aux = a[j];a[j] = a[j+1];a[j+1] = aux;k = j; // sinaliza a posio da ltima troca
}}d = k;/* Varre o vetor da direita para a esquerda */
for(j = d; j > e; j--) {if(a[j-1] > a[j]) {aux = a[j-1];a[j-1] = a[j];a[j] = aux;k = j; // sinaliza a posio da ltima troca
} }e = k;
}while(e < d); }
Varredura Interao VetorSalto esquerdo
para direitaSalto direto
para esquerdaPar
comparadoAo
1
123
45
2826 30 24 2526 2830 24 2526 28 3024 25
26 28 24 302526 28 24 25 30
111
10
000
00
28,2628,3030,2430,25
TrocaNo troca
Troca
TrocaFim da ao
2
6789
26 28 2425 3026 2824 25 302624 28 25 3024 26 28 25 30
0000
1110
24,2528,2426,24
No trocaTrocaTroca
Fim da ao
3101112
24 2628 25 3024 26 2825 3024 26 25 28 30
110
000
26,2828,25
No trocaTroca
Fim da ao
41314
24 2625 28 3024 25 26 28 30
0 1 26,25 TrocaFim da ao
-
8/7/2019 Trabalho de Classificao e pesquisa
4/8
Eficincia da permutao direta (Bubblesort)e ( Shakesort):
Mnimo Mdio Mximo
Comparaes (n2n) / 2 (n2n) / 2 (n2n) / 2
Movimentos 0 3 (n2n) / 4 3 (n2n) / 2
Mtodo do Pente CombSort.
Um ganho significativo no mtodo bubblesort pode ser obtido usando a estratgia depromover as chaves em direo s suas posies definitivas por saltos maiores do que apenasuma casa de cada vez. Essa alternativa, proposta por Lacey e Box, consiste em comparar no ospares consecutivos de chaves, mas pares formados por chaves que distam umas das outras umacerta distncia h. Na primeira varredura essa distncia dada pelo valor h = n div 1,3. Nasvarreduras subseqentes, esta distncia (tambm denominada salto) progressivamentediminuda do fator 1,3, at que seja igual a unidade. Neste momento, o mtodo se confunde como bubblesort tradicional.
Cada varredura rapidamente conduz as chaves para locais prximos do definitivo pormeio de grandes saltos. A medida que os saltos vo diminuindo de comprimento, aproximando-seda unidade, as chaves estaro j bem prximas de suas posies corretas, quando ento obubblesort se tornar eficiente. O fator 1,3 de reduo dos saltos foi obtido pelos autores doalgoritmo por simulao. Foram testados fatores que variavam de 1,1 a 1,45, sendo que o de valor1,3 foi o que apresentou melhores resultados, em mdia..A reduo do tempo de classificao desse mtodo em relao ao bubblesort tradicional (semqualquer tipo de otimizao) foi da ordem de 27 vezes. As sucessivas redues dos saltos soanlogas ao ato de pentear cabelos longos e embaraados, inicialmente apenas com os dedos edepois usando pentes com espaos entre os dentes cada vez menores. Da a denominao domtodo dada pelos autores.
Exemplo:Como o vetor possui 5 chaves, o salto inicial igual a 3.
Exemplo de aplicao do CombSort.
Como vemos a classificao do vetor, embora tambm tenha consumido 9 iteraes,demandou apenas trs trocas, enquanto o bubblesort, para ordenar o mesmo vetor, efetua 8 trocas. justamente neste ponto que reside a vantagem do combsort em relao ao bubblesort, uma vez
Varredura Interao Vetor Salto Par Comparado Ao
112
28 26 30 24 2524 26 30 28 25
33
28,2426,25
TrocaTroca
2345
24 25 30 28 2624 25 30 28 2624 25 30 28 26
222
24,3025,2830,26
No trocaNo troca
Troca
3
6789
2425 26 28 3024 2526 28 3024 25 2628 3024 25 26 2830
1111
24,2525,2626,2828,30
No trocaNo trocaNo trocaNo troca
-
8/7/2019 Trabalho de Classificao e pesquisa
5/8
que a operao de troca, por envolver vrios acessos memria, a que vai determinar avelocidade de classificao.
private static int newGap(int gap){gap = gap * 10 / 13;if(gap == 9 || gap == 10)
gap = 11;if(gap < 1)
return 1;return gap;
}
private static void conbSort(int a[]){int gap = a.length;boolean swapped;do{
swapped = false;gap = newGap(gap);for(int i = 0; i < (a.length - gap); i++){ if(a[i] > a[i + gap])
{ swapped = true;int temp = a[i];a[i] = a[i + gap];a[i + gap] = temp;
}}
} while(gap > 1 || swapped);}
Na primeira varredura h := n_elem div 1,3. Depois h diminudo do fator 1,3 a cadavarredura, ou seja, h := h div 1,3.
Classificao por Intercalao
Mtodo de Intercalao Mergesort.
MergeSort um algoritmo recursivo de ordenao que roda em O(n log n), no pior emelhor caso. Possui complexidade logartmica e faz parte de um grupo de algoritmos do tipodividir para conquistar, dividindo a sequncia original em pares de dados ordenados, e depois
juntando-os. O conceito por trs deste algoritmo combinar duas listas j ordenadas. O algoritmoquebra um array original em dois outros de tamanhos menores, recursivamente, at obter arraysde tamanho 1. Retorna ento da recurso combinando os resultados.
Desvantagem: faz uso de um array auxiliar com uma srie de chamadas recursivas,gerando um gasto extra de memria (o dobro).
Vantagens: O(n log n) no pior caso, e estvel, ou seja, mantendo a ordem original doselementos repetidos.
O algoritmo de ordenao MergeSort utiliza duas funes: Merge e MergeSort.
-
8/7/2019 Trabalho de Classificao e pesquisa
6/8
A funo Merge tem como entrada dois vetores ordenados e retorna um nico vetorordenado.
A funo MergeSort quebra um vetor em duas metades e se chama recursivamente,at que as metades tenham tamanho 1.
Ento as recurses so retornadas, combinado as metades j ordenadas.O algoritmo merge sort consiste em ir separando em metades uma lista de elementos, atficar com todos os elementos separados. Aps estes elementos estarem separados, o algoritmoprocede sua juno (merge), retornando no final uma nica lista com todos os elementosordenados. Este mtodo de ordenao altamente eficiente e tem uma formulao recursivamuito elegante. O algoritmo Merge Sort, tambm conhecido como ordenao por fuso ou porintercalao, utiliza como estratgia a diviso do vetor a ser ordenado em duas partes.
Essa diviso acontece recursivamente at que no seja mais possvel qualquer diviso dosvetores resultantes, ou seja, at o momento em que os vetores resultantes da diviso tenhamtamanho igual a 1. Aps subdividir recursivamente o vetor inicial em n partes, o algoritmo fazuma intercalao entre os elementos desses vetores at finalizar a pilha de processos recursivos.
Intercalao (= merge) de vetores ordenados
Dados vetores crescentes v[p .. q-1] e v[q .. r-1], rearranjar v[p .. r-1] em ordemcrescente. Basta tratar do caso em que os vetores v[p .. q-1] e v[q .. r-1] no so vazios.
p q-1 q r-1
111 333 555 555 777 999 999 222 444 777 888
fcil resolver o problema em tempo proporcional ao quadrado de r-p: basta ordenar ovetor v[p..r-1] sem dar ateno ao estado ordenado das duas "metades". O algoritmo recebe umvetor v[p..r-1] e rearranja o vetor em ordem crescente. O algoritmo recursivo. A base darecurso o caso p r-1; nesse caso no preciso fazer nada.
// A funo mergesort rearranja o vetor v[p..r-1]// em ordem crescente.
void mergesort (int p, int r, int v[]){if (p < r-1) {
int q = (p + r)/2;mergesort (p, q, v);mergesort (q, r, v);intercala (p, q, r, v);
}}
O resultado da diviso por 2 na expresso (p+r)/2 automaticamente truncado. Porexemplo, (3+6)/2 vale 4. Para rearranjar v[0..n-1] em ordem crescente basta executarmergesort (0, n, v).
0 1 2 3 4 5 6 7 8 9 10
111 999 222 999 333 888 444 777 555 666 555
111 999 222 999 333 888 444 777 555 666 555
111 999 222 999 333 888 444 777 555 666 555
-
8/7/2019 Trabalho de Classificao e pesquisa
7/8
111 999 222 333 999 444 777 888 555 555 666
111 222 333 999 999 444 555 555 666 777 888
111 222 333 444 555 555 666 777 888 999 999
Como o nmero de elementos do vetor reduzido metade em cada chamada domergesort, o nmero total de "rodadas" log2n. Na primeira rodada, nosso problema original reduzido a dois outros: ordenar v[0 .. n/2-1] e ordenar v[n/2 .. n-1]. Na segunda rodada temosquatro problemas: ordenar v[0..n/4-1], v[n/4..n/2-1], v[n/2..3n/4-1] e v[3n/4..n-1]. E assim pordiante. Como mergesort mais complexo, ele s realmente mais rpido na prtica quando n suficientemente grande.
//Implementao em Java do metodo Merge sortpublic static void mergeSort(int[ ] data, int first, int n){
int n1int n2if (n > 1){
n1 = n / 2;n2 = n - n1;mergesort(data, first, n1); // Sort data[first] through data[first+n1-1]mergesort(data, first + n1, n2); // Sort data[first+n1] to the end// Merge the two sorted halves.merge(data, first, n1, n2);
}}
private static void merge(int[ ] data, int first, int n1, int n2){int[ ] temp = new int[n1+n2];int copied = 0;int copied1 = 0;int copied2 = 0;int I;while ((copied1 < n1) && (copied2 < n2)){
if (data[first + copied1] < data[first + n1 + copied2])temp[copied++] = data[first + (copied1++)];
elsetemp[copied++] = data[first + n1 + (copied2++)];
}
while (copied1 < n1)temp[copied++] = data[first + (copied1++)];
while (copied2 < n2)temp[copied++] = data[first + n1 + (copied2++)];
for (i = 0; i < n1+n2; i++)data[first + i] = temp[i];
}A cada comparao, o menor valor armazenado no vetor de resultado e o contador do
vetor auxiliar que continha o elemento incrementado, dando incio a uma nova comparao. Porltimo, o algoritmo avalia qual o vetor auxiliar cujos elementos ainda no foram inseridos novetor resultado e faz a insero dos mesmos.
-
8/7/2019 Trabalho de Classificao e pesquisa
8/8
private int[] vetor;/** Mtodo recursivo que divide o vetor em dois e depois os mescla e ordena
*/public static void mergeSort(int[ ] v, int first, int n){int n1int n2if (n > 1){
n1 = n / 2;n2 = n - n1;mergeSort(v, first, n1);mergeSort(v, first + n1, n2);merge(v, first, n1, n2);
}}
/** Ordena dois trechos ordenados e adjacente de vetores e ordena-os conjuntamente*/
private void mesclar(int inicio, int meio, int fim) {int tamanho = fim - inicio + 1;/** Inicializao de um vetor temporario para auxiliar na ordenao o* vetor temporrio uma cpia do trecho que ser ordenado*/
int[] temp = new int[tamanho];System.arraycopy(vetor, inicio + posicao, temp, 0, tamanho);
/** Lao para ordenao do vetor, utilizando o vetor temporrio, usando* ndices i e j para cada trecho de vetor da mesclagem*/
int i = 0;int j = meio - inicio + 1;//A depender das condies, recebe um elemento de um trecho ou outrofor (int posicao = 0; posicao < tamanho; posicao++) {
vetor[inicio + posicao] =if (j
top related