Notazioni asintotiche Martedì 30 settembre 2014 • Punto della situazione – Cos’è un algoritmo – Tempo di esecuzione T(n) – Analisi di algoritmi: analisi asintotica di T(n) • Argomento di oggi: – Notazioni asintotiche: matematica! • Motivazioni: – Confrontare tempi di esecuzione di algoritmi fra loro o con funzioni standard (lineare, polinomiale, esponenziale…) • Argomento lezione precedente: Tempo di esecuzione di un algoritmo E’ tutto chiaro? Ricerca del massimo Esempio: ricerca del massimo fra n numeri a1, … , an. Un algoritmo (in pseudocodice): max = a1 For i = 2 to n If (ai > max) then max = ai Endif Endfor Pseudocodice di [KT] max a1 for i = 2 to n { if (ai > max) max ai } Pseudocodice di [CLRS] Struttura di un algoritmo (non ricorsivo) Può essere costituito da: • Una singola istruzione elementare • Un blocco sequenziale di istruzioni (allo stesso livello di indentazione) • Un’istruzione if: If(cond) then istr1 Else istr2 Endif • Un ciclo o loop for, while, repeat: – For i=a to b {istr} Endfor – While (cond){istr} – Repeat {istr} until (cond) Struttura dell’esempio 1. 2. 3. 4. 5. 6. max = a1 For i = 2 to n If (ai > max) then max = ai Endif Endfor E’ un blocco di 2 istruzioni: 1. Assegnamento 2-6. For L’istruzione For delle linee 2-6 è: For i=a to b {istr0} Endfor dove istr0 è l’istruzione if delle linee 3-5 L’istruzione If delle linee 3-5 è: If(cond) then istr1 Else istr2 Endif dove cond è il confronto: ai > max istr1 è l’assegnamento: max = ai istr2 è vuota Regole per il calcolo di T(n) (caso non ricorsivo) • il costo di un blocco sequenziale di istruzioni è pari alla somma dei costi delle singole istruzioni Altri esempi • Insertion-Sort su CLRS • In seguito semplificheremo l’analisi con notazioni asintotiche Tempo di esecuzione Tempo di esecuzione T(n) sarà misurato in termini del numero di operazioni elementari per eseguire l’algoritmo su un input di taglia n Assegnamento, incremento, confronto sono considerate operazioni elementari all’interno dell’algoritmo della ricerca del massimo. Richiedono tempo costante (= non dipendente dalla taglia n dell’input) ma a priori non quantificabile Analisi asintotica Vogliamo analizzare l’efficienza dell’algoritmo • Indipendentemente da implementazione, hardware etc. • Al crescere della taglia dell’input Studieremo il tempo in funzione della taglia dell’input : T(n) Studieremo la crescita della funzione T(n) al crescere di n • • • • «asintotica»: per n arbitrariamente grande per n che tende a infinito da un certo punto in poi per ogni n ≥ n0 Vantaggi dell’analisi asintotica • Indipendente da hardware • Effettuabile con pseudocodice prima di implementare l’algoritmo • Considera infiniti input Alternativa? Analisi su dati campione. Svantaggi: bisogna avere già implementato l’algoritmo; analizza numero finito di dati Caso peggiore, migliore, medio Analisi del caso peggiore: qualunque sia la distribuzione dell’input T(n) è limitata superiormente da f(n) Analisi del caso migliore: qualunque sia la distribuzione dell’input T(n) è limitata inferiormente da g(n) (poco significativa) Analisi del caso medio: nel caso di una distribuzione media o random (difficile da determinare) Notazioni asintotiche Nell’analisi asintotica analizziamo T(n) 1. A meno di costanti moltiplicative (perché non quantificabili) 2. Asintoticamente (per considerare input di taglia arbitrariamente grande, quindi in numero infinito) Le notazioni asintotiche: O, Ω, Θ, o, ω ci permetteranno il confronto tra funzioni, mantenendo queste caratteristiche. Idea di fondo: O, Ω , Θ, o, ω rappresentano rispettivamente ≤ , ≥ , =, <, > in un’analisi asintotica Funzioni T(n) Se T(n) rappresenta un tempo di esecuzione su un input di taglia n, allora: n è un intero positivo T(n) è un reale positivo T: N R+ Inoltre T(n) è una funzione non decrescente Funzioni standard Fra le funzioni non decrescenti T: N R+ ci interesseranno principalmente le seguenti (e le loro combinazioni): T1(n) = c, con c costante T2 (n)=log n T3 (n)=n T4 (n)=n2 T5 (n)= 2n Ordini di infinito Le funzioni c, log n, n, n2, 2n sono tutte funzioni positive di variabile positiva e non decrescenti, ma hanno una diversa crescita asintotica, ovvero un diverso ordine di infinito (come si dice in analisi matematica). Le notazioni O, Ω, Θ, o, ω misurano questo. Grafici delle funzioni 2n log 2 0 tende a - log 2 1 = 0 log 2 2 =1 log 2 n ≤ n per ogni n ≥ 1 n T(n) n2 log 2 n 3 3 ≤ log 2 n per ogni n ≥ 8 n Approssimativamente…. n ≤ n2 per ogni n ≥ 1 Un altro esempio log2(2n+1) = O( n+5 ) c, n0, t.c. log2(2n+1) ≤ c ( n+5 ) per ogni n ≥n0 Se 1 ≤ n log2 (2n+1) ≤ ≤ log2 (2n+n) = log2 (3n) = log2 (3)+ log2 (n) ≤ 1,585+ log2 n≤ ≤ 5 + log2 n ≤ 5+n Se log 2 n ≤ n n≥1 c=1 n 0 =1 Esempio n2 - 2n +1 = O(n2) 1. (tecnica per i polinomi) n2 - 2n +1 ≤ n2 + 2n +1 ≤ n2 + 2n2 +1 ≤ n2 +2n2+n2 = 4 n2 c = 4, n0=1 2. n2 - 2n +1 ≤ n2 +1 ≤ n2 + n2 =2n2 c = 2, n0=1 3. (disequazioni) n2 - 2n +1 ≤ 2 n2 sse n2 + 2n - 1 ≥ 0 n ≤ -1-√2 ed n ≥ -1+ √2 c = 2, n0=1 4. n2 - 2n +1 =(n-1) 2 ≤ n2 c = 1, n0=1 Nota: se esiste un coppia (c, n0), ne esistono infinite, ma per dimostrare O ne basta esibire 1 sola. Esempio (errore tipico) n2 + 5 = O(10n) ? Dimostrazione (forse) L’affermazione è Vera, perché per c=1, n2 + 5 ≤ 10 n per ogni n ≥ 1. Infatti: per n=1, 12 + 5 ≤ 10; per n=2, 22 + 5 ≤ 20; per n=3, 32 + 5 ≤ 30; per n=9, 92 + 5 ≤ 90. Fine della prova! La dimostrazione non è corretta perché ho dimostrato l’affermazione solo per alcuni valori di n ≥ 1, e non per ogni n ≥ 1. Si può dimostrare che n2 + 5 ≤ 10 n, solo per i valori compresi fra 1 e 9, risolvendo la disequazione di secondo grado. Inoltre ….. Esempio (continua) Inoltre si può dimostrare che: non esistono costanti c > 0, n0 ≥0, tali che n2 + 5 ≤ c n per ogni n ≥ n0. Infatti: n2 + 5 ≤ c n per ogni n ≥ n0 sse c ≥ (n2 + 5 )/n per ogni n ≥ n0, cioè sse c ≥ n + 5 /n per ogni n ≥ n0: assurdo! Una costante non può superare una quantità che cresce all’infinito, per ogni n ≥ n0 ! n2 + 5 ≠ O(n) Notazione asintotica Ω Notazione duale di O: f(n) = Ω (g(n)) se esistono costanti c > 0, n0 ≥0 tali che per ogni n ≥ n0 si ha f(n) ≥ c · g(n) ovvero hanno lo stesso ordine di infinito Θ limitazione esatta Θ è una limitazione esatta (tight bound) Esempio log 2 n = (log3 n) c, n0, t.c. c1 log3 n ≤ log2 n ≤ c2 log3 n per ogni n ≥n0 log2 n ≥ log3 n = c1 log3 n, per n≥1 log2 n = log2 3 log3 n = c2 log3 n, per n≥1 c1=1, c2= log2 3, n0 = 1 Notazione «o piccolo» Per indicare che f(n)=O(g(n)) ma f(n) ≠ Θ (g(n)) si scrive: f(n)=o(g(n)) (o «piccolo») Equivale a dire che: per ogni costante c > 0, esiste nc ≥0, tale che f(n)≤ c g(n) per ogni n ≥ nc. Esempio: n=o(n2) Per ogni valore di c, n ≤ c n2 non appena c n2 ≥ n, c n ≥ 1, n ≥ 1/c. Quindi fissato c basterà scegliere come nc un intero nc ≥ 1/c. Per c=2, sceglierò un intero n2 ≥ 1/2, n2 = 1. Per c=1/10, sceglierò un intero nc ≥ 10, nc = 10. etc. Notazione «o piccolo» (continua) Per indicare che f(n)=O(g(n)) ma f(n) ≠ Θ (g(n)) si scrive: f(n)=o(g(n)) (o «piccolo») Equivale a dire che: per ogni costante c > 0, esiste nc ≥0, tale che f(n)≤ c g(n) per ogni n ≥ nc. Esempio: 2n+1=o(n) ? Dimostro che: 2n+1=O(n). 2n+1 ≤ 2n+n=3n quindi 2n+1 ≤ c (n) é vera con c=3, n0=1. Ma 2n+1 ≤ c (n) non é vera per ogni valore di c: per c=1, 2, non esistono valori di n0 opportuni. Infatti 2n+1= Θ (n) Notazione «omega piccolo» Notazione duale di «o piccolo»: f(n) = ω (g(n)) f(n)=(g(n)) ma f(n) ≠ Θ (g(n)) ovvero per ogni costante c > 0, esiste nc ≥0, tale che f(n) ≥ c g(n) per ogni n ≥ nc. f(n) = ω (g(n)) se e solo se g(n) = o(f(n)) In termini di analisi …. matematica (ovvero f(n)=o(g(n)) ) (ovvero g(n)=o(f(n))) più precisamente: log n=o(radice(n)) Notation • Slight abuse of notation. T(n) = O(f(n)). – Asymmetric: • f(n) = 5n3; g(n) = 3n2 • f(n) = O(n3) = g(n) • but f(n) g(n). – Better notation: T(n) O(f(n)). Mettendo in evidenza che c’è una classe di funzioni O(f(n)). • Meaningless statement: “Any comparison-based sorting algorithm requires at least O(n log n) comparisons”. – Use for lower bounds. 36 Analisi asintotica di T(n) T(n) = O(g(n)) significa che il tempo di esecuzione, anche nel caso peggiore, è limitato superiormente da g(n) T(n) = Ω(g(n)) significa che il tempo di esecuzione, anche nel caso migliore, è limitato inferiormente da g(n) T(n) = Θ(g(n)) significa che nel caso peggiore è O(g(n)) e nel caso migliore è Ω(g(n)) (in pratica non vi è distinzione fra tempo di esecuzione nel caso peggiore e migliore) Esempio. TI(n), tempo di esecuzione di InsertionSort è TI(n)= Ω(n) e TI(n) =O(n2) TM(n ), tempo di esecuzione di MergeSort è TM (n)= Θ(n log n) Asymptotic Order of Growth • Upper bounds. T(n) is O(f(n)) if there exist constants c > 0 and n0 0 such that for all n n0 we have T(n) c · f(n). • Lower bounds. T(n) is (f(n)) if there exist constants c > 0 and n0 0 such that for all n n0 we have T(n) c · f(n). • Tight bounds. T(n) is (f(n)) if T(n) is both O(f(n)) and (f(n)). • Ex: T(n) = 32n2 + 17n + 32. – T(n) is O(n2), O(n3), (n2), (n), and (n2) . – T(n) is not O(n), (n3), (n), or (n3). 38 Esercizio 1 Esercizio 2 I calcoli riusciranno più semplici dopo che avremo studiato le proprietà delle notazioni asintotiche NOTA: Esistono anche funzioni (particolari) non confrontabili tramite O