Fondamenti di Ricerca Operativa

annuncio pubblicitario
Politecnico di Milano
Anno Accademico 2010/2011
Fondamenti di
Ricerca Operativa
Corso del Prof. Edoardo Amaldi
Stefano Invernizzi
Facoltà di Ingegneria dell’Informazione
Corso di Laurea Magistrale in Ingegneria Informatica
Fondamenti di Ricerca Operativa
Capitolo 1: La Ricerca Operativa
Capitolo 1: La Ricerca Operativa
Il concetto di Ricerca Operativa
Definizione
La Ricerca Operativa (in inglese detta Operations Research) è quella branca della matematica applicata nella quale si
utilizzano dei modelli matematici e dei metodi quantitativi avanzati per analizzare e risolvere problemi decisionali
complessi, con lo scopo generale di fornire uno strumento di supporto alla presa di decisioni.
Per brevità, la Ricerca Operativa viene spesso indicata mediante l’acronimo RO.
Problema decisionale
Il termine problema decisionale (o problema di scelta) è utilizzato per indicare un problema che consiste nella scelta
tra diverse alternative ammissibili, sulla base di uno o più criteri.
Esempi di problemi decisionali
Esempio n. 1: assegnamento di task
Come primo esempio di problema decisionale, supponiamo di avere un certo numero di progetti da assegnare ad
altrettanti ingegneri, ciascuno dei quali deve essere assegnatario di uno e un solo progetto. Supponendo che ogni
ingegnere possa svolgere uno qualsiasi tra i progetti dati e indicando con
il tempo che il -esimo ingegnere impiega
per lo svolgimento dell’ -esimo progetto, vogliamo che l’assegnamento dei progetti sia tale da rendere minimo il
tempo totale di esecuzione degli progetti.
Ingegnere
Progetto
2
6
3
8
4
9
5
7
8
Tabella 1: Tabella dei tempi di esecuzione degli m progetti da parte degli m ingegneri (m = 3).
A tale scopo, possiamo innanzitutto osservare che i possibili assegnamenti sono in numero finito, e precisamente sono
. Di conseguenza, è possibile valutare i tempi totali per ciascuna delle soluzioni ammissibili e risolvere il problema
mediante un’analisi esaustiva di tutte le possibilità. Ogni possibile soluzione può poi essere rappresentata mediante
una matrice
nella quale l’elemento di posizione
è uno zero se l’ -esimo progetto viene assegnato al -esimo
ingegnere, e in caso contrario è pari a zero. Ad esempio, se supponiamo che l’ -esimo progetto venga sempre
assegnato all’ -esimo ingegnere, la matrice che si ottiene è:
Come messo in evidenza dalla precedente formula la crescita del numero di casi possibili avviene in maniera
esponenziale rispetto al numero di ingegneri e progetti, perciò i tempi di esecuzione di un simile algoritmo con un
moderno calcolatore diventerebbero ben presto enormi (già con un numero
non particolarmente elevato si
raggiungerebbero tempi di esecuzione dell'ordine dei secoli).
Esempio n. 2: problema di network design
Un altro esempio di problema risolvibile mediante la ricerca operativa è quello che consiste nell’individuare il modo
per collegare un certo numero di città (o di uffici) mediante un insieme di collegamenti (sapendo che solo alcune
coppie prestabilite di città o uffici possono essere collegate in maniera diretta), facendo in modo che il costo totale di
collegamento risulti essere il minimo possibile.
3
Capitolo 1: La Ricerca Operativa
Fondamenti di Ricerca Operativa
La figura seguente mostra un possibile grafo
nel quale sono rappresentate le varie città da collegare,
mettendo in evidenza i collegamenti diretti possibili con i relativi costi, indicati dai numeri associati ai collegamenti
stessi. Si noti che si suppone che tutti i collegamenti siano bidirezionali.
1
2
7
1
3
5
1
Figura 1: Grafo dei possibili collegamenti diretti tra città e dei costi associati ai collegamenti stessi.
Per risolvere tale problema, è necessario costruire il grafo ricoprente connesso e aciclico con costo minimo tra tutti
quelli possibili. Il numero di sottografi con tali caratteristiche che si possono ottenere a partire da G dipende
naturalmente, oltre che dal numero di nodi, anche dal numero di possibili collegamenti diretti. Indichiamo con m il
numero di possibili collegamenti diretti. Se si suppone che la scelta di inserire oppure no uno di tali collegamenti nel
sottografo finale non influenzi le scelte successive (anche se è bene sottolineare che in realtà tali scelte non sono
indipendenti), allora il numero di sottografi possibili da analizzare sarebbe pari a
.
Supponendo che siano possibili tutti i collegamenti diretti tra le coppie di nodi del grafo, ovvero ipotizzando
, allora tale considerazione ci porta facilmente a dedurre che il numero di diverse soluzioni ammissibili
è non superiore a
situazione è pari a
. Più in particolare, è stato dimostrato che il numero di soluzioni alternative in questa
.
Esempio n. 3: organizzazione dei turni del personale
La Ricerca Operativa può anche essere utilizzata per organizzare i turni del personale, andando ad individuare la
soluzione che rispetti al meglio le varie esigenze e minimizzando al contempo il numero di persone coinvolte (al fine di
ridurre il costo da affrontare per il pagamento degli stipendi).
Esempio n. 4: organizzazione degli sportelli della banca
Un altro possibile problema di scelta si pone nel momento in cui si deve determinare il numero di sportelli che è
necessario aprire in una banca al fine di minimizzare il tempo di attesa per i clienti, stabilendo eventualmente anche la
tipologia di tali sportelli.
Esempio n. 5: scelta di un PC portatile
Un esempio di problema di scelta che è più facile trovarsi ad affrontare nella vita di tutti i giorni è quello della scelta
del PC portatile da comprare: in tal caso, occorre tenere conto di diversi criteri, tra i quali i più importanti sono il
prezzo, il peso e le prestazioni.
Cenni storici
Le origini della Ricerca Operativa sono legate all’ambito militare: tale disciplina è infatti nata durante la Seconda
Guerra Mondiale, con lo scopo di sfruttare al meglio le limitate risorse che gli eserciti dovevano assegnare alle varie
operazioni da compiere. In tale contesto nacque il termine Operations Research, che veniva allora utilizzato per
indicare il modo più efficace di condurre le operazioni. Tra i problemi risolti dalla Ricerca Operativa nell’ambito
militare si ricordano quelli di posizionamento dei radar, di approvvigionamento dei convogli e di logistica.
Nel dopoguerra ci si rese conto che le tecniche della Ricerca Operativa potevano essere usate anche in ambito
industriare ed economico: con il boom economico le dimensioni delle imprese e delle organizzazioni crebbe notevole,
e di conseguenza si rese necessario affrontare problemi molto più complessi di quelli ai quali si era abituati.
Lo sviluppo della Ricerca Operativa è stato inoltre fortemente incentivato prima dai progressi teorici nel Calcolo
Numerico, e poi soprattutto dalla massiccia diffusione dell’informatica, che consente di risolvere rapidamente gli
algoritmi utilizzati in tale disciplina.
In inglese si utilizza oggi il termine Management Science, che indica un ambito più “soft” della Ricerca Operativa.
4
Fondamenti di Ricerca Operativa
Capitolo 1: La Ricerca Operativa
Schema generale di uno studio di Ricerca Operativa
In generale, lo schema che si segue per la risoluzione di un problema decisionale mediante la Ricerca Operativa è
rappresentato nella figura seguente:
Problema
Modello
Algoritmo
Programma
Figura 2: Schema generale di uno studio di Ricerca Operativa.
Come messo in evidenza dal diagramma, si parte da un problema, dal quale si ricava un modello, ovvero una
rappresentazione semplificata della realtà. Il modello deve essere un giusto compromesso tra le esigenze di
semplificazione e la necessità di esprimere i dettagli relativi al problema in analisi.
A partire da tale modello si ricava poi un algoritmo, il quale verrà risolto per mezzo di un opportuno programma.
Caratteristiche dei problemi decisionali
I problemi decisionali si differenziano tra loro per una serie di caratteristiche, in base alle quali vengono identificate le
varie sotto-branche della Ricerca Operativa stessa. Le caratteristiche principali dei problemi decisionali sono:

Numero di decisori
Alcuni problemi decisionali prevedono la presenza di un solo soggetto incaricato di prendere la decisione stessa;
in altri casi invece i decisori in gioco sono più di uno: esempi di questo tipo sono i problemi relativi ad una
relazione di coppia, l’incontro tra la domanda e l’offerta nella compravendita di un bene, le decisioni prese
all’interno del C.d.A. di un’azienda, … .
I problemi decisionali che prevedono più di un decisore vengono studiati dalla branca della Ricerca Operativa nota
come Teoria dei Giochi.

Numero degli obiettivi
Talvolta i criteri in base ai quali effettuare la scelta sono più di uno (come nell’esempio della scelta del computer
portatile da acquistare). Tali problemi vengono risolti mediante la Programmazione multi-obiettivo.

Grado di certezza dei parametri
I parametri del modello matematico realizzato per la risoluzione del problema possono essere noti solamente con
un certo livello di incertezza, e non in maniera esatta: in tal caso si parla di Programmazione stocastica.
La Programmazione Matematica
Definizione
La Programmazione Matematica (PM) è quel ramo della Ricerca Operativa che si occupa di risolvere i problemi
decisionali con variabili di decisione reali, caratterizzati da un solo decisore, un solo criterio di scelta e che si svolgono
in ambito certo. La Programmazione Matematica è detta a volte anche Ottimizzazione Matematica.
Formalizzazione di un problema di PM
Un problema di Programmazione Matematica può perciò essere formalizzato mediante un modello costituito da:

Variabili di decisione
Indichiamo con il vettore delle variabili di decisione. Le variabili di decisione sono grandezze numeriche il cui
valore individua una soluzione del problema. Esse sono dette talvolta anche variabili di scelta e rappresentano di
fatto le variabili indipendenti del problema. In un problema di PM, tutte le variabili di decisione devono essere
reali, ovvero si deve avere:
5
Capitolo 1: La Ricerca Operativa

Fondamenti di Ricerca Operativa
Regione ammissibile
Chiamiamo regione ammissibile il sottoinsieme di
contenente tutti e soli i valori che può assumere
la soluzione da esso individuata sia ammissibile. Avremo perciò:
perché
La regione ammissibile è a volte indicata con il termine campo di scelta e identifica di fatto il range entro il quale si
troveranno i valori delle variabili di decisione. Essa è costituita da un insieme dei vincoli, solitamente
rappresentato da un sistema di equazioni o, più spesso, di disequazioni. Tali vincoli possono essere:

Vincoli tecnici, ovvero legati alle risorse utilizzabili e disponibili.
Altri vincoli, legati alla non negatività delle variabili (che di solito rappresentano delle quantità e perciò sono
sempre maggiori o uguali a zero), alla loro interezza, … .
Funzione obiettivo
La funzione obiettivo è una funzione definita da in , la quale esprime in modo quantitativo il gradimento o il
costo di ciascuna soluzione ammissibile. Essa corrisponde perciò, in maniera intuitiva, alla variabile dipendente
nel problema analizzato.
L’obiettivo che ci si pone è quello di minimizzare o di massimizzare la funzione obiettivo:
opt
con
, opt = min oppure opt = max.
Si noti che minimizzare una funzione equivale a massimizzare la sua opposta, perciò in seguito non ci
soffermeremo molto sulla distinzione tra le due diverse situazioni.
Risoluzione di un problema di Programmazione Matematica
 Individuazione di un ottimo globale
Risolvere un problema di PM consiste nell’individuare una soluzione ammissibile globalmente ottima, ovvero un
vettore
tale che:
1. Se opt = min, allora valga la relazione:
2.
Se opt = max, allora valga la relazione:

Casi particolari
Talvolta può avvenire che:
1. Il problema sia inammissibile, ovvero si abbia
. Questo significa che non è possibile fissare in alcun
modo i valori delle variabili di decisione rispettando i vincoli imposti dalla regione ammissibile, perché
quest’ultima è vuota.
2. Il problema sia illimitato, ovvero per una qualsiasi soluzione ammissibile, è possibile trovare un’altra
soluzione ammissibile migliore rispetto alla precedente. In simboli:
Se opt = min, allora
Se opt = max, allora
3. Vi sia un numero elevatissimo (anche infinito) di soluzioni ottime (cioè con lo stesso valore ottimo).

Ottimo locale
Per le problematiche appena elencate, in alcuni casi ci si deve accontentare di una soluzione ammissibile
localmente ottima, ovvero di una soluzione
tale che:
-
Se opt = min, allora:
-
Se opt = max, allora:
Per un valore opportuno. Naturalmente, un problema può ammettere più di un ottimo locale.
6
Fondamenti di Ricerca Operativa
Capitolo 1: La Ricerca Operativa
Casi particolari di Programmazione Matematica
Vediamo ora alcuni casi particolari di Programmazione Matematica.
Programmazione Lineare (PL)
Si parla di Programmazione Lineare (PL) quando la funzione
è lineare e la regione ammissibile è del tipo:
, con
Si noti che con
e
è indicato il numero di variabili di decisione e con
Programmazione Lineare Intera (PLI)
Si parla di Programmazione Lineare Intera (PLI) quando la funzione
, con
è lineare per ogni
.
il numero di vincoli.
è lineare e la regione ammissibile è del tipo:
e
è lineare per ogni
.
Si osserva perciò che la PLI è equivalente alla PL, con la sola aggiunta del vincolo di interezza di tutte le variabili di
decisione.
Programmazione Non Lineare
Si parla di Programmazione Non Lineare quando la funzione
racchiuso tra superfici regolari, ovvero del tipo:
, dove
è regolare e la regione ammissibile è un volume
è regolare per ogni
.
Possiamo perciò affermare che la Programmazione Non Lineare comprende al proprio interno sia i problemi di PL, sia i
problemi di PLI.
In ogni caso, parleremo in seguito soprattutto di problemi di Programmazione Lineare relativi a reti o grafi e, in un
secondo momento, di Programmazione Lineare Intera, senza invece analizzare il caso generale di Programmazione
Non Lineare.
Programmazione a molti obiettivi
Come abbiamo già accennato, in alcuni casi gli obiettivi possibili sono più di uno (programmazione a molti obiettivi). In
questo caso, solitamente si cerca di ricondursi al caso di programmazione ad un solo obiettivo. A tale scopo, gli
approcci possibili sono diversi, ma i due più importanti sono quelli che indicheremo come approccio senza priorità e
approccio con priorità.
Approccio senza priorità
L’approccio senza priorità prevede che, detto
un obiettivo da minimizzare e detto
un obiettivo da
massimizzare, si crei un nuovo obiettivo a partire da
e
convertiti opportunamente in unità di misura
omogenee, mediante l’utilizzo di due opportuni scalari e . Si otterrà così:
min
Approccio con priorità
Una soluzione alternativa è quella che consiste nell’ottimizzare uno degli obiettivi, considerato prioritario rispetto agli
altri, riducendo questi ultimi a semplici vincoli di qualità:
Dove è una costante opportuna. Ad esempio, nel caso della scelta del computer portatile, è possibile ottimizzare
rispetto alle prestazioni, imponendo però che il prezzo ed il peso siano inferiori a opportune soglie.
7
Capitolo 1: La Ricerca Operativa
Fondamenti di Ricerca Operativa
Programmazione Matematica e simulazione
Oltre all’approccio della Programmazione Matematica, è possibile adottare l’approccio della simulazione. Così come la
PM, quello della simulazione è un approccio di tipo modellistico, che prevede che si effettui una ricostruzione del
sistema reale, sul quale effettuare sperimentalmente la valutazione delle soluzioni possibili per individuare la migliore.
Ovviamente, non possono essere valutate tutte le soluzioni ammissibili, e perciò non si ha garanzia di ottimalità.
In generale, la simulazione si utilizza quando si devono affrontare dei problemi difficili da formalizzare. Inoltre, spesso
si utilizza la Programmazione Matematica per individuare le soluzioni di un problema, e poi attraverso la simulazione
si effettua una validazione delle soluzioni trovate o si valuta la qualità di queste ultime.
Esempi di modelli
Esempio n. 1: mix produttivo
Il testo del problema
Una azienda produce tre tipi di apparecchiature elettroniche, indicate con
,
e
. Le fasi critiche del ciclo
produttivo sono 3: assemblaggio, finitura e controllo di qualità. Si conoscono inoltre i tempi, espressi in ore-uomo,
necessari per il completamento di ciascuna fase produttiva per ogni singola apparecchiatura dei 3 tipi prima elencati:
Prodotto
Fase
Assemblaggio
80
70
120
Finitura
70
90
20
Controllo di qualità
40
30
20
Tabella 2: Ore-uomo necessarie per completare le fasi produttive in relazione ai tipi di apparecchiature prodotte.
La disponibilità produttiva dell’azienda nell’orizzonte di pianificazione espressa di 1000 ore-uomo per la fase di
assemblaggio, di 800 ore-uomo per la finitura e di 300 ore-uomo da dedicare al controllo di qualità.
È noto inoltre che il margine lordo unitario espresso in migliaia di euro è pari a 15 per il prodotto
prodotto
e a 2 per il prodotto .
, a 10 per il
Si suppone che l’azienda possa vendere tutto ciò che produce. Formulare in termini matematici il problema di
determinare un “piano” di produzione che massimizzi il margine lordo complessivo.
Il modello corrispondente
 Variabili di decisione
Nel caso analizzato, è opportuno usare 3 variabili di decisione, che indichino per ciascuna tipologia di
apparecchiatura la quantità di pezzi da produrre:
quantità di apparecchiature della tipologia prodotte dall’azienda (
)
 Funzione obiettivo
In questo caso, la funzione obiettivo è il margine di guadagno dell’azienda, che si desidera rendere massimo:

Vincoli
I vincoli da imporre sono i seguenti:
-
Limite della disponibilità produttiva relativa alla fase di assemblaggio:
-
Limite della disponibilità produttiva relativa alla fase di finitura:
-
Limite della disponibilità produttiva relativa alla fase di controllo di qualità:
- Non negatività delle quantità prodotto:
Si noti che in questo caso non è stato posto il vincolo di interezza delle variabili, perché ciò consente di rendere
molto più semplice la risoluzione del problema.
Il problema così formulato è un problema di ottimizzazione lineare.
8
Fondamenti di Ricerca Operativa
Capitolo 1: La Ricerca Operativa
Esempio n. 2: pianificazione degli investimenti
Il testo del problema
Una società di investimenti finanziari deve decidere la composizione di un portafoglio di titoli. Gli investimenti possibili
sono riassunti nella seguente tabella:
Investimento
A (settore auto)
B (settore auto)
C (settore informatica)
D (settore informatica)
E (settore elettrodomestici)
F (settore elettrodomestici)
G (titoli di stato a breve)
H (titoli di stato a lungo)
Area
Germania
Italia
U.S.A.
Italia
Italia
Francia
Italia
Inghilterra
Capitale [ ] (KEuro)
150
150
60
100
125
100
50
80
Rendimento atteso [
11%
9%
13%
10%
8%
7%
3%
5%
]
Tabella 3: Investimenti a disposizione della società di investimenti finanziari.
Il capitale a disposizione della società è di 600 KEuro. È noto anche che la società può compiere al massimo 5
investimenti, allo scopo di evitare un’eccessiva frammentazione della gestione. Inoltre, è necessario mantenere una
certa diversificazione per area geografica, e perciò non si possono effettuare più di 3 investimenti in Italia, né più di 3
investimenti all’estero.
Formulare in termini matematici il problema di selezione degli investimenti in modo tale da massimizzare il ritorno
atteso rispettando i vincoli che mirano a ridurre il rischio.
Il modello corrispondente
 Variabili di decisione
In questo caso, possiamo utilizzare una variabile di decisione per ogni investimento, assegnando a tale variabile il
valore 0 se il corrispondente investimento non viene effettuato, 1 in caso contrario:
-
(
)

Funzione obiettivo
La funzione obiettivo è il ritorno atteso, che deve essere massimizzato e che è dato dall’espressione seguente:

Vincoli
I vincoli da imporre sono i seguenti:
-
Investire un capitale non superiore a quello a disposizione della società:
-
Non superare i 3 investimenti effettuati in Italia:
-
Non superare i 3 investimenti effettuati all’estero:
-
Imposizione del fatto che le variabili abbiano il valore 0 o 1, e nessun altro valore.
Se ad esempio il testo del problema avesse richiesto anche che in presenza di almeno un investimento nel settore
informatico si dovesse effettuare almeno un investimento in titoli di stato, allora sarebbe stato necessario aggiungere
il vincolo:
9
Capitolo 1: La Ricerca Operativa
Fondamenti di Ricerca Operativa
Esempio n. 3: problema di assegnazione
Il testo del problema
Proviamo ora a formalizzare un modello matematico relativo all’esempio n. 1 di problema decisionale, già esposto in
precedenza.
Il modello corrispondente
 Variabili di decisione
-
-

Funzione obiettivo
Vogliamo minimizzare il tempo totale per l’esecuzione dei progetti, ovverto:

Vincoli
-
Ogni progetto deve essere assegnato ad uno e un solo ingegnere:
-
Ogni ingegnere deve essere assegnatario di uno e un solo progetto:
-
Imposizione del fatto che le variabili abbiano il valore 0 o 1, e nessun altro valore.
Se ad esempio il testo del problema avesse richiesto anche che in presenza di almeno un investimento nel settore
informatico si dovesse effettuare almeno un investimento in titoli di stato, allora sarebbe stato necessario aggiungere
il vincolo:
Esempio n. 4: localizzazione di impianti
Il testo del problema
Supponiamo che si abbiano 3 pozzi petroliferi, situati nei punti
,
e
, ciascuno
dei quali estrae greggio. Si vuole costruire una raffineria, e a tale scopo si desidera individuare la posizione in cui
localizzarla in modo da minimizzare il costo degli oleodotti (che si assume essere proporzionale al quadrato della
lunghezza degli oleodotti stessi). Si sa che è vietato costruire una raffineria nel raggio di 100 km attorno al punto
. Gli oleodotti possono però attraversare anche l’area vietata.
Il modello corrispondente
 Variabili di decisione

ascissa e ordinata del punto in cui situare la raffineria.
Funzione obiettivo
È il costo degli oleodotti, che deve essere minimizzato:

Vincoli
10
-
Il (
) deve avere una distanza da
-
I valori di
e
devono essere reali:
non inferiore a 100:
Fondamenti di Ricerca Operativa
Capitolo 2: Ottimizzazione su grafi
Capitolo 2: Ottimizzazione su grafi
Molti problemi decisionali possono essere formulati utilizzando il linguaggio messo a disposizione dalla teoria dei grafi,
anche se in alcuni casi si tratta di problemi che apparentemente non hanno la struttura di una rete. Riprendiamo
perciò il concetto di grafo per poi andare ad analizzare le tecniche di ottimizzazione sui grafi stessi.
Il concetto di grafo
Definizione di grafo non orientato
Un grafo non orientato (detto anche grafo semplice)
è una coppia ordinata di insiemi, nella quale è un
insieme di nodi (o vertici) e
è un insieme di coppie di nodi non ordinate, ciascuna delle quali è detta lato o
collegamento, che rappresenta appunto il collegamento tra i due nodi facenti parte della coppia stessa.
Si noti che le coppie non ordinate verranno in seguito distinte dalle coppie ordinate mediante l’utilizzo delle parentesi
quadre anziché delle parentesi tonde. In genere indicheremo
e
.
Esempio di grafo non orientato
La figura seguente mostra la rappresentazione schematica del grafo matematicamente così descritto:
1
2
3
5
4
Figura 3: Rappresentazione grafica di un esempio di grafo non orientato.
Definizione di grafo orientato
Un grafo orientato (o grafo diretto)
è una coppia ordinata di insiemi, nella quale è un insieme di nodi (o
vertici) e è un insieme di coppie di nodi ordinate, ciascuna delle quali è detta arco, che rappresenta appunto il
collegamento tra i due nodi facenti parte della coppia stessa.
In sostanza quindi un grafo orientato è del tutto simile ad un grado orientato, salvo il fatto che in un grafo orientato vi
è la possibilità che alcuni collegamenti possano essere percorsi solo in un verso e non nel verso opposto.
Esempio di grafo orientato
La figura seguente mostra la rappresentazione schematica del grafo matematicamente così descritto:
1
2
3
4
Figura 4: Rappresentazione grafica di un esempio di grafo orientato.
11
Capitolo 2: Ottimizzazione su grafi
Fondamenti di Ricerca Operativa
Definizioni relative ai grafi
Nodi adiacenti (successori)
In un grafo non orientato, due nodi sono detti adiacenti se esiste un lato che li collega, ovvero se esiste un lato avente
per estremi i due nodi in analisi.
In un grafo orientato, un nodo
si dice adiacente a
(o successore di ) se esiste l’arco
.
Lato (arco) incidente in un nodo e arco uscente da un nodo
In un grafo non orientato un lato si dice incidente in un nodo se il nodo è un estremo del lato stesso.
In un grafo orientato, un arco si dice incidente su un nodo se esiste un nodo
dice uscente da un nodo se esiste un nodo per il quale si ha
.
per il quale si ha
, mentre si
Grado di un nodo
In un grafo non orientato, chiamiamo grado di un nodo il numero di lati incidenti nel nodo stesso.
In un grafo orientato, si chiama grado di ingresso di un nodo il numero di archi incidenti sul nodo stesso, mentre si
chiama grado di uscita del nodo il numero di archi uscenti dal nodo stesso.
Cammino (orientato) da un nodo ad un altro
In un grafo non orientato, si chiama cammino dal nodo
al nodo
una sequenza di lati del tipo:
Analogamente, in un grafo orientato, si chiama cammino orientato dal nodo
al nodo
un insieme di archi del tipo:
Nodi connessi
In un grafo qualsiasi, un nodo
si dice connesso a un nodo
se esiste un cammino (orientato nel caso di grafo
adiacente) da a . Si osserva facilmente che due nodi adiacenti sono necessariamente connessi.
Grafo connesso
Un grafo si dice connesso se per ogni possibile coppia di nodi
oppure
esiste un cammino
(eventualmente orientato) da a . In altri termini, un grafo connesso è un grafo nel quale ogni nodo è connesso ad
ogni altro nodo.
Ciclo e circuito
In un grafo non orientato si dice ciclo un cammino da un nodo al nodo stesso. In altri termini, il ciclo è un cammino nel
quale vale
.
In un grafo orientato si dice circuito un cammino da un nodo al nodo stesso. Il circuito è quindi un cammino orientato
nel quale vale
.
Grafo ciclico e grafo aciclico
Un grafo si dice ciclico se contiene almeno un ciclo (o circuito). IN caso contrario, il grafo si dice aciclico.
Grafo completo
Un grafo si dice completo se ognuno dei suoi nodi è adiacente a tutti i restanti nodi del grafo stesso. In altri termini, un
grafo è completo se esistono tutti i lati (o tutti gli archi) possibili tra i nodi appartenenti all’insieme .
In un grafo non orientato completo si ha:
Mentre in un grafo orientato completo vale la relazione:
Si può affermare che nel caso generale il numero di archi non supera il valore indicato dalle formule sopra riportate.
12
Fondamenti di Ricerca Operativa
Capitolo 2: Ottimizzazione su grafi
Grafo bipartito
Un grafo si dice bipartito se esiste una bi-partizione
dell’insieme tale che nessun lato colleghi nodi dello
stesso sottoinsieme di . Per bi-partizione di
si intende chiaramente una coppia di insiemi
tale che
e
.
Si osserva che in un grafo bipartito il numero massimo di archi è dato dal prodotto tra le cardinalità delle due
partizioni di , ovvero:
Esempio:
La figura seguente mostra un esempio di grafo bipartito:
1
4
2
5
3
Figura 5: Esempio di grafo bipartito.
Si nota infatti in maniera immediata che ogni arco del grafo collega un nodo della bi-partizione
nodo della bi-partizione
.
con un
Taglio, taglio entrante e taglio uscente
Dato un grafo
e dato un insieme di nodi appartenenti a , si chiama taglio (o cut) indotto da e si indica
con
l’insieme di tutti e soli i lati aventi un estremo in e un estremo nel suo complemento,
, ovvero:
Si chiama inoltre taglio uscente
l’insieme di tutti e soli i lati (o archi) uscenti da un nodo appartenente a
incidenti su un nodo appartenente al complemento di S, indicato con
. In simboli:
e
Si chiama infine taglio entrante
l’insieme di tutti e soli i lati (o archi) incidenti su un nodo appartenente a
uscenti da un nodo appartenente al complemento di S, indicato con
. In simboli:
e
Si può facilmente osservare che in un grafo non orientato si ha:
Inoltre, vale sempre la relazione:
Sottografo
Dato un grafo
, diciamo che il grafo
contiene solamente lati che collegano nodi appartenenti a
è un sottografo di G se
,
, e inoltre
.
13
Capitolo 2: Ottimizzazione su grafi
Fondamenti di Ricerca Operativa
Gli alberi
Albero
Un albero
è un grafo non orientato, connesso e aciclico. Gli alberi sono anche detti tree. I nodi di grado 1
di un albero sono anche detti foglie.
Albero di supporto
Dato un grafo
tutti i nodi di , ovvero
e dato un albero
.
, diciamo che
Lato di diminuzione
Sia
un albero di supporto del grafo
all’insieme T si crea un ciclo
ed esiste un lato
. Un lato
con
è un albero di supporto di
se
contiene
è detto di diminuzione se aggiungendolo
.
Questo significa che un lato di diminuzione è un lato che, sostituito ad un altro lato all’interno dell’albero di supporto,
ci fa ottenere un nuovo albero di supporto con costo inferiore rispetto a quello di partenza.
Proprietà degli alberi
 Proprietà 1
Ogni albero che abbia
nodi ha almeno 2 foglie.
DIM: Procediamo per assurdo. Supponiamo di avere 0 foglie. In tal caso, tutti i nodi dell’albero hanno grado
maggiore di 1, perciò tutti i nodi dell’albero hanno almeno due lati incidenti. Siccome però non si possono
avere cicli, ogni nodo può essere visitato una sola volta, e perciò ogni volta che introduciamo un nodo,
dobbiamo aggiungere anche un lato che lo collega ad un nuovo nodo, con un procedimento che è infinito
(cioè sarebbe possibile un viaggio infinito su un grafo finito).
Lo stesso discorso può essere ripetuto ipotizzando la presenza di una sola foglia.

Proprietà 2
Ogni albero che abbia
nodi ha esattamente
lati.
DIM: Procediamo per induzione:
1. Caso base: consideriamo il caso
. In tal caso, non saranno presenti lati, e perciò la proprietà
risulta verificata, ovvero i lati presenti sono
.
2. Passo induttivo: dobbiamo verificare che se per un albero di nodi si hanno
lati, per un albero di
nodi si hanno lati.
Consideriamo a tal proposito un albero con
nodi. Se eliminiamo dall’albero una foglia e l’unico
lato su essa incidente, otteniamo un albero con nodi che, per la nostra ipotesi, ha
lati. Siccome
per ottenere tale albero abbiamo eliminato un solo lato dall’albero di partenza, significa
necessariamente che i lati di tale albero erano , ovvero
.

Proprietà 3
In ogni albero, esiste un unico cammino tra ogni coppia di nodi.

Proprietà 4
Aggiungendo ad un albero qualsiasi un qualsiasi lato, si crea uno ed un solo ciclo, formato dall’unico cammino che
congiunge i due lati uniti dal nuovo lato, e dal lato stesso.

Proprietà 5 (di scambio)
Sia
un albero di supporto di
. Sia inoltre un lato tale che
e sia l’unico ciclo
dell’albero
(come noto dalla proprietà 4, infatti, aggiungendo all’albero si ottiene un nuovo albero
con uno ed un solo ciclo).
Per ogni lato
14
, il grafo
è ancora un albero di supporto di .
Fondamenti di Ricerca Operativa
Capitolo 2: Ottimizzazione su grafi
Applicazioni dei grafi
A questo punto è opportuno andare ad analizzare quali sono le situazioni nelle quali i grafi si rendono utili per la
realizzazione del modello matematico di un certo problema.
Relazioni di precedenza
Una possibile applicazione dei grafi è quella che consiste nell’utilizzarli per la rappresentazione di relazioni di
precedenza, ad esempio tra attività. Nel dettaglio, per precedenza tra attività si intende dire che una certa attività è in
relazione di precedenza con un’altra se la prima deve necessariamente essere completata prima che possa iniziare la
seconda.
A tale scopo, è possibile utilizzare un grafo orientato nel quale i nodi rappresentano le singole attività, facendo poi in
modo che per ogni arco
l’attività sia prioritaria rispetto a .
Raggiungibilità tra luoghi
L’ambito nel quale risulta più intuitivo utilizzare i grafi è quello dello studio della raggiungibilità tra luoghi: ogni luogo
(ad esempio, ogni città) è rappresentato da un nodo del grafo e ogni collegamento diretto tra una città ed un’altra è
rappresentato mediante un arco dalla città di partenza a quella di arrivo (in generale è più opportuno utilizzare grafi
orientati, perché è possibile che vi siano strade a senso unico).
Relazioni di compatibilità e incompatibilità
Utilizzando una grafo bipartito è possibile mettere in evidenza una relazione di compatibilità o incompatibilità.
Supponiamo ad esempio di avere un insieme di persone ed un insieme di incarichi, e ipotizziamo che alcune persone
possano essere incompatibili con uno o più incarichi: possiamo rappresentare questa situazione mediante un grafo
bipartito, in modo che i nodi di una delle due partizioni del grafo siano le persone, i nodi dell’altra partizione siano gli
incarichi e i lati del grafo colleghino solo le persone agli incarichi con i quali sono incompatibili.
Rappresentazioni di un grafo
All’interno di un programma, un grafo può essere rappresentato mediante strutture dati di tipo diverso. Le soluzioni
più di frequente adottate sono 2: la matrice di incidenza nodo-nodo e la lista degli archi.
Matrice di incidenza nodo-nodo
Nel caso in cui il grafo sia molto denso o “quasi completo”, una maniera efficiente per rappresentare il grafo è quella
di utilizzare una matrice quadrata
(dove si ricorda che è il numero di nodi, ovvero
), nella quale l’elemento
alla posizione
ha valore 1 se e solo se esiste un arco (o lato) uscente dal nodo e incidente nel nodo del grafo,
mentre in caso contrario tale elemento assume il valore 0.
Naturalmente, in caso di grafo non orientato la matrice di incidenza nodo-nodo è sempre simmetrica.
Lista dei nodi incidenti (o dei nodi successori)
Una soluzione alternativa, adatta soprattutto nel caso in cui il grafo sia piuttosto sparso, consiste nel memorizzare
tutti i nodi del grafo, associando a ciascuno di essi una lista la quale rappresenti nel caso di grafo orientato l’elenco di
tutti i nodi successori al nodo al quale è associata la lista stessa; nel caso in cui il grafo in analisi sia un grafo non
orientato, tale lista rappresenta invece tutti i nodi incidenti nel nodo in analisi.
15
Capitolo 2: Ottimizzazione su grafi
Fondamenti di Ricerca Operativa
Il problema di raggiungibilità in un grafo orientato
Definizione del problema di raggiungibilità
Dato un grafo orientato
e un nodo , il problema della raggiungibilità consiste nel determinare l’insieme di
tutti e soli i nodi del grafo raggiungibili da .
Algoritmo di esplorazione del grafo
La soluzione a tale problema è data dall’algoritmo di esplorazione del grafo, il quale prevede che si utilizzi un insieme
, il quale potrebbe ad esempio, ma non necessariamente, essere gestito mediante una coda. Si utilizzerà inoltre
l’insieme che al termine conterrà l’insieme dei nodi raggiungibili da .
In particolare, l’algoritmo prevede che si parta dal nodo , aggiungendo tale nodo a . Fino a quando ci sono elementi
in , si procede prelevando da esso un certo nodo, che viene poi eliminato dall’insieme stesso e aggiunto ad . Si
aggiungono quindi a tutti i nodi adiacenti al nodo prelevato dallo stesso , e poi si passa ad un eventuale ulteriore
nodo presente in , ripetendo le operazioni appena illustrate.
Di seguito è riportato lo pseudo-codice relativo a tale algoritmo:
BEGIN
Q := {s}; M := ;
WHILE Q ≠
DO /* elabora un nodo raggiungibile h
scegliere un nodo h
Q e porre Q := Q \ {h};
M := M
{h}; /* marcare h */
FOR EACH j
S(h) DO
IF j
M AND j
Q THEN Q := Q
{j} END-IF
END-FOR
END-WHILE
END
Q */
Complessit{ dell’algoritmo di esplorazione del grafo
Ad ogni iterazione del ciclo while:
1.
2.
si sceglie un nodo
non ancora elaborato, lo si estrae da e lo si marca inserendolo in ;
si inseriscono in i vertici non ancora marcati che possono essere raggiunti direttamente da .
Siccome però ogni nodo viene considerato una sola volta, di fatto tutti i lati
volta, e perciò il contenuto del ciclo for each viene eseguito in totale esattamente
while ha invece una complessità pari a , perciò si ha:
Siccome nel caso peggiore sappiamo che vale la relazione:
Possiamo concludere:
16
vengono considerati una sola
volte. La parte restante del ciclo
Fondamenti di Ricerca Operativa
Capitolo 2: Ottimizzazione su grafi
Alberi di supporto di costo minimo
Il problema dell’individuazione degli alberi di supporto di costo minimo
 Formulazione matematica del problema
Il problema dell’individuazione di un albero di supporto di costo minimo può essere così formulato: dato un grafo
e data una certa funzione di costo
,
ovvero
, per ogni
si vuole determinare un albero di supporto di che abbia il costo minimo tra tutti i possibili alberi di supporto di
. Possiamo perciò affermare che la regione ammissibile è in questo caso l’insieme di tutti i possibili alberi di
supporto di , e che la funzione obiettivo è:
Dove

è il costo associato al lato del grafo di partenza.
Osservazioni
Il problema appena formulato ha numerose applicazioni, tra le quali la più classica è la progettazione di reti di
comunicazione, di teleriscaldamento, ... . Altre applicazioni sono ad esempio la memorizzazione compatta di
sequenze (DNA) e la diffusione di messaggi segreti.
Prendiamo in considerazione il caso applicativo in cui si voglia costruire una rete stradale per collegare tra loro un
certo numero di città (che saranno i nodi del grafo) mediante delle possibili strade (i lati del grafo), in modo tale
che il costo totale risulti essere minimo (potremmo ipotizzare di usare come funzione di costo i chilometri di
strada da costruire, ad esempio). Si nota che:
1.
Ogni coppia di città deve poter comunicare, e perciò la rete stradale deve essere un sottografo connesso del
grafo di partenza, che contenga tutti i nodi di quest’ultimo.
2.
Per avere costo minimo, è chiaro che non possono esserci cicli.
Da tali osservazioni consegue in maniera molto semplice che il sottografo ricercato è proprio un albero di
supporto di costo minimo.

Teorema di Arthur Cayley (1889)
Il teorema di Cayley afferma che, dato un grafo completo costituito da
supporto di tale grafo è pari a
, per
.
nodi, il numero di possibili alberi di
Di conseguenza, il numero di grafi possibili cresce in maniera estremamente rapida al crescere di : anche se il
problema è apparentemente molto semplice da risolvere (perché comunque è chiaro che il numero di sottografi
possibili di un grafo finito è finito, e perciò non può essere messa in dubbio la decidibilità del problema), occorre
individuare un algoritmo efficiente per risolverlo, perché l’esplorazione esaustiva di tutte le possibili soluzioni non
è attuabile nella pratica.

Proprietà degli alberi ottimi
Possiamo ora enunciare una proprietà che ci tornerà utile in seguito, e che risulta in realtà piuttosto ovvia dalla
definizione che abbiamo in precedenza dato del termine lato di diminuzione: un albero di supporto è ottimo se e
solo se non esistono lati di diminuzione.
17
Capitolo 2: Ottimizzazione su grafi
Fondamenti di Ricerca Operativa
L’algoritmo di Prim
L’algoritmo di Prim è un algoritmo che consente di risolvere il problema dell’individuazione di uno tra gli alberi di
supporto di costo minimo di un grafo dato.
In particolare, si tratta di un algoritmo greedy, ovvero un algoritmo che ad ogni passo compie la scelta localmente
migliore , senza rimettere in discussione le scelte precedenti.

Spiegazione intuitiva
In sostanza, l’algoritmo di Prim prevede che si parta da un nodo qualsiasi del grafo e che lo si inserisca in un
insieme di nodi inizialmente vuoto. Ad ogni passo si considera il taglio uscente da tale insieme di nodi e si
seleziona uno dei lati ad esso appartenente avente il costo minimo tra tutti quelli del taglio stesso. Il lato appena
selezionato viene inserito nel grafo di supporto minimo che costituirà al termine la soluzione del problema,
mentre il nodo sul quale incide tale lato verrà aggiunto all’insieme di nodi utilizzato dall’algoritmo stesso.
Il procedimento viene iterato e la procedura termina quando tutti i nodi sono stati aggiunti all’insieme (o,
equivalentemente, quando sono stati inseriti nell’albero di supporto esattamente
lati, perché è noto che un
albero con nodi ha
lati).

Pseudocodice
Di seguito è riportato lo pseudocodice dell’algoritmo (ipotizzando di avviare la procedura dal nodo 1):
BEGIN
T:= ;
S:={1};
WHILE |T| < n - 1 DO
individuare [v,h]
T := T
{[v,h]};
S := S
{h};
END-WHILE
δ(S) di costo minimo, con v
S e h
N \ S;
END


Analisi di complessità
La precedente implementazione ha un costo
: il ciclo while viene iterato
lato di costo minimo tra quelli del taglio ha, ad ogni iterazione, un costo
.
volte e l’individuazione del
Riduzione della complessità
Tuttavia, è possibile implementare l’algoritmo in una maniera più efficiente, con costo
. L’idea di base è
quella di conservare in un’opportuna struttura dati l’insieme dei lati appartenenti al taglio indotto sul grafo
dall’insieme dei nodi già aggiunti all’albero di supporto, conservando però solo un lato per ogni nodo di arrivo, e
precisamente quello a costo minimo tra tutti i nodi del taglio che incidono sul nodo di arrivo.
Per farlo, utilizziamo una struttura dati che prevede l’uso di:
18
-
un sottoinsieme
dei lati del grafo, il quale rappresenta tutti i lati già inseriti nell’albero;
-
un sottoinsieme , contenente tutti i nodi incidenti ai lati selezionati (perciò è l’insieme di tutti i nodi già
considerati nell’albero di supporto);
-
Un array che contiene, per ogni nodo non ancora inserito nell’albero di supporto, il costo minimo del lato
che colleghi un nodo qualsiasi di
con tale nodo (nel caso in cui non esistano collegamenti diretti, il
corrispondente valore viene posto ad ). In simboli:
-
Un array
contenente, per ogni nodo non ancora inserito nell’albero di supporto, il nodo precedente per
raggiungerlo con il lato il cui costo è individuato dal corrispondente valore inserito nell’array . In simboli:
Fondamenti di Ricerca Operativa
Capitolo 2: Ottimizzazione su grafi
L’algoritmo risulta perciò essere il seguente:
BEGIN
T := ; S := {1};
FOR j:=2 TO n DO
C[j] := c1j ;
pred[j] := 1;
END-FOR
FOR k:=1 TO n–1 DO
min := +∞;
FOR j := 2 TO
IF j
/*
nodi j
S
*/
/* selezionare n – 1 lati albero */
n DO
/* scegliere lato min in δ(S) */
S AND (C[j] < min) THEN
min := C[j];
h := j;
END-IF
END-FOR
S := S
{h}; T := T
{[pred[h],h]}; /* estendere S e T */
FOR j:=2 TO n DO
/* aggiornare C[j] e pred[j] j S */
IF j
S AND (chj < C[j]) THEN
C[j] := chj; pred[j] := h;
END-IF
END-FOR
END-FOR
END
Ovvero: iniziamo considerando il nodo 1. Aggiorniamo le strutture e
in modo che contengano i dati iniziali
(cioè inizialmente il predecessore di tutti i nodi è 1 con un costo pari al costo del lato che collega 1 al
corrispondente nodo).
Dopodiché, si itera per
volte il procedimento che consente di inserire un nuovo lato nell’albero di supporto
(sappiamo che un albero con nodi ha
lati). Ad ogni iterazione, si trova il minimo tra tutti i valori contenuti
in e si inseriscono in il lato corrispondente e in il nodo che viene raggiunto aggiungendo tale lato. Si
aggiornano poi le strutture e
.
La fase di inizializzazione ha una complessità
; si ha poi (in “serie” al precedente) un ciclo ripetuto
volte, all’interno del quale si hanno l’operazione di scelta del lato, che ha a sua volta un costo
, e quella di
aggiornamento, anch’essa con costo
. In conclusione, l’algoritmo ha complessità
.
Per grafi sparsi, ove
complessità a

, si può usare una struttura dati più sofisticata che consente di ridurre la
.
Esattezza dell’algoritmo
L’algoritmo di Prim è esatto, cioè fornisce sempre un albero di supporto di costo minimo, indipendentemente
dalla scelta del nodo di partenza e dalle scelte dei lati nei casi in cui, durante una certa iterazione, si abbiano più
lati di costo minimo.
Possiamo dimostrarlo sfruttando la proprietà che afferma che se un albero di supporto è ottimo, allora non
esistono lati di diminuzione. In particolare, da ciò consegue che, dato un sottoinsieme dei nodi del grafo di
partenza e dato un lato
appartenente al taglio
tale che sia un lato di costo minimo tra quelli di
, allora esiste un albero di supporto ottimo contenente (cioè ogni scelta fatta dall’algoritmo di Prim ci porta
ad un albero di costo ottimo).
Dimostriamo tale proposizione per assurdo: se esistesse un albero ottimo
tale che
, allora aggiungendo
all’albero si ottiene un ciclo nel quale esiste uno e un solo lato
. Si hanno perciò due possibilità:
1. Il costo di e quello di sono uguali (
), e quindi l’albero di partenza è ottimo perché ha lo stesso
costo di che, per ipotesi, è ottimo;
2. Il costo è superiore a quello di , perciò non è ottimo, perché è un lato di diminuzione.
19
Capitolo 2: Ottimizzazione su grafi

Fondamenti di Ricerca Operativa
Dimostrazione della proposizione sugli alberi di supporto a costo minimo
A questo punto, possiamo anche dimostrare la proposizione che abbiamo in precedenza solo enunciato, secondo
la quale un albero di supporto è a costo minimo se e solo se non possiede lati di diminuzione.
-
Risulta ovvio che se un albero è ottimo, esso non possiede lati di diminuzione (questo deriva dalla definizione
di lato di diminuzione, ed è la cosiddetta proprietà degli alberi ottimi). Del resto, abbiamo usato questa
proprietà per dimostrare l’ottimalità della soluzione fornita dall’algoritmo di Prim.
-
Vogliamo ora dimostrare che, se un albero non ha lati di diminuzione, allora è ottimo. Per farlo, possiamo
sfruttare il fatto che le soluzioni fornite dall’algoritmo di Prim sono sempre alberi ottimi.
Possiamo infatti mostrare che con semplici operazioni di scambio si può trasformare l’albero ottimo
fornito dall’algoritmo di Prim in senza modificare il costo. Supponiamo che lati di
non appartengano a
e mostriamo come con una operazione di scambio si può trasformare
in un albero con lo stesso costo di
ma con
lati che non appartengono a . Applicando volte un’operazione di questo tipo si ottiene un
albero identico a con
, e perciò è ottimo.
Supponiamo che sia il primo lato appartenente a
ma non a . Se aggiungiamo tale lato a , otteniamo un
ciclo. Naturalmente, nel ciclo così creatosi deve esistere un lato adiacente ad uno dei lati in comune tra e
. A questo punto possiamo osservare che:
1.
2.
Siccome per ipotesi non ci sono lati di diminuzione in , avremo
.
Siccome per ipotesi
è il risultato dell’algoritmo di Prim, allora dovremo avere
.
Di conseguenza, avremo
, e perciò abbiamo verificato che possiamo ottenere un grafo con
lati
diversi da , ma con lo stesso costo. Iterando il procedimento, otterremo , che perciò risulta avere lo stesso
costo dell’albero fornito dall’algoritmo di Prim, e perciò risulta essere ottimo.
L’algoritmo di Kruskal
L’algoritmo di Kurskal è un algoritmo alternativo rispetto a quello di Prim, che consente ancora l’individuazione di un
albero di supporto ottimo a partire da un certo grafo.

Spiegazione intuitiva
L’idea sulla quale si basa l’algoritmo di Kruskal è quella di ordinare secondo il loro costo tutti i lati che
costituiscono il grafo di partenza. Si procede poi inserendo nell’albero di supporto (inizialmente privo di lati) i lati
così ordinati, partendo da quelli con costo minore ed inserendoli solo a patto che l’inserimento del lato stesso non
provochi alcun ciclo. Una volta inseriti
lati, si è ottenuto un albero di supporto minimo.

Pseudocodice
Di seguito è riportato lo pseudocodice relativo all’algoritmo di Kruskal:
BEGIN
ordinare i lati di G secondo costi non decrescenti;
T* := ;
WHILE |T*| < (n-1) DO
scegliere un lato e
E di costo minimo;
E := E \ {e};
IF T*
{e} non ha cicli THEN
T* := T*
{e};
END IF
END-WHILE
END
20
Fondamenti di Ricerca Operativa

Capitolo 2: Ottimizzazione su grafi
Analisi della complessità
1. Come noto, l’algoritmo degli m lati che costituiscono il grafo di partenza ha un costo
2.
Si ha poi un ciclo iterato
volte, all’interno del quale si deve verificare se l’inserimento del nuovo lato
comporta la creazione di cicli. Tale verifica può avvenire in costo costante, a patto che si conosca la
componente connessa alla quale ciascun nodo appartiene: in questo caso infatti per verificare se si creano
cicli è sufficiente controllare se i nodi congiunti dal nuovo lato appartengono alla stessa componente
connessa (e in questo caso si avrà un ciclo) oppure no.
3.
In questo modo è però poi necessario eseguire, all’interno dello stesso ciclo iterato
un’operazione di aggiornamento delle etichette, che richiede un costo
.
volte,
In conclusione, la complessità dell’algoritmo è:
Siccome nel caso peggiore sappiamo che
, possiamo anche scrivere:
Si può però notare che, mediante l’uso di opportune strutture dati, è possibile ridurre ulteriormente la
complessità dell’algoritmo di Kruskal. In ogni caso, la complessità dell’algoritmo di Kruskal è superiore rispetto a
quella dell’algoritmo di Prim.

Esattezza dell’algoritmo di Kruskal
Consideriamo un generico lato scartato dall’albero ottenuto come risultato dell’algoritmo di Kruskal. Inoltre,
siccome i lati vengono esplorati in ordine non decrescente di costo, è chiaro che l’inserimento del lato darebbe
vita ad un ciclo nel quale tutti i lati diversi da hanno un costo non superiore al costo di , e perciò è facile
concludere che non esistono lati di diminuzione, e quindi per la condizione di ottimalità possiamo affermare che
l’albero è ottimo.
Verifica di ottimalità
La condizione di ottimalità può essere utilizzata per verificare se un certo albero di supporto è ottimo oppure no: è
sufficiente verificare che tutti i lati appartenenti al grafo di partenza ma non appartenenti a non siano lati di
diminuzione; se almeno uno è un lato di diminuzione, l’albero non è ottimo, altrimenti lo è.
21
Capitolo 2: Ottimizzazione su grafi
Fondamenti di Ricerca Operativa
Il problema dei cammini ottimi
Formulazione del problema dei cammini ottimi
 Introduzione al problema
Il problema dei cammini ottimi (o minimi, o massimi) è un problema molto diverso da quello dell’individuazione
dell’albero di supporto minimo. Ricercare i cammini ottimi significa infatti trovare per una certa coppia di nodi il
cammino più breve che consente di collegare i due nodi della coppia stessa.
Come vedremo, in realtà se si sovrappongono tutti i cammini ottimi a partire da una certa sorgente si ottiene
ancora un albero di supporto, che però non è affatto l’albero di supporto ottimo.

Formulazione matematica del problema
Dato un grafo orientato
, data una funzione di costo
, che associa ad ogni lato
appartenente ad il relativo costo , e dati due nodi e si vuole determinare un cammino di costo ottimo
(cioè o minimo o massimo) da a , dove è detto origine.

Applicazioni del problema
I problemi di cammini ottimi (minimi o massimi) hanno innumerevoli applicazioni; ad esempio:
1. Pianificazione e gestione di reti di trasporto, elettriche, idrauliche, di comunicazione, …
2. Pianificazione di progetti complessi (relazioni logiche tra entità).

Osservazioni
Si noti che la formulazione che abbiamo fornito fa riferimento ai grafi orientati, i quali però sono di fatto una
generalizzazione dei grafi non orientati: ogni grafo non orientato è rappresentabile mediante un grafo orientato
nel quale per ogni lato
, si ha sempre anche il lato
all’interno del grafo stesso.
Si noti inoltre che, come vedremo, in questo caso non è applicabile un approccio di tipo greedy: la soluzione
fornita dall’algoritmo non sarebbe infatti una soluzione ottima.
L’algoritmo di Dijkstra
 L’algoritmo
Sia dato un grafo orientato
e sia
il costo associato all’arco
, con
se
. Sia
inoltre
un nodo del grafo . L’algoritmo di Dijkstra consente di individuare un cammino minimo che ha
come sorgente per ognuno dei nodi appartenenti ad
come destinazione, a patto che per ogni nodo
appartenente ad A si abbia
.

Pseudocodice
Lo pseudocodice che rappresenta formalmente l’algoritmo è il seguente:
BEGIN
S := {s};
L[s] := 0;
pred[s] := s;
WHILE |S| ≠ n DO
individuare (v,h)
L[h] := L[v] + cvh;
pred[h] := v;
S := S
{h};
END-WHILE
END
22
δ+(S) : L[v] + cvh = min{L[i] + cij : (i,j)
δ+(S)};
Fondamenti di Ricerca Operativa

Capitolo 2: Ottimizzazione su grafi
Spiegazione dell’algoritmo
L’idea sulla quale si basa l’algoritmo è quella di esplorare tutti i nodi del grafo in ordine crescente rispetto al costo
di un cammino minimo da al nodo stesso.
Per fare ciò, si associa ad ogni nodo appartenente ad
un’etichetta
che, al termine dell’algoritmo,
rappresenta il costo minimo del cammino da a . Si associa inoltre ad ogni nodo anche un valore
, che
rappresenta il predecessore di nel cammino da a . L’etichetta è perciò del tipo
.
Nel dettaglio, si usano le seguenti strutture di dati:
1.
Un insieme
che, in ogni istante, rappresenta l’insieme di tutti i nodi le cui etichette sono definitive.
2.
I valori
3.
I predecessori di ogni nodo, ovvero
Di fatto quindi si inizia fissando l’etichetta del nodo , con il valore
. Dopodiché, si inserisce il nodo
nell’insieme , inizialmente vuoto, e si inizia ad iterare un procedimento che termina solo quando contiene tutti
gli nodi del grafo, e che prevede che ad ogni iterazione si considerino tutti gli archi
del taglio uscente da ,
e si individui quello tale che la somma tra il costo dell’arco
stesso e il costo per arrivare ad , ovvero
, sia
minima. A questo punto, si inserisce in il nodo e si aggiorna la sua etichetta, in modo che il predecessore di
sia e il costo sia dato dal costo dell’arco stesso , sommato al valore
.

Esattezza dell’algoritmo di Dijkstra
Possiamo ora dimostrare l’esattezza dell’algoritmo. Per farlo è sufficiente dimostrare che effettivamente
abbia in ogni passo il significato precedentemente descritto, ovvero:
Infatti, al termine dell’algoritmo avremo
, perciò tutti i costi saranno quelli dei cammini minimi.
Dimostriamolo per induzione sul numero di passi :
1.
2.
Base induttiva: se
, l’affermazione è senz’altro vera, perché abbiamo
,
e
Passo induttivo: ipotizziamo che l’affermazione sia vera al passo -esimo. Al passo
, inseriamo in il
nodo
. Chiamiamo il cammino ottenuto da a e verifichiamo che per ogni altro cammino da a
si ha
. Il cammino può essere scomposto in tre parti: ,
e , dove
è il primo arco
tra quelli di che appartiene anche al taglio uscente di (certamente ne esiste uno, ma potrebbe esisterne
anche più di uno).
Avremo allora:
Per l’ipotesi induttiva, avremo
. Inoltre,
applicabilità dell’algoritmo di Dijkstra. Perciò:
è certamente non negativo, per l’ipotesi di
Ma se applicando l’algoritmo abbiamo scelto il nodo , questo significa necessariamente che:
E perciò la proprietà continua a valore anche per il passo successivo
.
23
Capitolo 2: Ottimizzazione su grafi

Fondamenti di Ricerca Operativa
Analisi della complessità
La complessità dell’algoritmo dipende dal modo attraverso il quale viene individuato l’arco
del taglio di in ogni singola iterazione.
tra tutti quelli
Se tale arco viene individuato mediante una scansione completa di tutti gi archi del grafo, risulta ovvio che il costo
totale dell’algoritmo è:
Se invece le etichette
vengono determinate per aggiornamento, ovvero si memorizza qual è il lato tra quelli
dell’arco uscente di che consente di raggiungere il nodo con il costo minimo (tra tutti quelli del taglio uscente
da
stesso), sarà sufficiente considerare per ogni nodo non appartenente a
un solo arco, e quindi la
complessità totale diventa:
L’algoritmo di Floyd-Warshall
 L’algoritmo
Come abbiamo già sottolineato, l’algoritmo di Dijkstra non può essere applicato se i costi degli archi non sono
tutti non negativi.
In questo caso si usa allora l’algoritmo di Floyd-Warshall, il quale permette di determinare i cammini minimi tra
tutte le coppie di nodi di un grafo, anche in presenza di archi di costo negativo, a patto però che il problema sia
ben definito, ovvero che non vi siano cicli di costo complessivo negativo: in tal caso infatti più volte si percorre il
ciclo, minore sarà il costo, e perciò è chiaro che non si ha un cammino di costo minimo.
Nel caso in cui il problema sia mal posto, l’algoritmo consente di individuare l’anomalia.

Spiegazione dell’algoritmo
È dato un grafo orientato
, descritto mediante la matrice di incidenza nodo-nodo nella quale ogni
elemento
è il costo
dell’arco
, e nel caso in cui tale arco non appartenga ad è infinito.
Si utilizzano due matrici
: una matrice il cui generico elemento
è, al termine dell’algoritmo, il costo del
cammino minimo da a , ed una matrice il cui elemento
rappresenta alla fine il predecessore di nel
cammino minimo da a stesso.
La matrice
viene inizializzata in modo che sia uguale alla matrice di incidenza, mentre la matrice
inizializzata in modo che per ogni e si abbia
.
viene
Si procede poi considerando tutti gli nodi del grafo. Ad ognuna delle iterazioni, si considera, per ogni coppia di
nodi
tale che e siano diversi da
(senza però escludere il caso
), il cammino che si ottiene
triangolando rispetto ad . In altri termini, si confronta
con il costo del cammino che prevede di andare da ad
e poi da a , ovvero
. Se tale costo risulta inferiore rispetto a
, si pone
e si pone
. Al termine dell’iterazione, si verifica se esiste sulla diagonale principale almeno un elemento con costo
totale negativo: in caso affermativo, significa che il problema è mal posto; in caso contrario, si procede con la
prossima iterazione.
24
Fondamenti di Ricerca Operativa

Capitolo 2: Ottimizzazione su grafi
Pseudocodice
Di seguito è riportato lo pseudocodice che riassume l’algoritmo:
BEGIN
FOR i:=1 TO n DO
FOR j:=1 TO n DO
pij := i;
END-FOR
END-FOR
FOR h:=1 TO n DO
/* operazione triangolare su h */
FOR i:=1 TO n WITH i ≠ h DO
FOR j:=1 TO n WITH j ≠ h DO
IF (dih + dhj < dij) THEN
dij = dih + dhj;
pij := phj;
END-IF
END-FOR
END-FOR
FOR i:=1 TO n DO
IF dii < 0 THEN
STOP;
END-IF
/*
un circuito negativo */
END-FOR
END-FOR
END

Complessità
La complessità dell’algoritmo è
prevede iterazioni.
: risulta infatti chiaro che si hanno 3 cicli annidati, ciascuno dei quali
La programmazione dinamica
In Informatica, la programmazione dinamica è una tecnica di progettazione di algoritmi basata sulla divisione del
problema in sottoproblemi e sull'utilizzo di sottostrutture ottimali. In particolare, diciamo che un problema possiede
una sottostruttura ottimale se è possibile costruire efficientemente una soluzione ottimale a partire dalle soluzioni
ottimali dei suoi sottoproblemi.
Cercheremo ora di applicare il metodo della programmazione dinamica per l’individuazione dei cammini minimi
all’interno di un grafo orientato, nel caso particolare in cui il grafo non abbia circuiti.
Premessa: ordinamento topologico
 Definizione
Dato un grafo orientato aciclico
, è sempre possibile definire un ordinamento, detto topologico, tra
tutti gli archi appartenenti ad , in modo tale che per ogni
, si abbia
, dove il simbolo indica la
relazione “minore di” definita dall’ordinamento stesso.
Naturalmente, l’ordinamento topologico equivale ad assegnare un numero ad ognuno dei nodi del grafo.

Algoritmo per individuare l’ordinamento topologico
L’ordinamento topologico di un grafo può essere ottenuto mediante un semplice algoritmo:
1. Si individua il nodo
tale che
, ovvero tale che non esista alcun arco incidente su (ovvero
entrante in ), e si assegna a tale nodo il minore numero tra quelli non ancora assegnati (1 se è il primo).
2. Si elimina dal grafo il nodo , insieme a tutti gli archi da esso uscenti.
3. Si ripetono i punti precedenti, e si termina solo quando tutti i nodi sono stati eliminati dal grafo di partenza.
La complessità dell’algoritmo è:
25
Capitolo 2: Ottimizzazione su grafi
Fondamenti di Ricerca Operativa
Come usare la programmazione dinamica?
 Il problema
Come già accennato, il problema che vogliamo risolvere è quello di individuare, all’interno di un grafo orientato e
aciclico
, il cammino minimo da un nodo ad un nodo (dove
).

Spiegazione dell’algoritmo
Qualsiasi cammino minimo
che abbia almeno due archi può essere scomposto in due cammini
quali il secondo sia costituito solamente da un arco, ovvero
.
s
s
t
i
e
dei
t
Figura 6: Scomposizione del cammino.
Il costo di un cammino dal nodo a un qualsiasi nodo può essere indicato con
. Si può osservare che:
Nelle ipotesi che abbiamo fatto, è possibile definire l’ordinamento topologico dei nodi del grafo, e, considerata la
definizione di ordinamento topologico, possiamo con certezza affermare che se un nodo è incidente in ,
avremo
, quindi possiamo riscrivere la formula come:
Ponendo per semplicità
precedente:
, possiamo a questo punto scrivere una serie di equazioni da aggiungere alla
E possiamo facilmente risolvere tali equazioni in ordine inverso. In questo modo individuiamo i costi dei cammini
minimi da
a tutti gli altri nodi. Naturalmente poi il predecessore del nodo di arrivo finale sarà sempre il
valore scelto per ottenere il minimo, e quindi sulla base di questa informazione possiamo costruire l’albero dei
cammini minimi.

Analisi di complessità
1. Come accennato, l’ordinamento topologico ha complessità
.
2. Dopodiché, si esegue l’algoritmo vero e proprio, nel quale ogni arco viene considerato esattamente una volta,
e perciò la complessità totale di questa fase è
.
Possiamo allora concludere che la complessità dell’algoritmo è
.

Esattezza
L’algoritmo di Programmazione Dinamica per il problema dei cammini di costo ottimo (minimo o massimo) nei
grafi senza circuiti è esatto. Possiamo verificarlo grazie al seguente principio di ottimalità:
Per ogni cammino minimo (massimo) esiste un nodo
tale che il cammino può essere scomposto in due
sottocammini
26
e
, dove il sottocammino
è di costo minimo (massimo) da s a i.
Fondamenti di Ricerca Operativa
Capitolo 2: Ottimizzazione su grafi
27
Capitolo 4: Programmazione lineare
Fondamenti di Ricerca Operativa
Capitolo 4: Programmazione lineare
I problemi di programmazione lineare
La programmazione lineare (PL oppure LP) è quella branca della ricerca operativa che si occupa di studiare algoritmi di
risoluzione per problemi di ottimizzazione lineari. Un problema è detto lineare se sia la funzione obiettivo sia i vincoli
sono funzioni lineari.
Ipotesi alla base dei modelli di PL
Di conseguenza, i modelli che vengono risolti mediante la programmazione lineare si basano su alcune ipotesi:

Ipotesi di linearità
Questa ipotesi può in realtà essere vista come l’unione di due diverse ipotesi:
a)
Proporzionalità: il contributo di ogni variabile è dato dal prodotto tra il valore della variabile stessa ed una
certa costante. Non si può perciò tenere conto, ad esempio, delle economie di scala.
b) Additività: il contributo di tutte le variabili è dato dalla somma dei contributi delle singole variabili. Questo
non ci permette ad esempio di rappresentare alcune particolari situazioni, come quelle che si verificano nel
caso di prodotti in competizione tra di loro (in tal caso infatti i guadagni non sono tra loro indipendenti).

