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.
Respostas:
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.
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.
fonte
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:
Também há considerações didáticas a serem feitas:
fonte
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 .
fonte
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.
fonte
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.
fonte