Professional Documents
Culture Documents
Mpsi Devoir Tsparbrecouvrant
Mpsi Devoir Tsparbrecouvrant
1 Approche du problème
1.1 Problème du voyageur de commerce
On se donne n villes v0 , . . . , vn−1 , chaque ville étant reliée à chaque autre ville par une route dont la longueur est
connue. L’objectif est de construire un circuit élementaire : un chemin qui passe par chaque ville une fois et une seule
et qui revient à la ville de départ. On représente informatiquement le circuit par un tableau des n entiers distincts de
J0, n − 1K, la ville de départ n’est pas répétée à la fin du circuit dans la représentation.
Exemple. Avec n = 4, le circuit v2 → v0 → v1 → v3 → v2 sera représenté par le tableau [2, 0, 1, 3]
On s’intéresse, dans ce sujet, à la version planaire, donc les villes ont exactement deux coordonnées, et euclidienne
du problème c’est-à-dire qu’on suppose que toutes les villes sont connectées deux à deux par une route de longueur
égale à la distance euclidienne qui les sépare.
On représente une instance du problème par le tableau des coordonnées des villes.
1. Calculer le nombre de circuits élémentaires différents en fonction de n. Est-il envisageable d’écrire un programme
qui teste tous les circuits possibles pour n ≈ 100 ?
2 Fonctions outils
2.1 Calcul de longueur
4. Ecrire une fonction distance(ville1, ville2) qui prend en argument deux villes (représentées chacune par un
couple de coordonnées) et qui renvoie la distance euclidienne qui les sépare.
5. Ecrire une fonction matrice_des_distances qui prend en argument un tableau de villes et qui renvoie un tableau
de tableaux de distance matrice tel que matrice[i][j] contienne la distance euclidienne entre la ville d’indice i et
la ville d’indice j. Déterminer la complexité de la fonction en fonction du nombre de villes.
6. Ecrire une fonction longueur(matrice, circuit) qui prend en argument la matrice des distances et un circuit
et qui renvoie la longueur du circuit, c’est-à-dire la somme des longueurs des routes empruntées. Déterminer la
complexité de la fonction en fonction du nombre de villes.
7. Programmer un algorithme de tri (si possible de complexité quasi-linéaire).
3 Algorithme glouton
On cherche à construire une solution en effectuant localement le choix qui semble le meilleur. Plus précisément,
on construit le circuit de façon itérative en partant de la première ville puis en choisissant la prochaine ville qui est la
plus proche parmi les villes restantes à visiter.
Pour programmer cette fonction, on définira un tableau des indices des villes non visitées duquel on supprimera
au fur et à mesure les villes que l’on visite. Pour supprimer efficacement un indice de ville présent dans le tableau, on
remplacera cet indice par le dernier du tableau et on supprimera à la place la dernière case du tableau.
8. Ecrire une fonction glouton(distances) qui prend en argument la matrice des distances et renvoie le circuit
généré par l’algorithme décrit.
1
Devoir - Voyageur de commerce et arbre couvrant de poids minimum
9. Le résultat de l’algorithme précédent peut faire apparaître des croisements (comme sur la figure). En considérant
les 4 villes qui sont aux extrémités de deux segments du circuit qui se croisent, justifier qu’on peut reconstruire un
circuit plus court (en décroisant le croisement considéré). Quantifier le gain total de longueur en fonction des distances
entre les 4 villes considérées et déduire de cette quantification un critère pour savoir si deux segments se croisent.
10. Ecrire une fonction renverse_entre_indices(tableau, i, j) qui renverse une partie du tableau en argument :
la partie entre les indices i et j inclus. La fonction doit procéder par effet de bords.
Exemple. Si tableau = [2, 3, 1, 5, 6, 4], i = 1, j = 4, la fonction doit modifier le tableau en : [2, 6, 5,
1, 3, 4].
11. Ecrire une fonction decroise(distances, circuit) qui décroise un circuit tant qu’il possède des croisements.