1
Fork 0
mirror of https://github.com/Steffo99/appunti-magistrali.git synced 2024-11-25 03:34:17 +00:00
appunti-steffo/2 - Algoritmi e strutture dati/04 - Notazione asintotica.md

5.1 KiB

Notazione asintotica

La notazione asintotica è un sistema per stimare velocemente il costo di un algoritmo complesso.

Ci permette di confrontare velocemente il caso peggiore degli algoritmi.

In particolare, consideriamo il rapporto tra il numero di operazioni nel caso peggiore e la dimensione dell'input.

Limiti

Possiamo dare a questa stima dei limiti, superiore e inferiore, che rappresenteranno rispettivamente un costo che non sarà mai superato e un costo che verrà sempre superato.

Chiameremo questi limiti upper bound e lower bound; la loro combinazione darà un tight bound.

L'obiettivo sarà di ricavare i bound più precisi possibile per un dato algoritmo, ovvero l'upper bound più basso e il lower bound più alto.

O grande

"O grande"
O di g(n) "big-O"

Per rappresentare la stima, useremo una notazione particolare, detta O grande, con la seguente proprietà:

  • Date due funzioni f(n) : N -> R e g(n) : N -> R, diremo che f(n) ∈ O(g(n)) se e soltanto se ∃ c > 0, n ≥ n_0 tali che ∀ n ≥ 0, f(n) ≤ c * g(n)

Quando una funzione è O grande di un altra, significa che asintoticamente, la funzione in O grande è sempre maggiore di quella che sta venendo stimata.

Ipotesi

  • f(n) = 2n² + 3n + 6
  • g(n) = n²

Tesi

  • f(n) ∈ O(n²).

Svolgimento
Scrivo una disequazione, lasciando intatto il termine noto:

  1. 2n² + 3n + 6 ≤ 2n² + 3n² + 6
  2. n² ≤ 2n² + 3n² + n² = 6n² per n ≥ 3

Sappiamo, allora, che 2n² + 3n + 6 ≤ 6n².

Espressioni di O grande

Questa tabella rappresenta le espressioni di O grande più comunemente utilizzate, in ordine dalla più forte alla più debole.

Più forte significa che, per ogni riga della tabella, tutte le righe sottostanti sono contenute nell'espressione.

Ad esempio, O(n) ∈ O(1).

Espressione O() Nome
O(1) Costante
O(log log n) loglog
O(log n) Logaritmica
LaTeX (per c ≥ 1) Sublineare
O(n) Lineare
O(n log n) nlogn
O(n²) Quadratica
O(n³) Cubica
O(n^k) (per k ≥ 1) Polinomiale
O(a^n) (per a ≥ 1) Esponenziale
O(n!) Fattoriale

Polinomiale

Molto spesso, noteremo che il tempo richiesto da una funzione è O grande di un polinomio di grado K, ovvero f(n) ∈ O(n^k).

Notiamo che in questi casi, possiamo semplificare l'O grande al grado massimo del polinomio.

Ad esempio, O(n² + n + 1) = O(n²).

Dimostrazione

Per n > 0 \and 0 ≤ i ≤ k:
LaTeX

Proprietà di O grande

  1. f(n) ∈ O(g(n)) -> ∀ a > 0, a * f(n) ∈ O(g(n)).
  2. f(n) ∈ O(g(n)), d(n) ∈ O(h(n)) -> f(n) + d(n) ∈ O(g(n) + h(n)) -> O(max\{g(n), h(n)\})
  3. f(n) ∈ O(g(n)), d(n) ∈ O(h(n)) -> f(n) * d(n) ∈ O(g(n) * h(n))

In pratica, se una funzione è la somma di più termini, basta guardare l'O() più grande tra tutti i suoi termini; se invece una funzione è un prodotto di più termini, si possono omettere le costanti, e l'O() finale sarà dato dal prodotto degli O() dei termini.

Lower bound

Possiamo anche stimare il lower bound, il limite inferiore: il numero minimo di operazioni che viene effettuato nel caso migliore con la massima dimensione dell'ingresso.

Ω()

"Omega"
Omega di g(n) "big-Omega"

Esiste un equivalente di O grande per il lower bound: è detto Omega grande, o più semplicemente Omega, e funziona nello stesso identico modo, solo... al contrario.

Diremo che f(n) ∈ Ω(g(n)) se e solo se ∃ c > 0, n_0 ≥ 0 : ∀ n ≥ n_0 f(n) ≥ c * g(n).

Espressioni di Ω()

Anche in questa tabella le espressioni sono dalla più forte alla più debole.

Espressione Ω() Nome
Ω(n!) Fattoriale
Ω(a^n) (per a ≥ 1) Esponenziale
Ω(n^k) (per k ≥ 1) Polinomiale
Ω(n³) Cubica
Ω(n²) Quadratica
Ω(n log n) nlogn
Ω(n) Lineare
LaTeX (per c ≥ 1) Sublineare
Ω(log n) Logaritmica
Ω(log log n) loglog
Ω(1) Costante

Tight bound

Quando upper e lower bound coincidono, allora otteniamo un tight bound.

θ()

"Theta"
Theta di g(n) "big-Theta"

Anche per il tight bound abbiamo una notazione equivalente a O grande e Omega grande: Theta grande!

Diciamo che f(n) ∈ θ(g(n)) se e solo se ∃ c_1, c_2 > 0, n_0 ≥ 0 : ∀ n ≥ n_0, c_1 * g(n) ≤ f(n) ≤ c_2 * g(n).

Ha la particolarità che non valgono tutte le proprietà degli altri due: va usata quindi con cautela!

Risorse utili

khanacademy.org