Algoritmi e Strutture Dati con Laboratorio Testo e soluzione della prova scritta del 2 Febbraio 2010 1. Il grafo G = (V, E) è non diretto, connesso e pesato dalla funzione w : E → R. Sia T un albero coprente di G e c(T ) il numero di archi di E che hanno peso superiore al massimo arco in T ovvero se m = maxe∈T w(e) allora c(T ) = |{e ∈ E : w(e) > m}|. Si progetti un algoritmo che, con input il grafo pesato G, restituisce un albero coprente T di G che massimizza c(T ). Si dimostri la correttezza dell’algoritmo. Soluzione: Il minimo albero coprente minimizza l’arco di costo massimo. Ovvero se T ∗ è un MST di G, maxe∈T ∗ w(e) ≤ maxe∈T w(e) per ogni altro albero coprente T di G (si veda l’Esercizio 4 nella raccolta di esercizi svolti a lezione1 ). Sia T un albero coprente di G e e0 l’arco di peso massimo di T allora {e ∈ E : w(e) > w(e0 )} ⊆ {e ∈ E : w(e) > w(e∗ )}. Ovvero c(T ∗ ) ≥ c(T ) per ogni albero coprente T di G. 2. Sia C = {A1 , A2 , . . . , Am } una famiglia di insiemi in X (ovvero ogni Ai ⊆ X). Un sottoinsieme H di X è un insieme coprente se per ogni i = 1, . . . , m, H ∩ Ai 6= ∅ (ovvero se ogni insieme di C ha almeno un rappresentante in H). Si dimostri che il problema di decidere se l’insieme C ammette un insieme coprente di dimensione k è NP-completo. Soluzione: Il problema decritto è l’Hitting Set. Si veda l’Esercizio 11 nella raccolta di esercizi svolti a lezione1 . 3. Si assuma l’esistenza di una struttura dati S che permette le stesse operazioni permesse dalla struttura dati heap. Se n è il numero di elementi in S, il costo computazionale di ogni operazione è riassunta nella tabella che segue. Inserimento Ricerca minimo Cancellazione minimo Decremento chiave O(1) O(1) O(log n) O(1) La struttura S può essere utilizzata al posto della struttura dati Heap nell’implementazione dell’algoritmo di Dijkstra per il calcolo dei cammini minimi da un nodo s di un grafo G = (V, E) pesato con pesi non negativi. Si dimostri che in questo caso la complessità dell’algoritmo è O(|E| + |V | log |V |). Questo rappresenta un miglioramento o un peggioramento rispetto all’implementazione che utilizza la struttura Heap? Soluzione: Di seguito riportiamo lo pseudocodice dell’algoritmo di Dijkstra dove Q è la struttura utilizzata. 1 http://www.mat.uniroma2.it/∼rossig/ASDL/esercitazioni/asdl esercizi.pdf Input: G = (V, E); w : E → R+ , s ∈ V Output: La funzione d : V → R+ dove d(u) è la distanza minima da s a u. Q ← ∅; ∀u ∈ V − {s}, d(u) = +∞; d(s) = 0; ∀u ∈ V, insert(Q, hv, d(v)i); while Q 6= ∅ do u ← getmin(Q); delmin(Q) for all v ∈ N (u) do t ← d(u) + w(u, v); if t < d(v) then d(v) ← t; decreasekey(Q, hv, d(v)i); end if end for end while return d La complessità dell’algoritmo è la seguente: O(|V |×(num. di getmin +num. di delmin)+|E|×(num. di decreasekey)). Nel caso in cui venga utilizzata per Q la struttura S avremmo un costo O(|V | log |V | + |E|). Mentre se per Q viene utilizzato un Heap il costo sarebbe O(|E| log |V |) in quanto l’operazione di decreasekey ha complessità logaritmica nella dimensione della struttura. 2