Travelling Salesman -ongelma: Python, C++ algoritmi

Mikรค on Travelling Salesman -ongelma (TSP)?

Travelling Salesman Problem (TSP) on teoreettisen tietojenkรคsittelytieteen klassinen kombinatorinen ongelma. Tehtรคvรค pyytรครค lรถytรคmรครคn lyhimmรคn polun kaaviosta, jossa ehdolla kรคydรครคn kaikissa solmuissa vain kerran ja palataan lรคhtรถkaupunkiin.

Ongelmanselvitys antaa luettelon kaupungeista ja kunkin kaupungin vรคliset etรคisyydet.

Tavoite: Aloita lรคhtรถkaupungista vierailemalla muissa kaupungeissa vain kerran ja palaamalla takaisin alkuperรคiseen kaupunkiin. Tavoitteemme on lรถytรครค lyhin mahdollinen reitti edestakaisen reitin suorittamiseen.

Esimerkki TSP:stรค

Tรคssรค esitetรครคn kaavio, jossa 1, 2, 3 ja 4 edustavat kaupunkeja ja jokaiseen reunaan liittyvรค paino edustaa nรคiden kaupunkien vรคlistรค etรคisyyttรค.

Esimerkki TSP:stรค

Tavoitteena on lรถytรครค kiertueelle lyhin mahdollinen polku, joka alkaa lรคhtรถkaupungista, kulkee kaavion lรคpi samalla kun kรคy muissa kaupungeissa tai solmukohdissa vain kerran ja palaa lรคhtรถkaupunkiin.

Yllรค olevalle kaaviolle optimaalinen reitti on seurata vรคhimmรคiskustannuspolkua: 1-2-4-3-1. Ja tรคmรค lyhin reitti maksaisi 10+25+30+15 =80

Erilaisia โ€‹โ€‹ratkaisuja matkustavan myyjรคn ongelmaan

Erilaisia โ€‹โ€‹ratkaisuja matkustavan myyjรคn ongelmaan

Travelling Salesman Problem (TSP) on luokiteltu NP-kovaksi ongelmaksi, koska sillรค ei ole polynomiaikaalgoritmia. Monimutkaisuus kasvaa eksponentiaalisesti lisรครคmรคllรค kaupunkien mรครคrรครค.

On olemassa useita tapoja ratkaista matkustava myyjรค -ongelma (tsp). Joitakin suosittuja ratkaisuja ovat:

Raaka voima lรคhestymistapa on naiivi menetelmรค matkamyyjien ongelmien ratkaisemiseen. Tรคssรค lรคhestymistavassa laskemme ensin kaikki mahdolliset polut ja sitten vertaamme niitรค. Polkujen mรครคrรค kaaviossa, joka koostuu n kaupungista, on n! On laskennallisesti erittรคin kallista ratkaista matkustava myyjรค -ongelma tรคllรค raakavoimalla.

Haara ja sidottu menetelmรค: Tรคssรค lรคhestymistavassa ongelma on jaettu osaongelmiin. Nรคiden yksittรคisten osaongelmien ratkaisu tarjoaisi optimaalisen ratkaisun.

Tรคmรค opetusohjelma esittelee dynaamista ohjelmointitapaa, tรคmรคn haarautuneen ja sidotun menetelmรคn rekursiivisen version, joka ratkaisee matkustavan myyjรคn ongelman.

Dynaaminen ohjelmointi on tรคllainen menetelmรค optimaalisten ratkaisujen etsimiseen analysoimalla kaikki mahdolliset reitit. Se on yksi tรคsmรคllisistรค ratkaisumenetelmistรค, joka ratkaisee matkustavien myyntimiesten ongelmia suhteellisen korkeammalla hinnalla kuin ahneita menetelmiรค jotka tarjoavat lรคhes optimaalisen ratkaisun.

Tรคmรคn lรคhestymistavan laskennallinen monimutkaisuus on O(N^2 * 2^N) jota kรคsitellรครคn myรถhemmin tรคssรค artikkelissa.

Lรคhin naapuri menetelmรค on heuristinen ahne lรคhestymistapa, jossa valitsemme lรคhimmรคn naapurisolmun. Tรคmรค lรคhestymistapa on laskennallisesti halvempi kuin dynaaminen lรคhestymistapa. Mutta se ei takaa optimaalista ratkaisua. Tรคtรค menetelmรครค kรคytetรครคn lรคhes optimaalisiin ratkaisuihin.

Algoritmi matkustavan myyjรคn ongelmalle

Kรคytรคmme dynaamisen ohjelmoinnin lรคhestymistapaa Traveling Salesman -ongelman (TSP) ratkaisemiseen.

Ennen kuin aloitat algoritmin, tutustutaan joihinkin terminologioihin:

  • Graafi G=(V, E), joka on joukko pisteitรค ja kulmia.
  • V on pisteiden joukko.
  • E on reunojen joukko.
  • Vertices yhdistetรครคn reunojen kautta.
  • Dist(i,j) tarkoittaa ei-negatiivista etรคisyyttรค kahden kรคrjen, i ja j, vรคlillรค.

Oletetaan, ettรค S on kaupunkien osajoukko ja kuuluu joukkoon {1, 2, 3, โ€ฆ, n}, missรค 1, 2, 3โ€ฆn ovat kaupungit ja i, j ovat kaksi kaupunkia kyseisessรค osajoukossa. Nyt kustannus(i, S, j) mรครคritellรครคn siten, ettรค S:n lyhimmรคn polun vierailevan solmun pituus on tรคsmรคlleen kerran, jonka aloitus- ja lopetuspisteet ovat vastaavasti i ja j.

Esimerkiksi hinta (1, {2, 3, 4}, 1) tarkoittaa lyhimmรคn polun pituutta, jossa:

  • Aloituskaupunki on 1
  • Kaupungeissa 2, 3 ja 4 kรคydรครคn vain kerran
  • Loppupiste on 1

Dynaaminen ohjelmointialgoritmi olisi:

  • Aseta kustannus(i, , i) = 0, mikรค tarkoittaa, ettรค aloitamme ja lopetamme pisteeseen i, ja kustannus on 0.
  • Kun |S| > 1, mรครคritรคmme kustannus(i, S, 1) = โˆ missรค i !=1 . Koska aluksi emme tiedรค tarkkaa hintaa pรครคstรค kaupunkiin i kaupunkiin 1 muiden kaupunkien kautta.
  • Nyt meidรคn on aloitettava kello 1 ja suoritettava kiertue. Meidรคn on valittava seuraava kaupunki sillรค tavalla-

kustannus(i, S, j)=min hinta (i, Sโˆ’{i}, j)+dist(i,j) missรค iโˆˆS ja iโ‰ j

Annetun kuvion viereisyysmatriisi olisi seuraava:

Algoritmi matkustavan myyjรคn ongelmalle

dist(i,j) 1 2 3 4
1 0 10 15 20
2 10 0 35 25
3 15 35 0 30
4 20 25 30 0

Katsotaanpa, miten algoritmimme toimii:

Vaihe 1) Harkitsemme matkaamme alkaen kaupungista 1, vierailemme kerran muissa kaupungeissa ja palaamme kaupunkiin 1.

Vaihe 2) S on kaupunkien osajoukko. Algoritmimme mukaan kaikille |S| > 1, asetetaan etรคisyyskustannus(i, S, 1) = โˆ. Tรคssรค cost(i, S, j) tarkoittaa, ettรค aloitamme kaupungista i, vierailemme S:n kaupungeissa kerran ja nyt olemme kaupungissa j. Asetamme tรคmรคn polun hinnaksi รครคrettรถmรคksi, koska emme vielรค tiedรค etรคisyyttรค. Arvot ovat siis seuraavat:

Kustannus (2, {3, 4}, 1) = โˆ ; merkintรค tarkoittaa, ettรค aloitamme kaupungista 2, kuljemme kaupunkien 3, 4 lรคpi ja saavutamme 1. Ja polun hinta on รครคretรถn. Samalla lailla-

kustannus(3, {2, 4}, 1) = โˆ

kustannus(4, {2, 3}, 1) = โˆ

Vaihe 3) Nyt kaikille S:n osajoukoille meidรคn on lรถydettรคvรค seuraava:

kustannus(i, S, j)=min kustannus (i, Sโˆ’{i}, j)+dist(i,j), missรค jโˆˆS ja iโ‰ j

Tรคmรค tarkoittaa vรคhimmรคiskustannuspolkua alkaen kohdasta i, kรคymรคllรค lรคpi kaupunkien osajoukko kerran ja palaamalla kaupunkiin j. Ottaen huomioon, ettรค matka alkaa kaupungista 1, optimaalinen polkuhinta olisi = hinta(1, {muut kaupungit}, 1).

Selvitetรครคn, kuinka voimme saavuttaa sen:

Nyt S = {1, 2, 3, 4}. Siinรค on neljรค elementtiรค. Nรคin ollen osajoukkojen mรครคrรค on 2^4 tai 16. Nรคmรค osajoukot ovat

1) |S| = Nolla:

{ฮฆ}

2) |S| = 1:

{{1}, {2}, {3}, {4}}

3) |S| = 2:

{{1, 2}, {1, 3}, {1, 4}, {2, 3}, {2, 4}, {3, 4}}

4) |S| = 3:

{{1, 2, 3}, {1, 2, 4}, {2, 3, 4}, {1, 3, 4}}

5) |S| = 4:

{{1, 2, 3, 4}}

Koska aloitamme kohdasta 1, voimme hylรคtรค kaupungin 1 sisรคltรคvรคt osajoukot.

Algoritmin laskenta:

1) |S| = ฮฆ:

hinta (2, ฮฆ, 1) = dist(2, 1) = 10

hinta (3, ฮฆ, 1) = dist(3, 1) = 15

hinta (4, ฮฆ, 1) = dist(4, 1) = 20

2) |S| = 1:

hinta (2, {3}, 1) = dist(2, 3) + hinta (3, ฮฆ, 1) = 35+15 = 50

hinta (2, {4}, 1) = dist(2, 4) + hinta (4, ฮฆ, 1) = 25+20 = 45

hinta (3, {2}, 1) = dist(3, 2) + hinta (2, ฮฆ, 1) = 35+10 = 45

hinta (3, {4}, 1) = dist(3, 4) + hinta (4, ฮฆ, 1) = 30+20 = 50

hinta (4, {2}, 1) = dist(4, 2) + hinta (2, ฮฆ, 1) = 25+10 = 35

hinta (4, {3}, 1) = dist(4, 3) + hinta (3, ฮฆ, 1) = 30+15 = 45

3) |S| = 2:

hinta (2, {3, 4}, 1) = min [ dist[2,3]+kustannus(3,{4},1) = 35+50 = 85,

jaka[2,4]+kustannus(4,{3},1) = 25+45 = 70 ] = 70

hinta (3, {2, 4}, 1) = min [ dist[3,2]+kustannus(2,{4},1) = 35+45 = 80,

jaka[3,4]+kustannus(4,{2},1) = 30+35 = 65 ] = 65

hinta (4, {2, 3}, 1) = min [ dist[4,2]+kustannus(2,{3},1) = 25+50 = 75

jaka[4,3]+kustannus(3,{2},1) = 30+45 = 75 ] = 75

4) |S| = 3:

hinta (1, {2, 3, 4}, 1) = min [ dist[1,2]+kustannus(2,{3,4},1) = 10+70 = 80

jaka[1,3]+kustannus(3,{2,4},1) = 15+65 = 80

jaka[1,4]+kustannus(4,{2,3},1) = 20+75 = 95 ] = 80

Optimaalinen ratkaisu olisi siis 1-2-4-3-1

Algoritmi matkustavan myyjรคn ongelmalle

Pseudokoodi

Algorithm: Traveling-Salesman-Problem 
Cost (1, {}, 1) = 0 
for s = 2 to n do 
   for all subsets S belongs to {1, 2, 3, โ€ฆ , n} of size s 
      Cost (s, S, 1) = Infinity
   for all i ะ„ S and i โ‰  1 
      Cost (i, S, j) = min {Cost (i, S โ€“ {i}, j) + dist(i, j) for j ะ„ S and i โ‰  j} 
Return min(i) Cost (i, {1, 2, 3, โ€ฆ, n}, j) + d(j, i) 

Toteutus C/C++

Tรคssรค toteutus C++:

#include <bits/stdc++.h>
using namespace std;
#define V 4
#define MAX 1000000
int tsp(int graph[][V], int s)
{
    vector<int> vertex;
    for (int i = 0; i < V; i++)
        if (i != s)
            vertex.push_back(i);
    int min_cost = MAX;
    while(next_permutation(vertex.begin(), vertex.end()))
     {
        int current_cost = 0;
        int j = s;
        for (int i = 0; i < vertex.size(); i++) {
            current_cost += graph[j][vertex[i]];
            j = vertex[i];
        }
        current_cost += graph[j][s];
        min_cost = min(min_cost, current_cost);
        return min_cost;
	}
}
int main()
{
    int graph[][V] = { { 0, 10, 15, 20 },{ 10, 0, 35, 25 },{ 15, 35, 0, 30 },{ 20, 25, 30, 0 } };                      
    int s = 0;
    cout << tsp(graph, s) << endl;
    return 0;
}