Ipotesi di parametri costanti
Si assume che tutti i parametri numerici che compaiono nel modello assumano dei valori costanti e che possano
essere stimati con sufficiente precisione.

Ipotesi di divisibilità
Tutti i parametri che compaiono all’interno del modello possono assumere un qualsiasi valore reale.
Problema di programmazione lineare: forma generale
La forma generale di un problema di programmazione lineare prevede che si abbia una certa funzione da minimizzare
o da massimizzare e che la regione ammissibile sia costituita da vincoli di uguaglianza e di disuguaglianza debole.
Inoltre, alcune variabili devono essere non negative, altre invece possono anche essere libere:
,
,
Forma matriciale
Il problema appena introdotto può essere rappresentato anche in forma matriciale:
Soluzione ammissibile e soluzione ottima
 Una soluzione del problema è quindi un vettore
del problema stesso.

Una soluzione
è ammissibile se

Una soluzione
è ottima se
28
che assegna un valore a ciascuna delle
variabili di decisione
.
(si ipotizza che il problema sia di minimizzazione).
Fondamenti di Ricerca Operativa
Capitolo 4: Programmazione lineare
Risoluzione grafica dei problemi di PL
Il metodo grafico
Se il problema di PL è in 2 sole variabili, la regione ammissibile può essere facilmente rappresentata all’interno dello
spazio in due dimensioni.
Inoltre, le linee di livello sono delle rette e, calcolando il gradiente della funzione obiettivo, si può facilmente
individuare qual è la direzione di massimo aumento della funzione obiettivo stessa. Graficamente si può perciò
“seguire” questa direzione (o, se si deve minimizzare, ci si può muovere nella direzione opposta), ed individuare quale
è l’ultimo punto della regione ammissibile che si incontra seguendo la direzione prescelta: tale punto rappresenterà la
soluzione ottima del problema.
Formalizzazione dei concetti geometrici legati alla regione ammissibile
 Ogni vincolo di disuguaglianza definisce un semispazio affine nello spazio delle variabili. Il semispazio affine in
