#!/usr/bin/env python # coding: utf-8 # $\newcommand{\si}{\sigma} # \newcommand{\al}{\alpha} # \newcommand{\tta}{\theta} # \newcommand{\Tta}{\Theta} # \newcommand{\Si}{\Sigma} # \newcommand{\ld}{\ldots} # \newcommand{\cd}{\cdots} # \newcommand{\Ga}{\Gamma} # \newcommand{\bet}{\beta} # \newcommand{\cU}{\mathcal{U}} # \newcommand{\cN}{\mathcal{N}} # \newcommand{\R}{\mathbb{R}} # \newcommand{\p}{\mathbb{P}} # \newcommand{\f}{\frac} # \newcommand{\ff}{\frac{1}} # \newcommand{\ds}{\displaystyle} # \newcommand{\bE}{\mathbf{E}} # \newcommand{\E}{\mathbb{E}} # \newcommand{\bF}{\mathbf{F}} # \newcommand{\ii}{\mathrm{i}} # \newcommand{\me}{\mathrm{e}} # \newcommand{\hsi}{\hat{\sigma}} # \newcommand{\hmu}{\hat{\mu}} # \newcommand{\ste}{\, ;\, } # \newcommand{\op}{\operatorname} # \newcommand{\argmax}{\op{argmax}} # \newcommand{\lfl}{\lfloor} # \newcommand{\ri}{\right} # \newcommand{\supp}{\operatorname{supp}}$ # # Open In Colab # # # # # TP Recuit simulé pour le problème du voyageur de commerce # # ## Voyageur de commerce # # Dans ce TP, on s'intéresse au problème du [voyageur de commerce](https://fr.wikipedia.org/wiki/Problème_du_voyageur_de_commerce). Etant données $n$ villes, positionnées dans l'espace en positions $V_1, \ld, V_n$, le problème consiste à trouver une tournée de longueur minimale, c'est-à-dire une permutation $x$ du groupe symétrique $S_n$ minimisant la fonction # $$ # x \in S_n \longmapsto H(x) := \sum_{i=1}^n\op{dist} (V_{x(i)}, V_{x(i+1)})\;\;\text{ où }\; x(n + 1) := x(1). # $$ # La longueur d'une tournée joue le rôle d'énergie ici. # # Ce problème d'optimisation est très simple à décrire mais particulièrement difficile à résoudre. # Une méthode simple consisterait à calculer $H(x)$ pour toutes les permutations $x$. # Mais lorsque $n$ est élevé, cette méthode est irréalisable. C'est le cas dès que le nombre de villes dépasse la dizaine : le cardinal de $S_n$ est de $n!$ (par exemple, pour $n=30$, $n!\simeq 2.10^{32}$). # # Pour essayer de minimiser H, on propose d'appliquer l'algorithme de recuit simulé en se déplaçant sur $S_n$ aléatoirement de proche en proche, ce qui implique d'avoir, sur $S_n$, une notion d'*éléments voisins* (de *permutations voisines*). Par exemple, on peut considèrer comme voisines deux permutations qui se déduisent l'une de l'autre par la permutation de deux éléments seulement. Cette "notion de voisinage" fonctionne, mais dans notre algorithme, nous la remplaçons en fait par une autre, qui permet une convergence plus rapide : nous considérons deux permutations $(x_1,\ldots, x_n)$, $(y_1,\ldots, y_n)$ comme voisines si il existe $1\leq i