Lezione 4
Algoritmi di Approssimazione basati sulla
Programmazione Lineare
a cura di Clelia Sessa
In questa lezione saranno illustrati algoritmi di approssimazione basati sulla programmazione
lineare. Verranno trattati due problemi NP-completi: MIN-VERTEX-COVER (pesato) e SETCOVER (pesato), si vedrà dalla formulazione di tali problemi che essi sono problemi di
programmazione intera 0-1, di difficile soluzione. L’obiettivo è approssimare i due problemi in
modo da poter utilizzare la programmazione lineare, a tale scopo verranno considerate le relative
versioni “rilassate”.
4.0 Definizione Problema di Programmazione Lineare
Un Problema di Programmazione Lineare è un problema così strutturato:
(funzione obiettivo)
n
min/max f(x1…xn) = a1x1+…+anxn =

i 1
aixi con ai
(vincoli)

g(x1…xn) = b

con bi
Un problema di programmazione lineare può essere risolto in tempo polinomiale.
4.1 MIN–VERTEX-COVER (pesato) [CLRS par. 35.4]
Dati G = (V, E), una funzione costo (o peso) c: V  + , trovare V’  V vertex-cover che
minimizza c(V’), dove c(V’) =

vV '
c(v)
1
Esempio 1
V’= 1,5
c(V’) = 10+15 = 25
V’’= 2,3,4 c(V’’) = 1+2+3 = 6
c(V’’) < c(V’) anche se |V’’| > |V’|
2
1
10
1
3
5
15
2
4
3
Soluzione al MIN – VERTEX - COVER è V’’  V.
Una soluzione V’ è possibile vederla anche come un vettore binario di lunghezza |V|, che associa 1
se il vertice appartiene alla soluzione e 0 altrimenti.
Definizione:  vV la variabile xv
0 se vV’
1 se vV’
Esempio 2
In riferimento ai dati dell’esempio 1 si ha:
V’’= 2,3,4  (0, 1, 1, 1, 0)
c(V’’) =

vV
c(v) xv = c(1)*0+c(2)*1+c(3)*1+c(4)*1+c(5)*0 = c(2)+c(3)+c(4) = 6
Con l’introduzione della variabile booleana xv il problema del MIN–VERTEX-COVER
può essere riformulato in questo modo:
min

vV
c(v) xv
con vincoli:
xu + xv  1 (u, v)E
xv0,1  vV
2
Esempio 3
In riferimento ai dati dell’esempio 1 si ha :
min 10x1+x2+2x3+3x4+15x5
con vincoli:
x1 + x2  1
x1 + x3  1
x1 + x4  1
x2 + x5  1
x3 + x5  1
x4 + x5  1
xi 0,1 i = 1,…,5
Il problema così ridefinito è un problema di programmazione intera 0-1, questo problema è difficile
da risolvere, verrà quindi considerato un problema simile: la versione “rilassata”, allo scopo di poter
utilizzare la programmazione lineare.
4.1.1 Versione “RILASSATA”
min

vV
c(v) xv
con vincoli:
xu + xv  1 (u, v)E
xv0 xv1  vV
Questo è un problema di programmazione lineare e può essere risolto in tempo polinomiale.
Di seguito verrà indicato con minR =

vV
c(v) xv il minimo del problema rilassato e con C
*
la
soluzione ottimale del MIN–VERTEX-COVER.
Osservazione:  soluzione al problema 0-1  è soluzione al problema rilassato.
minR  c(C * ) costituisce un limite inferiore all’ottimo.
Approx_Min-Vertex-Cover_Pesato (G,c)
C
“Sia x il vettore soluzione del problema rilassato”
for ogni vV do
1
if x v 
2
then CC  v
return C
3
L’algoritmo prende in input il grafo G con funzione costo c associata ai vertici e restituisce in
1
output l’insieme dei vertici C per cui si ha un valore  .
2
Esempio 4
Se x = (
1 1
3
, , 0, , 1)
2 4
5
(1, 0, 0,
1, 1 )
C = 1, 4, 5
Adesso bisogna dimostrare che:
1) l’algoritmo è polinomiale
2) C è un Vertex - Cover
3) c(C * ) c(C)  2c(C * )
DIMOSTRAZIONI
1) L’algoritmo è polinomiale perché il problema rilassato è un problema di programmazione
lineare che si risolve in tempo polinomiale e il resto dell’algoritmo è eseguibile in O(|V|).
?
2)  (u, v)  E  u  C oppure v  C
1
1
x u + x v  1  x u > oppure x v >
2
2
 u  C oppure v  C  C è un Vertex - Cover.