lรคhtรถ:

80

Toteutus sisรครคn Python

from sys import maxsize
from itertools, import permutations
V = 4
def tsp(graph, s):
	vertex = []
	for i in range(V):
		if i != s:
			vertex.append(i)
    min_cost = maxsize
	next_permutation=permutations(vertex)
	for i in next_permutation:
		current_cost = 0
		k = s
		for j in i:
			current_cost += graph[k][j]
			k = j
		current_cost += graph[k][s]
		min_cost = min(min_cost, current_cost)
		return min_cost
graph = [[0, 10, 15, 20], [10, 0, 35, 25], [15, 35, 0, 30], [20, 25, 30, 0]]
		s = 0
print(tsp(graph, s))

lรคhtรถ:

80

Akateemiset ratkaisut TSP:lle

Tietojenkรคsittelytieteilijรคt ovat kรคyttรคneet vuosia etsiessรครคn parannettua polynomiaikaalgoritmia Travelling Salesman -ongelmaan. Toistaiseksi ongelma on edelleen NP-kova.

Vaikka viime vuosina on julkaistu joitakin seuraavista ratkaisuista, jotka ovat vรคhentรคneet monimutkaisuutta jossain mรครคrin:

  • Klassinen symmetrinen TSP ratkaistaan โ€‹โ€‹nollaliitemenetelmรคllรค.
  • Biogeografiaan perustuva optimointialgoritmi perustuu migraatiostrategiaan, joka ratkaisee optimointiongelmat, jotka voidaan suunnitella TSP:ksi.
  • Multi-Objective Evolutionary Algorithm on suunniteltu useiden TSP:iden ratkaisemiseen NSGA-II:n perusteella.
  • Multi-Agent System ratkaisee N kaupungin TSP:n kiinteillรค resursseilla.

Travelling Salesman -ongelman soveltaminen

Travelling Salesman Problem (TSP) -ongelmaa sovelletaan todellisessa maailmassa sekรค puhtaimmissa ettรค muunnetuissa muodoissaan. Jotkut niistรค ovat:

  • Mikrosirujen suunnittelu, logistiikka ja valmistus: Mikrosiruteollisuudessa esiintyy luonnollisesti sirun kiinnitysongelmia. Nรคmรค ongelmat voidaan suunnitella matkamyyjien ongelmiksi.
  • DNA-sekvensointi: Hieman muunneltua matkustava myyjรค -ongelmaa voidaan kรคyttรครค DNA-sekvensoinnissa. Tรคssรค kaupungit edustavat DNA-fragmentteja, ja etรคisyys edustaa kahden DNA-fragmentin vรคlistรค samankaltaisuuden mittaa.
  • Tรคhtitiede: Tรคhtitieteilijรคt soveltavat Travelling Salesman -ongelmaa minimoimaan eri lรคhteiden tarkkailuun kรคytettyรค aikaa.
  • Optimaalinen ohjausongelma: Travelling Salesman Ongelman muotoilua voidaan soveltaa optimaalisiin ohjausongelmiin. Saattaa olla useita muita rajoituksia lisรคtty.

TSP:n monimutkaisuusanalyysi

  • Ajan monimutkaisuus: Niitรค on yhteensรค 2N aliongelmat jokaiselle solmulle. Joten aliongelmien kokonaismรครคrรค olisi N*2N. Jokaisen osaongelman ratkaiseminen vaatii lineaarista aikaa. Jos alkuperรคsolmua ei ole mรครคritetty, meidรคn on suoritettava silmukoita N solmulle.

    Optimaalisen ratkaisun kokonaisaika monimutkaisuus olisi siis solmujen lukumรครคrรค * aliongelmien lukumรครคrรค * kunkin osaongelman ratkaisemiseen kuluva aika. Aika monimutkaisuus voidaan mรครคritellรค muodossa O(N2 * 2^N).

  • Avaruuden monimutkaisuus: Dynaaminen ohjelmointitapa kรคyttรครค muistia C(S, i) tallentamiseen, missรค S on kรคrkijoukon osajoukko. Niitรค on yhteensรค 2N alajoukot jokaiselle solmulle. Joten avaruuden kompleksisuus on O(2^N).

Seuraavaksi opit aiheesta Eratosthenes-algoritmin seula

Tiivistรค tรคmรค viesti seuraavasti: