Grafi e modelli su grafi - Dipartimento di Informatica e Sistemistica

annuncio pubblicitario
Capitolo 13
Grafi e modelli su grafi
In questo capitolo introduciamo la nozione di grafo ed alcune definizioni ad essa collegate. I
grafi sono una struttura matematica molto usata nelle applicazioni e si prestano a rappresentare
problemi apparentemente molto diversi tra di loro con un linguaggio semplice ed unificato.
Questo spiega la loro importanza nella matematica applicata e, in particolare, nella Ricerca
Operativa.
13.1
Definizioni fondamentali
Un grafo non orientato G = (V, E) è definito da un insieme finito V (G) = {v1 , . . . , vn } di
elementi detti nodi o vertici e da un insieme E(G) = {e1 , . . . , em } ⊆ V × V di coppie non
ordinate di nodi dette archi o spigoli.
Dato l’arco e = (v, w) = (w, v), i nodi v e w sono detti estremi di e, e si dice che l’arco e
incide su u e v. Una comoda rappresentazione del grafo viene mostrata in figura 13.1a. I nodi
sono rappresentati da cerchi, mentre gli archi sono tratti di curva congiungenti i due estremi.
Per il grafo G = (V, E) rappresentato in figura si ha
V = {v1 , v2 , v3 , v4 , v5 }
E = {e1 , e2 , e3 , e4 , e5 , e6 } = {(v1 , v2 ), (v2 , v3 ), (v1 , v5 ), (v3 , v5 ), (v3 , v4 ), (v4 , v5 )}.
Se gli estremi di un arco coincidono, l’arco è detto loop (Fig. 13.1b). I grafi di cui ci occuperemo
nel seguito non conterranno loop, a meno che non sia altrimenti specificato.
Due nodi u, v sono detti adiacenti (reciprocamente) se l’arco (u, v) appartiene ad E. Nella
figura sono adiacenti, per esempio, i nodi v1 e v2 . Due archi sono detti adiacenti se hanno un
estremo in comune, come gli archi e2 ed e4 in figura.
Si definisce intorno di un nodo v in G, indicato con ω(v), l’insieme dei nodi adiacenti a v.
Nella figura ω(v5 ) = {v1 , v3 , v4 }. Un nodo v si dice isolato se ω(v) = ∅. Si definisce stella di v
in G, indicata con δ(v), l’insieme degli archi incidenti su v. Nella figura δ(v5 ) = {e3 , e4 , e6 }.
Si definisce sottografo di G = (V, E) un grafo H = (W, F ) tale che W ⊆ V e F ⊆ E.
Si definisce sottografo indotto da W ⊆ V in G = (V, E) il grafo H = (W, F ), ove l’insieme
degli archi F è tale che l’arco (u, v) appartiene a F se e solo se: (u, v) ∈ W e (u, v) ∈ E.
Informalmente possiamo dire che il sottografo H eredita tutti gli archi di G i cui estremi sono
entrambi contenuti nel sottoinsieme W . In figura 13.2 vengono mostrati due sottografi del grafo
179
v2
v3
e2
e5
e1
e6
e3
v1
e
v4
e4
v
v5
b)
a)
Figura 13.1: a) Grafo non-orientato
b) Loop
di figura 13.1. Il primo non è un sottografo indotto (”manca” l’arco e4 ), mentre il secondo è
indotto in G dall’insieme di nodi {v2 , v3 , v4 , v5 }.
v2
e2
v3
v2
v3
e2
e5
v1
v4
e4
e1
e3
e6
v5
v5
b)
a)
Figura 13.2: a) Sottografo
b) Sottografo indotto
Un grafo orientato G = (V, E) è definito da un insieme finito V (G) = {v1 , . . . , vn } di elementi
detti nodi e da un insieme E(G) = {e1 , . . . , em } ⊆ V × V di coppie ordinate di nodi dette archi.
L’arco e = (v, u), si dice orientato dal nodo v al nodo u. I nodi v e u sono detti estremi di e, e si
dice che l’arco e incide su v e u. Notiamo che a differenza del caso non orientato, l’arco (v, u) è
distinto dall’arco (u, v). Una rappresentazione del grafo orientato viene mostrata in figura 13.3.
L’unica differenza con la rappresentazione del grafo non orientato sta nella presenza sull’arco di
una freccia che indica l’orientamento dell’arco stesso.
Analogamente al caso non-orientato, si definisce stella di v in G, indicata con δ(v), l’insieme
degli archi incidenti su v. In figura 13.3, ω(v1 ) = {e1 , e2 , e5 }. La stella δ(v) può essere partizionata in stella entrante δ e (v), cioè l’insieme degli archi entranti in v, e in stella uscente
δ u (v), l’insieme degli archi uscenti da v. Nell’esempio, δ e (v1 ) = {e2 }, mentre δ u (v1 ) = {e1 , e5 }.
Analogamente l’intorno ω(v) può essere partizionato in ω e (v) = {w : (w, v) ∈ δ e (v)} e
ω u (v) = {w : (w, v) ∈ δ u (v)}. Sottografi e sottografi indotti sono definiti come per il caso
non orientato.
180
v2
v3
e3
e6
testa
v4
e2
e1
v1
v
e4
v5
e5
coda
u
b)
a)
Figura 13.3: a) Grafo orientato
b) Arco orientato
Cammini, Cammini Orientati, Cicli. Dato un grafo G = (V, E) (indifferentemente orientato o non orientato), ove V = {v1 , . . . , vn } e E = {e1 , . . . , em } diremo cammino in (di) G, un
insieme ordinato P = {vj0 , eh1 , vj1 , eh2 , . . . , vjp−1 , ehp , vjp } con: jk ∈ {1, . . . , n}, hi ∈ {1, . . . , m},
per k = 0, . . . , p e i = 1, . . . , p, e con l’arco ehi incidente sui nodi vji−1 e vji .1 Notiamo che
nel caso del grafo orientato, l’orientamento degli archi del cammino è indifferente. Si richiede
semplicemente che l’arco ehi incida sui nodi vji−1 e vji . I nodi vj0 e vjp sono detti estremi del
cammino P . Un cammino è detto semplice se gli archi e i nodi che lo definiscono sono tutti
distinti.
v2
e2
v2
v3
e3
v3
e5
v1
e2
v4
e1
e3
v1
v5
e5
v5
b)
a)
Figura 13.4: Cammini semplici
In figura 13.4a è mostrato un cammino semplice del grafo non orientato di figura 13.1,
P = {v5 , e3 , v1 , e1 , v2 , e2 , v3 , e5 , v4 }, mentre in figura 13.4b è mostrato il cammino semplice
del grafo orientato di figura 13.3, P = {v5 , e5 , v1 , e2 , v2 , e3 , v3 }. In figura 13.5a è mostrato il
cammino (non semplice) del grafo non orientato di figura 13.1, P = {v1 , e1 , v2 , e2 , v3 , e5 , v4 ,
e6 , v5 , e4 , v3 , e5 , v4 }. Notiamo che se in un grafo esiste un cammino fra i nodi u e v, esisterà un
cammino semplice fra u e v.
1
Spesso, quando non c’è possibilità di ambiguità, un cammino viene indicato indicando la sequenza dei soli
nodi o quella dei soli archi
181
In un grafo orientato, chiameremo cammino orientato un cammino P = {vj0 , eh1 , vj1 , . . . , ehp , vjp }
tale che ehi = (vji−1 , vji ). Nel cammino orientato è dunque importante anche l’orientamento
degli archi. In figura 13.5b è mostrato il cammino orientato del grafo orientato di figura 13.3,
P = {v1 , e1 , v2 , e3 , v3 , e4 , v5 }. Se u e v sono, rispettivamente, il primo e l’ultimo nodo di un
cammino orientato P , si dirà che P va da u a v.2
v2
v3
e2
v2
v3
e5
v3
e5
e1
e3
e4
v4
v4
e4
e1
e6
v5
v1
v5
v1
a)
b)
Figura 13.5: a) Cammino (non semplice)
b) Cammino orientato
Un cammino è detto chiuso se i suoi estremi coincidono. Definiremo ciclo un cammino chiuso
C = {vj0 , eh1 , vj1 , . . . , vhp−1 , vhp−1 , ehp , vj0 }, tale che {vj0 , eh1 , vj1 , . . . , ehp−1 , vhp−1 } è un cammino
semplice. Il cammino chiuso P = {v1 , e1 , v2 , e2 , v3 , e3 , v4 , e4 , v2 , e5 , v5 , e6 , v1 } di figura 13.6a non
è un ciclo perchè il cammino P = {v1 , e1 , v2 , e2 , v3 , e3 , v4 , e4 , v2 , e5 , v5 } non è semplice (il nodo
v2 è contenuto due volte). In figura 13.6b è mostrato un ciclo. Notiamo che ancora una volta
l’orientamento degli archi nei grafi orientati è indifferente. Per i grafi orientati si definisce
ciclo orientato un camino orientato chiuso C = {vj0 , eh1 , vj1 , . . . , ehp−1 , vhp−1 , ehp , vj0 }, tale che
{vj0 , eh1 , vj1 , . . . , ehp−1 , vhp−1 } è un cammino orientato semplice (Fig. 13.6c)
e6
v1
v5
e5
e1
e4
v2
v4
e2
e3
v3
a)
b)
Figura 13.6: a) Cammino chiuso b) Ciclo
2
c)
c) Ciclo orientato
Spesso, quando si tratta di grafi orientati e non ci sia possibilità di ambiguità, si indica col nome di cammino
quello che più propriamente dovrebbe essere chiamato cammino orientato
182
Alberi. Dato un grafo G = (V, E) (orientato o non orientato), un nodo v ∈ V si dice connesso
a un nodo u ∈ V se esiste un cammino (non necessariamente orientato) tra v e u. Un grafo
(orientato o non orientato) è detto aciclico se non contiene cicli (non necessariamente orientati)
come sottografi. Si dice albero un grafo aciclico e connesso. Ogni grafo aciclico è l’unione di
uno o più alberi e viene detto foresta. In figura 13.7a è mostrato un albero, in figura 13.7b una
foresta.
v1
v1
v6
v2
v3
v2
v3
v5
v4
v5
v6
v4
v7
a)
b)
Figura 13.7: a) Albero
b) Foresta
Grafi bipartiti Un grafo G = (V, E) non orientato è detto bipartito se è possibile trovare una
partizione V1 , V2 dei suoi nodi 3 tale che gli estremi di ogni arco appartengono uno a V1 e uno
a V2 . Nella figura 13.8 è riportato un esempio di grafo bipartito.
Figura 13.8: Grafo bipartito
Spesso un grafo bipartito viene indicato, mettendo in evidenza la partizione dell’insieme dei
nodi, come G = (V1 , V2 , E).
3
Deve risultare, cioè, V1 ∪ V2 = V e V1 ∩ V2 = ∅
183
13.2
Rappresentazioni di un grafo
Un grafo G(V,E) può essere rappresentato in molti modi diversi. Nelle pagine precedenti abbiamo gia incontrato due modi diversi: la rappresentazione estensiva e quella grafica.
Nella rappresentazione estensiva vengono elencati tutti gli elementi dell’insieme V e tutti
quelli dell’insieme E, nella rappresentazione grafica, invece, il grafo viene rappresentato mediante un disegno in cui ai nodi si fanno corrispondere piccoli cerchi e agli archi tratti di curva congiungenti i cerchi. Già da questi due esempi si capisce che, benché concettualmente equivalenti,
questi modi diversi di rappresentare un grafo possano avere caratteristiche molto differenti. Per
esempio, la rappresentazione grafica è molto immediata e ci dà subito una visione intuitiva delle
caratteristiche del grafo, e molta della terminologia introdotta finora è ispirata proprio dalla
rappresentazione grafica. Tuttavia, se, come spesso accade nella pratica, il grafo ha moltissimi
nodi (per esempio migliaia) si capisce subito che la rappresentazione grafica non è più di pratica
utilità.
Allora è utile avere a disposizione diversi modi di rappresentare un grafo. La decisione di
scegliere una rappresentazione piuttosto che un’altra andrà poi fatta di volta in volta in base al
problema che si vuole risolvere, alle dimensioni del grafo, alle sue caratteristiche etc.
Nel seguito consideriamo la rappresentazione di un grafo tramite la matrice di incidenza. Tale
rappresentazione è preferibile in alcune applicazioni della Ricerca Operativa per la sua corrispondenza ad alcune formulazioni standard di modelli di ottimizzazione e la conseguente maggior
facilità di analisi del modello. La matrice di incidenza è una matrice n × m. La matrice ha
quindi un numero di righe pari al numero di nodi e un numero di colonne pari al numero di
archi.
Nel caso di grafi non orientati, il generico elemento ai,j della matrice sarà
½
aij =
1 se arco j incide su nodo i
0 altrimenti
Nel caso di grafi orientati, il generico elemento ai,j della matrice sarà pari a −1 se l’arco
j-esimo esce dal nodo i, sarà pari a 1 se l’arco j-esimo entra nel nodo i, sarà pari a 0 se l’arco
j-esimo non incide sul nodo i, ovvero

 −1
