41 1.4 Il problema dell`albero di copertura di costo minimo: algoritmo

ROC-00/01 Capitolo 1
1 . 4 Il problema dell'albero di copertura di costo minimo: algoritmo di Kruskal,
operazioni di Find-Union.
Nel corso di Programmazione Matematica è stato già introdotto il problema dell'albero di
copertura di costo minimo ed introdotto l'algoritmo di Kruskal, come un particolare algoritmo
Greedy. Nel seguito richiamiamo i principali concetti teorici legati agli algoritmi Greedy e
mostreremo le strutture di dati più adatte per un'implementazione efficiente dell'algoritmo di
Kruskal.
1.4.1 Sistemi di insiemi indipendenti
Sia E un insieme finito e F una famiglia di suoi sottoinsiemi (F ⊆ 2 E ), tale che valga la
seguente proprietà:
(1.4.1)
(A ⊆ B) & (B ∈ F) → A ∈ F;
Allora, chiameremo F una famiglia di insiemi indipendenti, e (E, F) un sistema di insiemi
indipendenti. Un insieme I ∈ F è detto un insieme massimale se e ∈ E \ I → I ∪ {e }∉ F. Data
una funzione w: 2E → R, chiameremo problema associato a (E, F) il seguente problema di
ottimizzazione:
Determinare un insieme I ∈ F massimale, tale che w(I) ≤ w(Y), ∀ Y ∈ F e massimale.
Analogamente possiamo far corrispondere a (E, F) un problema di massimo.
Il problema dell'albero di copertura di peso minimo
Dato il grafo simmetrico pesato (N, A, w) connesso, con:
N : insieme dei nodi [ |N| = n]
A : insieme degli archi [ |A| = m]
w : A → R+
[ pesi]
determinare un albero di copertura di peso minimo. L'insieme delle soluzioni ammissibili è:
(1.4.2)
T = {I ⊆ A: (N, I) è un albero di copertura per (N, A, w)}.
F = {I ⊆ A: (N, I) è un grafo parziale privo di cicli di (N, A, w)}.
Il peso di un insieme di archi I ⊆ A è dato da:
(1.4.3)
w(I) = Σ
e∈I w(e)
Il problema dell'albero di copertura di costo minimo può anche essere descritto come il
problema di minimo associato al sistema di insiemi indipendenti (A, F).
1.4.2 Algoritmo greedy
Si dice algoritmo "greedy" (vorace) un algoritmo che determina la soluzione attraverso una
sequenza di decisioni parziali (localmente ottime), senza mai tornare, modificandole, sulle
decisioni prese. Questi algoritmi, in generale, non garantiscono l'ottimalità né l'ammissibilità.
È conveniente fare riferimento a problemi rappresentati sotto forma di sistemi di insiemi
indipendenti; sia (E, F) un sistema di insiemi indipendenti, e sia data la funzione w : 2E → R.
Un algoritmo di tipo Greedy costruisce l'insieme S ∈ F, insieme degli elementi “inseriti”
nella soluzione, partendo dall'insieme vuoto ed inserendovi ad ogni passo l'elemento di E più
“promettente” fra quelli che non violano l'indipendenza dell'insieme. Nella sua forma più
generale un algoritmo di tipo Greedy è descritto dalla procedure GREEDY in figura 1.4.1. X
41
ROC-00/01 Capitolo 1
rappresenta l'insieme degli elementi ancora da valutare, R l'insieme degli elementi “cancellati”
dalla soluzione.
Procedure GREEDY(E,F,w)
begin
S := Ø; R := Ø; X := E;
repeat
e := BEST(X,w); X := X \ {e}; if IND(S,e) then S := S ∪ {e} else R := R ∪ {e}
until X = Ø or S is a solution
end. greedy
Fig. 1.4.1 - La procedura GREEDY
L'algoritmo fa uso delle due sottoprocedure BEST e IND:
BEST fornisce il migliore elemento di X sulla base di un prefissato criterio.
IND è una funzione logica così definita:

IND(S, e) = vero, se S ∪ {e }∈ F ,
falso, altrimenti.
Analizziamo la complessità della procedura GREEDY. Siano |E| = n, h(n) la complessità di
BEST e k(n) la complessità di IND. La complessità della procedura GREEDY è allora
O(n(h(n)+k(n))). Se supponiamo che gli elementi di E vengano ordinati all'inizio, e che quindi
ad ogni passo BEST fornisca il primo fra i rimanenti, la complessità diventa O(nlogn + nk(n)).
1.4.3 Matroidi
Si consideri il sistema di insiemi indipendenti (E, F) ed il problema ad esso associato con la
funzione obiettivo, da minimizzare, definita da (1.4.3).
Definizione - Il sistema (E, F) è un matroide se l'algoritmo greedy fornisce la soluzione
ottima per il problema associato nel caso in cui si definisca BEST(X,w) = argmin{w(e): e ∈ X}
[argmax{w(e): e ∈ X} per problemi di massimizzazione].
Il seguente teorema caratterizza i matroidi e consente in molti casi un loro agevole
riconoscimento.
Teorema 1.4.1 - Sia (E, F) un sistema di insiemi indipendenti. Le seguenti proposizioni
sono equivalenti:
1) (E, F) è un matroide;
2) Se Ip e Ip+1 appartengono ad F, con |Ip| = p e |Ip+1| = p+1, allora esiste un elemento e ∈
Ip+1 \ Ip tale che Ip ∪ {e }∈ F;
3) Se E' ⊆ E e I e J sono sottoinsiemi indipendenti massimali di E', allora è |I| = |J|.
Dimostrazione
(1) ⇒ (2): Supponiamo che sia vera la (1) e falsa la (2); siano Ip e Ip+1 due insiemi che rendono
falsa la (2). Consideriamo il problema di massimo associato a (E, F) con pesi:
p+2,
p+1,
w(e) = 
0,
se e ∈ I p ,
se e ∈ I p + 1 \ I p ,
se e ∉ I p+1 ∪ I p .
Osserviamo che Ip non è ottima, infatti: W(Ip+1) ≥ (p+1)2 > p(p+2) = W(Ip).
42
ROC-00/01 Capitolo 1
Tuttavia l'algoritmo greedy fornisce una soluzione che contiene tutti gli elementi di Ip oltre
ad eventuali elementi a peso nullo, e ciò contraddice l'ipotesi che (E, F) sia un matroide.
(2) ⇒ (3): Sia vera la (2) e siano I e J due insiemi massimali di E', con |I| < |J|. Per la (2) esiste
un elemento e appartenente a J, e quindi a E', tale che I ∪ {e }∈ F, ma ciò contraddice la
massimalità di I.
(3) ⇒ (1): Sia vera la (3) e falsa la (1). Sia w una funzione peso per cui il problema di massimo
associato a (E, F) non sia risolto dall'algoritmo greedy. Sia I = {e1,…, ei } la soluzione fornita
dall'algoritmo greedy e J = {e'1,…, e'j } la soluzione ottima, con W(I)<W(J). Si assume senza
perdita di generalità che sia w(e1)≥…≥w(ei), w(e'1)≥…≥w(e'j). Osserviamo che essendo I e J
massimali ed essendo vera la (3) è i = j. Dimostriamo ora per induzione che è w(eh) ≥ w(e'h),
h = 1, …, i. Ciò è vero per h = 1 (dalla definizione di algoritmo greedy). Sia h > 1 e w(eh) <
w(e'h), con w(ek) ≥ w(e'k), per k < h. Definiamo l'insieme A = {e : w(e) ≥ w(e'h)}; l'insieme
{e1, …, eh-1} è massimale per A, altrimenti l'algoritmo greedy non avrebbe scelto eh; ma e'1,
…, e'h è un sottoinsieme indipendente di A e ciò contraddice l'ipotesi che la (3) sia vera.◊
Si consideri il grafo non orientato (N, A, w) del problema dell'albero di copertura di costo
minimo, e il sistema di insiemi indipendenti (A, F) associato, dove F è definita in (1.4.2). È
facile verificare che si tratta di un matroide, infatti gli insiemi massimali hanno tutti la stessa
cardinalità: corrispondono agli alberi di copertura del grafo (foreste di copertura, nel caso che il
grafo non sia connesso). Un matroide di questo tipo viene detto matroide grafico. Ciò fornisce
implicitamente la prova di correttezza dell'algoritmo greedy per il problema dell'albero di
copertura di costo minimo.
1.4.4 Algoritmo di Kruskal
Riportiamo in figura 1.4.2 l'algoritmo di Kruskal introdotto nel corso di Programmazione
Matematica:
Procedure Kruskal(G,Fw,S)
begin
S := Ø; R := Ø; X := Sort(A);
repeat
Estrai da X il primo arco (u,v);
if Component(S,(u,v)) then R := R ∪ {(u,v)} else S := S ∪ {(u,v)}
until X = Ø or |S| = n-1
end.
Fig. 1.4.2 - La procedura Kruskal
La procedura cardine è la Component(S, (u,v)), che deve verificare se i nodi estremi
dell'arco (u,v) appartengono alla stessa componente connessa (true) o meno (false). A tal fine
introdurremo particolari strutture di dati che permettono la gestione di insiemi disgiunti (gli
insiemi di nodi appartenenti alla stessa componente connessa).
1.4.5 Gestione di insiemi disgiunti: le operazioni di Find e Union
Sia N = {1, 2, ..., n} un insieme di elementi (per il nostro problema, sono i nodi del grafo, ma
verranno indicati come “elementi” per non creare confusione con i “nodi” della struttura di dati),
e S1, S2, ..., Sm sottoinsiemi disgiunti di N. Gli insiemi Sj, j = 1,…, m, possono essere
rappresentati per mezzo di alberi.
43
ROC-00/01 Capitolo 1
Ogni insieme è rappresentato per mezzo di un albero i cui nodi sono gli elementi
dell'insieme stesso. Ogni elemento, x, punta al suo predecessore p(x). L'elemento radice
dell'albero punta a se stesso; tale elemento viene anche detto elemento canonico dell'insieme.
Un esempio è illustrato in figura 1.4.3.
x
a
bc
y
t
sv
d
r
g h us
ef
Fig. 1.4.3 - Due insiemi disgiunti di elementi canonici x e y
Definiamo le seguenti operazioni:
Makeset(x): costruisce un nuovo insieme {x}, con x non appartenente a nessuno degli insiemi
già esistenti; viene effettuata ponendo p(x) := x e costa O(1).
Find(x):
restituisce l'elemento canonico dell'insieme contenente x; comporta il percorrere il
cammino da x fino alla radice, e costa O(n).
Union(x,y): costruisce un nuovo insieme unione degli insiemi aventi x ed y come elementi
canonici (x≠y) in sostituzione dei due vecchi insiemi (che si assumono disgiunti);
infine restituisce l'elemento canonico del nuovo insieme; può essere realizzata
ponendo p(x) := y con costo O(1). L'operazione è descritta in figura 1.4.4.
y
x
y
x
Fig. 1.4.4 - L'operazione Union
Sia T un albero con radice x, e v un suo nodo. Definiamo:
0,
se v è una foglia,
altezza(v) = 
1+max{altezza(w):
p(w)=v},
altrimenti;

si ha che altezza(x) ≡ altezza dell'albero T. Un esempio è dato in figura 1.4.5.
x
e
b
a g f
h
altezza (a)= 0
altezza(e)= 2
altezza(x )=3
Fig. 1.4.5 - L'altezza dei nodi di un albero
Per rendere basso il costo dell'operazione Find, bisogna operare in modo da ridurre
l'altezza degli alberi. Un primo risultato in questa direzione può essere ottenuto effettuando
l'unione tra due insiemi in modo che sia l'albero meno alto ad essere collegato a quello più alto e
non viceversa. In tal caso, se i due alberi sono di altezza diversa, l'albero ottenuto attraverso
l'operazione di Union avrà l'altezza dell'albero più alto. Se i due alberi sono di uguale altezza,
l'altezza dell'albero unione sarà più grande di un'unità.
44
ROC-00/01 Capitolo 1
Naturalmente l'uso dell'altezza come criterio per l'operazione di unione non evita la
creazione di alberi molto alti se è grande il numero di operazioni da effettuarsi. Una tecnica che
consente di limitare consistentemente l'altezza degli alberi è quella del compattamento lungo
cammini (path compression), che viene effettuata nella Find. L'idea è quella di ristrutturare
l'albero ad ogni chiamata di Find in modo da ridurne l'altezza. Quest'idea è illustrata nella figura
1.4.6, dove è considerato il caso di una chiamata di Find applicata all'elemento a.
x
x
c
b
a
b
c
a
Fig. 1.4.6 - L'operazione di path compression
La tecnica di compattamento lungo i cammini rende costoso l'uso dell'altezza per le
operazioni di unione. Bisognerebbe dopo ogni chiamata di Find effettuare un aggiornamento
dell'altezza, operazione costosa perché implica la visita dell'albero. Si preferisce allora usare
invece dell'altezza la funzione rango. Si dice rango(x) una valutazione per eccesso dell'altezza di
x, ottenuta ponendo rango(x) = altezza(x) = 0 all'inizio quando gli insiemi sono formati da
elementi singoli; quindi successivamente ad ogni operazione di unione tra due alberi di elemento
canonico x e y, il rango viene aggiornato, come per l'altezza: se rango(x) < rango(y) si pone x
come figlio di y e il rango di y non cambia; se invece rango(x) = rango(y), oltre a porre x come
figlio di y, il rango di y cresce di un'unità. Praticamente l'effetto è quello di trascurare il
compattamento delle operazioni Find.
Esaminiamo ora gli effetti in termini di complessità computazionale di questo modo di
realizzare l'unione tra insiemi. Utilizzando il rango, è possibile valutare la complessità nel caso
peggiore di ciascuna operazione FIND, come si ricava dalle seguenti proposizioni.
Proposizione 1.4.1 - Il numero di nodi nell'albero di radice x è almeno 2rango(x).
Dimostrazione:
La prova è per induzione sul numero delle operazioni di unione. La tesi è certamente vera dopo
la prima operazione di unione. Assumiamo che sia ancora vera dopo la k-esima, e si effettui la
(k+1)-esima unione sugli alberi di radice x ed y. Se rango(x) ≠ rango(y), la proprietà continua
ad essere vera dopo l'operazione. Se rango(x) = rango(y), il nuovo albero avrà rango pari a
rango(x)+1, e conterrà almeno 2rango(x) + 2rango(y) = 2rango(x)+1 nodi, e quindi la proprietà
continua ad essere vera. La tesi è così dimostrata.◊
Proposizione 1.4.2 - La complessità di una operazione Find è O(logn).
Dimostrazione:
Il costo computazionale di una operazione Find(x) è dato dalla lunghezza del cammino dal nodo
x alla radice r dell'albero a cui x appartiene, e dunque è limitato da altezza(r). Dalla proposizione
1.4.1 risulta evidente che ogni nodo ha rango al più logn, e quindi per ogni radice r si ha
altezza(r) ≤ rango(r) ≤ logn ; dunque nel caso pessimo Find avrà complessità O(logn).◊
45
ROC-00/01 Capitolo 1
Le procedure Makeset, Find e Union sono descritte in figura 1.4.7.
Procedure Makeset(i)
begin
p[i] := i; rango[i] := 0
end.
Procedure Find(i)
begin
j := i;
while j ≠ p[j] do j := p[j]; while i ≠ j do begin w := p[i]; p[i] := j; i := w end;
return j
end.
Procedure Union(x,y)
begin
if rango[x] > rango[y] then begin w := y; y := x; x := w end;
else if rango[x] = rango[y] then rango[y] := rango[y]+1;
p[x] := y
end.
Fig. 1.4.7 - Le procedure Makeset, Find e Union
Analizziamo ora una sequenza di n operazioni Union, n operazioni Makeset ed m
operazioni Find. Ricordando che la complessità di Union e Makeset è O(1), si ha una
complessità (n + mlogn). Si può tuttavia dimostrare la seguente:
Osservazione - Una sequenza di n Makeset, m≥n Find, e n-1 Union, ha una complessità O(mα(m,n)) [Θ(m
α(m,n))], con α(m,n) inversa della funzione di Ackerman [ per n<216 è α(m,n) ≤ 3; agli effetti pratici possiamo
assumere α(m,n) una costante ≤ 4].
1.4.6 La procedura Component e la complessità di Kruskal
Una descrizione formale della procedura Component è data in figura 1.4.8.
Procedure Component(S,(u,v))
begin
x := Find(u); y := Find(v);
if x = y
then return true
else begin Union(x,y); return false end
end.
Fig. 1.4.8 - La procedura Component
La procedura Kruskal è ora completamente descritta. Si ricorda che l'inizializzazione
prevede una sequenza di n chiamate a Makeset, una per ogni nodo, per inizializzare la foresta
non contenente archi.
Analizziamo la complessità di Kruskal. L'inizializzazione prevede il preordinamento degli
archi, secondo i loro costi. Tale operazione ha complessità O(mlogn), che è la complessità di
Kruskal. Seguendo l'osservazione, se gli archi sono già ordinati secondo i loro costi e se si
adotta l'operazione di path compression, la complessità è O(mα(m,n)).
Comunque, nel caso peggiore si faranno 2m chiamate alla procedura Find; anche senza la
fase di path compression, Find ha complessità O(logn). Pertanto, Kruskal ha complessità
O(mlogn), anche nel caso non si effettuino le path compression.
46
ROC-00/01 Capitolo 1
1 . 5 . Il problema di flusso di costo minimo “multicommodity”
Quando in una rete sono assegnati flussi relativi a beni (commodities) diversi, che condividono
l'utilizzo degli archi, si parla di problemi di flusso di costo minimo di tipo “multicommodity”.
Sia k il numero di beni che si spostano lungo una rete G = (N, A). Le offerte e le domande
del generico bene (o commodity) h sono date dal vettore b(h), h = 1,…, k. Anche i costi e le
capacità associate agli archi del grafo sono definite per ciascuna commodity; indicheremo
(h)
(h)
pertanto con c(h) = [c(h)
ij ] e u = [u ij ] rispettivamente il vettore dei costi e quello delle capacità
relative alla commodity h, h = 1,…, k. Inoltre, ad ogni arco (i,j) ∈ A è associata una capacità
globale uij dell'arco che limita la quantità globale di beni che possono attraversare l'arco stesso.
(h)
Il vettore dei flussi x(h) = [x(h)
ij ], h = 1,…, k, fornisce, per ogni arco (i,j) ∈ A, il flusso x ij
della commodity h che attraversa tale arco.
Ricordando che E = [eik] indica la matrice di incidenza del grafo G, il problema di flusso
di costo minimo di tipo multicommodity può essere formulato nel seguente modo:
k
(P)
Min
∑ c(h)x(h)
h=1
Ex(h) = b(h)
(1.5.1)
k
∑ x(h)
h = 1,…, k
≤u
h=1
0 ≤ x(h) ≤ u(h)
h = 1,…, k
In forma estesa:
k
(P)
Min
∑ ∑ c (h)ij x(h)ij
(i,j)∈A h=1
x (h)
ij
(j,i)∈BS(i)
∑
(1.5.2)
0≤
-
∑ x (h)ij = b(h)i
i ∈ N,
∑
(i,j) ∈ A
(i,j)∈FS(i)
k
x (h)
ij
h=1
(h)
x(h)
ij ≤ x ij
≤ uij
h = 1,…, k
(i,j) ∈ A,
h = 1,…, k
Si noti che il doppio tipo di capacità sugli archi, sia quelle per singola commodity che
quella globale, permettono di escludere che particolari archi siano utilizzati per una specifica
commodity; basta infatti porre a zero le capacità di questi archi relative alla commodity in
questione. Ciò permette di non dover trattare grafi diversi, uno per commodity. Inoltre, un caso
particolare, sovente presente in problemi concreti, è che il costo unitario di attraversamento degli
archi possa essere uguale per tutte le commodities.
Studiamo il duale di (1.5.1), detto problema di potenziale multicommodity. Le variabili
(h)
(h)
sono un vettore di potenziale π(h) = [π(h)
i ] e un vettore µ = [µ ij ] per ogni commodity h, h =
1,…, k, oltre al vettore di variabili duali λ = [λij] associate ai vincoli globali di capacità:
k
(D)
Max
∑
h=1
(1.5.3)
π(h)b(h)
π(h)E
k
-
∑ µ(h)u(h)
- λu
h=1
- µ(h)
- λ ≤ c(h)
µ(h) ≥0, λ ≥ 0
47
h = 1,…, k
h = 1,…, k
ROC-00/01 Capitolo 1
o, in forma estesa:
k
(D)
∑ ∑
Max
(h)
π (h)
i b i -
h=1 i∈N
k
∑ ∑ µ (h)ij u(h)
ij - ∑ λ ij u ij
h=1 (i,j)∈A
(h)
π(h)
j -π i
(1.5.4)
- µ(h)
ij
(i,j)∈A
- λij ≤ c(h)
ij
µ(h)
ij ≥ 0
λij ≥ 0
(i,j) ∈ A,
h = 1,…, k
(i,j) ∈ A , h = 1,…, k
(i,j) ∈ A
La intera matrice A dei coefficienti in cui si considerano esplicitamente i vincoli globali di
capacità, ha una forma a blocchi diagonali, ciascuno formato dalla matrice E e da una sequenza
di matrici identità che legano i vari flussi di commodity relativi allo stesso arco. Pertanto A è
formata da nk+m righe e mk colonne:
 0 E … 0 
A= … … … …
 0 0 … E 
E 0 … 0
I
I … I
La matrice A non garantisce la proprietà di integralità; è cioè possibile, a causa dei vincoli
globali di capacità, che il flusso ottimo trovato mediante algoritmi del Simplesso per la Programmazione Lineare (o loro adattamento alla particolare struttura della matrice A) forniscano
soluzioni ottime frazionarie. Se non si hanno vincoli sull'integralità dei flussi, il problema
(1.5.1) è risolto. Altrimenti, il costo globale della soluzione frazionaria fornisce solo
un'approssimazione per difetto (lower bound) del valore ottimo della funzione obiettivo di
(1.5.1) quando si impone che i flussi siano valori interi. È possibile trasformare una soluzione
ottima frazionaria in una soluzione ammissibile intera, se esiste. Il costo di tale soluzione
ammissibile fornisce una valutazione per eccesso (upper bound) del costo della soluzione ottima
intera.
Per analizzare alcune proprietà del problema (1.5.1) quando aggiungiamo il vincolo di
interezza, studiamo il suo Rilassamento Lagrangiano ottenuto rilassando i vincoli globali di
capacità, i cui moltiplicatori di Lagrange sono le variabili duali λ = [λij]:
(P(λ)) φ(λ) = Min
k
∑
k
c(h)x(h)
h=1
+ λ ( ∑ x (h) - u )
h=1
Ex(h) = bh)
(1.5.5)
0≤
x(h) ≤ u(h)
h = 1,…, k
h = 1,…, k
Il problema da risolvere, detto duale generalizzato o duale Lagrangiano, è:
(1.5.6)
(DL)
Max
φ(λ)
λ≥0
La funzione obiettivo di (1.5.5), in forma estesa, è:
k
∑ ∑
(i,j)∈A h=1
k
(h)
c (h)
ij x ij
+
∑ λ ij ( ∑ x (h)ij - uij);
(i,j)∈A
h=1
48
ROC-00/01 Capitolo 1
raccogliendo assieme le parti, si ha
k
∑ ∑ (c (h)ij + λij)x(h)ij
∑ λ iju ij.
-
(i,j)∈A h=1
(i,j)∈A
_
Una volta assegnati
dei
valori
λ ≥ 0 ai moltiplicatori di Lagrange, il _problema (1.5.5),
_
parametrico in λ , può essere separato _in k problemi indipendenti (P h (λ )), per ciascuna
commodity h, h = 1,…, k, in cui la parte λu è omessa in quanto un valore costante:
_
(Ph(λ))
_
φh(λ) = Min
_
(h)
∑ c (h)
ij x ij
(i,j)∈A
Ex(h) = bh)
0 ≤ x(h) ≤ u(h)
(1.5.7)
_
_
dove c (h)
=
c
+
λ
ij
ij, per ogni (i,j) ∈ A. Il problema (1.5.7) è un problema di flusso di costo
ij
minimo e può essere risolto applicando uno degli algoritmi studiati (ad esempio il Simplesso per
flussi o il Simplesso per potenziali) fornendo peraltro una soluzione ottima intera se le capacità
_
degli archi e le domande/offerte dei nodi sono valori interi. Indichiamo comunque con x (h) la
soluzione ottima di (1.5.7).
_
Una volta risolti i k problemi (Ph(λ)), h = 1,…, k, si ha il seguente valore della funzione
obiettivo del problema (1.5.6):
(1.5.8)
k
_
_
φ(λ) = ∑ φ h ( λ) =
h=1
k
∑ ∑
_ _ (h)
c (h)
ij x ij −
(i,j)∈A h=1
∑
_
λ iju ij
(i,j)∈A
_
Il valore φ(λ) è un lower bound del valore ottimo della funzione obiettivo di (DL) che, a
sua volta è un lower bound del valore ottimo della funzione obiettivo di (1.5.1).
Dalla (1.5.8) si hanno anche preziose informazioni (in termini di subgradiente della
funzione poliedrale φ(λ))
_ che permettono di attivare un processo iterativo per costruire un
nuovo vettore di valori_λ' per cui trovare, risolvendo i problemi di flusso
(1.5.7),
dei nuovi
_
_
valori ottimi di flusso x '(h), h = 1,…, k, che forniscono un valore φ(λ') > φ(λ ), e quindi un
migliore lower bound.
La ricerca del migliore (più alto) lower bound e del migliore (più basso) upper bound
permette di restringere il margine di incertezza sul valore ottimo della funzione obiettivo e di
valutare l'errore relativo che si causa se si adotta la soluzione associata al miglior upper bound
come soluzione approssimata del problema.
I metodi di ottimizzazione basati sui rilassamenti, sull'utilizzo di lower e upper bounds sia
per la ricerca della soluzione ottima che per la valutazione della bontà di una soluzione
ammissibile sono l'oggetto dei corsi di Ottimizzazione Combinatoria e Ottimizzazione
Combinatoria: Laboratorio.
49