Probleme – Le voyageur de commerce : quatre niveaux d'élagage
Exercice · niveau 3 (difficile) · informatique (MP2I/MPI), chapitre 14 — Exploration exhaustive et retour sur trace
Énoncé
villes, une matrice de distances. On cherche la tournée la plus courte partant de la ville , passant une fois par chaque ville et revenant en .
- Écrire l'exploration exhaustive, et compter ses nœuds.
- L'améliorer en abandonnant toute tournée partielle déjà plus longue que le record.
- Amorcer le record par une solution gloutonne, puis ajouter un minorant du trajet restant. Mesurer chacun des quatre programmes.
- Que reste-t-il à faire pour traiter ?
Corrigé
1. L'exhaustif. On fixe la ville comme départ — cela divise déjà par le nombre de tournées, puisqu'une tournée circulaire peut être lue depuis n'importe laquelle de ses villes. Restent ordres.
(* Longueur de la tournée minimale partant de 0. Précondition : d est une
matrice n x n de distances positives, n >= 2. Complexité : O(n!). *)
let tsp d =
let n = Array.length d in
let vu = Array.make n false in
let best = ref max_int in
vu.(0) <- true;
let rec explorer k courant longueur =
if k = n then begin
let total = longueur + d.(courant).(0) in
if total < !best then best := total
end else
for s = 1 to n - 1 do
if not vu.(s) then begin
vu.(s) <- true;
explorer (k + 1) s (longueur + d.(courant).(s));
vu.(s) <- false
end
done
in explorer 1 0 0; !best
2. L'abandon des branches trop longues. Les distances étant positives, la longueur d'une tournée partielle ne peut que croître : dès qu'elle atteint le record, la branche est perdue. Il suffit de garder le for sous condition :
end else if longueur < !best then
for s = 1 to n - 1 do (* ... *) done
3. Le record amorcé et le minorant. Deux idées de plus.
Amorcer : au lieu de partir de max_int, calculer d'abord une tournée par le glouton du plus proche voisin (chapitre chap:gloutons) et en faire le record initial. L'élagage mord alors dès la première branche.
Minorer : soit la plus courte arête incidente au sommet . Une tournée partielle finissant en avec villes restantes devra emprunter au moins une arête depuis et au moins une depuis chaque ville de : sa longueur finale vaut donc au moins . Si ce minorant atteint le record, la branche est morte.
(* mini_incident.(s) = plus courte arête incidente à s, calculée une fois. *)
let coupe =
let reste = ref mini_incident.(courant) in
for s = 1 to n - 1 do if not vu.(s) then reste := !reste + mini_incident.(s) done;
longueur + !reste >= !best
Le minorant doit être optimiste, c'est-à-dire ne jamais dépasser la vraie longueur restante : sinon on couperait une branche contenant l'optimum et l'on rendrait un résultat faux, sans le savoir. Ici l'argument est immédiat — on compte, pour chaque ville restante, moins que ce qu'elle coûtera.
La mesure, sur villes du plan (donc tournées). Les quatre programmes rendent la même tournée optimale, de longueur .
| Programme | nœuds | rapport |
|---|---|---|
| (a) exhaustif | ||
| (b) + longueur partielle record | ||
| (c) + record amorcé par le glouton | ||
| (d) + minorant par les arêtes minimales | 3 332 | 33 |
Trois enseignements, et le deuxième est une surprise.
D'abord, le glouton du plus proche voisin donne , soit de plus que l'optimum : vite calculé, franchement mauvais. C'est le chapitre chap:gloutons en un chiffre.
Ensuite, amorcer le record n'a rien apporté — ligne (c), identique à (b). L'exploration en profondeur trouve elle-même une bonne tournée dès sa première descente, et le record du glouton ne la précède pas d'assez pour couper quoi que ce soit. Une amélioration plausible peut ne rien donner ; c'est la mesure qui le dit, pas l'intuition.
Enfin, le minorant apporte à lui seul un facteur de plus. Il coupe non pas quand la branche est déjà perdue, mais quand elle est condamnée — bien plus haut dans l'arbre. C'est précisément la différence entre le retour sur trace et la séparation et évaluation, que le chapitre chap:probabilistes traite pour elle-même.
4. Et pour ? vaut : aucun élagage constant n'y suffira. Il faut soit un minorant bien plus serré — l'arbre couvrant minimal des villes restantes, ou la relaxation continue —, soit renoncer à l'exactitude. Le problème est np-difficile (chapitre chap:decidabilite) : c'est le cas de figure annoncé à la fin de ce chapitre, et les trois issues y sont nommées.
Les autres exercices de ce chapitre Le cours du chapitre
Un blocage sur cet exercice ? Le tuteur d'Adloun guide par questions, sans donner la réponse.