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 esegue return 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