Algoritmo de classificação

Um algoritmo de ordenação é, em ciência da computação ou matemática , um algoritmo que permite organizar uma coleção de objetos de acordo com uma determinada relação de ordem . Os objetos a serem classificados são elementos de um conjunto fornecido com uma ordem total . Por exemplo, é comum classificar inteiros de acordo com a relação de ordem usual "é menor ou igual a". Os algoritmos de classificação são usados ​​em muitas situações. Eles são particularmente úteis para muitos algoritmos mais complexos , incluindo alguns algoritmos de pesquisa , como pesquisa dicotômica. Eles também podem ser usados ​​para formatar dados canonicamente ou torná-los mais legíveis para o usuário.

A coleção a ser ordenada é freqüentemente dada na forma de array , a fim de permitir acesso direto aos diferentes elementos da coleção, ou na forma de uma lista , que pode acabar sendo mais adequada para certos algoritmos e para o uso da programação funcional .

Um bom número de algoritmos de classificação procedem por comparações sucessivas e podem, portanto, ser definidos independentemente do conjunto ao qual os elementos pertencem e da relação de ordem associada. O mesmo algoritmo pode, por exemplo, ser usado para classificar números reais de acordo com a relação de ordem usual "é menor ou igual a" e cadeias de caracteres de acordo com a ordem lexicográfica . Esses algoritmos naturalmente se prestam a uma implementação polimórfica .

Os algoritmos de classificação são freqüentemente estudados em cursos de algoritmo para introduzir conceitos como complexidade algorítmica ou terminação .

Critérios de classificação

A classificação dos algoritmos de ordenação é muito importante, pois permite escolher o algoritmo mais adequado ao problema tratado, tendo em consideração as restrições por ele impostas. As principais características que distinguem os algoritmos de ordenação, além do seu princípio de funcionamento, são a complexidade temporal , a complexidade espacial e o caráter estável.

Princípio da Operação

É feita uma distinção entre algoritmos que procedem por comparações sucessivas entre elementos, conhecidas como "classificação por comparação", de algoritmos mais especializados que fazem suposições restritivas sobre a estrutura dos dados a serem classificados (por exemplo, classificação por contagem, aplicável apenas se os dados são tomadas em um conjunto limitado conhecido de antemão).

Os algoritmos de classificação por comparação lêem entradas apenas por meio de uma função de comparação binária ou ternária (quando o caso de igualdade é tratado de maneira diferente). Existem ainda princípios operacionais diferentes dentro desta classe: alguns algoritmos de classificação por comparação procedem por inserções sucessivas, outros por fusão, outros ainda por seleção.

Na ausência de detalhes, o termo “algoritmo de classificação” geralmente significa um algoritmo de classificação que procede por comparações.

Complexidade algorítmica

A complexidade do tempo é freqüentemente observada e é expressa como uma função do número de itens a serem classificados usando as notações de Landau e .

Alguns algoritmos de ordenação simples apresentam complexidade no tempo quadrático, ou seja , enquanto outros, mais desenvolvidos, apresentam complexidade quase linear .

A complexidade de tempo médio de um algoritmo baseado em uma função de comparação não pode ser melhor do que . Os tipos que requerem apenas comparações em média são, portanto, considerados ótimos. Esse resultado constitui um limite inferior assintótico, mas também mostramos que o número exato de comparações necessárias é reduzido em .

Demonstração

O problema de ordenação consiste, dada uma série de elementos de um conjunto totalmente ordenado (por exemplo, fornecido com a ordem usual), em determinar uma permutação de tal que é ordenado.

Para simplificar, presume-se que todos os elementos a serem classificados são distintos, o que torna a permutação única. O resultado permanece verdadeiro a fortiori no caso geral.

Um algoritmo de classificação por comparações sucessivas é modelado como uma árvore binária . Cada nó da árvore corresponde a uma comparação entre dois elementos e , e compreende dois filhos que representam as duas comparações possíveis a seguir, dependendo do resultado da primeira.

