No, il tuo codice ha una complessità temporale di O(2^|<DeltaTime>|)
,
Per una corretta codifica dell'ora corrente.
Per favore, lasciami prima scusarmi per il mio inglese.
Cos'è e come funziona Big O in CS
La notazione Big O non viene utilizzata per collegare l'input di un programma con il suo tempo di esecuzione .
La notazione Big O è, lasciandosi alle spalle il rigore, un modo per esprimere il rapporto asintotico di due quantità .
Nel caso dell'analisi algoritmica queste due grandezze non sono l'input (per il quale bisogna prima avere una funzione di "misura") e il tempo di esecuzione.
Sono la lunghezza della codifica di un'istanza del problema 1 e una metrica di interesse.
Le metriche comunemente utilizzate sono
- Il numero di passaggi necessari per completare l'algoritmo in un dato modello di calcolo.
- Lo spazio richiesto, se esiste un tale concetto, dal modello di calcolo.
Implicitamente si assume una TM come modello in modo che il primo punto si traduca nel numero di applicazioni della funzione di transizione 2 , cioè "passi", e il secondo traduca il numero di celle di nastro differenti scritte almeno una volta .
È anche spesso implicitamente assunto che possiamo usare una codifica polinomiale al posto di quella originale, ad esempio una funzione che ricerca un array dall'inizio alla fine ha O(n)
complessità nonostante il fatto che una codifica di un'istanza di tale array dovrebbe avere una lunghezza di n*b+(n-1)
dove b
è il numero (costante) di simboli di ogni elemento. Questo perché b
è considerata una costante del modello di calcolo e quindi le espressioni sopra e n
sono asintoticamente uguali.
Questo spiega anche perché un algoritmo come la Trial Division è un algoritmo esponenziale nonostante sia essenzialmente un for(i=2; i<=sqr(N); i++)
algoritmo simile 3 .
Vedi questo .
Ciò significa anche che la notazione O grande può utilizzare tutti i parametri necessari per descrivere il problema, non è insolito avere un parametro k per alcuni algoritmi.
Quindi non si tratta di "input" o di "non c'è input".
Caso di studio ora
La notazione Big O non mette in discussione il tuo algoritmo, presuppone solo che tu sappia cosa stai facendo. È essenzialmente uno strumento applicabile ovunque, anche ad algoritmi che possono essere deliberatamente complicati (come il tuo).
Per risolvere il tuo problema hai usato la data corrente e una data futura, quindi devono essere parte del problema in qualche modo; in poche parole: fanno parte dell'istanza del problema.
Nello specifico l'istanza è:
<DeltaTime>
Dove il <>
mezzo qualsiasi, non patologico, codifica di scelta.
Vedi sotto per chiarimenti molto importanti .
Quindi il tuo tempo di grande complessità O è giusto O(2^|<DeltaTime>|)
, perché fai un numero di iterazioni che dipende dal valore del tempo corrente. Non ha senso inserire altre costanti numeriche poiché la notazione asintotica è utile in quanto elimina le costanti (quindi ad esempio l'uso di O(10^|<DeltaTime>|*any_time_unit)
è inutile).
Dove sta la parte difficile
Abbiamo fatto un'ipotesi importante sopra: che il modello di calcolo reifica 5 volte, e per tempo intendo il tempo fisico (reale?). Non esiste un tale concetto nel modello computazionale standard, una MT non conosce il tempo, colleghiamo il tempo al numero di passaggi perché è così che funziona la nostra realtà 4 .
Nel tuo modello, tuttavia, il tempo fa parte del calcolo, puoi usare la terminologia delle persone funzionali dicendo che Main non è puro ma il concetto è lo stesso.
Per capirlo bisogna notare che nulla impedisce al Framework di utilizzare un tempo falso che viene eseguito due volte, cinque, dieci volte più velocemente del tempo fisico. In questo modo il codice verrà eseguito in "metà", "un quinto", "un decimo" del "tempo".
Questa riflessione è importante per la scelta della codifica di <DeltaTime>
, questo è essenzialmente un modo condensato di scrivere <(CurrentTime, TimeInFuture)>. Poiché il tempo non esiste al priorato, la codifica di CurrentTime potrebbe benissimo essere la parola Now (o qualsiasi altra scelta) il giorno prima potrebbe essere codificata come Ieri , rompendo l'assunto che la lunghezza della codifica aumenti come il tempo fisico va avanti (e quello di DeltaTime diminuisce)
Dobbiamo modellare correttamente il tempo nel nostro modello computazionale per fare qualcosa di utile.
L'unica scelta sicura che possiamo fare è codificare timestamp con lunghezze crescenti (ma ancora senza utilizzare unario) man mano che il tempo fisico avanza. Questa è l'unica vera proprietà del tempo di cui abbiamo bisogno e quella che la codifica deve catturare. È solo con questo tipo di codifica che il tuo algoritmo può dare una complessità temporale.
La tua confusione, se esiste, deriva dal fatto che la parola tempo nelle frasi "Qual è la sua complessità temporale ?" e "Quanto tempo ci vorrà?" significa cose molto diverse
Purtroppo la terminologia usa le stesse parole, ma puoi provare a usare la "complessità dei passaggi" nella tua testa e porsi nuovamente la tua domanda, spero che ti aiuterà a capire che la risposta è davvero ^ _ ^
1 Questo spiega anche la necessità di un approccio asintotico poiché ogni istanza ha una lunghezza diversa, ma non arbitraria.
2 Spero di usare qui il termine inglese corretto.
3 Anche questo è il motivo per cui spesso troviamo i log(log(n))
termini in matematica.
4 Ad esempio , un gradino deve occupare un intervallo di tempo finito, ma non nullo, né non connesso.
5 Ciò significa che il modo computazionale come conoscenza del tempo fisico in esso, cioè può esprimerlo con i suoi termini. Un'analogia è il modo in cui i generici funzionano nel framework .NET.
O(N)
complessitàO(1)