Estou acostumado a procurar a notação Landau (Big O, Theta ...) dos meus algoritmos manualmente, para garantir que eles sejam o mais otimizados possível, mas quando as funções estão ficando muito grandes e complexas, está acontecendo muito tempo para fazê-lo manualmente. também é propenso a erros humanos.
Passei algum tempo em Codility (exercícios de codificação / algo), e notei que eles fornecerão a notação Landau para sua solução enviada (tanto no uso de tempo quanto de memória).
Fiquei me perguntando como eles fazem isso ... Como você faria isso?
Existe outra maneira além da Análise Lexical ou da análise do código?
Esta questão diz respeito principalmente a PHP e / ou JavaScript, mas estou aberto a qualquer linguagem e teoria.
algorithms
complexity
big-o
static-analysis
big-theta
Julien L
fonte
fonte
Respostas:
Eu imagino que eles estão realmente estimando as medidas do Big O ... executando o programa para diferentes tamanhos de problemas, medindo o uso de tempo e espaço e ajustando curvas aos resultados.
O problema com essa abordagem é que ela pode errar se as funções de custo mudarem de forma à medida que N se torna grande; por exemplo
1000 N + N^1.5
.A análise e análise lexical não são suficientes. Você também precisa raciocinar sobre o comportamento do algoritmo. E fazer isso automaticamente para um algoritmo anteriormente desconhecido é difícil.
fonte
Eles não podem sem analisar o código.
Os exemplos abaixo, com "inflação / deflação" artificial de complexidade, provam que simplesmente medir o tempo de execução do programa não é suficiente para estimar com segurança o Big-O
A estimativa de tempo de execução para o acima seria aceitável para fornecer estimativas falsas - tempo constante para valores de
n
onde existe uma solução pré-calculada e tempo cúbico para valores ondeunfair slow-down
entra em ação - em vez de tempo quadrático "justo".fonte
Eu acho que isso não é possível.
Se você executar alguns testes com um número fixo de diferentes tamanhos de entrada, poderá calcular facilmente um polinômio, que aproximará os tempos de execução que você mediu muito bem. Então você acaba com um polinômio para todos os programas possíveis, o que significaria
P = NP
(sim!;)).Se você tentar fazer isso com manipulação simbólica, você acaba no
halting problem
. Como você não pode decidir se seu programa será interrompido, você não pode decidir qual complexidade de tempo de execução terá.No entanto, pode haver casos muito especiais, onde o método posterior é possível. Mas nesses casos, talvez tão pequeno, que é questionável se algum esforço é pago.
fonte
Como eu faria isso? Como resolvo quase qualquer problema, não quero me sentar e resolver . Eu simulo.
Para muitos problemas, pode ser suficiente executar o algoritmo várias vezes usando uma variedade de tamanhos e ajustar uma curva de regressão a esses resultados. Isso identificaria rapidamente alguns custos indiretos "fixos" específicos do seu algoritmo (a interceptação da curva) e como ele é dimensionado à medida que o tamanho do seu problema aumenta.
Serão necessários alguns ajustes para capturar soluções particularmente complicadas, mas especialmente se você estiver apenas procurando uma estimativa de estacionamento, poderá obtê-la dessa maneira e ver como sua estimativa difere dos resultados reais e decidir se é uma aproximação aceitável.
A maior fraqueza em minha mente com esse método é que, se o seu algoritmo for muito ruim, a etapa inicial "execute várias vezes" ficará feia. Mas, francamente, é esse o caso, que por si só deve ser um indicador de que você pode recuar e reconsiderar as coisas.
fonte
Minha intuição é que uma solução geral para esse problema é impossível; afirmar, como faz, fatos a priori sobre o tempo de execução dos algoritmos sem executá-los (você alude à análise lexical). Dito isso, é possível para algum algoritmo heurístico de uma classe (provavelmente grande) de algoritmos (já que fazemos isso o tempo todo), mas um algoritmo geral para fazer isso seria equivalente a resolver o problema de Entscheidung, que é conhecido por não ser possível (cf. Church, Turing, et al.). Tenho ~ 99,9% de certeza disso agora que penso nisso ...
fonte