Cosa costituisce un'unità di tempo nell'analisi di runtime?


8

Quando si calcola la dipendenza del runtime dall'input, quali calcoli vengono considerati? Ad esempio, penso di aver appreso che l'indicizzazione dell'array e le istruzioni di assegnazione non vengono conteggiate, perché?

Risposte:


6

Quando eseguiamo calcoli di complessità generalmente utilizziamo il modello RAM . In questo modello assumiamo che l'indicizzazione dell'array sia O (1). L'istruzione di assegnazione è come assegnare un valore ad alcune variabili nell'array di variabili . Questo è solo per comodità. Semplifica l'analisi dell'algoritmo. Nel mondo reale l'indicizzazione dell'array prende O (registro I) dove sono il numero di cose indicizzate.

Consideriamo generalmente cose che dipendono dalla dimensione dell'input, ad esempio loop. Anche se nel loop è presente un'operazione O (1) che viene eseguita n volte, l'algoritmo viene eseguito per O (n) tempo.

Ma l'operazione O (1) al di fuori del loop richiede solo tempo costante e O (n) + O (1) = O (n).

Leggi l'algoritmo di ordinamento radix da CLRS.


Che dire degli incrementi in un loop? Dovrebbero essere O (n) giusto?

per (int k = 0; k <N; k ++) {sum = sum + valori [k];} È il codice in questione. Si diceva che effettuasse 3N + 2 chiamate.

No. Per sum = sum + valori [k], + è O (1) e = è anche O (1). Ma il ciclo esegue O (N) volte . Quindi è O (N) * O (1 + 1) = O (N). Le chiamate O (3N + 2) sono solo O (N).
Pratik Deoghare,

Ma perché sono chiamate O (3N + 2)?

Il valore di accesso [k] è 1 chiamata. + è 1 chiamata. = è 1 chiamata. Questo spiega 3 chiamate effettuate N volte ma non so di +2.
Pratik Deoghare,

5

L'obiettivo finale è "tempo di esecuzione in secondi" o più in generale (trascurando le moderne funzionalità della CPU) "numero di cicli di clock". A quanto pare, questo è difficile da analizzare, ed è anche specifico della macchina o almeno del set di istruzioni. Pertanto, di solito non viene eseguito.

Il prossimo livello di astrazione è contare con precisione tutte le operazioni (di alcuni pseudo codici di tipo assembly), mantenendo i singoli costi delle operazioni (in cicli di clock) come parametri. Si noti che tale analisi si trova in "The Art of Computer Programming" di Knuth tra gli altri, quindi sicuramente c'è un posto per questo tipo di approccio, anche se è difficile e tende ad essere più difficile in presenza della gerarchia della memoria.

Ultimo ma non meno importante - e sicuramente il più importante - è l'analisi delle operazioni dominanti che ignorano i fattori costanti e le costellazioni che scompaiono asintoticamente (" -analisi"). Il ragionamento è che il runtime è destinato a comportarsi in modo asintotico come il numero di operazioni eseguite più frequentemente, moltiplicato per alcuni fattori a seconda dell'implementazione e della macchina effettive. Questo tipo di analisi produce risultati generali che si applicano a tutte le macchine (coperte dal modello RAM) ed è più facile da eseguire rispetto a quanto sopra. Tuttavia, può mancare di specificità.O

Lasciando indietro i quadri "classici", molti algoritmi sono dominati dalla memoria e / o dai costi di comunicazione, quindi in quel caso contano il numero e il volume delle memorie di memoria rispettivamente. le trasmissioni di rete sono ragionevoli (e forse sufficienti).

Inoltre, tieni presente che spesso non siamo così interessati alle prestazioni assolute di un algoritmo, ma a confrontarlo con gli altri. Anche questo può informare la scelta del parametro analizzato.

Quindi vedete, non esiste una risposta definitiva. A seconda degli obiettivi dell'analisi in corso, è possibile fornire diverse risposte.

Vedi anche la mia risposta qui per alcuni pensieri correlati, e la risposta di Sebastian su Quicksort per un esempio.


Non mi accontento di dire che l'approccio più importante che menzioni è interamente coperto dal modello RAM: il modello RAM di solito non tiene conto dei costi uniformi per la moltiplicazione (al fine di mantenere l'equivalenza dei problemi risolvibili dai TM nel poli-tempo con problemi risolvibile da RAM in poly-time). Tuttavia, si presume che la moltiplicazione abbia un costo costante nell'analisi di molti algoritmi
Cornelius Brand

@cbra: non ho riscontrato un modello RAM con un costo uniforme per tutto tranne che per la moltiplicazione. In particolare, non è necessario per poli-tempo-equivalenza.
Raffaello

Non sono sicuro di aver capito bene, ma quando si assegna un costo uniforme alla moltiplicazione, è possibile calcolare (quindi memorizzare) il numero in passi usando la quadratura ripetuta. 2(2n)O(n)
Cornelius Brand

@cbra Sembra che tu abbia un punto lì. Il modello RAM in forma "pura" non offre la moltiplicazione come azione atomica, ma la implementa aggiungendo ripetutamente. Pertanto, il costo uniforme per la moltiplicazione (e potenzialmente altre operazioni) è "pericoloso" in quanto interrompe determinate relazioni se applicato a problemi in cui il numero diventa grande (ovvero maggiore dell'input (?)).
Raffaello
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.