Cada execução do algoritmo em uma permutação de pode ser associada ao caminho que vai da raiz a uma folha correspondente a essa execução; duas entradas diferentes estão necessariamente associadas a dois caminhos diferentes. O número de permutações de elementos distintos dois por dois sendo , o número de folhas da árvore é maior ou igual a este valor.

Limite inferior para a complexidade do pior caso

Observe a altura da árvore ( ou seja, sua profundidade máxima, que corresponde ao número de comparações no pior caso ). O número máximo de folhas em uma árvore de altura binária é .

Por isso, é: . Por um lado ,. Por outro lado, usando a fórmula de Stirling , obtemos assintoticamente .

O fato de haver espécies mostra, por outro lado, que é possível ter de forma assintótica . Este limite, portanto, fornece a complexidade mínima no pior caso de um algoritmo de classificação por comparações.

Limite inferior para complexidade média

Dada uma árvore binária , denotamos a profundidade média das folhas de . Se todas as permutações dos elementos de entrada forem igualmente prováveis, então o número médio de comparações do tipo com uma árvore de comparação é .

Para um número fixo de nós, as árvores minimizantes são as árvores binárias completas (ou seja, aquelas cujas folhas estão no último ou penúltimo nível). Na verdade, em uma árvore incompleta, há uma folha profunda e, no máximo, uma folha funda . Pendurando a primeira folha na segunda, obtemos uma árvore como .

A função assume o mesmo valor para todas as árvores binárias completas com folhas. Qualquer um deles e sua altura. Todas as folhas são pelo menos profundas , então a profundidade média das folhas é de pelo menos (novamente usando a propriedade ).

Para certos tipos de dados (inteiros, cadeias de caracteres de tamanho limitado), no entanto, existem algoritmos que são mais eficientes em termos de tempo de execução, como classificação de contagem ou classificação de base . Esses algoritmos não usam a comparação entre os elementos (o limite n · log (n) não se aplica, portanto, a eles), mas exigem suposições sobre os objetos a serem classificados. Por exemplo, a classificação por contagem e a classificação por base se aplicam a inteiros que sabemos pertencer ao conjunto [1, m ] com uma suposição adicional para a classificação por base de que m é uma potência de 2 (c 'isto é, do formulário 2k ).

Ordenando no local

Diz- se que uma classificação está em vigor se ela usar apenas um número muito limitado de variáveis ​​e modificar diretamente a estrutura que está classificando. Isso requer o uso de uma estrutura de dados adaptada (uma matriz, por exemplo). Este personagem pode ser muito importante se você não tiver muita memória.

No entanto, em geral, os próprios dados não são movidos, mas apenas referências (ou ponteiros ) a eles são modificados .

Classificação estável

Uma classificação é considerada estável se preserva a ordem inicial dos elementos que a ordem considera iguais. Para definir essa noção, é necessário que a coleção a ser ordenada seja ordenada de uma determinada maneira (o que costuma ser o caso para muitas estruturas de dados , por exemplo, para listas ou arrays).

Exemplo:

Vamos definir a relação de ordem definida nos pares de inteiros por ssi , que permite ordenar dois pares de acordo com seu primeiro valor.

Ou seja, uma lista de pares de inteiros que se deseja ordenar de acordo com a relação previamente definida.

Uma vez que e são iguais para a relação , chamar um algoritmo de classificação com entrada pode levar a duas saídas diferentes:

e são classificados de acordo com , mas mantêm apenas a ordem relativa. Em , aparece antes , portanto, um algoritmo de classificação que teria tomado como entrada e retornado como saída seria instável.

Algoritmos de classificação instáveis ​​podem ser retrabalhados especificamente para torná-los estáveis; no entanto, isso pode custar a velocidade e / ou pode exigir espaço de memória adicional.

Entre os algoritmos listados abaixo, as classificações estáveis ​​são: a classificação por bolha , a classificação por inserção e a classificação por mesclagem . Os outros algoritmos requerem memória adicional para armazenar a ordem inicial dos elementos.

Classificação interna e externa

Uma classificação interna é realizada inteiramente na memória central, enquanto uma classificação externa usa arquivos em uma memória de massa para classificar os volumes que são muito grandes para caber na memória central. Certos tipos de classificação, como classificação por mesclagem ou classificação por distribuição, são facilmente adaptados para o uso de memória externa. Outros algoritmos, por outro lado, acessam os dados de forma que não se prestem a esse uso, pois exigiriam a realização constante de leituras / escritas entre as memórias principal e externa.

Classificação paralela

Certos algoritmos permitem explorar as capacidades multitarefa da máquina. Deve-se notar também que certos algoritmos, em particular aqueles que funcionam por inserção, podem ser iniciados sem conhecer todos os dados a serem ordenados; podemos então classificar e produzir os dados a serem classificados em paralelo.

Comparação de algoritmos

A tabela abaixo torna possível comparar diferentes algoritmos de classificação procedendo por comparações. y representa o número de itens a serem classificados. Todas as complexidades devem ser interpretadas usando um O maiúsculo de Landau . Presume-se que operações básicas como comparações e trocas podem ser realizadas em tempo constante.

Tabela comparativa de tipos usando comparações
Sobrenome Caso ideal Caso médio Pior caso Complexidade espacial Estábulo
Ordenação rápida em média, no pior caso; Variante Sedgewick: pior cenário
Não
Mesclar classificação sim
Classificar por pilha Não
Classificar por inserção sim
Introsort Não
Classificar por seleção Não
Timsort sim
Classificação de conchas
ou
para a
sequência de espaçamento mais conhecida
Não
Classificação por bolha sim
Triagem de árvores (árvore balanceada) sim
Smoothsort Não
Seleção de coquetéis sim
Classificação de pente Não
Tipo par-ímpar sim

Exemplos de algoritmos de classificação

Classificar por comparação

Algoritmos rápidos

Para um determinado algoritmo de classificação instável, é fácil obter uma variante estável usando uma matriz adicional para armazenar a ordem inicial dos elementos. No entanto, o algoritmo resultante não está em vigor.

Algoritmos moderadamente rápidos

Para um determinado algoritmo de classificação instável, é fácil obter uma variante estável usando uma matriz adicional para armazenar a ordem inicial dos elementos. No entanto, o algoritmo resultante não está em vigor. por trabalhar em listas).