se arco j esce dal nodo i
1
se
arco j entra nel nodo i

0
altrimenti
Nella matrice di incidenza ogni colonna ha esattamente due elementi diversi da zero; essi
sono in corrispondenza delle due righe della matrice relative ai due nodi estremi dell’arco.
aij =
Osservazione 13.2.1 La matrice di incidenza di un grafo orientato è totalmente unimodulare.
Infatti la condizione del Teorema 12.4.6 è soddisfatta ponendo tutti gli indici di riga in uno dei
due insiemi (ad es. Q1 = {1, . . . , n}, Q2 = ∅).
Esercizio 13.2.2 Dato il grafo G mostrato in Figura 13.9, scrivere la corrispondente matrice
d’incidenza nodi-archi.
Soluzione.
184
4
2
5
7
1
6
3
Figura 13.9: Esercizio 13.2.2
Per scrivere la matrice d’incidenza nodi-archi, dobbiamo innanzitutto numerare arbitrariamente
gli archi. In particolare, scegliamo e1 = (1, 2), e2 = (1, 3), e3 = (2, 4), e4 = (2, 5), e5 = (3, 2),
e6 = (3, 5), e7 = (3, 6), e8 = (4, 5), e9 = (5, 6), e10 = (5, 7), e11 = (6, 2), e12 = (7, 6), la
corrispondente matrice d’incidenza sarà:
1
2
3
4
5
6
7
 e1











13.3
-1
1
0
0
0
0
0
e2
-1
0
1
0
0
0
0
e3
0
-1
0
1
0
0
0
e4
0
-1
0
0
1
0
0
e5
0
1
-1
0
0
0
0
e6
0
0
-1
0
1
0
0
e7
0
0
-1
0
0
1
0
e8
0
0
0
-1
1
0
0
e9
0
0
0
0
-1
1
0
e10
0
0
0
0
-1
0
1
e11
0
1
0
0
0
-1
0
e12
0

0 

0 

0 

0 


