Suche…


Bemerkungen

Das Problem des reisenden Verkäufers besteht darin, die minimalen Kosten für das Durchlaufen von N Knoten genau einmal pro Knoten zu ermitteln. Die Reise von Scheitelpunkt i zum Scheitelpunkt j kostet cost[i][j] .

Es gibt zwei Arten von Algorithmen, um dieses Problem zu lösen: Exakte Algorithmen und Approximationsalgorithmen

Genaue Algorithmen

  1. Brute-Force-Algorithmus
  2. Dynamischer Programmieralgorithmus

Approximationsalgorithmen

Hinzugefügt werden

Brute-Force-Algorithmus

Ein Pfad durch jeden Knoten genau einmal ist gleichbedeutend mit der Anordnung des Scheitelpunkts. Um die minimalen Kosten für das einmalige Durchlaufen jedes Scheitelpunkts genau zu berechnen, können wir also jeden einzelnen der N! Permutationen der Zahlen von 1 bis N

Psuedocode

minimum = INF
for all permutations P

    current = 0                                

    for i from 0 to N-2
        current = current + cost[P[i]][P[i+1]]  <- Add the cost of going from 1 vertex to the next
    
    current = current + cost[P[N-1]][P[0]]      <- Add the cost of going from last vertex to the first

    if current < minimum                        <- Update minimum if necessary
        minimum = current
    
output minimum

Zeitkomplexität

Es gibt N! Permutationen zum Durchlaufen und die Kosten für jeden Pfad werden in O(N) berechnet. Daher benötigt dieser Algorithmus O(N * N!) Zeit, um die genaue Antwort auszugeben.

Dynamischer Programmieralgorithmus

Beachten Sie, dass, wenn wir den Pfad berücksichtigen (in Reihenfolge):

(1,2,3,4,6,0,5,7)

und der Weg

(1,2,3,5,0,6,7,4) 

Die Kosten für den Übergang vom Scheitelpunkt 1 zum Scheitelpunkt 2 zum Scheitelpunkt 3 bleiben gleich. Warum muss er neu berechnet werden? Dieses Ergebnis kann zur späteren Verwendung gespeichert werden.

Sei dp[bitmask][vertex] die minimalen Kosten für das Durchlaufen aller Scheitelpunkte, deren entsprechendes Bit in der bitmask auf 1 und am vertex endet. Zum Beispiel:

dp[12][2] 

   12   =   1 1 0 0
            ^ ^ 
vertices:   3 2 1 0

Da 12 1100 binär darstellt, repräsentiert dp[12][2] das Durchlaufen der Scheitelpunkte 2 und 3 im Graphen, wobei der Pfad am Scheitelpunkt 2 endet.

Daher können wir den folgenden Algorithmus verwenden (C ++ - Implementierung):

int cost[N][N];                        //Adjust the value of N if needed
int memo[1 << N][N];                   //Set everything here to -1
int TSP(int bitmask, int pos){
    int cost = INF;
    if (bitmask == ((1 << N) - 1)){      //All vertices have been explored
        return cost[pos][0];             //Cost to go back
    }
    if (memo[bitmask][pos] != -1){       //If this has already been computed
        return memo[bitmask][pos];       //Just return the value, no need to recompute
    }
    for (int i = 0; i < N; ++i){         //For every vertex 
        if ((bitmask & (1 << i)) == 0){  //If the vertex has not been visited
            cost = min(cost,TSP(bitmask | (1 << i) , i) + cost[pos][i]);   //Visit the vertex
        } 
    }
    memo[bitmask][pos] = cost;           //Save the result
    return cost;
}
//Call TSP(1,0)

Diese Zeile kann etwas verwirrend sein, lassen Sie sie langsam durchgehen:

cost = min(cost,TSP(bitmask | (1 << i) , i) + cost[pos][i]);

Hier bitmask | (1 << i) setzt das i-te Bit der bitmask auf 1, was bedeutet, dass der i-te Scheitelpunkt besucht wurde. Das i hinter dem Komma steht für das neue pos in diesem Funktionsaufruf, das den neuen "letzten" Scheitelpunkt darstellt. cost[pos][i] ist , die Kosten des Reisens von Vertex hinzufügen pos nach Knoten i .

Diese Zeile soll also den cost auf den minimal möglichen Wert für das Reisen zu jedem anderen noch nicht besuchten Scheitelpunkt aktualisieren.

Zeitkomplexität

Die Funktion TSP(bitmask,pos) hat 2^N Werte für bitmask und N Werte für pos . Jede Funktion benötigt O(N) Zeit (die for Schleife). Somit benötigt diese Implementierung O(N^2 * 2^N) Zeit, um die genaue Antwort auszugeben.



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow