La presentazione è in caricamento. Aspetta per favore

La presentazione è in caricamento. Aspetta per favore

Per valutare la complessità ammortizzata scomponiamo ogni Union: nelle due FindSet e nella Link che la costituiscono e valuteremo la complessità in funzione.

Presentazioni simili


Presentazione sul tema: "Per valutare la complessità ammortizzata scomponiamo ogni Union: nelle due FindSet e nella Link che la costituiscono e valuteremo la complessità in funzione."— Transcript della presentazione:

1 Per valutare la complessità ammortizzata scomponiamo ogni Union: nelle due FindSet e nella Link che la costituiscono e valuteremo la complessità in funzione del numero m di operazioni MakeSet, FindSet e Link così ottenute. Union(x, y) x = FindSet(x) y = FindSet(y) Link(x, y)

2 Se m' è il numero di operazioni MakeSet, FindSet e Union della sequenza originale allora m' m 3m' Quindi possiamo calcolare la complessità asintotica in funzione di m invece che di m'. Useremo il metodo del potenziale. Per definire la funzione potenziale ci servono alcune premesse.

3 MakeSet(x) x.p = x x.rank = 0 FindSet(x) if x.p x x.p = FindSet(x.p) return x.p Link(x, y) if x.rank > y.rank y.p = x else x.p = y if x.rank == y.rank y.rank = y.rank + 1

4 Proprietà dei ranghi Per ogni nodo x a) x viene creato come radice con x.rank = 0 b) x.rank aumenta soltanto finché x resta radice, dopo di che rimane invariato. c) Se x non è radice x.rank < x.p.rank d) x.p.rank può solo aumentare. e) dopo aver eseguito n operazioni x.rank < n

5 Le due funzioni level(x) e iter(x) Valgono le seguenti diseguaglianze Per ogni nodo x non radice definiamo due funzioni che misurano la differenza di rango tra x e x.p.

6 Dimostrazione:

7 Ad ogni nodo x attribuiamo un potenziale (o credito) (x) soddisfa le diseguaglianze Nel primo caso

8 Nel secondo caso

9 Definiamo un potenziale globale come somma dei potenziali di tutti i nodi Valutiamo la differenza di potenziale dovuta alla i- esima operazione:

10 Se la i-esima operazione è una MakeSet(x) il potenziale del nodo x è 0 mentre il potenziale degli altri nodi rimane invariato. Quindi

11 Dimostriamo che se x non è radice il potenziale di x non può aumentare, ossia Ed inoltre che se x.rank 1 e la i-esima operazione modifica o level(x) o iter(x) il potenziale diminuisce Supponiamo quindi che la i-esima operazione sia una Link o FindSet.

12 Dimostrazione: Se x non è radice x.rank non cambia. Inoltre Link e FindSet non cambiano n e quindi anche (n) non cambia. Se x.rank = 0 Supponiamo x.rank 1. Se level(x) e iter(x) non cambiano Se level(x) non cambia ma cambia iter(x) allora iter(x) può solo crescere e quindi

13 Se level(x) cambia, iter(x) può anche diminuire ma, per i limiti visti, un aumento di level(x) diminuisce (x) di almeno x.rank mentre una diminuzione di iter(x) aumenta (x) al più di x.rank-1. Anche in questo caso

14 Calcoliamo il costo ammortizzato delle tre operazioni MakeSet(x) x.p = x x.rank = 0 FindSet(x) if x.p x x.p = FindSet(x.p) return x.p Link(x, y) if x.rank > y.rank y.p = x else x.p = y if x.rank == y.rank y.rank = y.rank + 1

15 Costo ammortizzato di MakeSet(x)

16 Costo ammortizzato di Link(x,y) Il potenziale (x) dipende soltanto da x.rank e x.p.rank. Quindi gli unici elementi il cui potenziale può cambiare sono x, y e i figli di y. I figli di y non sono radici e il loro potenziale non può aumentare.

17 x è radice e diventa figlio di y ma il suo rango non cambia. Altrimenti Se x.rank = 0

18 y rimane radice e y.rank o rimane invariato o aumenta di 1. Quindi Dunque ed il costo ammortizzato di Link è

19 Costo ammortizzato di FindSet(x) Il costo reale è proporzionale al numero s di nodi del cammino percorso. Il potenziale della radice non cambia mentre i potenziali degli altri nodi possono solo diminuire. Consideriamo dapprima come cambia il potenziale dei nodi x del cammino che hanno x.rank > 0 e che sono seguiti da almeno un nodo y diverso dalla radice e tale che level(y) = level(x).

