O seguinte algoritmo determinístico (sem o comparador) funciona para uma tupla de entrada :( a1 1, … , Umn)
- Faça o Fisher-Yates embaralhar usando seu comparador com algum par estático (dizer ) como um coin flip (fazendo amostragem de aceitação-rejeição). Se o comparador emitir 1 pela primeira vez, use-o invertido para evitar um ciclo de rejeição sem fim no caso determinístico.uma1 1< a21 1
- (aceleração opcional: tente um único par vezes, em que n é o comprimento ou sua entrada. Se duas das saídas diferirem, retorne a permutação obtida em (1))nn
- Classifique sua matriz usando a classificação de mesclagem.
Dada uma relação de ordem determinística como comparador, esse algoritmo classifica uma matriz no tempo pois o embaralhamento de Fisher-Yates é executado em O ( n ) usando "bits aleatórios" não aleatórios máximos de O ( log n ) (por exemplo, chamadas para o seu comparador ) em cada etapa e classificação de mesclagem tem a mesma complexidade assintótica. O resultado de (1) é totalmente inútil neste caso, mas, como é seguido por uma espécie real, isso não faz mal.O (nlogn )O (n)O (logn )
Dado um giro real da moeda, pois o comparador (1) permite a matriz com igual probabilidade para cada permutação e se você realmente tiver que fazer (3) (você deixou de fora (2) ou (2) falhou em determinar a aleatoriedade)), isso não é verdade. dano porque a distribuição de seu resultado depende apenas da ordem de sua entrada, que é distribuída uniformemente entre todas as permutações por causa de (1); portanto, o resultado de todo o algoritmo também é uniformemente distribuído. O número de vezes que cada amostragem de aceitação-rejeição deve ser repetida é distribuído geometricamente (rejeitar com probabilidade ) e, portanto, tem um valor esperado<2. Cada repetição usa no máximobits delogn, portanto, a análise de tempo de execução é quase a mesma do caso determinístico, mas obtemos apenas umtempodeexecução esperadodeO(nlogn), com a possibilidade de não terminação (termina comquase certeza).< 12< 2registronO (nlogn )
Como Joe apontou: Se você não gostar do teste do primeiro bit em (1), faça (3) e depois (1) e use que sempre é 0 , pois a matriz já está classificada no caso determinístico. Além disso, você deve subtrair seu número aleatório do limite superior do intervalo no loop, porque o limite superior do número aleatório gera a permutação idêntica. Mas lembre-se de que (2) é proibido, pois você sempre deve fazer o embaralhamento no caso de resgate.uman< a1 10 0
Você pode até usar as mesmas chamadas para o seu comparador para (1) e (3), mas provar que o resultado é distribuído uniformemente é pelo menos muito mais difícil, se possível.
O algoritmo a seguir não possui fases distintas para ordenar e ordenar, mas é assintoticamente mais lento. É essencialmente
tipo de inserção com
pesquisa binária . Vou usar
para indicar a entrada e
b k = ( b k , 1 , ... , b k , k ) para indicar o resultado após o
k -ésimo rodada:
a = ( a1 1, … , Umn)bk= ( bk , 1, … , Bk , k)k
- Defina b1 , 1= a1 1
- Se então b 2 = ( a 2 , a 1 ) e ( c , d ) : = ( 2 , 1 ) else b 2 = ( a 1 , a 2 ) e ( c , d ) : = ( 1 , 2 ) . Em ambos os casos, um d <uma2< a1 1b2= ( a2, um1 1)(c,d):=(2,1)b2=(a1,a2)(c,d):=(1,2) sempre será 0 (ou seja, falso) para um comparador não aleatório.ad<ac0
- Para obter para k ≥ 3, obtenha b k - 1 primeiro.bkk≥3bk−1
- Deixe- e k ' = 2, l , ou seja, k ' é a menor potência de 2 não menor do que k .l=⌈log2k⌉k′=2lk′2k
- i0=0j∈{1,…,l}
ij=⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪ij−1+2l−jij−1ij−1+2l−jij−1ij−1+2l−j>k−1∧ad<acij−1+2l−j>k−1∧¬(ad<ac)ij−1+2l−j≤k−1∧bk−1,ij−1+2l−j<akij−1+2l−j≤k−1∧¬(bk−1,ij−1+2l−j<ak)
- il>kbk=(bk−1,1,…,bk−1,il−1,ak,bk−1,il,…,bk−1,k−1)
- bn
k−1k
Observe que esse algoritmo é ineficiente em ambos os modos, comparado à ordenação aleatória e mesclada de Fisher-Yates, pois inserir um elemento em uma posição arbitrária é caro se o uso de uma matriz e a pesquisa binária precisar de tempo linear ao usar uma lista. Mas talvez uma modificação da classificação da pilha ou da árvore de maneira semelhante possa levar a um algoritmo mais rápido.