Os algoritmos de classificação genérica geralmente levam um conjunto de dados para classificar e uma função comparadora que pode comparar dois elementos individuais. Se o comparador for uma relação de ordem¹, a saída do algoritmo será uma lista / matriz classificada.
Gostaria de saber, porém, quais algoritmos de classificação realmente funcionariam com um comparador que não é uma relação de ordem (em particular uma que retorna um resultado aleatório em cada comparação). Por "trabalho", quero dizer aqui que eles continuam retornando uma permutação de suas entradas e rodando em sua complexidade de tempo tipicamente citada (em vez de degradar sempre o pior cenário possível, ou entrar em um loop infinito ou elementos ausentes). A ordenação dos resultados seria indefinida. Melhor ainda, a ordenação resultante seria uma distribuição uniforme quando o comparador for um lançamento de moeda.
Do meu cálculo mental, parece que uma classificação de mesclagem seria boa com isso e manteria o mesmo custo de tempo de execução e produziria uma ordenação aleatória justa. Eu acho que algo como uma classificação rápida, no entanto, degeneraria, possivelmente não terminaria e não seria justo.
Quais outros algoritmos de classificação (exceto a classificação por mesclagem) funcionariam conforme descrito com um comparador aleatório?
Para referência, um comparador é uma relação de ordem, se for uma função adequada (determinística) e satisfizer os axiomas de uma relação de ordem:
- é determinístico:
compare(a,b)
para um determinadoa
eb
sempre retorna o mesmo resultado. - é transitivo:
compare(a,b) and compare(b,c) implies compare( a,c )
- é anti-simétrico
compare(a,b) and compare(b,a) implies a == b
- é determinístico:
(Suponha que todos os elementos de entrada sejam distintos, portanto a reflexividade não é um problema.)
Um comparador aleatório viola todas essas regras. No entanto, existem comparadores que não são relações de ordem e ainda não são aleatórios (por exemplo, eles podem violar talvez apenas uma regra e apenas para elementos específicos do conjunto).
fonte
Respostas:
Então, basicamente, você deseja saber se existe algum algoritmo de classificação que não seria degradado do seu caso médio se receber uma função de comparação semelhante a:
... em que Random.Next () é um método que produzirá um número inteiro gerado aleatoriamente entre um limite inferior e superior inclusivo especificado.
A resposta é, na verdade, que os algoritmos de classificação mais básicos serão executados de acordo com o caso médio, porque eles obedecem a pelo menos uma das duas condições a seguir:
Por exemplo, SelectionSort percorre a sub-lista de elementos não classificados, encontra o elemento "mínimo" e / ou "maior" (comparando cada um com o maior até agora), coloca-o em sua posição correta e repete. Como resultado, mesmo com um comparador não determinístico, no final de cada iteração, o algoritmo encontrou um valor que considera menor ou maior, troca-o pelo elemento na posição que está tentando determinar e nunca considera esse elemento novamente, portanto, ele obedece à condição 2. No entanto, um A e B podem ser comparados várias vezes durante esse processo (como o exemplo mais extremo, considere várias passagens de SelectionSort em uma matriz classificada em ordem inversa), por isso viola a condição 1 .
MergeSort obedece à condição 1, mas não 2; À medida que as sub-matrizes são mescladas, os elementos na mesma sub-matriz (no lado esquerdo ou direito) não são comparados entre si porque já foi determinado que os elementos desse lado da matriz estão em ordem entre si; o algoritmo compara apenas o elemento menos imerso de cada sub-matriz com o outro para determinar qual é menor e deve seguir em seguida na lista mesclada. Isso significa que quaisquer dois objetos exclusivos A e B serão comparados entre si no máximo uma vez, mas o índice "final" de qualquer elemento na coleção completa não será conhecido até que o algoritmo esteja completo.
O InsertionSort obedece apenas à Condição 1, apesar de sua estratégia e complexidade gerais parecerem mais com SelectionSort. Cada elemento não classificado é comparado aos elementos classificados, o maior primeiro, até encontrar um que seja menor que o elemento sob inspeção. o elemento é inserido nesse ponto e, em seguida, o próximo elemento é considerado. O resultado é que a ordem relativa de qualquer A e B é determinada por uma comparação e nunca são realizadas comparações adicionais entre A e B, mas a posição final de qualquer elemento não pode ser conhecida até que todos os elementos sejam considerados.
O QuickSort obedece a ambosCondições. Em cada nível, um pivô é escolhido e organizado de forma que o lado "esquerdo" contenha elementos menos que o pivô e o lado "direito" contenha elementos maiores que o pivô. O resultado desse nível é QuickSort (esquerda) + pivô + QuickSort (direita), o que basicamente significa que a posição do elemento pivô é conhecida (um índice maior que o comprimento do lado esquerdo); o pivô nunca é comparado a qualquer outro elemento depois de ter sido escolhido como um pivô (ele pode ter sido comparado com elementos de pivô anteriores, mas esses elementos também são conhecidos e não estão incluídos em nenhum sub-arranjo) E os A e B que terminam em lados opostos do pivô nunca são comparado. Na maioria das implementações do QuickSort puro, o caso base é um elemento; nesse momento, o índice atual é o índice final e nenhuma comparação adicional é feita.
EDITAR MUITO TEMPO DEPOIS: Existem alguns "tipos" projetados especificamente como exemplos do que não fazer que incorporam um comparador aleatório; talvez o mais famoso seja o BogoSort. "Dada uma lista, se a lista não estiver em ordem, embaralhe a lista e verifique novamente". Teoricamente, acabará atingindo a permutação correta de valores, assim como o "BubbleSort não otimizado" acima, mas o caso médio é de fatorial (N! / 2) e devido ao problema de aniversário (após permutações aleatórias suficientes maior probabilidade de encontrar permutações duplicadas do que as únicas) existe uma possibilidade diferente de zero de o algoritmo nunca concluir para oficialmente o algoritmo não ter limite de tempo.
fonte
Edit: O problema é mais interessante como eu pensava, então aqui está um comentário adicional:
Seria divertido calcular os tempos médios de execução para os outros algoritmos, dada essa função de comparação uniforme.
fonte
A fusão com um comparador aleatório justo não é justa. Não tenho prova, mas tenho evidências empíricas MUITO fortes. (Justo significa distribuído uniformemente.)
fonte
Uma pergunta muito relacionada é respondida em Todos os tipos de permutações (pérola funcional) por Christiansen, Danilenko e Dylus. Eles executam um algoritmo de classificação na mônada da lista , que simula essencialmente o não determinismo, retornando todas as permutações de uma determinada lista de entrada. A propriedade interessante é que cada permutação é retornada exatamente uma vez.
Citando o resumo:
fonte