Algoritmos lentos

Esses algoritmos têm uma complexidade assintótica e, portanto, são considerados lentos para entradas cujo tamanho é superior a algumas dezenas de elementos.

Algoritmos muito lentos

Esses algoritmos têm uma complexidade assintótica pior do que , que é a complexidade dos algoritmos mais intuitivos.

  • Classificação Estúpida - Não termina no pior caso, na média e no melhor caso; instável, mas no lugar. A classificação estúpida consiste em verificar se os itens estão ordenados e se não estão, embaralhando-os aleatoriamente e, em seguida, repetindo a operação.
  • Classificando fantoches ( tipo de fantoches ) - ou aproximadamente  ; instável e não no lugar . Essa classificação consiste em trocar o primeiro e o último elemento, se necessário, em seguida, classificar recursivamente os primeiros dois terços, depois os dois últimos e, em seguida, os dois primeiros da matriz novamente.

Classifica usando a estrutura de dados

  • Contando tipo ou triagem por contagem ( contagem espécie ): algoritmo linear, T (n) = O (n), estável, mas requer o uso de uma segunda lista do mesmo comprimento que a lista de ser resolvida. Seu uso depende da condição de que os valores a serem ordenados sejam números naturais dos quais conhecemos os extremos;
  • Classificar por base ( classificação raiz ): também é uma classificação linear sob certas condições (menos restritiva do que para classificação por contagem), T (n) = O (n), estável, mas também requer o uso de uma segunda lista do mesmo comprimento como a lista a classificar;
  • Classificação de pacotes ( classificação de balde ): Estável e linearmente complexa - assume que os dados a serem classificados são distribuídos uniformemente em um intervalo real .

Classificações externas

