OTTIMIZZIAMO! Seconda parte

Download Report

Transcript OTTIMIZZIAMO! Seconda parte

Ottimizziamo!
Progetto Lauree Scientifiche
3 Dicembre 2010
Istituto “A. Bassi” - Lodi
Giovanni Righini
([email protected])
Dipartimento di Tecnologie dell’Informazione (Crema)
Università degli Studi di Milano
Il postino del quartiere Martinetta
• Ogni giorno dall’ufficio postale che si trova nel centro
della città un postino deve recarsi nel quartiere
Martinetta e distribuire la posta a tutti gli indirizzi.
• Per farlo, egli deve percorrere tutte le strade del
quartiere.
• Poiché procede in bicicletta e non c’è traffico nel
quartiere, egli può anche pedalare contromano nelle
strade a senso unico, e inoltre può distribuire la posta su
entrambi i lati di ogni strada percorrendola una volta
sola.
• Per ottimizzare il tempo a sua disposizione, egli
vorrebbe trovare il percorso di minima lunghezza.
– Dalla mappa stradale ricaviamo un grafo, composto da
nodi e archi.
– Alcuni archi sono orientati (sensi unici), altri no.
– Nel passaggio dalla mappa al grafo abbiamo operato
alcune semplificazioni:
• tutte le strade in entrata e uscita dal quartiere sono state troncate
ad un certo punto (a seconda della presenza o assenza di
abitazioni);
• le strade secondarie o private sono state trascurate;
• i sensi unici sono stati rappresentati ma li trascureremo nel
risolvere il problema.
– Tutti i nodi del grafo sono stati numerati per identificarli con
maggiore comodità e in modo non ambiguo.
– A tutti gli archi del grafo è stato associato un costo, che
rappresenta la lunghezza dell’arco in un’opportuna unità di
misura.
Abbiamo un grafo con 29 nodi e 34 archi.
Problema. Sapreste trovare il percorso che consente al
postino di attraversare tutti i 34 archi del grafo, partendo
dal nodo 1 e tornando al nodo 1?
Osservazione. Sarebbe utile non dover percorrere nessun
arco più di una volta.
Osservazione. Alcuni archi del grafo terminano in un nodo da
cui non si possono raggiungere altri archi. Il postino deve
quindi tornare sui suoi passi, percorrendo necessariamente
questi archi prima in un direzione e poi nell’altra.
Esempio. Il postino dovrà andare dal nodo 22 al 24 e poi dal 24
non potrà fare altro che tornare al 22. Quindi l’arco 22-24 sarà
percorso due volte.
Possiamo identificare facilmente tutti questi casi: corrispondono
ai nodi che hanno grado uguale a 1.
Il grado di un nodo è il numero di archi di cui il nodo è estremo
o, in altri termini, il numero di archi incidenti in quel nodo.
Gli archi incidenti in nodi di grado 1 vanno raddoppiati (percorsi
2 volte): anche il loro costo deve essere conteggiato 2 volte.
Dopo questa modifica nel grafo non ci sono più nodi di
grado uguale a 1.
Possiamo porci di nuovo la domanda precedente.
E’ possibile percorrere tutti gli archi del grafo una volta
sola, partendo dal nodo 1 e tornando al nodo 1?
Provate…
Dopo questa modifica nel grafo non ci sono più nodi di
grado uguale a 1.
Possiamo porci di nuovo la domanda precedente.
E’ possibile percorrere tutti gli archi del grafo una volta
sola, partendo dal nodo 1 e tornando al nodo 1?
Provate… “No”.
Non c’è modo di percorrere tutti gli archi di questo grafo
esattamente una volta tornando al punto di partenza.
In altri termini, non c’è modo di disegnare questo grafo, un
arco dopo l’altro, senza staccare la matita dal foglio.
Poniamoci allora una domanda
più generale: “Quali
condizioni deve soddisfare
un grafo per essere
disegnabile senza staccare
la matita dal foglio?”
Questa questione fu affrontata
e risolta nel 1736 da un
grande matematico: lo
svizzero Leonhard Euler
(1707-1783).
I sette ponti di Königsberg
“Si può fare una passeggiata che torni al punto di partenza dopo
aver attraversato esattamente una volta ciascuno dei 7 ponti?”
Anche in questo caso la risposta è “No”.
Sapreste dimostrarlo?
Anche in questo caso la risposta è “No”.
Sapreste dimostrarlo?
Eulero formulò il problema usando un grafo.
I nodi sono le 4 zone della città e gli archi sono i 7 ponti.
Egli considerò poi il grado dei quattro nodi, cioè il numero di
archi incidenti in essi.
Nodo
Grado
Nord
3
Sud
3
Est
3
Isola
5
• Lungo ogni percorso, ogni nodo viene raggiunto e
lasciato un ugual numero di volte.
• Quindi il grado di ogni nodo lungo il percorso è pari al
doppio del numero di visite a quel nodo e quindi è un
numero pari.
• Affinché ogni arco venga percorso esattamente una
volta, è quindi necessario che tutti i nodi abbiano grado
pari.
• A Königsberg non è così: tutti i nodi hanno grado dispari!
Ecco perché la passeggiata sui sette ponti non è
possibile.
• Si può dimostrare che la condizione di Eulero sul grado
dei nodi è anche sufficiente, purché il grafo sia
connesso.
• Un grafo che rispetta queste condizioni è un grafo
euleriano e su di esso è possibile percorrere un ciclo
euleriano.
L’analisi del grafo rivela la presenza di 10 nodi di grado dispari.
Per rendere euleriano questo grafo dobbiamo aggiungere
altri archi (pagando i corrispondenti costi).
Gli archi da aggiungere corrisponderanno ad ulteriori
passate lungo le vie del quartiere, come gli archi verdi
che abbiamo già aggiunto.
Quanti archi dobbiamo aggiungere?
Per rendere euleriano questo grafo dobbiamo aggiungere
altri archi (pagando i corrispondenti costi).
Gli archi da aggiungere corrisponderanno ad ulteriori
passate lungo le vie del quartiere, come gli archi verdi
che abbiamo già aggiunto.
Quanti archi dobbiamo aggiungere?
Dobbiamo far diventare pari il grado dei nodi che hanno
grado dispari.
Ogni volta che aggiungiamo al grafo un arco, aumentiamo
di 1 il grado di entrambi i suoi estremi.
Se sono 10 i nodi il cui grado deve essere aumentato,
dobbiamo aggiungere almeno 5 archi, che non abbiano
estremi in comune.
Nel nostro grafo esistono 5 archi con questa proprietà?
Provate...
Per rendere euleriano questo grafo dobbiamo aggiungere
altri archi (pagando i corrispondenti costi).
Gli archi da aggiungere corrisponderanno ad ulteriori
passate lungo le vie del quartiere, come gli archi verdi
che abbiamo già aggiunto.
Quanti archi dobbiamo aggiungere?
Dobbiamo far diventare pari il grado dei nodi che hanno
grado dispari.
Ogni volta che aggiungiamo al grafo un arco, aumentiamo
di 1 il grado di entrambi i suoi estremi.
Se sono 10 i nodi il cui grado deve essere aumentato,
dobbiamo aggiungere almeno 5 archi, che non abbiano
estremi in comune.
Nel nostro grafo esistono 5 archi con questa proprietà?
Provate...
No, non esistono.
Dobbiamo generalizzare leggermente la nostra richiesta.
Per aumentare di 1 il grado di due nodi si può inserire
– un arco che li collega direttamente
– un cammino, che li collega indirettamente.
Il grado di ogni nodo lungo il cammino aumenta di 2 e quindi
non cambia parità.
Il grado degli estremi del cammino aumenta di 1 e quindi
cambia parità.
Cerchiamo allora 5 cammini, che abbiano come estremi i 10
nodi di grado dispari e senza estremi in comune.
Provate...
Dobbiamo generalizzare leggermente la nostra richiesta.
Per aumentare di 1 il grado di due nodi si può inserire
– un arco che li collega direttamente
– un cammino, che li collega indirettamente.
Il grado di ogni nodo lungo il cammino aumenta di 2 e quindi
non cambia parità.
Il grado degli estremi del cammino aumenta di 1 e quindi
cambia parità.
Cerchiamo allora 5 cammini, che abbiano come estremi i 10
nodi di grado dispari e senza estremi in comune.
Provate...
Ci sono tante soluzioni possibili!
Come trovare la migliore, cioè quella di costo minimo?
E’ un problema di ottimizzazione.
Lo affronteremo definendone i 4 componenti fondamentali:
– i dati,
– le variabili,
– i vincoli,
– l’obiettivo
e useremo il linguaggio matematico per definirli.
Dati (= “ciò che si sa”)
Abbiamo dieci nodi da connettere a due a due e ci serve
conoscere i costi di ogni connessione.
Domanda. Poiché i nodi sono dieci, quante sono le
connessioni possibili?
Dati (= “ciò che si sa”)
Abbiamo dieci nodi da connettere a due a due e ci serve
conoscere i costi di ogni connessione.
Domanda. Poiché i nodi sono dieci, quante sono le
connessioni possibili?
Risposta. Sono tutte quelle da ogni nodo ad ogni altro (10
x 10), tranne che tra un nodo a sè stesso: 10 x 10 – 10 =
90.
Domanda. Qual è il costo di connessione da un generico
nodo A ad un generico nodo B?
Dati (= “ciò che si sa”)
Abbiamo dieci nodi da connettere a due a due e ci serve
conoscere i costi di ogni connessione.
Domanda. Poiché i nodi sono dieci, quante sono le
connessioni possibili?
Risposta. Sono tutte quelle da ogni nodo ad ogni altro (10
x 10), tranne che tra un nodo a sè stesso: 10 x 10 – 10 =
90.
Domanda. Qual è il costo di connessione da un generico
nodo A ad un generico nodo B?
Risposta. E’ la lunghezza del cammino minimo da A a B.
Dati (= “ciò che si sa”)
• Siccome consideriamo il grafo simmetrico, trascurando i
sensi unici, ci basta calcolare la metà dei valori, perché
la lunghezza di ogni cammino minimo da A a B è uguale
alla lunghezza del cammino minimo da B ad A.
• Una volta trovati tutti i cammini minimi che ci servono
(che sono quindi 45) ne memorizziamo le lunghezze in
una matrice, cioè in una tabella con tante righe e tante
colonne quanti i nodi di grado dispari.
• Per la simmetria, ci basta metà della matrice.
• Non servono neanche gli elementi sulla diagonale
principale della matrice.
Dati (= “ciò che si sa”)
Dist.
3
4
7
8
12
13
14
19
20
27
3
4
1
7
10
8
4
12
13
13
11
14
7
19
15
20
12
27
18
9
3
6
12
5
9
10
7
7
6
9
3
14
9
11
11
14
8
17
20
14
2
6
4
6
4
8
11
9
5
5
17
15
11
11
6
Variabili (= “ciò che va deciso”)
• Domanda. Quali scelte dobbiamo fare?
Variabili (= “ciò che va deciso”)
• Domanda. Quali scelte dobbiamo fare?
• Risposta. Dobbiamo decidere se inserire nel grafo una
connessione tra due nodi di grado dispari oppure no.
• Domanda. Quante sono le variabili?
Variabili (= “ciò che va deciso”)
• Domanda. Quali scelte dobbiamo fare?
• Risposta. Dobbiamo decidere se inserire nel grafo una
connessione tra due nodi di grado dispari oppure no.
• Domanda. Quante sono le variabili?
• Risposta. Sono tante quante le connessioni possibili,
cioè 45.
• Domanda. Quali valori possono assumere?
Variabili (= “ciò che va deciso”)
• Domanda. Quali scelte dobbiamo fare?
• Risposta. Dobbiamo decidere se inserire nel grafo una
connessione tra due nodi di grado dispari oppure no.
• Domanda. Quante sono le variabili?
• Risposta. Sono tante quante le connessioni possibili,
cioè 45.
• Domanda. Quali valori possono assumere?
• Risposta. Solo due valori: “sì” e “no”. Useremo a questo
scopo 0 per indicare “no” (connessione non scelta) e 1
per indicare “sì” (connessione scelta)
Variabili (= “ciò che va deciso”)
Var.
3
4
7
8
12
13
14
19
20
27
3
4
7
8
12
13
14
19
20
27
1
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
1
Notazione matematica
Indichiamo le distanze (date) con d(A,B) per ogni coppia di
nodi di grado dispari A e B.
Indichiamo le variabili con x(A,B) per ogni coppia di nodi di
grado dispari A e B.
Vincoli (= “ciò che non si può fare”)
• Domanda. Quali condizioni devono essere rispettate
affinché la soluzione sia ammmissibile?
Vincoli (= “ciò che non si può fare”)
• Domanda. Quali condizioni devono essere rispettate
affinché la soluzione sia ammmissibile?
• Risposta. Dobbiamo imporre che ogni nodo di grado
dispari sia estremo di esattamente uno dei cammini
scelti. In altri termini, il numero di variabili poste a 1 sulla
sua riga e sulla sua colonna deve complessivamente
essere pari a 1.
• Esempio (nodo 12). Corrisponde a riga e colonna n.5.
x(3,12) + x(4,12) + x(7,12) + x(8,12) +
+ x(12,13) + x(12,14) + x(12,19) + x(12,20) + x(12,27) = 1
Obiettivo (= “ciò che si desidera”)
Domanda. Cosa vogliamo ottimizzare?
Obiettivo (= “ciò che si desidera”)
Domanda. Cosa vogliamo ottimizzare?
Risposta. Vogliamo minimizzare i costi complessivi dei
cammini scelti. Tali costi sono dati dalla somma delle
distanze d(A,B) corrispondenti alle posizioni (A,B) della
matrice in cui abbiamo deciso di porre x(A,B) = 1.
In linguaggio matematico possiamo quindi indicare con z la
lunghezza complessiva dei cammini scelti e definirla
così:
z = d(3,4) x(3,4) +...+ d(3,27) x(3,27) +
+ d(4,7) x(4,7) +...+ d(4,27) x(4,27) +
+ ... +
+ d(20,27) x(20,27).
E adesso?
• Adesso che il problema di ottimizzazione è stato
formulato matematicamente può essere risolto con un
opportuno algoritmo.
• L’algoritmo si può eseguire a mano oppure lo si può far
eseguire ad un calcolatore!
• Proviamo...
La soluzione ottimale!
La soluzione ottimale è proprio quella indicata nella tabella
precedente. Il suo costo è pari a 19.
Il grafo che otteniamo ha finalmente tutti i nodi di grado
pari: è un grafo euleriano.
Il costo totale della soluzione così ottenuta è dato da:
– il costo di tutti i 34 archi del quartiere (141),
– il costo di tutti gli archi che abbiamo dovuto
raddoppiare a causa dei nodi di grado 1 (53),
– il costo di tutti i cammini che abbiamo dovuto
aggiungere per rendere euleriano il grafo (19).
In totale: 141 + 53 + 19 = 213.
Resta un ultimo semplice problema.
Domanda. Come si costruisce il percorso del postino (ciclo
euleriano) a partire dal grafo euleriano?
Risposta. Esiste un facile algoritmo:
• Si inizializza il nodo corrente al nodo 1
• iterativamente si sceglie un arco incidente al nodo
corrente per raggiungere un nuovo nodo corrente.
• Ogni volta che si percorre un arco lo si cancella.
• Ogni volta che si deve decidere quale arco percorrere
bisogna controllare che cancellandolo il grafo rimanga
connesso (a parte i nodi di grado 0).