20 Sia k = level(y) = level(x). Allora dopo la compressione Dunque iter(x) aumenta di almeno 1 e quindi

21 I nodi rimanenti sono la radice, il primo nodo se ha rango 0 e per ogni livello k lultimo nodo del cammino avente level(x) = k. Siccome i livelli distinti sono al più (n) ci sono al più (n)+2 nodi il cui potenziale può rimanere invariato mentre il potenziale degli altri s- (n)-2 diminuisce di almeno 1. Quindi ed il costo ammortizzato di FindSet è

22 Esercizio 31. (Problema 22-3 del libro.) In un albero T il minimo antenato comune di due nodi u e v è il nodo w a profondità massima che è antenato sia di u che di v. u v w

23 Nel problema dei minimi comuni antenati off-line sono dati un albero T con n nodi ed una lista L = (u 1,v 1 ),...,(u m,v m ) di m coppie di nodi Si chiede di calcolare la lista W = w 1,...,w m dei minimi comuni antenati di ogni coppia.

24 Lalgoritmo di Tarjan risolve il problema in tempo lineare O(n+m) con una sola percorrenza dellalbero. I nodi dellalbero hanno i seguenti campi: - child : punta al primo figlio - sibling : punta al fratello - ancestor : punta ad un antenato - color : white allinizio e poi diventa black. oltre ai campi p e rank per insiemi disgiunti.

25 MinComAnt(u) MakeSet(u) u.ancestor = u v = u.child while v nil // percorre la lista dei figli MinComAnt(v) Union(u,v) FindSet(u).ancestor = u v = v.sibling u.color = black for ogni v tale che (u,v) (u i,v i ) L if v.color == black w i = FindSet(v).ancestor Lalgoritmo di Tarjan:

26 x0x0 x1x1 x2x2...... r0r0 r1r1 r k-1 S0S0 S1S1 S2S2 S k-1 x k-1 r2r2 r i = rappresentante MinComAnt(u) x 0 = root, x k = u xkxk

27 Esercizio 30. (Problema 22-1 del libro) Sia dato linsieme T = {1, 2,..., n} ed una sequenza S = {o 1, o 2,..., o n+m } di n+m operazioni delle quali n sono Insert che inseriscono gli elementi di T una e una sola volta ed m sono ExtractMin che estraggono il minimo tra gli elementi inseriti e non ancora estratti. Supponiamo che ogni ExtractMin della sequenza sia preceduta da più Insert che ExtractMin.

28 Una possibile sequenza con n = 9 ed m = 6 è: In cui le Insert sono indicate con i valori 1, 2,..., n inseriti mentre le ExtractMin sono indicate con E j per j = 1,…, m. S = { 4, 8, E 1, 3, E 2, 9, 2, 6, E 3, E 4, E 5, 1, 7, E 6, 5 }

29 Si chiede un algoritmo efficiente che data la sequenza S di operazioni calcoli la sequenza X = {x 1, x 2,..., x m } degli m elementi estratti. Il risultato dovrebbe essere Ad esempio, con X = {4, 3, 2, 6, 8, 1} S = { 4, 8, E 1, 3, E 2, 9, 2, 6, E 3, E 4, E 5, 1, 7, E 6, 5 }

30 Soluzione. Per ogni valore i = 1,…,n calcoliamo lindice j delloperazione ExtractMin che lo estrae e poniamo X j = i. Se i non viene estratto poniamo j = m+1 e non memorizziamo i in X.

31 S ={4, 8, E 1, 3, E 2, 9, 2, 6, E 3, E 4, E 5, 1, 7, E 6, 5, C 7 } Consideriamo la sequenza dellesempio in cui abbiamo aggiunto alla fine un contenitore C 7 a cui associare i valori non estratti. Lelemento 1 viene estratto da E 6. Poniamo quindi X 6 = 1 e a questo punto lestrazione E 6 è stata effettuata.

