Recherche…


Remarques

Le problème du vendeur itinérant est le problème de trouver le coût minimum de déplacement à travers N sommets exactement une fois par sommet. Il y a un coût de cost[i][j] pour passer du sommet i au sommet j .

Il existe 2 types d’algorithmes pour résoudre ce problème: Algorithmes exacts et algorithmes d’approximation

Algorithmes exacts

  1. Algorithme de force brutale
  2. Algorithme de programmation dynamique

Algorithmes d'approximation

Être ajouté

Algorithme de force brutale

Un chemin à travers chaque sommet exactement une fois est identique à l'ordre du sommet d'une certaine manière. Ainsi, pour calculer le coût minimum de déplacement à travers chaque sommet exactement une fois, nous pouvons forcer chacun des N! permutations des nombres de 1 à 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

La complexité du temps

Il y a N! les permutations doivent se faire et le coût de chaque chemin est calculé dans O(N) , donc cet algorithme prend le temps O(N * N!) pour sortir la réponse exacte.

Algorithme de programmation dynamique

Notez que si nous considérons le chemin (dans l'ordre):

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

et le chemin

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

Le coût pour passer du sommet 1 au sommet 2 jusqu'au sommet 3 reste le même, alors pourquoi faut-il le recalculer? Ce résultat peut être enregistré pour une utilisation ultérieure.

Soit dp[bitmask][vertex] le coût minimum de déplacement à travers tous les sommets dont le bit correspondant dans bitmask est défini sur 1 terminant au vertex . Par exemple:

dp[12][2] 

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

Puisque 12 représente 1100 en binaire, dp[12][2] représente les sommets 2 et 3 du graphe avec le chemin se terminant au sommet 2.

On peut donc avoir l'algorithme suivant (implémentation C ++):

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)

Cette ligne peut être un peu déroutante, alors parcourons-la lentement:

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

Ici, bitmask | (1 << i) place le bit i du bitmask à 1, ce qui représente que le iième sommet a été visité. Le i après la virgule représente le nouveau pos dans cet appel de fonction, qui représente le nouveau "dernier" sommet. cost[pos][i] est d'ajouter les frais de déplacement du sommet pos Vertex i .

Ainsi, cette ligne consiste à mettre à jour la valeur du cost à la valeur minimale possible du déplacement vers tous les autres sommets non encore visités.

La complexité du temps

La fonction TSP(bitmask,pos) a 2^N valeurs pour le bitmask et N valeurs pour pos . Chaque fonction prend le temps O(N) pour s'exécuter (la boucle for ). Ainsi, cette implémentation prend du temps O(N^2 * 2^N) pour sortir la réponse exacte.



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow