Il problema
del
commesso
viaggiatore
Vediamo un esempio di
“informatica”
•
•
•
•
•
Modellazione astratta di un problema reale
Definizione di algoritmi che lo risolvano
Ricorsione
Confronto tra l’efficienza di diversi algoritmi
Esistenza di problemi difficili
Avete mai pianificato un viaggio
in più tappe?
Quale metodo avete usato per
minimizzare la distanza totale
percorsa?
Cartina alla mano non sembra così
difficile ... soprattutto per poche tappe
Pensate però per esempio di dover
pianificare le tappe della campagna
elettorale negli USA ...
?
Definiamo meglio il problema
Traveling Salesman’s Problem
(TSP)
• Un commesso viaggiatore deve visitare un certo
numero di città
• Conosce la distanza da una città all’altra
• Vuole determinare il cammino più breve che gli
permetta di partire da casa sua e di farvi ritorno
dopo aver visitato ogni città una sola volta
• Come può fare?
Caratteristiche del problema
• TSP è uno dei problemi più studiati in informatica
• Appartiene alla classe dei problemi difficili (NPhard), vedremo poi in che senso
• La prima formulazione risale al 1857 e all’icosian
game inventato dal matematico William Hamilton
Icosian Game (1857)
Scopo: trovare un tour lungo gli spigoli di un dodecaedro
Icosian Game: Scacchiera
Il tour deve passare una sola volta da ogni nodo
È un caso molto particolare di TSP!
Forma generale TSP
• La formulazione generale considera forme
geometriche qualsiasi e distanze tra le città
• Venne introdotta tra gli anni ’40 e ’50
• Nel corso degli anni ha trovato numerose
istanziazioni interessanti:
– logistica e trasporti
– costruzione di circuiti stampati (pianificazione del
cammino del trapano)
– protocolli di routing
– DNA sequencing
– ...
Modelliamo e studiamo
TSP
Quali informazioni ci servono?
Città = nodi
AOSTA
MILANO
TORINO
GENOVA
Distanze = archi pesati
AOSTA
186
115
142
TORINO
MILANO
246
140
169
GENOVA
Modello = Grafo (non orientato, pesato)
6
A
4
B
5
6
C 2
8
F
3
Archi=strade
4
D
7
E
9
6
Nodi=città
2
G
Pesi=distanze
Definizione di grafo
grafo (semplice) G = (V, E):
• insieme V di nodi o vertici
• insieme E di archi (o spigoli, ingl. edges)
• ogni arco è una coppia di nodi distinti, detti estremi
dell’arco
due tipi di grafi:
• non orientati (undirected): gli archi non hanno un verso,
cioè, formalmente, sono coppie non ordinate
• orientati (directed): gli archi hanno un verso, cioè sono
coppie ordinate
Altre definizioni
• cammino = sequenza di nodi v0 … vn con n  0, (vi, vi+1)
arco per ogni 0  i < n
• lunghezza di un cammino = numero archi = numero dei
nodi – 1
• ciclo = cammino (non nullo) in cui il primo nodo coincide
con l'ultimo
• ciclo hamiltoniano = ciclo in cui tutti i nodi sono distinti
tranne il primo e l’ultimo
• grafo pesato = grafo + funzione c che associa a ogni arco
un peso (costo)
• costo di un cammino = somma costi archi
cammino in grafo
6
A
4
B
5
6
C 2
4
D
7
8
F
3
E
9
6
2
G
A C D E G = cammino con costo 4+2+4+2=14
Ciclo = cammino chiuso
6
A
4
B
5
6
C 2
4
D
7
8
F
3
E
9
6
2
G
A C D E B A = ciclo con costo 4+2+4+3+6
Ciclo hamiltoniano (tour)
6
A
4
B
5
6
C 2
4
D
7
8
F
3
E
9
6
2
G
È un ciclo che visita TUTTI i nodi UNA SOLA volta
Ciclo non hamiltoniano
6
A
4
B
5
6
C 2
4
D
7
8
F
3
E
9
6
2
G
Non visita tutti i nodi!
Ciclo non hamiltoniano
6
A
4
B
5
6
C 2
4
D
7
8
F
3
E
9
6
2
G
A C F D E G E … G E B A: G ed E visitati varie volte
TSP come problema sui grafi
dato un grafo pesato G
calcolare un
ciclo hamiltoniano di costo minimo
In termini più informatici:
dare un algoritmo che dato un grafo pesato
G calcoli un ciclo hamiltoniano di costo
minimo
G
min, costomin
Min_ham
Algoritmo
• Algoritmo: sequenza di istruzioni eseguibile
“automaticamente”
• Esempi di istruzioni:
– variabile = valore
– SE (condizione) ALLORA azione
– SE (condizione) ALLORA azione ALTRIMENTI azione
- PER OGNI (valore in insieme) azione
- FINCHÈ (condizione) azione
Scritto in un linguaggio di programmazione può essere
eseguito da un calcolatore
Problema preliminare: quanti e quali cicli hamiltoniani (a partire
da A) contiene il seguente grafo?
A
2
B
1
5
6
E
3
1
C
3
D
Algoritmo richiesto
G, v1
hcicli
Ham
Versione testuale (ricorsiva) dell’algoritmo
Ham(G, v1 … vk, hcicli) =
SE (ci sono nodi non in v1 … vk) ALLORA
PER OGNI (arco (vk,v) con v non in v1 … vk)
Ham(G, v1 … vk v, hcicli)
ALTRIMENTI
SE (c’è arco(vk, v1)) ALLORA
hcicli = hcicli + v1 … vk v1
Chiamata iniziale
hcicli = insieme vuoto
Ham(G, v1, hcicli)
Modifichiamo in modo da trovare il cammino minimo
algoritmo richiesto:
G, v1
min, costomin
Min_ham
Modifichiamo in modo da trovare il cammino
minimo
Min_ham(G, v1 … vk, costo, min, costomin) =
SE (ci sono nodi in G non in v1 … vk) ALLORA
PER OGNI (arco (vk,v) con v non in v1 … vk)
Min_ham(G, v1 … vk v, costo+c(vk,v), min, costomin)
ALTRIMENTI
SE (c’è arco(vk, v1)) E costo+ c(vk, v1) < costomin
ALLORA
min = v1 … vk v1
costomin = costo+ c(vk, v1)
Chiamata iniziale:
costomin = +∞
Min_ham(G, v1, min, costomin)
Quanto “costa” questo algoritmo?
• Se il grafo è completo, ossia c’è un arco per
ogni coppia di nodi (come avviene nel TSP)
i cicli hamiltoniani sono tanti quante le
permutazioni dei nodi
Se il grafo è completo, equivalentemente:
Generate & Test
costomin = +∞
Min_ham(G, min, costomin)
PER OGNI (permutazione v1 … vn dei nodi di G)
costo = c(v1, v2)+....+ c(vn-1, vn)
SE costo < costomin ALLORA
min = v1 … vn
costomin = costo
È possibile evitare di generare TUTTE le permutazioni?
In qualche caso …
Min_ham(G, v1 … vk, costo, min, costomin) =
SE (ci sono nodi non in v1 … vk) ALLORA
PER OGNI (arco (vk,v) con v non in v1 … vk)
SE costo+costo(vk,v) < costomin ALLORA
Min_ham(G, v1 … vk v, costo+c(vk,v), min, costomin)
ALTRIMENTI
SE (arco(vk, v1)) E costo+ c(vk, v1) < costomin
ALLORA
min = v1 … vk v1
costomin = costo+ c(vk, v1)
Tuttavia, questo non migliora le prestazioni
dell’algoritmo “in generale” …
C’è sempre un caso peggiore
Problema
• Trovare una soluzione esatta del problema
TSP (cioè calcolare un tour minimo) è
difficile anche per un elaboratore
• La difficoltà è legata al numero di possibili
percorsi che occorre esplorare per calcolare
quello minimo
Per capire la difficoltà del problema
... facciamo due conti
• Negli USA ci sono 49 stati continentali + un
distretto
• Supponiamo che si programmi di fare un
solo comizio in ogni stato
Quanti percorsi devo considerare per
calcolare il migliore?
• Partendo da Washington, ci sono 49
possibili scelte per la prima tappa
• Fissata la prima tappa, rimangono 48 scelte
per la seconda tappa
• Fissata la seconda tappa, rimangono 47
scelte per la terza tappa
• ...
Il numero di possibili percorsi tra i quali
trovare il più breve è
49! = 49 * 48 * ... * 3 * 2 * 1
... nell’ordine di 1062 cioè maggiore del
numero di atomi di cui è composta la Terra
Ricapitolando
• Grafo completo = esiste un arco per ogni coppia di nodi
• Il numero di cicli hamiltoniani in un grafo completo con n
nodi è pari a (n-1)!
• Il numero di cicli hamiltoniani cresce esponenzialmente
col numero dei nodi
Si può veramente risolvere?
Sì, è stato calcolato nel 1954!
È stato risolto per molte più città!
per esempio 13,509 città
Metodi di risoluzione per TSP
Algoritmi per TSP
Algoritmi esatti
Applicabili solo a problemi con un numero di città
relativamente basso
Algoritmi euristici
Producono soluzioni probabilmente buone, ma
non necessariamente ottimali
Problema
• Abbiamo visto che per TSP con molte città
il numero di possibili percorsi può essere
astronomico!
• Provate a pensare e scrivere un algoritmo
euristico ... quello che probabilmente usate
nei vostri viaggi ...
Un Algoritmo Euristico
Nearest Neighbour (NN)
• Partendo da un nodo iniziale scelto a piacere, ci
muoviamo sempre verso la città più vicina non
ancora visitata
• L’algoritmo termina quando abbiamo visitato tutte
le città
Esempio Nearest Neighbour
A
5
C
B
2
4
4
2
3
D
...
Algoritmo Nearest Neighbour
NN(G, cammino) =
SE (ci sono nodi non in cammino) ALLORA
nodomin = nodo non in cammino più “vicino” a cammino.fine
cammino = cammino + nodomin
NN(G,cammino)
ALTRIMENTI
cammino = cammino + cammino.inizio
Chiamata iniziale:
cammino = v1
NN(G, cammino)
Algoritmo Nearest Neighbour
NN(G, cammino) =
SE (ci sono nodi non in cammino) ALLORA
costomin = +∞
PER OGNI (arco(cammino.fine,v) con v non in cammino)
SE c(cammino.fine,v) < costomin
ALLORA
nodomin = v;
costomin = c(cammino.fine,v)
cammino = cammino + nodomin
NN(G,cammino)
ALTRIMENTI
cammino = cammino + (cammino.fine,cammino.inizio)
Chiamata iniziale:
cammino = v1
NN(G, cammino)
Osservazioni su NN
• È un algoritmo intuitivo
• Non dà sempre la soluzione ottimale (cercare di
ottenere un vantaggio immediato non sempre è la
scelta migliore...)
• Tuttavia è una buona approssimazione
dell’algoritmo esatto
Esistono molti altri algoritmi
• Algoritmi basati su programmazione intera
lineare (LIP)
– si codifica il problema come un insieme di
disequazioni ed una funzione costo
– si usano euristiche per problemi di LIP
• Algoritmi genetici
• ...
Sistemi per risolvere TSP
• Concorde: http://www.tsp.gatech.edu/
• Nel 2004 ha calcolato un tour minimo attraverso
24.978 citta’ in Svezia (72.500 km)
• Idea: si calcola una soluzione con un
algoritmo euristico e poi si controlla
che sia ottimale
Esercizi
Applicate l’algoritmo Nearest Neighbour al
seguente grafo a partire dal nodo A
6
A
5
4
C 2
6
5
3
8
F
3
1
D
3
8
B
E
9
6
2
G
4
Applicate l’algoritmo Nearest Neighbour al
seguente grafo a partire dal nodo E
6
A
5
4
C 2
6
5
3
8
F
3
1
D
3
8
B
E
9
6
2
G
4
Aggiungete pesi (qualsiasi) sugli archi in modo
che la soluzione calcolata con l’algoritmo NN a
partire dal nodo A non sia quella ottimale
A
B
C
D
Scarica

Il Problema del Commesso Viaggiatore