1 
-1
Alcuni esempi di problemi su grafo
In questa ultima sezione verranno formulati alcuni problemi utilizzando il formalismo dei grafi.
Scopo di questi esempi non è quello di dare una panoramica completa di quei problemi la cui
formulazione (e risoluzione) è basata sui grafi (non sarebbe sufficiente un intero corso dedicato a questo tema!). Piuttosto vogliamo mostrare come problemi molto diversi tra loro possano essere formulati (e risolti) usando una rappresentazione basata sui grafi, che spesso contribuisce a rendere chiari problemi apparentemente molto intricati, dando cosı̀, inoltre, una prova
dell’importanza della scelta di un buon modello nella risoluzione di un problema e della necessità
di disporre di un ampio spettro di modelli per poter adeguatamente modellare problemi pratici.
185
13.3.1
Modelli di distribuzione di flusso a costo minimo
Modelli di distribuzione di flusso a costo minimo nascono naturalmente quando si voglia determinare il modo più economico di trasportare merci da alcune origini a delle destinazioni
attraverso una rete fisica.
Per formulare questo problema consideriamo una rete orientata G = (V, E) con associato ad
ogni arco (i, j) ∈ E un costo cij (negativo, positivo o nullo), una capacità uij ≥ 0 ed un limite
inferiore lij , con 0 ≤ lij ≤ uij . Supponiamo inoltre che a ciascun nodo i di V sia associato un
numero intero b(i), con la convenzione che:
- b(i) > 0 indica la presenza di offerta (il nodo i viene detto origine);
- b(i) < 0 indica la presenza di domanda (il nodo i viene detto destinazione);
- b(i) = 0 indica l’assenza di offerta e di domanda (il nodo i viene detto di trasferimento).
Nel seguito supporremo valida la seguente ipotesi:
Ipotesi di ammissibilità. L’offerta totale uguaglia la domanda totale; ovvero, formalmente:
X
b(i) = 0.
(13.1)
i∈V
Definizione 13.3.1 Un flusso ammissibile in una rete G è un vettore non negativo x ∈ IR|E|
che soddisfa i seguenti vincoli:
– vincoli di capacità: per ogni arco (ij) ∈ E:
lij ≤ xij ≤ uij .
– vincoli di bilanciamento della massa: per ogni nodo k ∈ V
X
(jk)∈ω − (k)
X
xjk −
xki = b(k).
(ki)∈ω + (k)
Il costo di un flusso è definito come la somma
X
cij xij .
(ij)∈E
Il problema del flusso a costo minimo, si può enunciare come segue:
trovare una distribuzione ammissibile di flusso sulla rete G tale in modo da minimizzare il costo
totale.
Se si indica con AG la matrice d’incidenza della rete, con b = (b(1), . . . , b(n))T il vettore
m
della domanda/offerta, con c ∈ IRm il vettore dei costi e con l ∈ IRm
+ ed u ∈ IR+ i vettori le cui
componenti rappresentano il limite inferiore e la capacità dell’arco corrispondente, il problema
di flusso a costo minimo può essere scritto nel seguente modo:
min cT x
AG x = b
l≤x≤u
186
(PC )
Nel caso di rete non capacitata, cioè quando si abbia lij = 0 e uij = ∞, allora il problema di
flusso a costo minimo si scrive:
min cT x
AG x = b
x≥0
(Q).
In questo caso il problema è anche noto in letteratura come problema di trasferimento (transhipment problem).
Osservazione 1 Questa formulazione richiede n vincoli di bilanciamento ed m vincoli di non
negatività. In realtà però, sommando i vincoli di bilanciamento si ottiene:
n
X
X
akj xij =
k=1 (ij)∈E
n
X
b(k).
k=1
Pn
In effetti, poiché per ipotesi si ha k=1 b(k) = 0, e inoltre la somma delle righe della matrice
d’incidenza è uguale alla riga nulla (vedi Teorema ??), si ottiene l’identità 0 = 0. Quindi, in
realtà un’equazione dei vincoli di bilanciamento si può ottenere come combinazione lineare delle
altre ed è quindi ridondante.
Osservazione 2 L’ipotesi di ammissibilità consente di assicurare l’esistenza di una soluzione
ammissibile per il problema di trasferimento (P̃ ). Si ha infatti, il seguente teorema:
Teorema 13.3.2 (Ipotesi di ammissibilità) Condizione necessaria e sufficiente per l’esistenza
di una soluzione ammissibile per problema di trasferimento (Q) è cha valga (13.1).
Teorema 13.3.3 (Proprietà di interezza) Dato un problema di flusso a costo minimo che
soddisfa l’ipotesi di ammissibilità, se i vettori l, u e b sono interi non negativi, se il problema
ha una soluzione ottima, allora ha una soluzione intera dello stesso valore.
Grazie a quest’ultima proprietà, è possibile costruire algoritmi polinomiali che consentano di
trascurare eventuali vincoli di interezza sulle variabili, riducendo cosı̀ un problema di ottimizzazione combinatoria in un problema di ottimizzazione continua.
Alcuni problemi classici di ottimizzazione su reti possono essere formulati come problemi di
flusso a costo minimo.
Nei prossimi paragrafi analizzeremo alcuni modelli su reti che sono una particolarizzazione
dei modelli di flusso a costo minimo.
Esempio 13.3.4 (Modello di flusso a costo minimo) Una unità portarei navale deve compiere una missione di tre giorni in oceano. Sono noti i seguenti fabbrisogni giornalieri di aerei
necessari per portare a termine la missione:
Aerei
1o giorno
40
2o giorno
70
È noto inoltre che
187
3o giorno
60
- non sono possibili rifornimenti in oceano;
- non si può usare un aereo dopo una giornata di missione se non dopo una revisione;
- le revisioni possono essere fatte di giorno o di notte con costi diversi; in particolare, revisionare
di giorno costa £8, revisionare di notte costa £15;
- un aereo nuovo costa £20;
- le squadre di revisione sono in grado di revisionare quanti aerei si desidera.
Formulare il problema di PL per decidere quanti aerei nuovi imbarcare e quanti aerei (e quando)
revisionare per portare a termine la missione a costo minimo.
Analisi del problema
Si tratta di un problema di flusso a costo minimo su reti spazio-temporali.
Formulazione
Per determinare quali sono le variabili di decisione si devono individuare le possibilità di acquisto
e/o di revisione nei tre giorni di missione. Distinguiamo i seguenti intervalli temporali:
T1 : primo giorno; si possono utilizzare solo aerei nuovi. Indichiamo questa quantità con x100 .
T2 : notte tra il primo ed il secondo giorno; si possono revisionare gli aerei usati il primo giorno;
T3 : il secondo giorno; si possono utilizzare aerei nuovi ed aerei revisionati nel periodo T2 . Indichiamo rispettivamente con x200 e x212 queste quantità.
Si possono inoltre revisionare aerei usati il primo giorno.
T4 : notte tra il secondo ed il terzo giorno; si possono revisionare aerei usati il primo o il secondo
giorno.
T5 : terzo giorno; si possono utilizzare aerei nuovi oppure aerei utilizzati il primo giorno e revisionati nel periodo T2 , T3 o T4 oppure aerei utilizzati il secondo giorno e revisionati nel
periodo T4 . Indichiamo queste quantità rispettivamente con x300 , x312 , x313 , x314 , x324 .
– Variabili. Le variabili di decisione sono quindi le quantità di aerei utilizzati, cioè:
xkij
dove l’apice k = 1, 2, 3 indica il giorno. I pedici ij indicano rispettivamente il giorno in cui gli
aerei sono stati usati ed il periodo in cui sono stati revisionati. Osserviamo che non ha alcun
senso revisionare aerei usati il secondo giorno nel periodo T5 perché non potrebbero essere mai
utilizzati. L’indice i vale 1, 2, l’indice j vale 2, 3, 4 (con riferimento all’intervallo temporale Tj .)
Questa situazione è schematizzata nella seguente tabella:
nuovi
revisionati
T2
T3
T4
1o giorno
x100
-
– Vincoli. Per quanto riguarda i vincoli abbiamo:
188
2o giorno
x200
x212
-
3o giorno
x300
x312
x313
3
x14 x324
• vincoli di non negatività: si tratta di quantità di aerei utilizzati, quindi:
xkij ≥ 0
∀k, i, j
• vincoli di interezza: si tratta di quantità indivisibili
xkij ∈ Z;
• vincoli di domanda: sono noti i fabbisogni giornalieri di aerei. Il primo giorno dobbiamo
avere 40 aerei, quindi :
x100 = 40.
Il secondo giorno gli aerei utilizzati devono essere pari a:
x200 + x212 = 70.
Analogamente per il terzo giorno
x300 + x312 + x313 + x314 + x324 = 60
• vincoli di continuità: la quantità di aerei revisionati nel periodo Tj non può superare la
quantità di aerei disponibile in quel periodo:
x212 + x312 + x313 + x314 ≤ x100
x324 ≤ 70.
Inoltre la quantità totale di aerei usata non può superare la quantità totale di aerei che è
stata acquistata; supponendo che gli aerei usati vadano ad un deposito finale, si ha che il
primo giorno vengono mandati al deposito finale gli aerei usati che non sono più revisionati,
cioè:
x100 − (x212 + x312 + x313 + x314 )
analogamente il secondo giorno:
70 − x324
ed il terzo giorno tutti gli aerei usati vanno al deposito, cioè 60.
La quantità di aerei nuovi è pari a x100 +x200 +x300 , quindi complessivamente dovremo avere:
x100 + x200 + x300 = 40 − x212 − x312 − x313 − x314 + 70 − x324 + 60,
cioè
x200 + x300 + x212 + x312 + x313 + x314 + x324 = 130
189
(13.2)
– Funzione obiettivo. La funzione obiettivo è il costo totale dovuto all’acquisto e alla revisione
dergli aerei. Gli aerei nuovi costano £20 e corrispondono ai valori di i = j = 0, quindi il costo
totale di acquisto è
20
3
X
xk00 = 20(x300 + x200 + x300 ).
k=1
Gli aerei revisionati di giorno (corrispondono al periodo T3 ) costano £8, quindi:
8
X
xki3 = 8x313
k,i
Gli aerei revisionati di notte (corrispondono ai periodi T2 , T4 ) costano £15 quindi:
15
X X
xkij = 15(x212 + x312 ) + 15(x314 + x324 ).
k,i j=2,4
Complessivamente, il problema si scrive:

minx 20(x300 + x200 + x300 ) + 8x313 + 15(x212 + x312 + x314 + x324 )




x100 = 40



 x2 + x2 = 70


00
12


3
3
3
3
3


 x00 + x12 + x13 + x14 + x24 = 60
x2 + x3 + x3 + x3 ≤ x1
12
12
13
14
00

3 ≤ 70


x

24



x200 + x300 + x212 + x312 + x313 + x314 + x324 = 130





xkij ≥ 0
∀ k, i, j


 k
xij ∈ Z
Vediamo come questo problema può essere interpretato come un modello di flusso a costo
minimo. Si tratta di definire una rete in cui archi e/o nodi corrispondono ad aerei usati e/o
revisionati in intervalli di tempo diversi. Costruiamo una rete orientata in questo modo: introduciamo un nodo sorgente s che rappresenta lo stato iniziale, ovvero il deposito da cui si
possono acquistare arei nuovi. Siano 1, 2, 3 tre nodi che rappresentano l’inizio rispettivamente
del primo, secondo e terzo giorno. Avremo gli archi (s, 1), (s, 2), (s, 3) con un flusso su di essi che
rappresenta il numero di aerei nuovi acquistati il primo, secondo e terzo giorno. Introduciamo
anche un nodo pozzo t che rappresenta lo stato finale, ovvero il deposito degli aerei usati. Siano
10 , 20 , 30 tre nodi che rappresentano la fine rispettivamente del primo, secondo e terzo giorno.
Avremo gli archi (10 , t), (20 , t), (30 , t) con un flusso su di essi che rappresenta il numero di aerei
usati il primo, secondo e terzo giorno e che non sono più revisionati. Inoltre ci saranno gli archi
(1, 10 ), (2, 20 ), (3, 30 ) con un flusso su di essi che rappresenta il numero di aerei utilizzati durante
il primo, secondo, terzo giorno. Ovviamente questo flusso è fissato e noto (sono i fabbrisogni
giornalieri). Introduciamo poi altri tre nodi 4, 5, 6 che corrispondono agli intervalli di tempo
T2 , T3 , T4 , cioè esiste l’arco (i0 , j) con i0 = 10 , 20 , 30 e j = 4, 5, 6 se è possibile revisionare gli aerei
usati nel giorno i durante l’intervallo di tempo corrispondente a j. In particolare avremo gli
archi:
 0
(1 , 4)


 0
aerei
(1 , 5) aerei
0

 (1 , 6) aerei

(20 , 6) aerei
usati
usati
usati
usati
il
il
il
il
1◦
1◦
1◦
2◦
190
giorno
giorno
giorno
giorno
revisionati
revisionati
revisionati
revisionati
T2
T3
T4
T4
Non ci sono archi di questo tipo uscenti da 30 . Ci sono anche archi del tipo (j, i) con j = 4, 5, 6
e i = 1, 2, 3 se è possibile utilizzare aerei revisionati nel periodo corrispondente a j il giorno i.
In particolare avremo gli archi:

(4, 2)


 (4, 3)
aerei
aerei

(5,
3)
aerei


(6, 3) aerei
revisionati
revisionati
revisionati
revisionati
T2
T2
T3
T4
usati
usati
usati
usati
il
il
il
il
2◦
3◦
3◦
3◦
giorno
giorno
giorno
giorno
Non ci sono archi di questo tipo entranti in 1. Complessivamente la rete è riportata in Figura
13.10
1
40
1'
4
S
2
70
T
2'
5
3
60
3'
6
Figura 13.10: Rete relativa all’Esercizio 13.3.4
Osservazione Notiamo che si tratta di determinare il flusso a costo minimo su una rete
(non capacitata) con alcuni valori di flusso assegnati. Il nodo s è il nodo origine con b(s) =
−(x100 + x200 + x300 ) < 0. Il nodo t è il nodo destinazione con b(t) > 0. tutti gli altri nodi sono di
trasferimento con b(i) = 0. Il vincolo (13.2) corrisponde all’ipotesi di ammissibilità. Mentre gli
altri vincoli di continuità sono i vincoli di conservazione ai nodi di trasferimento 10 e 20 . I vincoli
di domanda sono i vincoli di conservazione negli altri nodi di trasferimento.
Validazione del modello
Si può osservare che si possono eliminare alcuni archi dalla rete del modello e quindi alcune
variabili. In particolare, si può eliminare l’arco (4, 3) perché non conviene revisionare di notte
aerei che potrebbero essere revisionati il giorno successivo (non ci sono limitazioni sul numero
di aerei che si possono revisionare). Inoltre si può eliminare l’arco (10 , t) perché il primo giorno
conviene revisionare quanti più aerei possibile piuttosto che comperarne di nuovi. Con lo stesso
ragionamento si può eliminare l’arco (s, 3) cioè non comperare aerei nuovi il terzo giorno, ma
usare solo aerei revisionati, poiché la quantità di aerei necessaria è inferiore al numero di aerei
usati il secondo giorno. Questo corrisponde ad eliminare le variabili x300 , x312 . Quindi, il vincolo
(13.2) diventa:
x200 + x100 = 70 − x324 + 60
191
Con queste considerazioni si ottiene il seguente modello:

