Homework 2 Mennillo Valerio M63001277 Trapani Alessia M63001278 October 19, 2021 1 Homeworks esercitativi 1.1 Esercizio 2.1. Ricorrenze √ T (n) = T ( n) + Θ(log log n) Come consigliato, si effettua un cambio di variabili m = log n da cui discende n = 2m . Si riscrive quindi la ricorrenza come T (m) = T (2m/2 ) + Θ(log m). Si passa ad una nuova ricorrenza definita come S(m) = S(m/2) + Θ(log m) e si utilizza il metodo dell’albero di ricorsione. Si nota subito come a=1 e quindi il numero di figli è 1 mentre la dimensione del sottoproblema si dimezza ogni volta. Si nota, inoltre, che l’altezza dell’albero di ricorsione è data dall’equazione log(m/2i ) = 1 da cui si ricava i = log m/2. - log m X2 i=0 m m m log 2 log 2 log 2 X X X 1 m m c m m c log i = c(log m−i) = c log m− ci = c(log +1) log m−c log (log + 1)) = ((log m)2 +log m) 2 2 2 2 2 2 i=0 i=0 i=0 Scegliendo appositamente le costanti, si dimostra come 2c ((log m)2 + log m) sia limitato superiormente e inferiormente da funzioni del tipo d(log m)2 permettendoci di concludere che S(m)=Θ((log m)2 ) da cui, ripercorrendo in inverso la sostituzione, T(n)=Θ((log (log n))2 ). - T(n) = 10T(n/3) + 17n1.2 Si applica il primo caso del metodo dell’esperto. Si individuano a=10, b=3 e f (n) = 17n1.2 . Si determina quindi nlogb a− =nlog3 10− =n2.09− . Scegliendo ad esempio = 0.09, si nota che f (n) = O(n2 ) e ne si deduce che T (n) = Θ(n2.09 ). 1.2 Esercizio 2.2. Ordinare da 0 a n3 − 1 in O(n) è possibile utilizzando Radix Sort con particolare algoritmo di ordinamento Counting Sort. Per rappresentare un numero compreso tra 0 e n3 − 1 necessitiamo di log n3 bit. Utilizzando le proprietà del logaritmo, si arriva a definire il numero di bit b=3 log2 n. Dalla teoria sappiamo che affinché la complessità sia lineare, basta scegliere r≈log2 n, in particolare si sceglie r=log2 n. L’equazione che si costruisce è quindi: 3 log2 n b (n + 2blog2 nc ) ≤ 3(n + n) = 6n = O(n) ( )(n + 2r ) = r log2 n 2 2.1 Homeworks di verifica Homework 6.1. Costruire un heap mediante inserimento a) Le procedure BUILD-MAX-HEAP e BUILD-MAX-HEAP v2 creano sempre lo stesso heap se vengono eseguite con lo stesso array di input. Nella prima, ci si assicura della proprietà di MaxHeap applicando MaxHeapify ”dal basso verso l’alto” solo ai nodi non foglia. Nella seconda, invece, si ricrea ogni volta l’heap e la proprietà di MaxHeap è assicurata dall’inserimento di MAX-HEAP-INSERT. MAX-HEAP-INSERT ci permette di: [...] 1 b) BUILD-MAX-HEAP v2 richiama n-1 volte la funzione MAX-HEAP-INSERT. MAX-HEAP-INSERT, a sua volta, richiama HEAP-INCREASE-KEY che, a sua volta, contiene l’unico ciclo di interesse: w h i l e ( i >1 and A[ Parent ( i )] <A[ i ] ) : exchange A[ i ] <−> A[ Parent ( i ) ] i <− Parent ( i ) Immaginando una rappresentazione ad albero, il caso peggiore è quando i valori più alti sono nei nodi foglia. I nodi foglia sono nell’estremità ”destra” dell’array nel caso peggiore. Si è costretti quindi a ”risalire” tutta la struttura, visto che A[Parent(i)] risulta sempre minore di A[i]. Bisogna scambiarli per assicurare la proprietà MaxHeap. Il numero di scambi è log2 n. Nel caso peggiore, questo ragionamento viene ripetuto per ogni elemento. Si parla quindi di complessità Θ(n log n) 2.2 a) Homework 6.2. Sorting almost sorted list (MIT 2) L’array con più inversioni è quello che presenta gli elementi in ordine decrescente: [n, n − 1, n − 2, . . . , 1] Calcoliamo il numero di inversioni partendo dal primo elemento (n) e andando avanti: − n avrà n − 1 inversioni; − n − 1 avrà n − 2 = (n − 1 − 1) inversioni; −... − 2 avrà 1 inversione; − 1 avrà 0 inversioni. Possiamo quindi scrivere una sommatoria per ottenere il numero massimo di inversioni: n X i=1 i−1= n X i=1 i− n X 1= i=1 n(n − 1) n(n + 1) −n= 2 2 b) INSERTION-SORT(A) viene eseguito nel tempo O(n + I) dove I è il numero di inversioni in A Si nota che il ciclo interno dell’Insertion Sort, ogni volta che A[i]>A[j] con i<j, scambia i valori corrispondenti alle posizioni (i,j) e la coppia risulta proprio essere un’inversione. Una iterazione del loop interno risolve una inversione. Sapendo che al termine il numero di inversioni è zero, il loop interno è O(I). Il loop esterno invece è O(n) da cui si conclude O(n+I). INSERTION-SORT(A) viene eseguito nel tempo O(nk) Sappiamo che potenzialmente la distanza tra un generico A[i] e la sua posizione esatta A[j] è alpiù k. Quindi j ∈ [i − k, i − k + 1, ..., i, ..., i + k − 1, i + k]. Nel caso peggiore, ci sono alpiù 4k elementi che possono generare inversione di A[i] che, considerate per gli n elementi, genera 4kn inversioni. Sostituendo I, si può concludere che O(n+I)=O(n+4nk)=O(nk). c) 2