Algoritmi e Strutture Dati con Laboratorio

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