Não, seu código tem complexidade de tempo de O(2^|<DeltaTime>|)
,
Para uma codificação adequada da hora atual.
Por favor, deixe-me primeiro pedir desculpas pelo meu inglês.
O que é e como o Big O funciona no CS
A notação Big O não é usada para amarrar a entrada de um programa com seu tempo de execução .
A notação Big O é, deixando para trás o rigor, uma forma de expressar a proporção assintótica de duas quantidades .
No caso da análise de algoritmo, essas duas grandezas não são a entrada (para a qual é necessário primeiro ter uma função de "medida") e o tempo de execução.
Eles são o comprimento da codificação de uma instância do problema 1 e uma métrica de interesse.
As métricas comumente usadas são
- O número de etapas necessárias para concluir o algoritmo em um determinado modelo de computação.
- O espaço necessário, se tal conceito existir, pelo modelo de computação.
Implicitamente é assumido um TM como o modelo de forma que o primeiro ponto se traduz no número de aplicações da função de transição 2 , ou seja, "etapas", e o segundo ponto traduz o número de células de fita diferentes escritas pelo menos uma vez .
Também é frequentemente assumido implicitamente que podemos usar uma codificação relacionada polinomialmente em vez da original, por exemplo, uma função que pesquisa uma matriz do início ao fim tem O(n)
complexidade, apesar do fato de que uma codificação de uma instância de tal matriz deve ter comprimento de n*b+(n-1)
onde b
é o número (constante) de símbolos de cada elemento. Isso ocorre porque b
é considerada uma constante do modelo de cálculo e, portanto, as expressões acima e n
são assintoticamente iguais.
Isso também explica por que um algoritmo como a Divisão de Teste é um algoritmo exponencial , apesar de ser essencialmente um for(i=2; i<=sqr(N); i++)
algoritmo semelhante 3 .
Veja isso .
Isso também significa que a notação grande O pode usar quantos parâmetros forem necessários para descrever o problema, não é incomum ter um parâmetro k para alguns algoritmos.
Portanto, não se trata de "entrada" ou de "não há entrada".
Estudo de caso agora
A notação Big O não questiona seu algoritmo, apenas assume que você sabe o que está fazendo. É essencialmente uma ferramenta aplicável em qualquer lugar, até mesmo para algoritmos que podem ser deliberadamente complicados (como o seu).
Para resolver o seu problema você usou a data atual e uma data futura, então elas devem fazer parte do problema de alguma forma; Simplificando: eles são parte da instância do problema.
Especificamente, a instância é:
<DeltaTime>
Onde o <>
significa qualquer codificação não patológica de escolha.
Veja abaixo esclarecimentos muito importantes .
Portanto, o seu grande tempo de complexidade O é justo O(2^|<DeltaTime>|)
porque você faz uma série de iterações que dependem do valor do tempo atual. Não há sentido em colocar outras constantes numéricas, pois a notação assintótica é útil, pois elimina constantes (então, por exemplo, o uso de O(10^|<DeltaTime>|*any_time_unit)
é inútil).
Onde está a parte complicada
Fizemos uma suposição importante acima: que o modelo de computação reafirma 5 tempo, e por tempo quero dizer o tempo físico (real?). Não existe tal conceito no modelo computacional padrão, uma TM não conhece o tempo, relacionamos o tempo com o número de passos porque é assim que a nossa realidade funciona 4 .
No seu modelo, no entanto, o tempo faz parte do cálculo, você pode usar a terminologia de pessoas funcionais dizendo que Main não é puro, mas o conceito é o mesmo.
Para entender isso deve-se observar que nada impede o Framework de usar um tempo falso que roda duas, cinco, dez vezes mais rápido que o tempo físico. Desta forma, seu código será executado na "metade", "um quinto", "um décimo" do "tempo".
Esta reflexão é importante para escolher a codificação de <DeltaTime>
, esta é essencialmente uma forma condensada de escrever <(CurrentTime, TimeInFuture)>. Visto que o tempo não existe a priory, a codificação de CurrentTime poderia muito bem ser a palavra Now (ou qualquer outra escolha) no dia anterior poderia ser codificada como Yesterday , quebrando a suposição de que o comprimento do aumento de codificação conforme o tempo físico avança (e o de DeltaTime diminui)
Temos que modelar corretamente o tempo em nosso modelo computacional para fazer algo útil.
A única escolha segura que podemos fazer é codificar timestamps com comprimentos crescentes (mas ainda sem usar unário) conforme o tempo físico avança. Esta é a única propriedade verdadeira do tempo de que precisamos e que a codificação precisa capturar. É apenas com esse tipo de codificação que seu algoritmo pode ter uma complexidade de tempo.
Sua confusão, se houver, surge do fato de que a palavra tempo nas frases 'Qual é sua complexidade de tempo ?' e 'Quanto tempo vai demorar?' significa coisas muito diferentes
Infelizmente, a terminologia usa as mesmas palavras, mas você pode tentar usar "etapas complexas" em sua cabeça e fazer novamente a si mesmo sua pergunta, espero que isso o ajude a entender que a resposta é realmente ^ _ ^
1 Isso também explica a necessidade de uma abordagem assintótica, pois cada instância tem um comprimento diferente, embora não arbitrário.
2 Espero estar usando o termo inglês correto aqui.
3 Também é por isso que frequentemente encontramos log(log(n))
termos na matemática.
4 Id est, uma etapa deve ocupar algum intervalo de tempo finito, mas não nulo, nem conectado.
5 Isso significa que o modo computacional como um conhecimento do tempo físico nele, ou seja, pode expressá-lo com seus termos. Uma analogia é como os genéricos funcionam na estrutura .NET.
O(N)
complexidade, nãoO(1)