è infatti un sottoinsieme di
del tipo
, dove
rappresenta il gradiente. Il semispazio
affine è sempre delimitato dall’iperpiano
.
Nel caso in cui si abbia
, un semispazio affine non è altro che un semipiano.

La regione ammissibile è un poliedro P, ovvero l’intersezione di un numero finito di semispazi affini. La regione
ammissibile può essere vuota, limitata oppure illimitata.

La regione ammissibile è sempre convessa. Si ricorda che un insieme
è convesso se, per ogni coppia di
punti appartenenti all’insieme stesso, il segmento che congiunge tali punti appartiene interamente ad .
Il segmento che congiunge due punti
e
è l’insieme di tutte le combinazioni convesse di
e
:
Possiamo facilmente verificare che la regione ammissibile è convessa: intuitivamente un semispazio affine è
convesso, e l’intersezione finita di insiemi convessi è sempre a sua volta un insieme convesso.

Chiamiamo vertici del poliedro tutti e soli i punti del poliedro stesso che non possono essere espressi come
combinazione convessa di una coppia di due diversi punti del poliedro stesso.

Un poliedro non vuoto ha sempre un numero di vertici finito e maggiore o uguale ad 1.

Una direzione ammissibile di un poliedro P è un vettore
(
) tale che per ogni punto
ad , il raggio di tale punto è completamente contenuto in P. Il raggio di
è così definito:
Intuitivamente, ciò significa che ci si può “muovere illimitatamente” da
all’interno del poliedro P.
nella direzione
appartenente
, restando sempre

