Tempo di computazione (Running Time) di programmi Misure del tempo: metodi principali 1. Benchmarking 2. Analisi Tempo di computazione (Running Time) di programmi Misure del tempo: metodi principali 1. Benchmarking 2. Analisi Benchmarking: usato per confrontare programmi. Si cerca una collezione di input che sia rappresentativa dell’insieme dei possibili dati reali. Il giudizio di confronto viene espresso sugli input scelti. Tempo di computazione (Running Time) di programmi Misure del tempo: metodi principali 1. Benchmarking 2. Analisi Benchmarking: usato per confrontare programmi. Si cerca una collezione di input che sia rappresentativa dell’insieme dei possibili dati reali. Il giudizio di confronto viene espresso sugli input scelti. Es. • • • per algoritmi di sorting si può scegliere la collezione: prime 20 cifre p codici postali italiani numeri telefonici di Roma Tempo di computazione (Running Time) di programmi ANALISI: analizza il r.t. di un dato programma Si raggruppano input per dimensione (es. ordinamento: dimensione = numero elementi da ordinare, sistema di n equazioni in n incognite: dimensione = n) Tempo di computazione (Running Time) di programmi ANALISI: analizza il r.t. di un dato programma Si raggruppano input per dimensione (es. ordinamento: dimensione= numero elementi da ordinare, sisteme di n equazioni in n incognite: dimensione=n) Running time: funzione T(n), con n = (dimensione input), che rappresenta il numero di “unità di tempo” usate dall’algoritmo Tempo di computazione (Running Time) di programmi ANALISI: analizza il r.t. di un dato programma Si raggruppano input per dimensione (es. ordinamento: dimensione= numero elementi da ordinare, sisteme di n equazioni in n incognite: dimensione=n) Running time: funzione T(n), con n=dimensione input, che rappresenta il numero di “unità di tempo” usate dall’algoritmo Unità di tempo varia: es. numero di istruzioni semplici in linguaggio usato (C). Tempo effettivo dipende da vari paramentri: velocità del processore usato, compilatore,…. Tempo di computazione (Running Time) di programmi Worst case (caso peggiore): su diversi input di stessa dimensione n si possono avere r.t. differenti Tempo di computazione (Running Time) di programmi Worst case (caso peggiore): su diversi input di stessa dimensione n si possono avere r.t. differenti T(n)=worst case r.t. = max tempo su qualsiasi input di dimentsione n Tempo di computazione (Running Time) di programmi Worst case (caso peggiore): su diversi input di stessa dimensione n si possono avere r.t. differenti T(n)=worst case r.t. = max tempo su qualsiasi input di dimentsione n Es. cerca min A[0..n-1] (dimensione=n) 1. small=0; 2. for(j=1; j<n; j++) 3. if(A[j]<A[small]) 4. small=j; Tempo di computazione (Running Time) di programmi Worst case (caso peggiore): su diversi input di stessa dimensione n si possono avere r.t. differenti T(n)=worst case r.t. = max tempo su qualsiasi input di dimentsione n Es. cerca min A[0..n-1] (dimensione=n) 1. small=0; 2. for(j=1; j<n; j++) 3. if(A[j]<A[small]) 4. small=j; | | | | | Linea 1. 2. 3. 4. | | | | | Numero operazioni 1 1 + n + (n-1) =2n n-1 n-1 (worst case) TOTALE: 1+2n+2(n-1)=4n-1 T(n)=4n-1 Tempo di computazione (Running Time) di programmi Confronto di r.t. Dato un problema consideriamo 2 algoritmi A e B con r.t. T’(n) e T’’(n) T’(n)=100n T’’(n)=2n2 T’’(n) T’(n) n n<50, T’’(n) < T’(n) n>50, T’’(n) > T’(n) n=100, T’’(n) = 2 T’(n) n=1000, T’’(n) = 20 T’(n) Tempo di computazione (Running Time) di programmi T’(n)=100n T’’(n)=2n2 Unità di tempo= 1ms (millisec) 1000 operazioni/sec sec (1000ms) | max n per A | (100n=1000*sec) 1 10 100 1000 | | | | 10 100 1000 10000 | max n per B | | | | | | | | | | ( 2n2=1000*sec) 22 70 223 707 | Tempo di computazione (Running Time) di programmi T’(n)=100n T’’(n)=2n2 Unità di tempo= 1ms (millisec) 1000 operazioni/sec sec (1000ms) | max n per A | (100n=1000*sec) 1 10 100 1000 | | | | 10 100 1000 10000 | max n per B | | | | | | | | | | ( 2n2=1000*sec) 22 70 223 707 | Se calcolatori diventano 100 volte più veloci (unità di tempo =1/100 di ms 100.000 operazioni/sec) In 10 sec A passa da n=100 ad n=10000 (*100) B passa da n=70 ad n=707 (*10) Notazione O-grande e r.t. approssimato Dato un programma ed un input, r.t. dipende ancora da 1. Calcolatore usato (velocità di esecuzione istruzioni) 2. Compilatore (numero istruzioni macchina/istruzione C) Quindi non ha senso parlare di tempo in sec per analizzare un algoritmo. Notazione O-grande e r.t. approssimato Dato un programma ed un input r.t. dipende ancora da 1. Calcolatore usato (velocità di esecuzione istruzioni) 2. Compilatore (numero istruzioni macchina/istruzione C) Quindi non ha senso parlare di tempo in sec per analizzare un algoritmo. Per nascondere effetti di 1. e 2. si usa la notazione O-grande (big-Oh) che ignora le costanti Es. 4m-1=O(m) (ignorando la costante moltiplicativa 4 e quella additiva 1) Notazione O-grande e r.t. approssimato Un r.t. T(n) si assume essre definito solo per n>0 e che T(n)>0 per ogni n. Definizione Dati il r.t. T(n) ed una funzione f(n), definita per ogni intero n>0, T(n)=O(f(n)) Esistono n0>0 e c>0 tali che per ogni n>n0 risulta T(n)< c f(n) Notazione O-grande e r.t. approssimato Un r.t. T(n) si assume essre definito solo per n>0 e che T(n)>0 per ogni n. Definizione Dati il r.t. T(n) ed una funzione f(n), definita per ogni intero n>0, T(n)=O(f(n)) Esistono n0>0 e c>0 tali che per ogni n>n0 risulta T(n)<cf(n) Es. Dato T(0)=0 e T(n)=(n+1)*(n+2), n>0 mostriamo che T(n)= O(n2). (cioè f(n)=n2) Notazione O-grande e r.t. approssimato Un r.t. T(n) si assume essre definito solo per n>0 e che T(n)>0 per ogni n. Definizione Dati il r.t. T(n) ed una funzione f(n), definita per ogni intero n>0, T(n)=O(f(n)) Esistono n0>0 e c>0 tali che per ogni n>n0 risulta T(n)<cf(n) Es. Dato T(0)=0 e T(n)=(n+1)*(n+2), n>0 mostriamo che T(n)= O(n2). (cioè f(n)=n2) Prendiamo n0=1, c=6: T(n) =(n+1)(n+2)=n2+3n+2 <n2+3n2+2n2 (per n>1, n0=1<n<n2) =6n2=c n2= c f(n) Notazione O-grande e r.t. approssimato Costanti non hanno valore T(n)=O(d T(n)), per ogni costante d Infatti: siano n0=0, c=1/d. Si ha T(n)=(1/d) d T(n)= c (d T(n)) Notazione O-grande e r.t. approssimato Low-order terms non hanno valore Dato il polinomio T(n)=aknk+ak-1nk-1+…+a1n+a0, con ak>0 risulta T(n)=O(nk) Notazione O-grande e r.t. approssimato Low-order terms non hanno valore Dato il polinomio T(n)=aknk+ak-1nk-1+…+a1n+a0, con ak>0 risulta T(n)=O(nk) Siano n0 1, c k a i 0 , ai 0 i (nota ai c per ogni 0 i k ) Notazione O-grande e r.t. approssimato Low-order terms non hanno valore Dato il polinomio T(n)=aknk+ak-1nk-1+…+a1n+a0, con ak>0 risulta T(n)=O(nk) Siano n0 1, k a c i 0 , ai 0 i k Si ha (nota ai c per ogni 0 i k ) T (n) ai n i i 0 k k a n i k i a n i i 0 , ai 0 (essendo 1 n) i 0 , ai 0 nk k k k a n c cn . i i 0 , ai 0 Notazione O-grande e r.t. approssimato Low-order terms non hanno valore Dato il polinomio T(n)=aknk+ak-1nk-1+…+a1n+a0, con ak>0 risulta T(n)=O(nk) Es. T(n) 10 n 5 3n 3 - 2n 2 1 n0 1, c k a i 0 , ai 0 i 10 3 1 14 T(n) 10 n 5 3n 3 - 2n 2 1 10 n 5 3n 3 1 10 n 5 3n 5 n 5 14n 5 cn 5 Notazione O-grande e r.t. approssimato La funzione g(n) cresce più rapidament e di h(n) se h ( n) lim 0 n g ( n) Tasso di crescita Ha valore solo il termine che cresce più rapidamente. Se g(n) cresce più rap. di h(n) g(n)+h(n)=O(g(n)) Notazione O-grande e r.t. approssimato La funzione g(n) cresce più rapidament e di h(n) se h( n) lim 0 n g ( n ) Tasso di crescita Ha valore solo il termine che cresce più rapidamente. Se g(n) cresce più rap. di h(n) g(n)+h(n)=O(g(n)) Es. T(n) = 2n+n3 = O(2n), infatti 3 n lim n 0 n 2 Notazione O-grande e r.t. approssimato La funzione g(n) cresce più rapidament e di h(n) se h( n) lim 0 n g ( n ) Tasso di crescita Ha valore solo il termine che cresce più rapidamente. Se g(n) cresce più rap. di h(n) g(n)+h(n)=O(g(n)) Es. T(n)=2n+n3=O(2n), infatti n3 lim n 0 n 2 Verificarlo in modo diretto esibendo le costanti n0 e c Notazione O-grande e r.t. approssimato Transitività Se f(n)=O(g(n)) e g(n)=O(h(n)) allora f(n)=O(h(n)) Notazione O-grande e r.t. approssimato Transitività Se f(n)=O(g(n)) e g(n)=O(h(n)) allora f(n)=O(h(n)) f(n)=O(g(n)) Esistono c’, n’ tali che f(n) < c’ g(n) per ogni n>n’ g(n)=O(h(n)) Esistono c’’, n’’ tali che g(n) < c’’ h(n) per ogni n>n’’ Notazione O-grande e r.t. approssimato Transitività Se f(n)=O(g(n)) e g(n)=O(h(n)) allora f(n)=O(h(n)) f(n)=O(g(n)) Esistono c’, n’ tali che f(n) < c’ g(n) per ogni n>n’ g(n)=O(h(n)) Esistono c’’, n’’ tali che g(n) < c’’ h(n) per ogni n>n’’ Quindi, prendiamo n0=max { n’,n’’ } e c=c’c’’ Per n>n0 f(n) < c’ g(n) < c’ (c’’ h(n)) = c h(n) Notazione O-grande e r.t. approssimato Si vuole come O-grande la funzione con il minimo tasso di crescita!!! Es. f(n)=12n +3, si ha f(n)=O(n) risulta anche f(n)=O(n2), f(n)=O(n3), f(n)=O(2n), …. ma non è quello che vogliamo. Notazione O-grande e r.t. approssimato Esercizio.Mostrare che g(n)+f(n)=O(max{f(n),g(n)}) Esercizio.Mostrare che se T(n)=O(f(n)) e S(n)=O(g(n)) allora T(n)S(n)=O(f(n)g(n)) Running Time di programmi Trova f(n) tale che T(n)=O(f(n)) Running Time di programmi Trova f(n) tale che T(n)=O(f(n)) Istruzioni semplici (assegnamento, confronto,…) tempo costante O(1) Running Time di programmi Trova f(n) tale che T(n)=O(f(n)) Istruzioni semplici (assegnamento, confronto,…) tempo costante O(1) Cicli for: for (i=1,i<=n,i++) I 1. se I=operazione semplice risulta O(n) 2. Se I ha r.t. O(f(n)) risulta O(nf(n)) es. for(i=1,i<=n,i++) A[i]=1 T(n)=O(n) for(i=1,i<=n,i++) for(j=1,j<=n,i++) A[i]=A[i]+A[j] T(n)=O(n*n) =O(n2) Running Time di programmi If (C) I else I’: (normalmente C è O(1)) 1. se I,I’ sono istruzioni semplici O(1) 2. se I ha r.t. O(f(n)) e I’ ha r.t. O(g(n)) O(max (f(n), g(n)) Running Time di programmi If (C) I else I’: (normalmente C è O(1)) 1. se I,I’ sono istruzioni semplici O(1) 2. se I ha r.t. O(f(n)) e I’ ha r.t. O(g(n)) O(max (f(n), g(n)) es. if (A[0]=0) for(i=1,i<=n,i++) A[i]=1; else for(i=1,i<=n,i++) for(j=1,j<=n,i++) A[i]=A[i]+A[j] T(n)=O(max (n, n2)) =O(n2) Running Time di programmi Cicli while e do while: simili al ciclo for (non conosciamo esplicitamente il numero di iterazioni) es. Dato un array A di n elementi i=0; while (x<>A[i] && i<n) i=i+1; (caso peggiore: n iterazioni) T(n)=nO(1)=O(n) Running Time di programmi Sequenze di istruzioni: si devono sommare i tempi delle singole istruzioni. Si usa la regola della somma. Date {I1; I2; . . . Im;} con O(f1) O(f2) . . . O(fm) Risulta O(f1(n)) + O(f2(n))+…+ O(fm(n))= O(fi(n)) fj(n)=O(fi(n)) per ogni j diverso da i. Running Time di programmi Chiamate a funzioni: si deve sommare il tempo della funzione chiamata. (se A chiama B: si calcola il r.t. di B e si somma al r.t. delle altre istruzioni di A) Running Time di programmi Chiamate a funzioni: si deve sommare il tempo della funzione chiamata. (se A chiama B: si calcola il r.t. di B e si somma al r.t. delle altre istruzioni di A) Chiamate ricorsive: determiniamo T(n) in modo induttivo 1. Tempo di una chiamata che non usa ricorsione = t (=O(1)) 2. Si esprime T(n) in termini del tempo T(n’) della chiamata ricorsiva Running Time di programmi Chiamate ricorsive: determiniamo T(n) in modo induttivo 1. Tempo di una chiamata che non usa ricorsione=t (=O(1)) 2. Si esprime T(n) in termini del tempo T(n’) della chiamata ricorsiva Running Time di programmi Chiamate ricorsive: determiniamo T(n) in modo induttivo 1. Tempo di una chiamata che non usa ricorsione=t (=O(1)) 2. Si esprime T(n) in termini del tempo T(n’) della chiamata ricorsiva Es. int fact(int n) { if (n<=1) return 1; else return n*fact(n-1)} T(1)=t T(n)=T(n-1)+c Running Time di programmi Es. int fact(int n) { if (n<=1) return 1; else return n*fact(n-1)} T(1)=t T(n)=c+ T(n-1) Vogliamo il valore di T(n) (non dipendente da T(n’)) Abbiamo T(n)=c+ T(n-1) =c+ c+ T(n-2)= 2c +T(n-2) Running Time di programmi Es. int fact(int n) { if (n<=1) return 1; else return n*fact(n-1)} T(1)=t T(n)=c+ T(n-1) Abbiamo T(n)=c+T(n-1) =c+ c+ T(n-2)= 2c +T(n-2) =2c +c +T(n-3)=3c +T(n-3) Running Time di programmi Es. int fact(int n) { if (n<=1) return 1; else return n*fact(n-1)} T(1)=t T(n)=c+ T(n-1) Abbiamo T(n)=c+T(n-1) =c+ c+ T(n-2)= 2c +T(n-2) =2c +c +T(n-3)=3c +T(n-3) … =ic +T(n-i) Running Time di programmi Es. int fact(int n) { if (n<=1) return 1; else return n*fact(n-1)} T(1)=t T(n)=c+ T(n-1) Abbiamo T(n)=c+T(n-1) =c+ c+ T(n-2)= 2c +T(n-2) =2c +c +T(n-3)=3c +T(n-3) … =ic +T(n-i) (per i=n-1) =(n-1)c+T(1) =(n-1)c+t= O(n) Running Time di programmi Esercizio. Dimostrare per induzione su n che la relazione di ricorrenza T(1)=t T(n)=c+ T(n-1) ha come soluzione T(n)=(n-1)c + t Running Time di programmi Esercizio. Dimostrare per induzione su n che la relazione di ricorrenza T(1)=t T(n)=c+ T(n-1) ha come soluzione T(n)=(n-1)c + t Base n=1. T(1)=t=(1-1)c+t. OK. Running Time di programmi Esercizio. Dimostrare per induzione su n che la relazione di ricorrenza T(1)=t T(n)=c+ T(n-1) ha come soluzione T(n)=(n-1)c + t Base n=1. T(1)=t=(1-1)c+t. OK. Passo. Sia n> 1. Assumiamo T(n)=(n-1)c + t. Consideriamo T(n+1) Running Time di programmi Esercizio. Dimostrare per induzione su n che la relazione di ricorrenza T(1)=t T(n)=c+ T(n-1) ha come soluzione T(n)=(n-1)c + t Base n=1. T(1)=t=(1-1)c+t. OK. Passo. Sia n> 1. Assumiamo T(n)=(n-1)c + t. Consideriamo T(n+1) T(n+1)=c + T(n) (per definizione) =c + (n-1)c + t (per i.i.) = nc +t Running Time di programmi Esercizio. Considerare la relazione di ricorrenza T(0)=T(1)= 1 T(n)=2 T(n-2) 1. Determinare T(2), T(3), T(4), T(5): 2. Determinare T(n) in termini di T(n-4): 3. Determinare T(n) in termini di T(n-6): 4. Determinare T(n) in termini di T(n-2i): 5. Determinare T(n): Running Time di programmi Esercizio. Considerare la relazione di ricorrenza T(0)=T(1)= 1 T(n)=2 T(n-2) 1. Determinare T(2), T(3), T(4), T(5): T(2)=2, T(3)=2, T(4)=4, T(5)=4 1. Determinare T(n) in termini di T(n-4): 2. Determinare T(n) in termini di T(n-6): 3. Determinare T(n) in termini di T(n-2i): 4. Determinare T(n): Running Time di programmi Esercizio. Considerare la relazione di ricorrenza T(0)=T(1)= 1 T(n)=2 T(n-2) 1. Determinare T(2), T(3), T(4), T(5): T(2)=2, T(3)=2, T(4)=4, T(5)=4 1. Determinare T(n) in termini di T(n-4): T(n)=2T(n-2)=4 T(n-4) 1. Determinare T(n) in termini di T(n-6): 2. Determinare T(n) in termini di T(n-2i): 3. Determinare T(n): Running Time di programmi Esercizio. Considerare la relazione di ricorrenza T(0)=T(1)= 1 T(n)=2 T(n-2) 1. Determinare T(2), T(3), T(4), T(5): T(2)=2, T(3)=2, T(4)=4, T(5)=4 1. Determinare T(n) in termini di T(n-4): T(n)=4 T(n-4) 2. Determinare T(n) in termini di T(n-6): T(n)=4 T(n-4)= 8 T(n-6) 1. Determinare T(n) in termini di T(n-2i): 2. Determinare T(n): Running Time di programmi Esercizio. Considerare la relazione di ricorrenza T(0)=T(1)= 1 T(n)=2 T(n-2) 1. Determinare T(2), T(3), T(4), T(5): T(2)=2, T(3)=2, T(4)=4, T(5)=4 1. Determinare T(n) in termini di T(n-4): T(n)=4 T(n-4) 2. Determinare T(n) in termini di T(n-6): T(n)=8 T(n-6) 3. Determinare T(n) in termini di T(n-2i): T(n)=2i T(n-2i) 4. Determinare T(n): Running Time di programmi Esercizio. Considerare la relazione di ricorrenza T(0)=T(1)= 1 T(n)=2 T(n-2) 1. Determinare T(2), T(3), T(4), T(5): T(2)=2, T(3)=2, T(4)=4, T(5)=4 1. Determinare T(n) in termini di T(n-4): T(n)=4 T(n-4) 2. Determinare T(n) in termini di T(n-6): T(n)=8 T(n-6) 3. 4. se se Determinare T(n) in termini di T(n-2i): T(n)=2i T(n-2i) Determinare T(n): n pari, i=n/2, T(n-2i)=T(0) T(n)=2n/2T(0)=2n/2 n disp., i=(n-1)/2, T(n-2i)=T(1) T(n)=2(n-1)/2T(1) =2(n-1)/2 Soluzioni Relazioni di ricorrenza 1. T(1)=a T(n)= b+T(n-1), n>1 T(n)=(n-1)b+a=O(n) Soluzioni Relazioni di ricorrenza 1. T(1)=a T(n)= b+T(n-1), n>1 2. T(k)=a T(n)=T(n-1)+g(n) T(n)=O(n) T(n)=a + g(k+1)+…+g(n) T(n) = g(n)+T(n-1) = g(n)+g(n-1)+T(n-2)=… Soluzioni Relazioni di ricorrenza 1. T(1)=a T(n)= b+T(n-1), n>1 2. T(k)=a T(n)=T(n-1)+g(n) T(n)=O(n) T(n)=a + g(k+1)+…+g(n) T(n) = g(n)+T(n-1) = g(n)+g(n-1)+T(n-2)=… … = g(n)+g(n-1)+…+g(k+1)+T(k) Soluzioni Relazioni di ricorrenza 1. T(1)=a T(n)= b+T(n-1), n>1 2. T(k)=a T(n)=T(n-1)+g(n) T(n)=(n-1)b+a T(n)=a + g(k+1)+…+g(n) T(n) = g(n)+T(n-1) = g(n)+g(n-1)+T(n-2)=… … = g(n)+g(n-1)+…+g(k+1)+T(k) 3. T(1)=1 T(n)=T(n-1)+n (g(i)=i) T(n)=1 + 2+…+n=n(n+1)/2 Soluzioni Relazioni di ricorrenza 4. T(1)=a T(n)=2T(n/2)+g(n) T ( n) log2 n n ) an 2 g ( 2j j 0 j Soluzioni Relazioni di ricorrenza 4. T(1)=a T(n)=2T(n/2)+g(n) T ( n) log2 n 1 n ) an 2 g ( 2j j j 0 T (n) g (n) 2T (n / 2) g (n) 2 g (n / 2) 4T (n / 4) ... i 1 i 1 g (n) 2 g (n / 2) ... 2 T (n / 2 ) 2 T (n / 2 ) i i 2 g( i j 0 log2 n 1 n i 1 2i ) 2 T (n / 2 ) [Per i log n-1, 2 j n ) an 2 g ( 2j j 0 i 1 i i 1 n] Soluzioni Relazioni di ricorrenza 4. T(1)=a T(n)=2T(n/2)+g T ( n) log2 n 1 j 2 g an j 0 g log2 n 1 2 j an j 0 g 2log2 n an gn an (a g )n Soluzioni Relazioni di ricorrenza 4. T(1)=a T(n)=2T(n/2)+n T ( n) log2 n 1 2 (n / 2 ) an j j 0 log2 n 1 n an j 0 n(log 2 n) an O(n(log 2 n)) j