Quais são as razões para aprender diferentes algoritmos / estruturas de dados que atendem ao mesmo objetivo?

91

Eu me pergunto sobre essa questão desde que eu era estudante de graduação. É uma questão geral, mas irei elaborar com exemplos abaixo.

Eu já vi muitos algoritmos - por exemplo, para problemas de vazão máxima, conheço três algoritmos que podem resolver o problema: Ford-Fulkerson, Edmonds-Karp & Dinic, com Dinic tendo a melhor complexidade.

Para estruturas de dados - por exemplo, pilhas - existem pilhas binárias, pilhas binomiais e pilhas de Fibonacci, com a pilha de Fibonacci tendo a melhor complexidade geral.

O que me deixa confuso é: existem razões pelas quais precisamos conhecê-las todas? Por que não apenas aprender e se familiarizar com a melhor complexidade?

Eu sei que é o melhor se conhecemos todos eles, só quero saber se existem razões "mais válidas", como alguns problemas / algoritmos só podem ser resolvidos usando A, mas não B , etc.

shole
fonte
17
Como eu sempre digo: estes (geralmente) não são "melhores". Depois de definir explicitamente o que você quer dizer com "melhor", a resposta se torna óbvia.
Raphael
2
Essa é uma boa pergunta, mas está relacionada ao que eu consideraria um buraco na sua educação que você poderia corrigir. Essa é uma experiência prática. Se você realmente não escreveu esses algoritmos durante a sua educação, considere escrevê-los agora. Suspeito que a resposta a essa pergunta se tornaria rapidamente óbvia quando você tentasse encontrar usos para eles.
Sam
@Sam Pela minha experiência, o que eu pensei é que, em palestras ou em alguns livros didáticos, eles são informativos, introduzem muitos algoritmos, análises, etc., mas não muitos casos práticos ou cenários de amostra que A superará B. Eles podem cobrir um gênero de algoritmos A a Z, e alguns problemas de lição de casa, mas para mim todos eles podem ser resolvidos apenas por A, ou apenas por Z, etc., portanto, a pergunta feita.
shole
5
Se você insiste em deixar de lado o interesse acadêmico, a melhor razão prática para aprender algoritmos abaixo do ideal é que você possa reconhecê-los pelo que são e otimizá-los, refatorando-os aos melhores. Você não pode atualizar um arco e flecha para uma arma se não souber o que é um arco e flecha.
21316 Candied_orange
1
Na verdade, propusemos um site StackExchange para ajudar especificamente com questões de educação em CS como esta. Venha nos apoiar aqui: area51.stackexchange.com/proposals/92460/…
vk2015

Respostas:

121

Há um livro a ser escrito em algum momento, com o título de trabalho Estruturas de Dados, Algoritmos e Trocas . Quase todos os algoritmos ou estruturas de dados que você provavelmente aprenderá no nível de graduação têm algum recurso que o torna melhor para alguns aplicativos do que para outros.

Vejamos a classificação como exemplo, já que todos estão familiarizados com os algoritmos de classificação padrão.

Primeiro, a complexidade não é a única preocupação. Na prática, os fatores constantes são importantes, e é por isso que, digamos, a classificação rápida tende a ser usada mais do que a classificação de pilha, mesmo que a classificação rápida tenha uma terrível complexidade do pior caso.

O(nregistron)

Em outros casos, as idéias de um algoritmo ou estrutura de dados podem ser aplicáveis ​​a um problema de finalidade especial. A classificação por bolha parece ser sempre mais lenta que a inserção em hardware real, mas às vezes a idéia de executar uma passagem por bolha é exatamente o que você precisa.

Considere, por exemplo, algum tipo de visualização em 3D ou videogame em uma placa de vídeo moderna, onde você gostaria de desenhar objetos da ordem da mais próxima à câmera até a mais distante da câmera por razões de desempenho, mas se você não conseguir o pedido exato, o hardware cuidará dele. Se você estiver se movendo pelo ambiente 3D, a ordem relativa dos objetos não mudará muito entre os quadros, portanto, executar uma passagem de bolha por quadro pode ser uma troca razoável. (O mecanismo Source da Valve faz isso para efeitos de partículas.)

Há persistência, simultaneidade, localidade do cache, escalabilidade em um cluster / nuvem e várias outras razões possíveis pelas quais uma estrutura ou algoritmo de dados pode ser mais apropriada que outra, mesmo com a mesma complexidade computacional para as operações importantes para você.

Dito isto, isso não significa que você deve memorizar um monte de algoritmos e estruturas de dados por precaução. A maior parte da batalha é perceber que existe uma troca a ser explorada em primeiro lugar e saber onde procurar se você acha que pode haver algo apropriado.

Pseudônimo
fonte
7
Ótima resposta com ótimos exemplos! Não sabia sequer passar bolha tem seu uso prático no mundo real ...
shole
1
@shole Não tenho muita experiência no ramo de jogos, mas todos os itens acima são importantes em vários graus. (Obviamente, o tipo de algoritmo, estrutura de dados e matemática de que você precisa para jogos provavelmente é diferente daquele exigido para bancos de dados ou bioinformática ou o que você tem.) Se eu fosse você, iria aqui e começaria a assistir: handmadehero. org Também vale a pena espreitar em gamedev.stackexchange.com
Pseudônimo
1
A eficiência do cache é um grande fator pouco pesquisado (google "muro de memória").
Raphael
6
Cuidado, o Quicksort é muito mais rápido, em média, do que o Heapsort, mas o Heapsort é mais consistente (sua variação no tempo de execução é menor e o pior caso é muito melhor). E o Heapsort pulando na matriz versus as verificações lineares do Quicksort da esquerda e da direita fazem uma enorme diferença quando o cache / paginação entra em jogo.
21816 vonbrand
1
@shole Em que tipo de desenvolvimento de jogos você está interessado? Há pelo menos dois subcampos muito diferentes, gráficos 3D e jogabilidade (que inclui IA). Eu só tenho experiência com gráficos, mas posso dizer que estruturas de dados e matemática são extremamente importantes em gráficos e algoritmos, em menor grau. Se você estiver usando um mecanismo, a maioria dessas coisas será resolvida, mas você ainda deve entender a matemática básica da geometria 3D.
Gardenhead 17/02
51

Além do fato de existirem inúmeras medidas de custo (tempo de execução, uso de memória, falhas de cache, previsões incorretas de ramificações, complexidade de implementação, viabilidade de verificação ...) em uma infinidade de modelos de máquinas (TM, RAM, PRAM, ...) , média versus pior caso, bem como considerações de amortização para pesar uma contra a outra, também existem diferenças funcionais além do escopo da especificação básica dos livros didáticos.

Alguns exemplos:

  • O Mergesort é estável onde o Quicksort não é.
  • As árvores de pesquisa binária fornecem iteração em ordem, as hashtables não.
  • Bellman-Ford pode lidar com pesos negativos, Dijkstra não.

Também há considerações didáticas a serem feitas:

  • Quão fácil é entender uma solução mais envolvente que a mais simples? (Árvores AVL (e sua análise) sem BSTs; Dinic sem Ford-Fulkerson; ...)
  • Você vê os mesmos princípios e padrões quando é exposto a apenas uma solução por problema em comparação a ser exposto a muitas soluções?
  • A exposição a apenas uma solução por problema fornece treinamento suficiente (para o domínio)?
  • Você deve saber a amplitude de quais soluções foram encontradas (para impedir que você reinvente a roda repetidamente¹)?
  • Quando exposto a apenas uma solução por problema, você entenderá outras soluções encontradas na natureza (por exemplo, em uma biblioteca de programação do mundo real)?

  1. Isso é algo que vemos muito nos tipos de programadores que não têm uma rica caixa de ferramentas de CS à sua disposição.