A questo punto, abbiamo tutti gli elementi che ci consentono di definire formalmente una rappresentazione dei
poliedri: ogni punto del poliedro P può essere rappresentato come una combinazione convessa dei suoi vertici,
più una eventuale direzione ammissibile .

Se il poliedro P è limitato, ogni punto di P può essere rappresentato come combinazione convessa dei suoi vertici.
29
Capitolo 4: Programmazione lineare
Fondamenti di Ricerca Operativa
Teorema fondamentale
Dato un problema di PL (di minimizzazione), se il poliedro delle sue soluzioni ammissibili non è vuoto, allora o esiste
almeno un vertice ottimo, oppure il valore della funzione obiettivo non è limitato inferiormente (cioè non esiste una
soluzione ottima).
Possiamo fare alcune osservazioni:

I punti interni del poliedro delle soluzioni ammissibili non sono mai soluzioni ottime: spostandosi anche di poco
nella direzione di massimo aumento (o diminuzione) della funzione obiettivo, si troverà sempre una soluzione
migliore.

In un vertice ottimo, tutte le direzioni che permettono di rispettare l’ammissibilità sono delle direzioni
peggioranti.

Il problema di programmazione lineare può sempre essere risolto in un tempo finito: è sufficiente esaminare tutti
i vertici del poliedro delle soluzioni ammissibili, che sappiamo essere in numero finito. Naturalmente però il
numero di vertici è molto spesso elevatissimo, e la complessità di una soluzione di questo genere è del tutto
inaccettabile nella pratica. Per tale motivo, vengono utilizzati opportuni algoritmi, dei quali il più noto è il metodo
del simplesso.
Possibili soluzioni dei problemi di PL
I problemi di PL possono essere:

