Università degli studi di Messina – Facoltà di Ingegneria Corso di Laurea in Ingegneria Informatica e delle Telecomunicazioni Fondamenti di Informatica II Prof. D. Bruneo Complessità Computazionale La Nozione di Algoritmo Informalmente, un algoritmo è un procedimento formato da una sequenza finita di operazioni elementari che trasforma uno o più valori di ingresso (input) in uno o più valori di uscita (output) Dato un algoritmo A, denoteremo con fA la funzione che associa a ogni ingresso x di A la corrispondente uscita fA(x) Questa corrispondenza tra input e output rappresenta il problema risolto dall’algoritmo Fondamenti di Informatica II Prof. D. Bruneo 2 Definizione di Problema Formalmente, un problema è una funzione: f : DI → DS definita su un insieme DI di elementi che chiameremo istanze, a valori su un insieme DS di soluzioni Un problema verrà in generale descritto usando la seguente rappresentazione: Problema NOME Istanza: x ∈ DI Soluzione: Fondamenti di Informatica II f ( x) ∈ DS Prof. D. Bruneo 3 Algoritmi e Problemi Diremo che un algoritmo A risolve un problema f se f(x) = fA(x) per ogni istanza x L’esecuzione di un algoritmo su un dato input richiede il consumo di una certa quantità di risorse: tempo di computazione spazio di memoria usato numero di dispositivi di calcolo utilizzato È in generale importante saper valutare la quantità di risorse consumate perché un consumo eccessivo può pregiudicare le stesse possibilità di utilizzo di un algoritmo Noi faremo riferimento a modelli di calcolo formati da un solo processore trattando, quindi, unicamente la teoria degli algoritmi sequenziali Fondamenti di Informatica II Prof. D. Bruneo 4 Studio degli Algoritmi Possiamo raggruppare le problematiche riguardanti lo studio degli algoritmi in tre ambiti principali: Sintesi: dato un problema f, costruire un algoritmo A per risolvere f, cioè tale che f = fA Analisi : dato un algoritmo A ed un problema f, dimostrare che A risolve f, cioè che f = fA (correttezza) e valutare la quantità di risorse usate da A (complessità concreta) Classificazione: data una quantità T di risorse, individuare la classe di problemi risolubili da algoritmi che usano al più tale quantità Fondamenti di Informatica II Prof. D. Bruneo 5 Complessità di un Algoritmo Due misure ragionevoli per sistemi di calcolo sequenziali sono i valori: TA (x) tempo di calcolo S A (x) spazio di memoria Valori richiesti da un algoritmo A su input x Una soluzione che fornisce buone informazioni su TA e su SA consiste nell’introdurre il concetto di “dimensione” di un’istanza Fondamenti di Informatica II Prof. D. Bruneo 6 Tempo di Calcolo Dato un algoritmo A su un insieme di input I, può accadere che due istanze x, x'∈ I di eguale dimensione, cioè tali che: x = x' diano luogo a tempi di esecuzione diversi, ovvero: TA ( x ) ≠ T A ( x ' ) Come definire allora il tempo di calcolo di A in funzione di una sola dimensione? Fondamenti di Informatica II Prof. D. Bruneo 7 Tempo di Calcolo (cont.) Una possibile soluzione è quella di considerare il tempo peggiore su tutti gli input di dimensione n fissata. Una seconda è quella di considerare il tempo medio. Avremo quindi: Complessità “nel caso peggiore” In questo modo la complessità diventa una funzione T(n) definita sugli interi positivi, con tutti i vantaggi che la semplicità di questa notazione comporta Complessità “nel caso medio” Risulta significativa la cosiddetta “complessità asintotica”, cioè il comportamento della funzione T(n) per grandi valori di n Quale delle due complessità fornisce più informazione? Entrambe hanno vantaggi e svantaggi. Ad esempio la complessità “nel caso peggiore” fornisce spesso una valutazione troppo pessimistica; viceversa, la complessità “nel caso medio” assume una distribuzione uniforme sulle istanze, ipotesi discutibile in molte applicazioni Fondamenti di Informatica II Prof. D. Bruneo 8 Esempio – Ricerca Esaustiva int Ricerca_esaustiva (int a[], int key; int n){ int i; C1 for (i=1; a[i]!=key && i!=n; i++); C2 return (a[i]==key ? i :0); C3 } Il tempo di esecuzione si esprime come: T(n) = C1 + αC2 + C3 dove α = n se l’elemento non esiste i se l’elemento è in posizione i Come fissare α ? Assumendo una distribuzione uniforme, l’elemento si troverà mediamente in posizione 1 1 n 1 n (n +1) n +1 ∑n ∗i = n ∑i = n 2 = 2 i =1 i =1 n conviene, però, prescindere da distribuzione e ordinamento dei dati Fondamenti di Informatica II Prof. D. Bruneo 9 Complessità in Tempo – Ordini di Grandezza Il criterio principale solitamente usato per valutare il comportamento di un algoritmo è basato sull’analisi asintotica della sua complessità in tempo (nel caso peggiore o in quello medio). In particolare l’ordine di grandezza di tale quantità, al tendere di n a ∞ fornisce una valutazione della rapidità di incremento del tempo di calcolo al crescere delle dimensioni del problema Una differenza anche piccola nell’ordine di grandezza della complessità di due procedure può comportare enormi differenze nelle prestazioni di due algoritmi Fondamenti di Informatica II Prof. D. Bruneo 10 Tempi effettivi La seguente tabella fornisce un’idea più precisa del tempo effettivo corrispondente a funzioni di complessità tipiche. Si è supposto di poter eseguire un’operazione elementare in un microsecondo. Si sono confrontati i tempi di calcolo richiesti su istanze di varie dimensioni da sei algoritmi di complessità in tempo differente. Complessità n=10 n=20 n=50 n=100 n=103 n=104 n=105 n=106 n 10μs 20μs 50μs 0,1ms 1ms 10ms 0,1s 1s nlog2n 33,2μs 86,4μs 0,28ms 0,6ms 9,9ms 0,1s 1,6s 19,9s n2 0,1ms 0,4ms 2,5ms 10ms 1s 100s 2,7h 11,5g n3 1ms 8ms 125ms 1s 16,6mn 11,5g 31,7a ≈300c 2n 1ms 1s 35,7a ≈1014c ∞ ∞ ∞ ∞ 3n 59ms 58mn ≈108c ∞ ∞ ∞ ∞ ∞ μs = microsecondi a = anni c = secoli ms = millisecondi s = secondi mn = minuti h = ore ∞ = periodo superiore al millennio Fondamenti di Informatica II Prof. D. Bruneo 11 Considerazioni Dall’analisi della tabella precedente si possono trarre le seguenti considerazioni: Gli algoritmi dotati di una complessità in tempo lineare o di poco superiore (nlogn) sono utilizzabili in maniera efficiente anche per elevate dimensioni dell’input Gli algoritmi che hanno una complessità dell’ordine di nk (con k≥2) sono applicabili solo quando la dimensione dell’ingresso non è troppo elevata Gli algoritmi che hanno una complessità esponenziale (ad esempio 2n o 3n) presentano tempi di calcolo proibitivi anche per dimensioni di input limitate Fondamenti di Informatica II Prof. D. Bruneo 12 Considerazioni (cont.) Si potrebbe pensare che le valutazioni generali riportate precedentemente dipendano dall’attuale livello tecnologico e siano destinate ad essere superate con l’avvento di una tecnologia più sofisticata che permetta di produrre strumenti di calcolo sensibilmente più veloci In realtà: algoritmi lineari (n) o quasi lineari (nlogn) traggono pieno vantaggio dal passaggio alla tecnologia più potente algoritmi polinomiali (n2) traggono un vantaggio evidente ma smorzato algoritmi esponenziali (2n) non traggono nessun vantaggio Fondamenti di Informatica II Prof. D. Bruneo 13 Espressioni Asintotiche Il comportamento asintotico ci permette di valutare l’efficienza quando le dimensioni tendono all’infinito, considerando il caso peggiore tra quelli di pari dimensione. In certi casi si valuta il caso medio, ma è più complicato Analisi asintotica di un algoritmo Valutazione comportamento asintotico di una sequenza di interi {T(n)}. dove: ∀n ∈ N T (n) : quantità di una certa risorsa consumata su un input di dimensione n (nel caso peggiore o in quello medio) Fondamenti di Informatica II Prof. D. Bruneo 14 Relazioni tra sequenze numeriche Date due funzioni f,g definite su N a valori in R+ si possono definire le seguenti relazioni: 1) f(n) è “o grande” di g(n) f (n) = O( g (n)) 2) f(n) è “omega grande” di g(n) f (n) = Ω( g (n)) 3) f(n) e g(n) hanno lo stesso ordine di grandezza Fondamenti di Informatica II f (n) = Θ( g (n)) Prof. D. Bruneo 15 Relazioni tra sequenze numeriche (cont.) 1) f (n) = O( g (n)) Si dice che f(n) è “o grande” di g(n) se: ∃c > 0, n0 ∈ N : ∀n > n0 ⇒ f (n) ≤ c ∗ g (n) si dice anche che f(n) ha ordine di grandezza minore o uguale a quello di g(n) Esempi: 5n 2 + n = O ( n 2 ) Fondamenti di Informatica II 3n 4 = O(n 5 ) n log n = O(n 2 ) Prof. D. Bruneo 16 Relazioni tra sequenze numeriche (cont.) 2) f (n) = Ω( g (n)) Si dice che f(n) è “omega grande” di g(n) se: ∃c > 0, n0 ∈ N : ∀n > n0 ⇒ f (n) ≥ c ∗ g (n) si dice anche che f(n) ha ordine di grandezza maggiore o uguale a quello di g(n) Esempi: 10n 2 log n = Ω(n 2 ) Fondamenti di Informatica II n1 k = Ω(log n) per ogni intero k>0 1 k en = Ω( n) Prof. D. Bruneo 17 Relazioni tra sequenze numeriche (cont.) 3) f (n) = Θ( g ( n)) Si dice che f(n) e g(n) hanno lo stesso ordine di grandezza se: ∃c, d > 0, n0 ∈ N : ∀n > n0 ⇒ c ∗ g (n) ≤ f (n) ≤ d ∗ g (n) Esempi: 5n 2 + n = Θ(n 2 ) 100n log 2 n = Θ(n log 2 n) Fondamenti di Informatica II 2 1 log(1 + ) = Θ( ) n n Prof. D. Bruneo 18 Proprietà Dalle definizioni precedenti si deducono le seguenti proprietà: f (n) = O( g ( n)) ⇔ g (n) = Ω( f (n)) f (n) = Θ( g (n)) ⇔ f (n) = O ( g (n)), f (n) = Ω( g (n)) Fondamenti di Informatica II Prof. D. Bruneo 19 Regole Dalla definizione di “O grande” discende che: 1) I fattori costanti non interessano f (n) = O( g (n)) ⇒ c ∗ f (n) = O( g (n)), ∀c > 0 2) I termini di grado inferiore non interessano f (n) = ak n k + ak −1n k −1 + + a1n + a0 , ak > 0 ⇒ f (n) = O(n k ) 2) Vale la regola della somma f 1( n) = O( g 1( n)) ⇒ f 1 ( n) + f 2 ( n) = O(max[ g1 (n ), g 2 ( n)]) f 2 ( n) = O( g 2 ( n)) Le stesse regole valgono per Ω, Θ Fondamenti di Informatica II Prof. D. Bruneo 20 Dimostrazione Al fine di dimostrare la regola della somma si consideri: f 1 ( n) = O ( g 1( n)) f 2 ( n) = O ( g 2 ( n)) dalla definizione di “o grande” risulta: f1 ( n) ≤ a ∗ g 1( n) f 2 ( n) ≤ b ∗ g 2 (n ) quindi: f1 (n) + f 2 (n) ≤ ag1 (n) + bg 2 (n) ≤ (a + b) ∗ max[ g1 (n), g 2 (n)] da cui deriva: f1 (n) + f 2 (n) = O (max[ g1 (n), g 2 (n)]) Fondamenti di Informatica II Prof. D. Bruneo 21 Considerazioni Non è corretto considerare solo il caso migliore per valutare il comportamento asintotico di un algoritmo. Il fatto che un algoritmo nel caso migliore abbia una complessità lineare non basta per affermare che l’algoritmo appartenga a Θ(n) oppure a O(n). Per lo stesso motivo non è corretto neppure affermare che l'algorimto appartiene a Θ(n2) solo perché nel caso peggiore la complessità è quadratica. Viceversa, è corretto affermare che, nel caso migliore, la complessità dell'algoritmo è Θ(n), che nel caso medio e nel caso peggiore la complessità è Θ(n2) e, più in generale, che l'algoritmo è O(n2) ovvero è Ώ(n). Un altra importante considerazione fa riferimento ai casi in cui non sono verificate le condizioni che sono alla base dell’introduzione delle notazioni asintotiche. Infatti, proprio perché le notazioni introdotte sono asintotiche, vengono trascurati i termini di ordine inferiore e le costanti moltiplicative. Tuttavia, nel caso in cui è necessario confrontare algoritmi aventi tempi di esecuzione T(n) il cui andamento al limite è uguale (es. sono entrambe O(n2)), non è più possibile trascurare tali termini. In tal caso per stabilire quale algoritmo è più conveniente usare bisogna necessariamente tener conto, in primo luogo delle costanti moltiplicative e poi dei termini di ordine inferiore. Fondamenti di Informatica II Prof. D. Bruneo 22 Tempo di esecuzione: Operazioni semplici Le seguenti operazioni hanno un tempo di esecuzione dell’ordine di: T(n) = O(1) operazioni aritmetiche (+,*,…) operazioni logiche(&&, ||,….) confronti (<=, ==…) operazioni di accesso a strutture dati semplici (p.e.: ad elem. di array) operazioni di assegnazioni di valore (p.e.: a=b) senza chiamate di funzione operazioni di lettura e scrittura (p.e.: printf(“...”)) operazioni di controllo (p.e.: break,continue, return) Spiegazione intuitiva: sono operazioni che possono essere realizzate con poche istruzioni in linguaggio macchina Fondamenti di Informatica II Prof. D. Bruneo 23 Tempo di esecuzione: Blocchi di comandi semplici Un blocco composto da una serie di comandi semplici ha un tempo di esecuzione dell’ordine di: T(n) = O(1) Infatti, per la regola della somma, ogni somma di un numero costante di O(1) restituisce come risultato O(1) Fondamenti di Informatica II Prof. D. Bruneo 24 Tempo di esecuzione: ciclo for ciclo for La complessità di un ciclo for è data dal prodotto della complessità del corpo del for stesso per il numero di volte che esso viene eseguito. O(1) inizializza O(1) test k volte corpo end T(n) = O(k*f(n)) O(f(n)) incremento O(1) Trattandosi di ciclo non predeterminato, sarà necessario distinguere un caso migliore ed un caso peggiore. Dette kmin e kmax il numero minimo e massimo di volte che viene iterato un generico ciclo for si potranno ottenere i tempi di esecuzione Tmin e Tmax Il caso del ciclo while risulta essere analogo Fondamenti di Informatica II Prof. D. Bruneo 25 Tempo di esecuzione: costrutto if-then-else If-then-else O(1) test parte if O(f(n)) parte else La complessità di un istruzione del tipo if <condizione> then <istruzioni ramo then> else<istruzioni ramo else> è limitata superiormente dal ramo che ha la complessità maggiore. In realtà bisogna anche considerare il tempo impiegato a verificare la condizione, che in genere ha complessità costante O(1). O(g(n)) T(n) = O(max[f(n),g(n)]) Ragionamenti analoghi valgono nel caso di un costrutto di tipo case. Fondamenti di Informatica II Prof. D. Bruneo 26 Tempo di esecuzione: chiamata di funzioni La complessità di una chiamata di funzione è data dalla somma di due termini: il costo, in termini di complessità computazionale, dell’esecuzione della funzione stessa ed il costo della chiamata. Quest’ultimo è in genere trascurabile, ma non lo è se si effettuano chiamate per valore che hanno l’effetto di copiare sullo stack la struttura dati d la cui dimensione n è proprio quella da cui dipende la nostra funzione T(n) di interesse. Tuttavia, se la struttura dati è un vettore ed il linguaggio considerato è il C, poiché alla funzione viene passato di fatto il puntatore al primo elemento del vettore, il tempo di chiamata è indipendente da n. T(n) = O(ffunzione(n)+fchiamata(n)) T(n) = O(ffunzione(n)) Fondamenti di Informatica II Passaggio dell’intera struttura dati Passaggio del puntatore alla struttura dati Prof. D. Bruneo 27 Tempo di esecuzione: funzioni ricorsive La complessità di una funzione ricorsiva (cioè di una funzione che contiene al suo interno una chiamata a se stessa) non può essere calcolata con le tecniche precedenti. Infatti, data una generica funzione ricorsiva R, la complessità della chiamata di un’istanza ricorsiva di R, che compare nel corpo di R stessa, dovrebbe essere data dalla somma del costo di chiamata e del costo dell’esecuzione dell’istanza di R. Ma quest’ultimo costo è proprio quello che stiamo cercando di calcolare, ed è quindi incognito. Per risolvere questo problema è necessario esprimere il tempo incognito T(n) dell’esecuzione di R, come somma di due contributi: un tempo O(f(n)) che deriva dall’insieme di tutte le istruzioni che non contengono chiamate ricorsive, ed un tempo T(k) che deriva dalle chiamate ricorsive, invocate su di una dimensione del dato di ingresso più piccola, cioè con k < n. Otterremo quindi un’equazione, detta formula di ricorrenza, del tipo: T(n)=aT(n/b)+O(f(n)) Fondamenti di Informatica II Prof. D. Bruneo 28 Tempo di esecuzione: funzioni ricorsive (cont.) Ad esempio, nell’ambito del paradigma divide-et-impera, avremo ricorrenze del tipo: T(n)= O(1) per n≤c aT(n/b)+C(n)+D(n) per n>c derivanti dall’aver diviso un certo problema padre in a sottoproblemi figlio di dimensione n/b, avendo indicato con C(n) il costo derivante dalla combinazione dei risultati e con D(n) il costo relativo alla divisione del problema padre nei problemi figlio ed essendo costante (e quindi pari a O(1)) il tempo per la soluzione dei problemi nel caso banale, cioè quando n<c. Per risolvere una formula di ricorrenza, e quindi giungere a determinare la complessità asintotica di T(n), è possibile adottare dei particolari metodi di soluzione. Uno di questi (detto metodo iterativo) consiste semplicemente nell’iterare la ricorrenza proposta, finché non si riesce a trovare una generalizzazione. A questo punto occorre trovare il valore per il quale si chiude la ricorrenza, sostituirlo nella formula generale e calcolare il risultato applicando le regole per limitare le sommatorie. Fondamenti di Informatica II Prof. D. Bruneo 29 Esercizio 1 Calcolare la complessità in funzione di n≥0 della seguente funzione: int g (int n){ int a=n; if (n<=500) for (int i=1; i<=n; i++) for (int j=1; j<=n;j++) a+=n; else for (int i=1; i<=n; i++) a+=n; return a; } Soluzione: Istruzione ricorrente: a+=n; O(n2) per n ≤500 (istr. ricorrente in un doppio ciclo for ciascuno dei quali itera n volte) T(n)= O(n) per n >500 (istr. ricorrente in un ciclo for da 1 ad n. Complessità asintotica) Fondamenti di Informatica II Prof. D. Bruneo 30 Esercizio 2 Dato il seguente frammento di programma: i=n; while (i>=1) { for (int j=1; j<=n;j++) a++; i=E; } calcolare la complessità asintotica in funzione di n nei casi: a) E=i-1; b) E=i-n; Fondamenti di Informatica II c) E=i/2. Prof. D. Bruneo 31 Esercizio 2: soluzione Istruzione ricorrente: a++; Tale istruzione verrà eseguita almeno n volte nel for, resta da determinare la stima delle iterazioni nel ciclo esterno (while) in funzione di n che andranno a moltiplicare le iterazioni del ciclo interno (n) => T(n) = O(T(while)*n). Il while itera per i che va da n ad 1 variando nei tre casi il passo di decremento => 1≤i≤n. Calcoliamo dunque la complessità del while: a) i=E=i-1: il passo è lineare => il while itera n volte => T(n) = O(n*n) = O(n2); b) i=E=i-n: alla prima iterazione i=n, viene eseguito il for e dunque ad i viene assegnato i-n => i=0 che non soddisfa la condizione del while => una sola iterazione => T(n) = O(n*1) = O(n); Fondamenti di Informatica II Prof. D. Bruneo 32 Esercizio 2: soluzione (cont.) c) I=E=i/2: supponiamo sia k il numero di iterazioni del quale vogliamo stabilire una stima della complessità in funzione di n: inizialmente passo K passo K-1 passo K-2 … passo k-z passo j … passo 1 i=n; i=n/2; i=n/4; i=n/8; … i=n/2z+1; i=n/2k-j+1; … i=n/2k=1; Da cui possiamo stimare k: k = log2n Il che vuol dire che la complessità asintotica sarà: T(n) = O(n*log2n) Fondamenti di Informatica II Prof. D. Bruneo 33 Esercizio 3 a Date le seguenti dichiarazioni di funzione, calcolare la complessità in funzione di n>0 della chiamata P(F(n),y). int F(int n) { int b; int a=1; for (int i=1; i<=n; i++) for (int j=1; j<=n;j++) a++; b= a/n; return 2*b; } void P (int m, int &x) { for (int i=1; i<=m*m; i++) x+=3; } Fondamenti di Informatica II Prof. D. Bruneo 34 Esercizio 3 a: soluzione L’istruzione ricorrente di F si trova all’interno del doppio for, cioè: a++; Quella di P è invece localizzata all’interno del for: x+=3; La complessità di F risulta essere: TF(n) = O(n2) essendo l’istruzione ricorrente iterata in un doppio for con 1≤ i ≤ n e step unitario, quella di P: TP(m) = O(m2) in quanto il ciclo itera per i tra 1 ed m2 con incremento unitario. Il valore restituito dalla funzione F che diventa il limite del ciclo in P (il parametro m) facendo un semplice calcolo risulta essere uguale ad n, per cui nella stima della complessità possiamo sostituire ad m n; da cui la complessità totale si trova sommando le complessità delle due funzioni, essendo la loro esecuzione non sovrapposta ne iterata: T(n) = TF(n) + TP(n) = O(n2) + O(n2) = O(n2) Fondamenti di Informatica II Prof. D. Bruneo 35 Esercizio 3 b Come nell’esempio precedente ma con F definita come segue: int F(int n) { int b; int a=1; for (int i=1; i<=n; i++) for (int j=1; j<=n;j++) a++; b= a; return 2*b; } Soluzione : La complessità delle due funzioni rimane invariata rispetto al caso precedente, differisce invece il valore restituito dalla funzione F, che sarà n2: TF(n) = O(n2); TP(m) = O(m2) T(n) = TF(n) + TP(n) = O(n2) + O(n4) = O(n4) Fondamenti di Informatica II Prof. D. Bruneo 36 Esercizio 4 Calcolare la complessità in funzione di n>0 del seguente ciclo: for (int j=1; j<=f(n);j++) a+=n; int f (int n){ int a=0; for (int j=1; j<=n;j++) a+=n; return a; } Soluzione: numero di iterazioni = risultato[f(n)]: somma n volte n => n2 complessità di una iterazione: complessità della chiamata f(n): TF(n) = O(1) + O(n) + O(1) = O(n) complessità del for: numero iterazioni * complessita’ di una iterazione: Tfor(n)= O(n2 *n) = O(n3 ) Fondamenti di Informatica II Prof. D. Bruneo 37 Esercizio 5 Calcolare la complessità della funzione seguente (ricerca binaria) int binSearch (int A [], int n, int x) { int i=0; int j=n­1; while (i <= j) { int k=(i+j)/2; if (x == A[k]) return 1; if (x < A[k]) j= k­1; else i= k+1; } return 0; } Fondamenti di Informatica II Prof. D. Bruneo 38 Esercizio 5: soluzione La funzione binSearch implementa l’algoritmo di ricerca dicotomica o binaria su vettori ordinati. È basato sul principio divide et impera: scelto come elemento pivot quello con indice medio, si confronta l’elemento in tale posizione nel vettore col valore ricercato, se il confronto dà esito positivo si è ultimata la ricerca, altrimenti prosegue su una parte del vettore, per vettori ordinati in ordine crescente, quella a destra del pivot se l’elemento ricercato è maggiore di quest’ultimo, a sinistra nel caso opposto. Per calcolarne la complessità utilizziamo una variabile k che conta il numero di cicli effettuati: inizialmente i=0; passo K passo K-1 passo K-2 … passo K-z ... passo j … passo 1 i=1/2(n+1); i=3/4(n+1); i=7/8(n+1); … i=[(2z+1-1)/2z+1](n+1); i=[(2k-j+1-1)/2k-j+1](n+1); … i=[(2k-1)/2k](n+1)=n-1. Da cui possiamo stimare k: k = log2[(n + 1)/2] Il che vuol dire che la complessità asintotica sarà: Fondamenti di Informatica II O(log2n) Prof. D. Bruneo 39 Esercizio 6 Calcolare la complessità asintotica in funzione di n della seguente funzione ricorsiva che calcola il fattoriale di un numero int fattoriale(int n){ if (n==1) return 1; else return n*fattoriale(n-1); } Fondamenti di Informatica II Prof. D. Bruneo 40 Esercizio 6: soluzione La formula di ricorrenza è data in questo caso da: T(n)= O(1) per n=1 T(n-1)+O(1) per n>1 quindi: T n=T n−1O 1=T n−2O 1O 1=T n−3O 1O 1O 1 generalizzando: k T n=T n−k ∑ O 1 i=1 la ricorsione si chiude quando T(•) sarà pari ad 1 quindi per k=n-1, quindi n−1 n −1 n i=1 i=1 i=1 T n=T 1∑ O 1=O 1∑ O 1= ∑ O 1=O n Fondamenti di Informatica II Prof. D. Bruneo 41