AlgoLab - MST code binomiali Algoritmi per il calcolo di MST: uso di code unificabili Laboratorio di Algoritmi 02/03 Prof. Ugo de’ Liguoro
AlgoLab - MST code binomiali Alberi di copertura minima (MST) G = (V, E) sia un grafo non orientato, con archi pesati w: E ! ; T = (V, A), dove A µ E, è un albero di copertura minima (MST) di G se: 1. T è aciclico (dunque un albero): una copertura di G; 2. w(T) = (u, v) 2 A w(u,v) è minimo tra tutte le coperture di G. bcd hgf aei w(T) = 37
AlgoLab - MST code binomiali Schema degli algoritmi greedy per MST Generic-MST (G) 1. A Ã ; 2. while A non forma una copertura 3.do cerca (u, v) 2 E[G] n A che sia safe per A 4. A Ã A [ {(u, v)} 5. return A L’arco (u, v) è safe per A se esiste un MST T per G t.c. a) A µ T b) (u, v) 2 T n A
AlgoLab - MST code binomiali Tagli e “safe edges” Un taglio (cut) di G è una partizione {S, V[G] n S} di V[G] Un arco (u, v) 2 E[G] scavalca (crosses) {S, V[G] n S} se: {u, v} Å S ; Æ {u, v} Å V[G] n S ; Un taglio rispetta A se nessun (u, v) 2 A lo scavalca Teorema. Se A è incluso in un MST per G, {S, V[G] n S} è un taglio di G che rispetta A, allora un arco (u, v) 2 E[G] t.c. w(u, v) = min{w(a, b) | (a, b) scavalca {S, V[G] n S}} è safe per A.
AlgoLab - MST code binomiali MST-Mergeable-Heap MST-Mergeable-Heap(G) // G grafo pesato, non orientato, connesso 1. T à // grafo non orientato aciclico, inizialmente vuoto 2. for ogni vertice v i 2 V[G] 3.do V i à {v i } 4.E i à {(v i, v) 2 E[G]} 5. while esiste più di un V i 6. do scegli un V i 7.estrai da E i un arco di peso minimo (u, v) 8.siano u 2 V i, v 2 V j 9if i j 10. thenT à T [ {(u, v)} 11.V i à V i [ V j, ditruggendo V j 12.E i à E i [ E j
AlgoLab - MST code binomiali Correttezza Se la partizione P ha più di un elemento ed A è l’insieme degli archi correntemente in T, allora per ogni V i 2 P: 1) {V i, V[G] n V i } rispetta A 2) 9 (u, v) 2 E i t.c. (u, v) scavalca {V i, V[G] n V i } Quindi: a) E i ; b) sebbene l’arco di peso minimo (u, v) estratto alla linea 7 non sia necessariamente quello che scavalca il taglio {V i, V[G] n V i }, se alla linea 9 i j allora w(u, v) è minimo tra i pesi degli archi che scavalcano il taglio: dunque (per il teorema) è safe per A c) quando |P| = 1, V[G] = V[T] e dunque T è un MST per G.
AlgoLab - MST code binomiali Pseudocodifica MST-Mergeable-Heap(G) 1. T à Empty-Graph (), P à Empty-Partition () 2. for ogni vertice v i 2 V[G] 3.do V i à Make-Set (P, v i ) 4. E i à Make-Heap () 5. for ogni (v i, v) 2 E[G] 6. doinfo[x] à (v i, v) 7.key[x] = w (v i, v) 8.Binomial-Heap-Insert (E i, x) 9. while esiste più di un V i 2 P 11. do scegli un V i 2 P 12.(u, v) à Binomial-Heap-Extract-Min (E i ) 13.a à Find-Set (u), b à Find-Set (v) 14if a b 15. thenT à T [ {(u, v)} 16.Union (P, a, b) 17.E a à Binomial-Heap-Union (E a, E b )
AlgoLab - MST code binomiali Note sulla realizzazione in Java (1) Estendiamo Graph con la classe UnorderedGraph : aggiunge un campo private int Totalweight; // somma dei pesi degli archi aggiunge un metodo public int getTotalweight() // ritorna il val. Ccorrente di Totalweight ridefinisce il metodo public void addArc (int i, int j, int weight) // aggiunge l'arco non orientato {i, j} di peso // weight, ed incrementa Totalweight ospita il metodo pubblico MSTMergeableHeap ()
AlgoLab - MST code binomiali Note sulla realizzazione in Java (2) Realizziamo la partizione P sull’insieme degli indici del vettore Graph.vertices, ossia {0, …, Graph.cardVertexes()-1 } usando DisjointSetsOfInt. Modifichiamo DisjointSetsOfInt per poter sapere quando la cardinalità di P è 1: aggiungiamo un campo privato private int card; // cardinalità della partizione ed un metodo pubblico che lo ispeziona public int Cardinality ()
AlgoLab - MST code binomiali Note sulla realizzazione in Java (3) Per avere code di archi modifichiamo MergeableQueue in modo da trattare chiavi di tipo Comparable, usando il metodo compareTo dovunque occorra confrontare due chiavi Per realizzare le code unificabili E i ed associarle agli elementi V i di P utilizziamo un array MergeableQueue edgesSet[] = new MergeableQueue[cardVertexes()]; ed usiamo gli indici dei vertici per associare ad ogni rappresentante di un elemento in P la relativa coda di archi.
AlgoLab - MST code binomiali Note sulla realizzazione in Java (4) Per gli archi usiamo una classe Edge, privata e interna a Graph, avente i campi: int fst, snd; // indici dei vertici in Graph.vertices int weight; // peso dell’arco Per essere trattata come campo chiave in una coda di priorità, la classe implementa Comparable ed ha quindi un metodo public int compareTo (Object o) // ritorna –1 se this o // supponendo o di classe Edge, e facendo il confronto // sul campo weight
AlgoLab - MST code binomiali Riferimenti Basato sul testo: Intoduction to Algorithms, di Cormen et alii. Gli algoritmi MST sono illustrati nel cap. 24 eedl testo di Cormen. L’algoritmo MST-Mergeable-Heap è l’esercizio 20-2 del testo di Cormen. Le funzioni utilizzate nella pseudocodifica sono illustrate nei capitoli 20 (code unificabili con alberi binomiali) e 22 (insiemi disgiunti) dello stesso testo.