470 likes | 581 Views
Ottimizziamo! Progetto Lauree Scientifiche 3 Dicembre 2010 Istituto “A. Bassi” - Lodi. Giovanni Righini (giovanni.righini@unimi.it) Dipartimento di Tecnologie dell’Informazione (Crema) Università degli Studi di Milano. Il postino del quartiere Martinetta.
E N D
Ottimizziamo!Progetto Lauree Scientifiche3 Dicembre 2010Istituto “A. Bassi” - Lodi Giovanni Righini (giovanni.righini@unimi.it) 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.
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.
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.
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)
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).