Non, votre code a une complexité temporelle de O(2^|<DeltaTime>|)
,
Pour un codage correct de l'heure actuelle.
S'il vous plaît, laissez-moi d'abord m'excuser pour mon anglais.
Qu'est-ce que et comment Big O fonctionne dans CS
La notation Big O n'est pas utilisée pour lier l'entrée d'un programme à son temps d'exécution .
La notation Big O est, en laissant la rigueur derrière elle, un moyen d'exprimer le rapport asymptotique de deux quantités .
Dans le cas de l'analyse d'algorithme, ces deux grandeurs sont ne pas l'entrée (pour laquelle il faut d'abord avoir une fonction "mesure") et le temps d'exécution.
Ce sont la longueur du codage d'une instance du problème 1 et une métrique d'intérêt.
Les métriques couramment utilisées sont
- Le nombre d'étapes nécessaires pour compléter l'algorithme dans un modèle de calcul donné.
- L'espace requis, s'il existe un tel concept, par le modèle de calcul.
On suppose implicitement un TM comme modèle de sorte que le premier point se traduit par le nombre d'applications de la transition 2 fonction de , c'est-à-dire «étapes», et le second traduit le nombre de cellules de bande différentes écrites au moins une fois .
Est-il aussi souvent supposé implicitement que nous pouvons utiliser un codage polynomialement lié au lieu de l'original, par exemple une fonction qui recherche un tableau du début à la fin est O(n)
complexe malgré le fait qu'un codage d'une instance d'un tel tableau devrait avoir une longueur de n*b+(n-1)
oùb
est le nombre (constant) de symboles de chaque élément. En effet, il b
est considéré comme une constante du modèle de calcul et donc l'expression ci-dessus et n
sont asymptotiquement identiques.
Cela explique également pourquoi un algorithme comme la Division de première instance est un algorithme exponentiel bien qu'il soit essentiellement un for(i=2; i<=sqr(N); i++)
algorithme similaire 3 .
Voir ça .
Cela signifie également que la grande notation O peut utiliser autant de paramètres dont on peut avoir besoin pour décrire le problème, n'est-il pas inhabituel d'avoir un k paramètre pour certains algorithmes.
Donc ce n'est pas de "l'entrée" ou de "qu'il n'y a pas d'entrée".
Étude de cas maintenant
La notation Big O ne remet pas en question votre algorithme, elle suppose simplement que vous savez ce que vous faites. C'est essentiellement un outil applicable partout, même à un algorithme qui peut être délibérément délicat (comme le vôtre).
Pour résoudre votre problème, vous avez utilisé la date actuelle et une date future, elles doivent donc faire partie du problème d'une manière ou d'une autre; en termes simples: ils font partie de l'instance du problème.
Plus précisément, l'instance est:
<DeltaTime>
Où le <>
signifie un codage de choix, non pathologique.
Voir ci-dessous pour des clarifications très importantes .
Donc, votre grand temps de complexité O est juste O(2^|<DeltaTime>|)
, car vous effectuez un certain nombre d'itérations qui dépendent de la valeur du temps actuel. Il ne sert à rien de mettre d'autres constantes numériques car la notation asymptotique est utile car elle élimine les constantes (donc par exemple l'utilisation deO(10^|<DeltaTime>|*any_time_unit)
est inutile).
Où est la partie délicate
Nous avons fait une hypothèse importante ci-dessus: que le modèle de calcul réifie 5 temps, et par temps j'entends le temps physique (réel?). Un tel concept n'existe pas dans le modèle de calcul standard, une MT ne connaît pas le temps, nous associons le temps au nombre d'étapes car c'est ainsi que fonctionne notre réalité 4 .
Dans votre modèle, cependant, le temps fait partie du calcul, vous pouvez utiliser la terminologie des personnes fonctionnelles en disant que Main n'est pas pur mais que le concept est le même.
Pour comprendre cela, il faut noter que rien n'empêche le Framework d'utiliser un faux temps qui s'exécute deux, cinq, dix fois plus vite que le temps physique. De cette façon, votre code fonctionnera dans «la moitié», «un cinquième», «un dixième» du «temps».
Cette réflexion est importante pour le choix du codage de <DeltaTime>
, c'est essentiellement une manière condensée d'écrire <(CurrentTime, TimeInFuture)>. Puisque le temps n'existe pas au prieuré, le codage de CurrentTime pourrait très bien être le mot Now (ou tout autre choix) la veille pourrait être codé comme Hier , là en cassant l'hypothèse que la longueur du codage augmente avec le temps physique avance (et celui de DeltaTime diminue)
Nous devons modéliser correctement le temps dans notre modèle de calcul afin de faire quelque chose d'utile.
Le seul choix sûr que nous pouvons faire est d'encoder des horodatages avec des longueurs croissantes (mais toujours sans utiliser unaire) au fur et à mesure que le temps physique avance. C'est la seule vraie propriété du temps dont nous avons besoin et celle dont l'encodage a besoin pour capturer. Ce n'est qu'avec ce type d'encodage que votre algorithme peut avoir une complexité temporelle.
Votre confusion, le cas échéant, provient du fait que le mot temps dans les phrases «Quelle est sa complexité temporelle ? et "Combien de temps cela prendra-t-il?" signifie des choses très très différentes
Hélas, la terminologie utilise les mêmes mots, mais vous pouvez essayer d'utiliser "étapes de complexité" dans votre tête et vous poser à nouveau votre question, j'espère que cela vous aidera à comprendre que la réponse est vraiment ^ _ ^
1 Cela explique aussi la nécessité d'une approche asymptotique que chaque instance a un autre, mais pas arbitraire, longueur.
2 J'espère que j'utilise le terme anglais correct ici.
C'est aussi pourquoi nous trouvons souvent des log(log(n))
termes en mathématiques.
4 Id est, un pas doit occuper un intervalle de temps fini, mais non nul, ni non connexe.
5 Cela signifie que le mode de calcul en tant que connaissance du temps physique en elle, qui est peut l' exprimer à ses conditions. Une analogie est le fonctionnement des génériques dans le framework .NET.
O(N)
pas la complexitéO(1)