3) Innanzitutto c(C * ) c(C) perché si tratta di un problema di minimizzazione.
Sia C * la soluzione ottima del problema Min-Vertex-Cover_Pesato e sia minR il valore di
una soluzione ottima del problema di programmazione lineare, si ha che:
minR  c(C * )
minR =



c(v) x v
1
2

c(v)
vV
x (v ) 
vV
c(v) x v
vV
x (v ) 

1
2
1
2
4

1
c(v)
2 vC
1
= c(C)
2
=
c(C ) 2 minR  2c(C
*
)
L’algoritmo Approx_Min_Vertex-Cover_Pesato è 2-approssimato.
4.2 SET-COVER (pesato)
[Vaz. parr. 14.1-14.2]
Dati un insieme X = x1, x2, …, xn, una famiglia  P (X), (S, SX), una funzione costo (o
peso) c:   + , trovare una sottofamiglia C   che ricopre X (xX, xS ,  S C ) che
minimizza c(C )
0 se S  C
Definendo una variabile booleana xs
1 se S  C
Il problema può essere riformulato come segue:
min

c(S) xS
S
con vincoli:

xS  1  xX
S: xS
xS0,1
 S
Questo problema è di programmazione intera 0-1, ed è difficile da risolvere, verrà quindi
considerato un problema simile: la versione “rilassata”, allo scopo di poter utilizzare la
programmazione lineare .
5
4.2.1 Versione “RILASSATA”
min

c(S) xS
S
con vincoli:

xS  1  xX
S: xS
xS  0
xS  1
 S
Questo è un problema di programmazione lineare e può essere risolto in tempo polinomiale.
Osservazione:  soluzione al problema 0-1  è soluzione al problema rilassato.
Indicando con minR =

c(S) xS, il minimo del problema rilassato e con C * la soluzione ottimale
S
del MIN- SET-COVER si ha:
minR  c(C * ) costituisce un limite inferiore all’ottimo.
4.2.2 Problema di P. L. con fattore f
Definizione:  xX f(x) = | S   | x  S| è detta frequenza di x
Definizione:  = max f(x) è detta frequenza massima
xX
Esempio 1
= 3
S1, S3, S4
 = S1, S2, S3, S4
6
Approx_Set-Cover_Pesato
C 
“Sia x il vettore soluzione del problema rilassato”
for ogni S do
1
if x S 
f
then C  C  S
return C
L’algoritmo restituisce in output la famiglia C di sottoinsiemi di S che hanno un valore 
1
.
f
Esempio 2
In riferimento all’esempio 1 dove  = 3
2 1 1 4
1
1
Se x = ( , , , ) vengono selezionati gli elementi 
=
3 5 3 9
3
f
che rappresentati tramite il vettore binario sono (1, 0, 1, 1) cioè C =  S1, S3, S4
Adesso bisogna dimostrare che:
1) l’algoritmo è polinomiale
2) C ricopre X
3) c(C * ) c(C )   c(C * )
DIMOSTRAZIONI
1) L’algoritmo è polinomiale perché il problema rilassato è un problema di programmazione
lineare che si risolve in tempo polinomiale e il resto dell’algoritmo è eseguibile in tempo
polinomiale.
2) Per dimostrare che C sia la soluzione restituita dall’algoritmo, si deve verificare che
?
 x  X   S C t.c. x  S, xs = 1

algo
1
 S C
f
xS
La sommatoria è definita su tutti gli S, quindi x contiene esattamente f(x) elementi, ed f(x)  
dato che tale somma è  1, quindi ci deve essere almeno un elemento  1 diviso il numero di
1
elementi, cioè  x S 
e in base all’algoritmo viene arrotondato e messo in C , questo implica
f
che in C c’è un insieme che contiene x. Poiché questo vale  x  X, alla fine in C ci sarà almeno
un insieme per ogni elemento di X, ossia C è un set-cover di X.
x S  1   S t.c. x S 
3) Innanzitutto c(C
*
) c(C) perché si tratta di un problema di minimizzazione.
7
La soluzione al problema rilassato è minR =