min 20(x200 + x100 ) + 8x313 + 15(x212 + x314 + x324 )





x100 = 40




x200 + x212 = 70



 x3 + x3 + x3 = 60
13
14
24

x212 + x313 + x314 = 40




x324 ≤ 70





x200 + x324 = 90


 xk ≥ 0
∀ k, i, j
ij
Modelli di trasporto. Il problema di trasporto definito nel paragrafo 3.3.2, può essere formulato come problema di flusso a costo minimo su una rete non capacitata in cui non ci sono nodi di
trasferimento. Infatti, possiamo associare a questo problema un grafo bipartito G = (X, Y, E);
l’insieme X rappresenta i nodi origini ed i nodi di Y sono i nodi destinazione. L’insieme dei nodi
è V = X ∪ Y (|V | = n + m). Esiste un arco per ogni coppia ij con i ∈ X e j ∈ Y (|E| = nm).
A ciascun arco (ij) è associato un costo. Per ogni (i, j) ∈ E, lij = 0 e uij = ∞. Infine, per ogni
nodo i ∈ X, si pone b(i) = ai , mentre per ogni nodo i ∈ Y , si pone b(i) = −bj .
L’ipotesi (3.10) corrisponde all’ipotesi di ammissibilità. Una rete corrispondente a un problema di trasporto viene detta rete di trasporto.
Il problema di trasporto, come caso particolare del problema di flusso a costo minimo, gode
ancora della proprietà espressa dal Teorema di interezza. Quindi, se nel problema dei trasporti
ai , i = 1, . . . , m e bj , j = 1, . . . , n sono interi e se il problema ammette soluzione ottima, allora
ha una soluzione ottima intera.
Modelli di assegnamento I problemi di assegnamento sono un caso particolare del problema
di trasporti in cui si ha lo stesso numero di origini e di destinazioni. Un generico problema di
assegnamento consiste nel determinare il modo ottimale di assegnare lavori a persone o, più in
generale, di assegnare mezzi (persone, macchine, etc. ) ad attività.
Supponiamo che n persone P1 ,. . . ,Pn , debbano svolgere n lavori L1 ,. . . , Ln ; ciascun lavoro
deve essere svolto esattamente da una persona e ciascuna persona deve svolgere un lavoro.
Naturalmente le persone hanno diversi livelli di esperienza, competenza ed abilità e quindi si
può introdurre un costo dell’assegnamento della persona i al lavoro j; indichiamo tale costo con
cij e supponiamo che sia noto. Questo costo può, ad esempio, essere interpretato come tempo
medio impiegato dalla persona i ad eseguire il lavoro j.
Il problema consiste, quindi, nell’assegnare i lavori alle persone minimizzando il costo totale
di realizzazione di tutti i lavori.
Questo tipo di problemi sorge in molte situazioni pratiche: esempi tipici sono i problemi
di assegnamento del personale all’interno di una azienda e i problemi di assegnare determinati
mezzi di trasporto ad alcune particolari linee. Esempi di questo tipo verranno esaminati in
dettaglio nel seguito.
Se indichiamo con X l’insieme delle persone (|X| = n), con Y l’insieme dei lavori (|Y | = n)
e con E l’insieme degli assegnamenti possibili, cioè delle possibili coppie (ij) con i ∈ X e j ∈ Y,
192
allora il problema di assegnamento è un problema di flusso a costo minimo su una rete di
trasporto rappresentata da un grafo bipartito con V = X ∪ Y e b(i) = 1 per ogni i ∈ X e
b(j) = −1 per ogni j ∈ Y. Inoltre per ogni (ij) si ha lij = 0 e uij = 1.
Esempio 13.3.5 Assegnazione delle aule. In una facoltà universitaria vi sono nello stesso
orario n corsi e m aule disponibili. Per ragioni di capienza delle aule e di attrezzature disponibili,
ogni corso può essere tenuto solo in alcune delle aule. Il problema è quello di stabilire quale è il
numero massimo di corsi che è possibile tenere nell’orario considerato.
Il problema può essere scritto come problema su grafi nel seguente modo: sia G(V, E) un grafo
bipartito in cui l’insieme di nodi V = V1 ∪ V2 in cui l’insieme V1 corrisponde ai corsi, l’insieme di
nodi V2 corrisponde alle aule ed esiste un arco fra due nodi i e j (con i appartenente ad V1 e j
appartenente a V2 ) se (e solo se) il corso i può essere tenuto nell’aula j. Il problema di stabilire
qual è il numero massimo di corsi che è possibile tenere nell’orario considerato può ora essere
formulato come il problema di scegliere sul grafo il massimo numero di archi (corrispondenti ad
assegnazioni di corsi ad aule) tali che due archi scelti non siano mai adiacenti. Infatti se due archi
fossero adiacenti in un nodo dell’insieme V1 , allora vorrebbe dire che uno stesso corso si tiene
contemporaneamente in due aule diverse. Se due archi fossero adiacenti in un nodo dell’insieme
V2 , allora vorrebbe dire che in una stessa aula si tengono contemporaneamente due corsi. In
entrambi i casi le assegnazioni di aule non sono ovviamente ammissibili. Questo problema è
detto di accoppiamento bipartito.
Esempio 13.3.6 In un Dipartimento universitario, sono attivati cinque corsi diversi che possono essere tenuti da cinque professori. Ogni professore esprime delle preferenze sul corso che
vorrebbe tenere, indicando un punteggio. A preferenza più alta corrisponde un punteggio più
alto. I punteggi sono riportati nella seguente tabella:
insegnante1
insegnante2
insegnante3
insegnante4
insegnante5
corso1
7
7
4
5
4
corso2
5
9
6
4
5
corso3
4
7
5
5
5
corso4
4
9
8
7
8
corso5
5
4
5
4
9
Si vuole assegnare ciascun professore ad un corso cercando di massimizzare il valore medio inteso
come media delle preferenze.
Analisi Si tratta di un problema di assegnamento in cui i lavori sono i corsi. Indichiamo con
cij il punteggio assegnato dal professore i al corso j.
Formulazione
– Variabili. Le variabili di decisione sono le variabili booleane:
½
xij =
1 se l’insegnante i è assegnata al corso j
0 altrimenti.
i, j = 1, . . . , 5.
– Funzione obiettivo. Indicando con cij il punteggio assegnato dall’insegnante i alla corso j, la
funzione obiettivo è il valore medio delle preferenze:
193
5 X
5
1X
cij xij .
5 i=1 j=1
– Vincoli. I vincoli di assegnamento sono:
x11 + x12 + x13 + x14 + x15
x21 + x22 + x23 + x24 + x25
x31 + x32 + x33 + x34 + x35
x41 + x42 + x43 + x44 + x45
x51 + x52 + x53 + x54 + x55
x11 + x21 + x31 + x41 + x51
x12 + x22 + x32 + x42 + x52
x13 + x23 + x33 + x43 + x53
x14 + x24 + x34 + x44 + x54
x15 + x25 + x35 + x45 + x55
=1
=1
=1
=1
=1
=1
=1
=1
=1
=1
Quindi, complessivamente il problema si scrive:

P
P

min 5i=1 5j=1 cij xij




x11 + x12 + x13 + x14 + x15





x
21 + x22 + x23 + x24 + x25