Os algoritmos de classificação também devem ser adaptados de acordo com as configurações do computador em que são usados. Nos exemplos citados acima, assume-se que todos os dados estão presentes na memória principal (ou acessíveis na memória virtual). A situação se torna mais complexa se alguém deseja classificar volumes de dados maiores do que a memória principal disponível (ou se alguém busca melhorar a classificação otimizando o uso da hierarquia de memória).

Esses algoritmos são geralmente baseados em uma abordagem bastante semelhante à classificação por mesclagem . O princípio é o seguinte:

  • dividir o volume de dados a serem classificados em subconjuntos de tamanho menor do que a memória rápida disponível;
  • classificar cada subconjunto na memória principal para formar “monotonias” (subconjuntos classificados);
  • interclasse de monotonias.

Escolha empírica de um algoritmo de classificação

Existem muitos algoritmos, mas alguns são usados ​​muito mais do que outros na prática. A classificação por inserção é freqüentemente elogiada para dados pequenos, enquanto algoritmos assintoticamente eficientes, como classificação por mesclagem , o heapsort ou quicksort serão usados ​​para dados maiores.

Existem implementações perfeitamente otimizadas, que geralmente são algoritmos híbridos . Timsort, portanto, usa os métodos de classificação por mesclagem e classificação por inserção , e é usado por Android , Java e Python, entre outros  ; O Introsort , que combina classificação rápida e classificação de heap , é usado em algumas implementações de classificação C ++ .

A comparação empírica de algoritmos não é fácil na medida em que muitos parâmetros são levados em consideração: tamanho dos dados, ordem dos dados, hardware usado, tamanho da RAM, etc. Por exemplo, os testes realizados em dados sorteados ao acaso não representam necessariamente com muita fidelidade os comportamentos obtidos com dados reais.

Acesso a RAM

Para comparar diferentes algoritmos, é importante levar em consideração o tamanho dos dados a serem classificados, bem como a quantidade de RAM disponível. Quando não há RAM suficiente para armazenar os dados, o computador recorre ao uso de memória externa, resultando em tempos de acesso significativamente mais longos.

Nessa situação, algoritmos que funcionam sucessivamente em partes menores da entrada (que serão, por exemplo, mescladas posteriormente) tenderão a funcionar melhor do que algoritmos como quicksort, que realizarão mais acesso à memória externa.

Também é possível evitar tais situações, por exemplo, associando os dados a serem classificados com chaves menores e classificando essas chaves diretamente na RAM. Quando o tamanho dos dados for muito grande, um algoritmo de ordenação externo será usado para minimizar o número de acessos à memória externa.

Assuntos relacionados

Entre os problemas próximos à ordenação, podemos citar a ordenação parcial  (in) , que consiste, para fixo, em ordenar os menores elementos, ou o problema de seleção , que consiste em encontrar o -ésimo menor elemento da entrada. Embora a classificação de toda a entrada possa resolver esses problemas, existem soluções mais sutis e menos dispendiosas. Esse é o caso, por exemplo, da seleção rápida , que tem semelhanças com a classificação rápida .

Por outro lado, podemos tentar construir algoritmos que misturam aleatoriamente a entrada fornecida a eles; é o caso, por exemplo, da mistura Fisher-Yates .

Outro problema é classificar um array que já está quase classificado (este é o caso de big data, onde algoritmos convencionais são desqualificados). Isso pode reabilitar algoritmos como classificação de inserção .

História

A criação da primeira rotina de triagem é atribuída a Betty Holberton , durante a Segunda Guerra Mundial.

Apêndices

Notas e referências

  1. http://www.site.uottawa.ca/~kiringa/courses10/csi3530/ch13_extsort_csi3530-10.ppt
  2. http://www.umiacs.umd.edu/research/EXPAR/papers/3670.html
  3. Podemos fazer a classificação por mesclagem uma classificação no local e sempre dentro , mas o algoritmo faz mais cópias e é mais complicado de programar
  4. Conheça os programadores da ENIAC, os pioneiros da indústria de software , intel.fr, junho de 2016

Bibliografia

links externos

<img src="https://fr.wikipedia.org/wiki/Special:CentralAutoLogin/start?type=1x1" alt="" title="" width="1" height="1" style="border: none; position: absolute;">