Ao calcular a dependência do tempo de execução da entrada, quais cálculos são considerados? Por exemplo, acho que aprendi que a indexação de array e as instruções de atribuição não são contadas, por que isso?
8
Ao calcular a dependência do tempo de execução da entrada, quais cálculos são considerados? Por exemplo, acho que aprendi que a indexação de array e as instruções de atribuição não são contadas, por que isso?
Ao fazer cálculos de complexidade, geralmente usamos o modelo de RAM . Neste modelo, assumimos que a indexação da matriz é O (1). A declaração de atribuição é como atribuir algum valor a alguma variável na matriz de variáveis . Isto é apenas por conveniência. Simplifica a análise do algoritmo. No mundo real, a indexação de array leva O (log I) onde I é o número de coisas indexadas.
Geralmente consideramos coisas que dependem do tamanho da entrada, por exemplo, loops. Mesmo se houver operação O (1) no loop e for executada n vezes, o algoritmo será executado pelo tempo O (n).
Mas a operação O (1) fora do loop leva apenas tempo constante e O (n) + O (1) = O (n).
Leia sobre o algoritmo de classificação de radix no CLRS.
O objetivo final é "tempo de execução em segundos" ou mais geralmente (desconsiderando os recursos modernos da CPU) "número de ciclos de clock". Acontece que isso é difícil de analisar e também é específico da máquina ou, pelo menos, do conjunto de instruções. Portanto, geralmente não é feito.
O próximo nível de abstração é contar com precisão todas as operações (de algum pseudocódigo no estilo de montagem), mantendo o custo da operação individual (em ciclos de clock) como parâmetros. Observe que essa análise é encontrada em "A arte da programação de computadores", de Knuth, entre outras. Portanto, certamente há um lugar para esse tipo de abordagem, mesmo que seja difícil e tenda a ser mais difícil na presença da hierarquia de memória.
Por último, mas não menos importante - e certamente mais proeminente - é a análise de operações dominantes, ignorando fatores constantes e as contribuições assintoticamente desaparecidas ("O -analysis "). O raciocínio é que o tempo de execução deve se comportar assintoticamente como o número de operações executadas com mais frequência, vezes algum fator, dependendo da implementação e da máquina reais. Esse tipo de análise produz resultados gerais que se aplicam a todas as máquinas (cobertas por RAM) e é mais fácil de executar do que o descrito acima, mas pode não ter especificidade.
Deixando para trás as estruturas "clássicas", muitos algoritmos são dominados pelo custo de memória e / ou comunicação, portanto, nesse caso, contar o número e o volume de memória considera as respectivas. transmissões de rede é razoável (e talvez suficiente).
Além disso, lembre-se de que muitas vezes não estamos tão interessados no desempenho absoluto de um algoritmo, mas em compará-lo com outros. Isso também pode informar a escolha do parâmetro analisado.
Então você vê, não há uma resposta definitiva. Dependendo dos objetivos da análise em questão, diferentes respostas podem ser dadas.
Veja também a minha resposta aqui para alguns pensamentos relacionados, e a resposta de Sebastian no Quicksort, por exemplo.
fonte