x31 + x32 + x33 + x34 + x35





x41 + x42 + x43 + x44 + x45



x51 + x52 + x53 + x54 + x55

x11 + x21 + x31 + x41 + x51




x12 + x22 + x32 + x42 + x52






 x13 + x23 + x33 + x43 + x53



 x14 + x24 + x34 + x44 + x54



x15 + x25 + x35 + x45 + x55



xij ≥ 0
=1
=1
=1
=1
=1
=1
=1
=1
=1
=1
Colorazione di una carta geografica. Il problema è quello di stabilire il numero minimo di
colori necessario per colorare una carta geografica, assegnando colori alle varie nazioni rappresentate sulla carta, in modo che due nazioni adiacenti (che quindi abbiano un tratto di frontiera
in comune) siano sempre colorate in modo diverso. Si suppone che ogni nazione sia formata da
una unica regione connessa e che nazioni adiacenti abbiano una linea di confine in comune di
lunghezza maggiore di zero (e non quindi solo un singolo punto in comune). Assegnando ad ogni
nazione un nodo di un grafo e collegando due nodi se e solo se le due nazioni corrispondenti sono
adiacenti, si ottiene un grafo (che viene detto planare).
La famosa “congettura dei quattro colori”, ormai da chiamare “teorema dei quattro colori”,
afferma che ogni carta geografica è colorabile utilizzando al più quattro colori. Questa congettura
era già nota nel 1840. Nel corso di oltre un secolo sono state fornite dimostrazioni per molti casi
particolari del problema (oltre a molte dimostrazioni della congettura, poi rivelatesi sbagliate o
194
valide per particolari classi di grafi). Solo nel 1976 la congettura è stata dimostrata in tutta la
sua generalità usando gli strumenti della teoria dei grafi.
Attraversamento di un fiume Su di una riva di un fiume vi è un pastore con un cane lupo,
un agnello e un cesto di cavoli. Per attraversare il fiume il pastore dispone di una piccola barca
che permette di trasportare, oltre al pastore, un solo altro passeggero (il cane lupo, l’agnello o il
cesto di cavoli). Se su di una riva restano soli il cane lupo e l’agnello, il cane lupo puo uccidere
l’agnello. Se restano soli l’agnello e il cesto di cavoli, l’agnello puo mangiare i cavoli. Il problema
è quello di stabilire se è possibile trasferire tutto sull’altra riva del fiume senza mai lasciare soli
cane lupo e agnello o agnello e cesto di cavoli.
Il problema puo essere facilmente formulato come problema di esistenza di un cammino su
di un opportuno grafo.
Sia dato il grafo G = (V, E) dove i nodi corrispondono a tutti i possibili stati ammissibili del
sistema pastore-lupo-agnello-cavoli. I possibili stati ammissibili del sistema sono i seguenti:
PLAC pastore, lupo,agnello e cavoli sulla riva di partenza nessuno sulla riva di arrivo
PLC pastore, lupo e cavoli sulla riva di partenza agnello sulla riva di arrivo
PAC pastore, agnello e cavoli sulla riva di partenza lupo sulla riva di arrivo
PLA pastore,lupo e agnello sulla riva di partenza cavoli sulla riva di arrivo
PA pastore e agnello sulla riva di partenza lupo e cavoli sulla riva di arrivo
LC lupo e cavoli sulla riva di partenza pastore e agnello sulla riva di arrivo
A agnello sulla riva di partenza pastore lupo,e cavoli sulla riva di arrivo
L lupo sulla riva di partenza pastore,agnello e cavoli sulla riva di arrivo
C cavoli sulla riva di partenza pastore,lupo e agnello sulla riva di arrivo
∅ nessuno sulla riva di partenza pastore,lupo,agnello e cavoli sulla riva di arrivo
Altri stati del sistema non sono ammissibili; per esempio non è ammissibile lo stato PL in quanto
lascerebbe agnello e cavoli soli sulla riva di arrivo.
Nel grafo G esiste un arco tra due nodi se è possibile passare da uno all’altro dei due stati
corrispondenti con un solo viaggio in barca. Il grafo associato al problema viene riportato in
figura 13.11.
Si noti che in questo caso il grafo è simmetrico in quanto, se è possibile passare dal nodo A al
nodo B, allora è anche possibile passare da B a A; per semplicità quindi il grafo viene riportato
come grafo non orientato.
L’esistenza di una soluzione equivale all’esistenza di un cammino tra il nodo PLAC e il nodo
∅. Il numero minimo di viaggi necessario per compiere l’operazione è pari a 7 e corrisponde al
cammino con il minimo numero di archi tra il nodo PLAC e il nodo ∅. Si noti che esistono due
possibili cammini semplici tra i due nodi, entrambi con 7 archi.
195
LC
PLAC
PLC
L
C
PLA
PAC
A
PA
Ø
Figura 13.11: Esistenza tra un cammino tra due nodi
13.4
Il problema del cammino minimo
13.4.1
Definizione del problema
Dato un grafo orientato G = (V, E), associamo a ciascun arco e = (u, v) ∈ E un numero reale
le , detto peso dell’arco. Per ogni cammino orientato P = {v1 , e1 , . . . , ep , vp }, denotiamo con
l(P ) il peso di P , ossia la somma dei pesi degli archi di P . Il problema del cammino minimo
può essere enunciato nel modo seguente:
dati due nodi s ∈ V e t ∈ V , trovare un cammino orientato P ∗ in G da s a t di peso minimo.
Si osservi che (i) se non esiste un cammino orientato da s a t in G, il problema non ha
soluzioni ammissibili; (ii) se esiste un ciclo orientato in G di peso negativo la soluzione del
problema è illimitata (poiché conterrà tale ciclo ripetuto un numero illimitato di volte).
In Figura 13.12 è mostrato un grafo orientato contenente un ciclo orientato di peso negativo.
I pesi degli archi sono mostrati in figura in prossimità di ciascun arco. Un cammino minimo
conterrà i nodi e gli archi del ciclo un numero illimitato di volte.
1
1
t
2
s
2
2
2
-5
Figura 13.12: Grafo con ciclo di peso negativo
Il problema del cammino minimo dal nodo s al nodo t, può essere formulato come problema
di flusso a costo minimo, fatte le seguenti assunzioni:
196
• la rete sia non-capacitata;
• per ogni nodo i ∈ V − {s, t}, si ponga b(i) = 0;
• si ponga b(s) = 1 e b(t) = −1.
È facile vedere che ogni flusso ammissibile corrisponde a inviare un flusso unitario dal nodo s
al nodo t; utilizzando l’ipotesi di interezza del flusso su ogni arco, un flusso unitario corrisponde
a un cammino diretto da s a t (formato dagli archi il cui flusso corrispondente è uguale a uno).
Dunque, il flusso di costo minimo corrisponderà al cammino di costo minimo da s a t.
È possibile formulare il problema del cammino minimo come problema di Programmazione
Lineare associando una variabile booleana xij con ogni arco (i, j) ∈ E. In particolare un modello
lineare può essere cosı̀ costruito:
– Variabili. Si definiscono le variabili booleane
½
1 se (i, j) ∈ P
0 altrimenti
m
Il vettore x ∈ R si chiama vettore di incidenza del cammino P.
– Funzione obiettivo. La funzione obiettivo è il peso del cammino:
xij =
X
cij xij .
(i,j)∈E
– Vincoli. I vincoli devono imporre che si abbia effettivamente un cammino semplice da s a t,
cioè:
• in ciascun nodo k che non sia s o t incidono esattamente due archi del cammino, uno entrante
e l’altro uscente. Questo si esprime con i vincolo:
X
xik −
(ik)∈ω − (k)
X
xkj = 0
∀k ∈ V − {s, t}
(kj)∈ω + (k)
• dalla sorgente s esce esattamente un arco e nel pozzo t entra esattamente un arco; cioè:
P
P
x − (tj)∈ω+ (t) xtj = 1
−
P(it)∈ω (t) it
P
(is)∈ω − (s) xis
−
(sj)∈ω + (s) xsj
= −1
Se poniamo b = (1 − 1 0 . . . 0)T , e consideramo la matrice di incidenza A della rete G, allora
questi vincoli si possono esprimere in forma matriciale come:
Ax = b.
13.5
Cammini minimi e massimi su grafi aciclici
Una classe di grafi orientati di particolare interesse in campo applicativo è la classe di grafi
aciclici. Per esempio il grafo di attività di un progetto con vincoli di precedenza fra le attività
è aciclico (vedi il capitolo “Tecniche reticolari di programmazione delle attività”). La ricerca
di cammini minimi o massimi su tali grafi è uno strumento di progetto di notevole importanza.
197
Come si vedrà nel seguito, i due problemi di minimo e di massimo sono, in questo caso particolare,
risolti da due algoritmi identici eccetto che per la sostituzione di un massimo a un minimo nella
formula ricorsiva alla base del procedimento. Nel seguito verrà prima considerato il caso di un
problema di cammino minimo. Per poter procedere con la descrizione dell’algoritmo, è necessario
studiare prima una particolare tecnica di numerazione dei nodi di un grafo aciclico.
13.5.1
Numerazione topologica dei nodi di un grafo
Una caratteristica peculiare dei grafi aciclici (sia G = (V, E) il grafo, con|V | = n e |E| = m)
consiste nella possibilità di numerare i nodi del grafo con i numeri 1,2,3,....,n-1,n in modo tale
che:
se esiste un arco dal nodo i al nodo j allora j > i
Tale numerazione viene detta numerazione topologica dei nodi del grafo e non è in generale
unica.
Non tutti i grafi possono essere numerati topologicamente. In effetti l’esistenza di una numerazione topologica dei nodi di un grafo caratterizza esattamente la classe dei grafi aciclici.
Vale infatti il seguente teorema.
Teorema 13.5.1 Un grafo è aciclico se e solo se esiste una numerazione topologica dei suoi
nodi.
Dimostrazione.
Sufficienza. Supponiamo che esista una numerazione topologica dei nodi e facciamo vedere che
l’ esistenza di un ciclo porterebbe ad una contraddizione. Possiamo assumere che i nodi siano
numerati topologicamente, indicheremo l’i-esimo nodo di questa particolare numerazione, come
vi . Se esiste un ciclo (orientato) vuol dire che esiste una successione di nodi (vi , vj , vk , . . . , vr , vs )
tali che
- esistono gli archi (vi , vj ), (vj , vk ), . . ., (vr , vs );
- vi = vs .
Ma allora, da una parte, siccome la numerazione è topologica abbiamo i < j < k < . . . < r < s,
cioè i < s, mentre dall’altra, poiché vi = vs abbiamo i = s. Questa è una contraddizione e cosı̀
il grafo deve essere aciclico.
Necessità. Supponiamo che il grafo sia aciclico e mostriamo che deve esistere almeno una
numerazione topologica. La dimostrazione è costruttiva, faremo cioè vedere che esiste una
numerazione topologica costruendone una.
Come primo passo osserviamo che se il grafo è aciclico, deve esistere almeno un nodo che
non abbia archi entranti. Infatti, se ciò non fosse vero, potremmo ragionare nel modo seguente.
Prendiamo un nodo qualunque, chiamiamolo v1 . Siccome tutti i nodi hanno archi entranti
esiste un nodo predecessore di v1 , indichiamolo con v2 ; notiamo che per come abbiamo scelto v2
esiste l’arco (v2 , v1 ) (attenzione, questa è una numerazione non topologica). Possiamo ripetere
il ragionamento con v2 e trovare un nodo v3 tale che esista l’ arco (v3 , v2 ). Siccome stiamo
supponendo, per assurdo, che tutti gli archi abbiano degli archi entranti, possiamo ripetere il
ragionamento quante volte vogliamo. Notiamo che ogni nodo generato deve essere diverso dai
precedenti, altrimenti avremmo trovato un ciclo, contraddicendo l’aciclicità del grafo. D’altra
198
parte, arrivati a vn i nodi del grafo sono “finiti” e quindi il predecessore di vn che stiamo
supponendo esistente per assurdo, deve per forza essere uno dei nodi già esaminati. Cosı̀ si
viene a formare un ciclo.
Quindi dato un grafo aciclico deve per forza esistere almeno un nodo che non ha archi entranti.
Prendiamo uno di questi nodi e numeriamolo con il numero 1. Eliminiamo dal grafo il nodo 1 e
tutti gli archi uscenti da esso. Il nuovo grafo che otteniamo è ovviamente ancora un grafo aciclico.
Quindi per lo stesso ragionamento fatto prima deve esistere almeno un nodo che non ha archi
entranti. Prendiamo uno di questi nodi e numeriamolo con il numero 2. Notiamo che ovviamente
se consideriamo il grafo originario il nodo 2 può avere archi entranti, ma solo provenienti dal
nodo 1 e quindi la condizione i < j è rispettata. Possiamo ora ripetere il procedimento n volte
(quanti sono i nodi) ed ottenere cosı̀ una numerazione topologica del grafo.
2
Il precedente teorema è importante, anche perché nella dimostrazione della necessità è sostanzialmente dato un algoritmo per numerare topologicamente i nodi di un grafo.
Riesponiamo qui l’algoritmo per chiarezza.
- Siccome il grafo è aciclico, deve esistere almeno un nodo con solo archi uscenti;
- individuiamo uno di questi nodi e attribuiamogli il numero 1;
- cancelliamo il nodo numerato e tutti gli archi adiacenti, nel nuovo grafo ridotto individuiamo
un nodo con soli archi uscenti e attribuiamogli il numero 2, e cosı̀ via fino ad aver numerato
tutti i nodi
La correttezza e validità di questa procedura è stata provata nella dimostrazione della necessità
del Teorema 13.5.1.
Notiamo che se ad un certo punto dell’applicazione della procedura non possiamo procedere,
se succede cioè che ad un determinato passo non riusciamo a trovare un nodo senza archi entranti,
questo vuol dire che il grafo considerato contiene un ciclo.
Quindi la procedura per la numerazione topologica di un grafo può anche essere utilizzata
per determinare se un grafo è aciclico o meno.
Come esempio consideriamo il grafo di figura 13.13.
B
D
A
C
Figura 13.13: Numerazione dei nodi di un grafo
199
Si tratta di decidere se il grafo è aciclico e, in caso, numerare i nodi topologicamente. I vari
passi dell’algoritmo sono riportati qui di seguito
Passo
1
2
3
4
Nodo senza
archi entranti
A
B
C
D
Nodi non ancora
numerati
B,C,D
C,D
D
∅
Numerazione
A=1
B=2
C=3
D=4
Il procedimento è terminato con la numerazione di tutti i nodi. Il grafo è dunque aciclico e la
numerazione trovata è topologica.
Supponiamo ora che nel precedente grafo l’arco (B, D) sia orientato da D a B. Ovviamente
si verrebbe a creare un ciclo. Se proviamo ad applicare la procedura per la determinazione di
una numerazione topologica possiamo iniziare numerando il nodo A come nodo 1. Ma dopo non
possiamo più procedere perché eliminato il nodo A e gli archi da esso uscenti ((A,B) e (A,C))
non è più possibile individuare un nodo che non abbia archi entranti.
13.5.2
Un algoritmo per il cammino minimo su grafi aciclici
La numerazione dei nodi di un grafo aciclico descritta nella sezione precedente consente di
costruire un algoritmo di soluzione per il problema di cammino minimo particolarmente semplice.
Infatti, nella ricerca di un cammino tra una qualsiasi coppia di nodi i e j del grafo, a causa della
numerazione attribuita ai nodi, si può affermare che:
se j < i allora non esistono cammini da i a j;
se j > i allora gli unici nodi che è necessario considerare nella ricerca del cammino da i a j
sono i nodi con indice k tale che i < k < j.
Infatti, se il cammino passasse per un nodo h > j, allora non potrebbe tornare su j, a causa
della mancanza di archi che collegano nodi con indice maggiore a nodi con indice minore; se
passasse per un nodo h < i, allora dovrebbe esistere un cammino da i a h, il che comporterebbe
l’esistenza di archi che collegano nodi con indice maggiore a nodi con indice minore.
Sulla base di queste considerazioni, è possibile impostare un algoritmo per il calcolo dell’albero
dei cammini minimi tra un nodo del grafo (per esempio il nodo 1) e tutti i nodi con indice superiore (per quelli con indice inferiore non esiste sicuramente un cammino; ovviamente, se il
nodo di partenza è quello contrassegnato con l’indice 1, allora si tratta di calcolare l’albero dei
cammini minimi tra il nodo 1 e tutti gli altri). L’algoritmo per il calcolo dell’albero dei cammini
minimi dal nodo 1 a tutti gli altri nodi si basa sul calcolo in sequenza dei cammini minimi dal
nodo 1 al nodo 2, dal nodo 1 al nodo 3, dal nodo 1 al nodo 4, e cosı́ via. Indichiamo con:
- pi,j il peso dell’arco (i, j) che parte dal nodo i e arriva al nodo j;
- ω e (i) l’insieme dei nodi predecessori del nodo i;
- d∗ (i) il valore del cammino minimo dal nodo 1 al nodo i;
200
- J(i) il nodo che precede i su tale cammino (nel caso il cammino minimo non sia unico, allora
se ne sceglie uno qualsiasi fra quelli minimi).
Possiamo allora illustrare l’algoritmo per il calcolo dei percorsi minimi.
- d∗ (1) := 0; J(1) := 1;
- per j = 2, 3, 4, . . . , n − 1, n ripeti la seguente serie di operazioni
d∗ (j) := mini∈ωe (j) {d∗ (i) + pi,j };
J(j) := valore di i per cui si è verificato il minimo;
Si noti che una volta assegnato un peso d∗ (i) a un nodo (cioè un valore del cammino minimo
dal nodo 1 al nodo considerato), tale peso non viene più modificato nel corso dell’algoritmo, ma
indica in modo definitivo il valore del cammino. Questo è dovuto al fatto, già citato, che tutti
i nodi successivi non devono essere considerati per il calcolo del percorso dal nodo 1 al nodo
i. Inoltre dai valori J(i) è possibile ricostruire in modo immediato l’albero (o uno dei possibili
alberi) dei cammini minimi.
La dimostrazione della correttezza della procedura segue immediatamente dal Teorema ??.
Esempio 13.5.2 Come esempio consideriamo il grafo di figura 13.14.
2
3
1
1
1
3
4
1
3
Figura 13.14: Percorso minimo su grafi aciclici
Si tratta di determinare l’albero dei cammini minimi tra il nodo 1 e tutti gli altri nodi. I
vari passi dell’algoritmo, corrispondenti alla successione di nodi visitati, (si osservi che in questo
caso particolare l’indice del passo coincide con l’indice del nodo visitato) portano alla seguente
successione di valori d∗ (i) e J(i)
Passo
1
2
3
4
Valore di d∗ (i)
d∗ (1) = 0
d∗ (2) = 1
d∗ (3) = min{3, 1 + 1} = 2
d∗ (4) = min{1 + 3, 2 + 1} = 3
201
Valore di J(i)
J(1) = 1
J(2) = 1
J(3) = 2
J(4) = 3
2
1
1
1
4
1
3
Figura 13.15: Albero dei cammini minimi
Il corrispondente albero dei cammini minimi è riportato in figura 13.15
Esempio 13.5.3 Sia dato il grafo di Figura 13.16. Determinare l’albero dei cammini minimi,
1
B
3
4
2
A
E
4
5
10
C
F
3
3
2
D
3
2
G
Figura 13.16: Grafo Esercizio 13.5.3
utilizzando l’algoritmo per grafi aciclici.
Soluzione. Si deve prima numerare topologicamente il grafo. I passi sono riportati nella
seguente tabella ed il grafo risultante in Figura 13.17
Passo
1
2
3
4
5
6
7
Nodo senza
archi entranti
A
BoD
B
C
EoG
G
F
Nodi non ancora
numerati
B,C,D,E,F,G
B,C,E,F,G
C,E,F,G
E,F,G
F,G
F
∅
202
Numerazione
A=1
D =2
B=3
C=4
E=5
G=6
F=7
Osserviamo che la numerazione topologica in questo esempio non é unica; infatti ai passi 2 e
5 potevamo scegliere tra due nodi. Applichiamo ora l’algoritmo. I passi sono riportati nella
1
3
3
4
2
1
5
4
5
10
4
7
3
3
2
2
3
2
6
Figura 13.17: Numerazione topologica del grafo di Figura 13.16
seguente tabella
Passo
1
2
3
4
5
4
4
Valore di d∗ (i)
d∗ (1) = 0
d∗ (2) = 3
d∗ (3) = 4
d∗ (4) = min{0 + 2, 3 + 2, 4 + 3} = 2
d∗ (5) = min{4 + 1, 2 + 5} = 5
d∗ (6) = min{3 + 2, 2 + 3} = 5
d∗ (7) = min{2 + 10, 5 + 4, 5 + 3} = 8
Valore di J(i)
J(1) = 1
J(2) = 1
J(3) = 1
J(4) = 1
J(5) = 3
J(6) = 4
J(7) = 6
Il corrispondente albero dei cammini minimi è riportato in figura 13.18.
13.5.3
Un algoritmo per il cammino massimo su grafi aciclici
Se il problema di ottimo è quello della determinazione del cammino di peso massimo sul grafo,
allora è facile convincersi che basta sostituire nella formula ricorsiva al min un max e tutte le
considerazioni fatta continuano, in questo caso particolare di grafi aciclici, a essere valide.
L’algoritmo per il calcolo dei cammini massimi su grafici aciclici è allora il seguente
- f (1) := 0; J(1) := 1;
- per j = 2, 3, 4, . . . , n − 1, n ripeti la seguente serie di operazioni
f (j) := maxi∈ωe (j) {f (i) + pi,j };
J(i) := valore di i per cui si è verificato il massimo;
Come esempio consideriamo sempre il grafo di figura 13.14 Si tratta di determinare l’albero dei
cammini massimi tra il nodo 1 e tutti gli altri nodi. I vari passi dell’algoritmo portano alla
seguente successione di valori f (i) e J(i)
203
4
5
3
5
1
7
4
8
2
2
6
3
5
Figura 13.18: Albero dei cammini minimi
Passo
1
2
3
4
Valore di f (i)
f (1) = 0
f (2) = 1
f (3) = max{3, 1 + 1} = 3
f (4) = max{1 + 3, 3 + 1} = 4
204
Valore di J(i)
J(1) = 1
J(2) = 1
J(3) = 1
J(4) = 2 (oppure J(4) = 3)
Scarica