c(S) x S , dove minR c(C
*
). Inoltre
S
c(C )   minR
Infatti:
minR =

c(S) x S 
S rilax

c(S) x S 
S rilax
xS 
1
f

c(S) =
1
c(C)
f
S rilax
1
f
Quindi si ha un algoritmo di approssimazione per Set-Cover con fattore f.
4.2.3 Problema di P. L. versione Random
In questo paragrafo verrà formulato un nuovo algoritmo randomizzato allo scopo di ottenere
un’approssimazione nell’ordine di O(log n).
L’idea è partire dalla soluzione ottima del problema rilassato e interpretare le sue componenti non
intere come le probabilità con cui prendere nella soluzione l’insieme corrispondente.
Sia x = p una soluzione ottima al problema di programmazione lineare. Per ogni insieme S, S
viene preso con probabilità ps. Sia C la collezione di insiemi presi.
Il costo medio di questa soluzione è:
Ec(C) =
 c(S)  Probabilità di prendere S =  c(S)  ps = OPT
S
S
Infatti, per definizione, la media è data dal costo di ogni elemento per la rispettiva probabilità, ma le
probabilità sono proprio le ps e la somma dei costi per le ps non è altro che la soluzione al problema
rilassato.
Adesso bisogna controllare che la famiglia così costruita sia un cover.
Dato x  X, si suppone che sia coperto (ovvero appartenga) dagli insiemi S1, S2, …, Sk, e si calcola
la probabilità che questo avvenga:
Pr{x sia coperto da C} = 1- Pr{x non sia coperto da C} =
= 1 - Pr{ S1 non è stato inserito in C  S2 non stato inserito in C  …  Sk non è stato
inserito in C}=
(poiché gli eventi sono indipendenti, la probabilità della congiunzione è uguale al prodotto delle probabilità)
= 1- Pr{ S1 non è stato inserito in C} × … ×Pr{ Sk non è stato inserito in C} =
(poiché si mette ciascun S in C con prob. ps, la prob. che non venga messo è (1- ps))
= 1 – (1 – p1) (1 – p2) (1 – pK) 
1
1
(dalla teoria del calcolo delle probabilità si ha che)  1 – (1 – )k (si può dimostrare che)  1 –  k
k
e
Si ottiene quindi:
Pr{x sia coperto da C} = 1- Pr{x non sia coperto da C} 
1

e
8
Pr{x non sia coperto da C} 
1
 x  X.
e
Viene riapplicato lo stesso procedimento allo scopo di abbassare la probabilità che l’insieme
ottenuto non sia un cover, cioè si costruisce nello stesso modo un’altra famiglia e si unisce a quella
precedente. Quindi vengono costruite allo stesso modo d×log n famiglie e la loro unione è chiamata
C’. Dove d è una costante scelta in modo che risulti:
1
1
( ) dlog n 
e
4n
Pr{x non sia coperto da C’ } (
1 dlog n
1
)

e
4n
Questa è la probabilità che un generico x  X non sia coperto, quindi:
1
1
Pr{ C’ non sia un cover per X}  n

4n
4
Si ha che :
Ec(C' )  OPT d log n
Disuguaglianza di Markov: Data una variabile casuale X con valor medio E[X],
E  X 
vale che Pr{X  t}    .
t
Applicando la disuguaglianza di Markov con t = 4d log n  OPTf . Si ottiene:
E c(C' )
d log n  OPTf
1
= .

4
4d log n  OPTf
4d log n  OPTf
1
La probabilità dell’unione di due eventi sfavorevoli è 
2
Pr c(C)  4d log n  OPTf  
Pr{C è un cover  c(C’)  4d log n  OPTf } 
1
2
Osservazione: E’ possibile verificare in tempo polinomiale se C’ soddisfa entrambe queste
condizioni. Il numero medio di ripetizioni è al più 2.
Bibliografia
[1] Appunti della lezione del 14/12/2004
[2] Min-Vertex-Cover [CLRS par. 35.4]
[3] Set-Cover [Vazirani parr. 14.1-14.2]
9