Rafael
fonte
4
+1 por incluir razões didáticas! Relacionado a várias das justificativas (especialmente a segunda e a terceira), ver como os algoritmos e as estruturas de dados são desenvolvidos e otimizados ensina técnicas de desenvolvimento e otimização e uma compreensão das compensações (aprendendo não apenas "o que", mas também "como" e "por que" )
Paul A. Clayton
2
Uma consideração adicional é que analisar as diferentes alternativas oferece exemplos de ferramentas úteis para analisar novos algoritmos para configurações talvez incomuns.
vonbrand 17/02
1
Bom ponto, @vonbrand. A análise de complexidade amortizada foi inventada para entender o comportamento das árvores espalhadas, mas as árvores espalhadas raramente são usadas na prática. Bem, não espalhe árvores como publicado, de qualquer maneira. O kernel do Windows NT usa famosas árvores de splay para implementar mapas de memória virtual, mas não é reordenado em todas as pesquisas.
Pseudônimo
1
@vonbrand Sim. Eu entenderia como alguém principalmente interessado na dimensão da caixa de ferramentas em uma classe de algoritmos zombaria por esse motivo.
Raphael
7

No mundo real , em algum momento você provavelmente estará trabalhando em um software que foi escrito por uma equipe de outras pessoas. Alguns desses softwares foram escritos antes de você nascer!

Para entender os algoritmos / estruturas de dados usados, é muito útil conhecer um grande número de algoritmos / estruturas de dados, incluindo opções que não são mais consideradas "estado da arte".

Você também precisará trabalhar em algoritmos que não são padrão e são usados ​​apenas no aplicativo em que você está trabalhando. Quando você precisar melhorar esses algoritmos, descobrirá que seu cérebro foi preenchido com métodos úteis para aprimorá-los, ao estudar como outras pessoas aprimoraram os algoritmos.

É isso que diferencia alguém que estudou ciência da computação de alguém que acabou de aprender a programar. Na maioria dos trabalhos em que trabalhei, houve tempo em que estudei ciência da computação e resolvi um problema que um programador “aprendeu com livros” não, mas 95% das vezes descobri que estudar ciência da computação não me dava vantagem. sobre outros programadores experientes .

Ian Ringrose
fonte
a menos que 95% das coisas que você está tentando resolver estejam relacionadas ao aprendizado de máquina. Não vejo como o programador normal pode ter a chance certa de tentar qualquer um dos problemas enfrentados por problemas reais de ML.
Pinocchio
3
Objetivo: conseguir um emprego com uma taxa melhor que 5%.
Raphael
Lembre-se de que estudar CS tem sido uma ótima maneira de reunir conhecimento sobre algoritmos e estruturas de dados. Codificação é a melhor ocupação - para codificadores.
19716
5

Muitas pessoas mencionaram, com razão, que muitas vezes não existe um melhor algoritmo - isso depende da situação.

Há também a possibilidade de um dia você se deparar com uma situação desconhecida. Quanto mais algoritmos você souber, maior será a chance de você conhecer um que seja quase uma solução que possa usar como base.

Bloke Down The Pub
fonte
5
Esta resposta repete apenas pontos dos mais antigos.
Raphael
1

Muitas ótimas respostas, apenas algo que acho que está faltando, embora a resposta de Raphael mencione isso.

A facilidade de implementação também é algo a ser levado em consideração.
Isso geralmente não é um problema com algoritmos de classificação, porque a maioria das plataformas / linguagens já possui um implementado (e geralmente melhor do que você poderia fazer), mas algoritmos mais incomuns podem não estar disponíveis.
Dependendo do seu problema, você pode não precisar do melhor algoritmo absoluto se o tempo de implementação for de 1 dia versus 2 semanas.

Leherenn
fonte