32 Lelemento 2 viene estratto da E 3. Quindi X 3 = 2 S ={4, 8, E 1, 3, E 2, 9, 2, 6, E 3, E 4, E 5, 1, 7, E 6, 5, C 7 } X ={#, #, 2, #, #, 1} S ={4, 8, E 1, 3, E 2, 9, 2, 6, E 3, E 4, E 5, 1, 7, E 6, 5, C 7 } X ={#, #, #, #, #, 1} La situazione è: Lelemento 3 viene estratto da E 2. Quindi X 2 = 3 S ={4, 8, E 1, 3, E 2, 9, 2, 6, E 3, E 4, E 5, 1, 7, E 6, 5, C 7 } X ={#, 3, 2, #, #, 1} Lelemento 4 viene estratto da E 1. Quindi X 1 = 4

33 Lelemento 5 non viene estratto e rimane associato a C 7. Noi infatti manteniamo associato ogni valore alla ExtractMin successiva non ancora effettuata o a C 7 se non ce ne sono altre. Lelemento 6 è associato ad E 4 e quindi X 4 = 6. S ={4, 8, E 1, 3, E 2, 9, 2, 6, E 3, E 4, E 5, 1, 7, E 6, 5, C 7 } X ={4, 3, 2, #, #, 1} La situazione è

34 Lelemento 7 è associato a C 7 e viene scartato. Lelemento 9 è associato a C 7 e viene scartato. Il risultato è quindi X = {4, 3, 2, 6, 8, 1} S ={4, 8, E 1, 3, E 2, 9, 2, 6, E 3, E 4, E 5, 1, 7, E 6, 5, C 7 } X ={4, 3, 2, 6, #, 1} Lelemento 8 è associato ad E 5 e quindi X 5 = 8. S ={4, 8, E 1, 3, E 2, 9, 2, 6, E 3, E 4, E 5, 1, 7, E 6, 5, C 7 } X ={4, 3, 2, 6, 8, 1} La situazione è

35 Implementazione. Usiamo una struttura dati per insiemi disgiunti. Manteniamo raggruppati in un insieme I j gli elementi associati ad ogni E j non ancora effettuata e in un insieme I m+1 quelli associati a C m+1.

36 Su questi insiemi vogliamo eseguire in tempo costante le operazioni MakeSet(i), Union(i,h), FindSet(i) ed inoltre FindIndex(i) che calcola lindice j della E j non effettuata (o lindice m+1 di C m+1 ) a cui lelemento i risulta associato. Le prime tre sono quelle standard e per poter eseguire la FindIndex(i) basta memorizzare nel rappresentante di ogni insieme lindice j della E j non effettuata (o lindice m+1 di C m+1 ) a cui linsieme è associato.

37 Rimane un problema: qualcuno degli insiemi può essere vuoto mentre la struttura dati per insiemi disgiunti richiede che essi siano tutti non vuoti. Allinizio creiamo quindi m+1 insiemi I 1,…,I m+1 dove I j = {n+j} contiene soltanto lelemento fittizio e memorizziamo lindice j nellunico nodo. Tempo O(m). Per ovviare a questo aggiungiamo ad ogni insieme I j un elemento fittizio di valore i = n+j.

38 Percorriamo quindi la sequenza delle operazioni e, finché non troviamo la prima ExtractMin, aggiungiamo gli elementi inseriti allinsieme I 1. Dopo di che gli elementi inseriti prima della seconda ExtractMin vengono aggiunti a I 2 e così via fino ad aggiungere ad I m+1 tutti gli elementi inseriti dopo lultima ExtractMin. Tempo O(n+m).

39 Per aggiungere un nuovo elemento i ad un insieme I j dobbiamo usare la MakeSet(i) e poi usare la Union(i, m+j) per riunire i due insiemi (ricordiamo che m+j è lelemento fittizio di I j ). Naturalmente se lunione cambia il rappresentante occorre ricordarsi di memorizzare lindice j dellinsieme nel nuovo rappresentante.

40 Quando il nostro algoritmo decide che lelemento i viene estratto da E j dobbiamo porre X[j] = i A questo punto, siccome E j è stata eseguita, gli elementi dellinsieme I j a cui appartiene i devono essere associati alla successiva ExtractMin E k non ancora eseguita o a C m+1 se tutte le ExtractMin successive sono state eseguite.

41 Dobbiamo però prima trovare h. Per fare questo manteniamo i rappresentanti degli insiemi I j in una lista doppiamente concatenata e ordinata rispetto allindice j. Occorre quindi effettuare una Union(i,h) dove h è un elemento di I k associato ad E k o di I m+1 associato a C m+1.

42 Supponiamo di aver elaborato gli elementi 1,…,i-1. Per trovare lindice j della ExtractMin non saturata che estrae i basta calcolare j = FindIndex(i). Se j = m+1 lelemento i è stato inserito dopo lultima ExtractMin non saturata e quindi non viene estratto. Altrimenti esso è estratto da E j e possiamo porre X[j] = i. Tutto questo richiede un tempo costante per ciascun elemento e quindi tempo O(n) in totale.


Scaricare ppt "Per valutare la complessità ammortizzata scomponiamo ogni Union: nelle due FindSet e nella Link che la costituiscono e valuteremo la complessità in funzione."

Presentazioni simili


Annunci Google