Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Spaziale
Biagio Pelaia
biagiopelaia@gmail.com
1. Complessità Computazionale
Per Complessità Computazionale si intende la quantità di risorse di calcolo di cui un algoritmo necessita durante
la propria esecuzione. E’ anche detta Complessità Temporale sebbene non sia una misura del tempo fisico di
esecuzione dell’algoritmo ma una valutazione del numero di operazioni che l’algoritmo compie, da cui ovviamente
dipenderà il tempo stesso di esecuzione. Ai fini di valutare la complessità computazionale di un algoritmo non è
indicativo misurarne la durata dell’esecuzione in termini di tempo fisico poichè, come facilmente intuibile, essa
dipende da molti fattori sia hardware che software. La potenza di calcolo della macchina ovviamente influenza
la velocità di esecuzione di qualsiasi istruzione che si esegue sulla stessa, ma anche fattori relativi alla gestione
dell’avvicendamento dei vari processi da parte del sistema operativo, nei sistemi operativi non real-time, influisce
su quello che è il tempo di esecuzione di un algoritmo, che non può essere conosciuto deterministicamente e
quindi non può essere usato come valore di riferimento. E’ stato fin da subito necessario stabilire un sistema che
non dipendesse in alcun modo dalla tecnologia e dall’ambiente di esecuzione del codice.
4. O(n)
Spesso non è possibile, ma in generale non è assolutamente necessario, contare precisamente quante operazioni
svolgerà un algoritmo. E’ necessario indicare al massimo quante potrebbe svolgerne, quello che è definito Upper-
bound. E’ esattamente ciò che sta a significare la notazione O(n). Matematicamente:
La fig. 1 rappresenta graficamente il concetto di f (n) = O(g(n)). Se noi diciamo che la complessità di un metodo
è O(n2 ), vuol dire che non conosciamo esattamente il numero di operazioni che esso esegue, ma sappiamo che tale
numero è limitato superiormente dalla funzione n2 . La complessità che stiamo cercando di definire corrisponde
alla f (n) nel grafico: non la conosciamo perfettamente, sappiamo che è limitata superiormente da g(n), a cui
corrisponde n2 .
5. ω(n)
La notazione ω(n) , molto spesso indicata anche come o(n) ( letto: O piccolo di n), rappresenta il caso spec-
ulare rispetto alla notazione O(g(n)): se questa rappresenta un upperbound, la notazione ω(n) rappresenta un
lowerbound, per la funzione che stiamo considerando. Matematicamente
f (n) = ω(g(n)) ⇔ ∃ α > 0, n0 > 0 | f (n) >= αg(n)), ∀n > n0 (2)
Graficamente:
La fig. 2 rappresenta graficamente il concetto di f (n) = ω(g(n)). Se noi diciamo che la complessità di un metodo
è ω(n), vuol dire che non conosciamo esattamente il numero di operazioni che esso esegue, ma sappiamo che tale
numero è limitato inferiormente dalla funzione n. La complessità che stiamo cercando di definire corrisponde
alla f (n) nel grafico: non la conosciamo perfettamente, sappiamo che è limitata inferiormente da g(n), a cui
corrisponde n.
6. Θ
La notazione f (n) = Θ(g(n)) indica una caratterizzazione più precisa della funzione che descrive la complessità
computazionale di un metodo. in particolare:
(
f (n) = O(g(n))
⇔ f (n) = Θ(g(n)) (3)
f (n) = ω(g(n))
La 3 ci dice che la funzione f può essere definita Θ(g(n)) se è contemporaneamente O(g(n)) e ω(g(n)) . Cioè se
la funzione f è limitata sia superiormente che inferiormente da una funzione g... di fatto le 2 funzioni coincidono.
Attenzione al fatto che la funzione f deve essere contemporaneamente O(g(n)) e ω(g(n)) per essere Θ(g(n)).
Questo vuol dire che se f (n) = Θ(g(n)) possiamo dire senza errore che f (n) = O(g(n)), o che f (n) = ω(g(n)),
ma non viceversa ( considerando le singole condizioni o ed ω).
8. Complessità Spaziale
Per complessità spaziale di un algoritmo si intende la quantità di risorse che esso utilizza in termini di spazio di
memoria, escluso lo spazio per l’allocazione dell’input e dell’output dell’algoritmo stesso, che ovviamente vanno
necessariamente allocati, indipendentemente dalla strategia di soluzione implementata. Dunque la complessità
spaziale di un algoritmo è data dalla dimensione delle strutture dati che esso alloca come supporto all’esecuzione
dei calcoli, espressa in funzione della dimensione dell’input, usando le sopracitate notazioni 0, ω e Θ , con la
medesima semantica adottata per esprimere la complessità computazionale. Un algoritmo che prende in ingresso
una lista lunga n elementi, e restituisca un intero, se non costruisce alcuna struttura dati di supporto ha complessità
spaziale costante, indicata con T heta(1) ( si può dire senza errore O(1)). Se invece, per qualche motivo, alloca
una lista di supporto di dimensione pari alla dimensione della struttura in ingresso, e l’output è sempre un intero,
ha occupato uno spazio di memoria lineare rispetto alla dimensione dell’input. La sua complessità spaziale sarà
O(n).Quanto appena detto vale solo per gli algoritmi iterativi.
9. La ricorsione
La valutazione della compelssità computazionale per la ricorsione non differisce molto da quella della valutazione
della complessità computazionale di algoritmi iterativi. Si ottiene ”contando” quante chiamate vengono eseguite,
che di solito non contengono altri elementi di grande onere computazionale al loro interno. La complessità com-
putazionale di un algoritmo ricorsivo è dunque data dal numero totale delle chiamate che esso effettuerà, poichè
ovviamente il metodo finisce quando tutte esse saranno finite. La complessità spaziale degli algoritmi ricorsivi
è data dal numero di chiamate a metodo contemporaneamente aperti in memoria. Ogni chiamata corrisponde
all’apertura di un record di attivazione nello stack, e quindi all’occupazione di uno spazio, non molto grande,
ma che va moltiplicato per il numero di chiamate. Le chiamate totali che esegue un metodo ricorsivo spesso non
sono tutte contemporaneamente aperte in memoria ma alcune si chiudono per lasciare posto ad altre. Ecco perchè
non conta la totalità delle chiamate come complessità spaziale, ma il numero massimo di chiamate contempo-
raneamente aperte in memoria. Tipicamente la ricorsione peggiora la complessità spaziale rispetto alla tecnica
iterativa.