es1: complessità lineare “nascosta”
def es1(n):
t = 0
n = abs(n)
if n > 100:
return 1
for i in range(n):
t += 3
return t
abs
costa- quel
for
costerebbe , ma dato che da 100 in poi la funzione eseguereturn 1
, che ha complessità , la peggiore complessità temporale possibile sarebbe , quindi . In sostanza, l’unico caso rilevante in asintotica è il limite che tende a infinito della dimensione dell’input, che in questo caso è costante.
es2: complessità che sembra oscillare
def es2(n):
while n >= 0:
if n%2:
return 1
n -= 2
return 0
Se n
è dispari, la complessità è , mentre se n
è pari la complessità è .
Il limite della successione definita su n
non esiste perché la funzione oscilla, quindi è difficile calcolare la probabilità; ma per fortuna n
pari e n
dispari sono due casi equiprobabili, cioè abbiamo una probabilità del 50% di avere complessità o , quindi in questo caso la complessità media corrisponde alla media (media pesata, nel caso più generale) delle complessità , ovvero (NON perché non ha sempre esattamente complessità ).
es3:
def es3(n):
n = abs(n)
x = r = 0
while x*x < n:
x += 1
r += 3*x
return r
Si procede per esclusione, ignorando le istruzioni costanti fuori dal while
.
while x*x < n: # n è la variabile indipendente
# 2 istruzioni costanti (in totale costano O(1))
# x aumenta sempre di 1
Dato che while
si ferma quando (), cioè quando , quindi la complessità è .
es4: complessità logaritmica
def es4(n):
x = r = 0
while n > 1:
r += 2
n = n//3
return r
Ogni volta, n
diventa un terzo di quanto era prima e determina anche il numero di iterazioni ( = numero di iterazioni).
Il programma si fermerà quando → , quindi la complessità sarà .
es6:
def es6(n):
p = 2
while n >= p:
p = p*p
return p
p
cresce esponenzialmente ad ogni (!!!) iterazione () e il programma si ferma quando , sostituendo otteniamo che , quindi , cioè la complessità è .
es7:
def es7(n):
u, t, s = 1
while u <= n:
for j in range(t):
s += 1
u += 1
t += 1
return s
La prima volta il for viene eseguito una volta, poi due volte, poi tre etc, perché ad ogni iterazione del while, il for si allunga di 1 iterazione, perché viene incrementato di uno.
es9:
def es9(n):
n = abs(n)
s, p = n, 2
i, r = 1
while s >= 1:
s = s // 5
p += 2
p = p*p
while i*i*i < n:
for j in range(p):
r += 1
i += 1
return r
- Il primo while ha complessità .
- Nel secondo while ogni volta si incrementa di 1 e si ferma quando , quindi quando .
- Il for annidato, dipendente da , avrà iterazioni.
- Quindi il secondo while avrà la complessità totale uguale al prodotto delle complessità del for interno e del while esterno, quindi .
- La complessità del programma sarà la maggiore tra il primo e il secondo while, quindi