Problemi con soluzione ottima e unica (nel caso con
ottimo del poliedro delle soluzioni ammissibili).

Problemi con un numero infinito di soluzioni ottime (nel caso con
, ciò equivale ad individuare un intero lato
del poliedro delle soluzioni ammissibili costituito da soluzioni ottime).

Problemi di PL illimitati (il poliedro delle soluzioni ammissibili è illimitato e non esiste alcuna soluzione ottima).

Problemi di PL inammissibili (la regione ammissibile è vuota).
, ciò equivale ad individuare uno ed un solo vertice
Rappresentazione di un problema di PL in forma standard
Forma standard
Ogni problema in forma generale può essere rappresentato da un problema equivalente in una forma diversa, detta
forma standard, nella quale la funzione obiettivo deve sempre essere minimizzata, tutti i vincoli vengono trasformati
in vincoli di uguaglianza e tutte le variabili devono essere non negative:
(o equivalentemente scriviamo
30
)
Fondamenti di Ricerca Operativa
Capitolo 4: Programmazione lineare
Dalla forma generale alla forma standard
Per passare dalla forma generale alla forma standard è necessario seguire un semplice procedimento, nel corso del
quale è possibile che vengano introdotte nuove variabili e nuovi vincoli.
1.
Se il problema era di massimizzazione, occorre trasformarlo in un problema di minimizzazione, semplicemente
cambiando il segno a e ricordando che il valore ottimo di trovato al termine, dovrà essere cambiato di segno:
2.
I vincoli del tipo “minore o uguale” vengono trasformati in uguaglianze aggiungendo una variabile di scarto , non
negativa, che viene sommata alla parte sinistra della disuguaglianza:
diventa
3.
I vincoli del tipo “maggiore o uguale” vengono trasformati in uguaglianze aggiungendo una variabile di surplus ,
non negativa, che viene sottratta alla parte sinistra della disuguaglianza:
diventa
4.
Se una variabile
è libera, allora viene eliminata dal problema e sostituita con altre 2 variabili non negative
, che rappresentano la “componente positiva” di
quindi
e quella negativa. Ad ogni occorrenza di
e
sostituiamo
.
Equivalenza tra le due rappresentazioni
Le due rappresentazioni, come già accennato, sono equivalenti:
1.
Data una soluzione ammissibile di un problema in forma generale, possiamo estendere questa soluzione,
assegnando le variabili aggiuntive nell’unico modo possibile, imposto dalle equazioni che definiscono la regione
ammissibile del corrispondente problema in forma standard.
2.
Per passare dalla soluzione di un problema di PL in forma standard alla soluzione del problema di PL di partenza,
in forma generale, è sufficiente eliminare dalla soluzione delle variabili di scarto e di surplus.
Naturalmente, questa corrispondenza vale anche per le soluzioni ottime.
31
Scarica