Apprentissage interactif de la théorie des graphes
Apprentissage interactif de la théorie des graphes
Guest User
Using app without sign in
Détecteur de chemins hamiltoniens
Chemin visitant chaque sommet exactement une fois
Sélectionnez un algorithme et générez les étapes pour commencer la visualisation
Un chemin hamiltonien visite chaque sommet d'un graphe exactement une fois ; un cycle hamiltonien revient en plus au sommet de départ. Décider si un tel chemin existe est NP-complet, en net contraste avec le chemin eulérien, vérifiable en temps linéaire.
Les algorithmes exacts utilisent le backtracking : étendre un chemin partiel d'un sommet à la fois, en élaguant quand le sommet courant n'a pas de voisin non visité. La programmation dynamique sur sous-ensembles (la même technique de masque de bits que Held-Karp) résout le problème en O(n au carré fois 2 puissance n). Des règles d'élagage utiles incluent les vérifications de degré et les tests de connexité du graphe restant. Pour des classes spéciales de graphes, comme les tournois ou les graphes vérifiant les conditions de degré de Dirac ou Ore, l'existence est garantie et des algorithmes constructifs existent.
Les chemins hamiltoniens apparaissent dans l'assemblage de génomes, la conception et le test de circuits, les jeux de casse-tête comme le parcours du cavalier, et comme cœur structurel du TSP. En entretien, la solution de programmation dynamique par masque de bits est une question difficile standard, et le contraste avec le chemin eulérien teste la clarté conceptuelle.
Aucun algorithme polynomial n'est connu, la formulation honnête est donc un retour sur trace avec élagage. C'est l'élagage qui le rend utilisable.
CheminHamiltonien(graphe):
pour chaque sommet de depart s:
si backtrack([s], {s}): renvoyer le chemin
renvoyer aucun
backtrack(chemin, visites):
si visites contient tous les sommets: renvoyer vrai
u = chemin.dernier
pour chaque voisin v de u non visite:
// Elagage qui se rentabilise:
// - un sommet non visite devenu inatteignable -> echec
// - deux sommets non visites ou plus de degre 1
// dans le graphe restant -> echec
visites.ajouter(v)
si backtrack(chemin + [v], visites): renvoyer vrai
visites.retirer(v) // defaire et essayer le suivant
renvoyer fauxL'élagage par atteignabilité est le plus déterminant. Après avoir choisi un chemin partiel, lance un parcours rapide sur les sommets non visités; si l'un d'eux se trouve désormais coupé de l'extrémité courante, la branche est morte et peut être abandonnée immédiatement plutôt qu'après l'exploration d'un sous-arbre entier. Sur les graphes creux, cela transforme une recherche intraitable en une recherche rapide, même si le pire cas demeure exponentiel.
Cherche un chemin hamiltonien depuis A sur un graphe à cinq sommets, et vois pourquoi ce même graphe n'admet aucun cycle hamiltonien.
Graphe d'exemple: Arêtes non orientées A-B, B-C, C-D, D-E, plus les deux cordes A-C et B-D.
Deux chemins hamiltoniens existent, A-B-C-D-E et A-C-B-D-E, mais aucun cycle hamiltonien. Le sommet E de degré 1 tranche presque à lui seul les deux questions: il se contraint lui-même à être une extrémité et exclut tout cycle, puisqu'un cycle exige que chaque sommet soit de degré au moins 2. Vérifier les degrés avant de chercher coûte peu et se révèle souvent décisif.
Temps: O(V!) naïf, O(V^2·2^V) avec PD · Espace: O(V·2^V) avec PD
Le retour sur trace naïf explore des permutations et vaut O(V factorielle) au pire, ce qui est sans espoir au-delà d'une douzaine de sommets. La programmation dynamique de Held-Karp sur les sous-ensembles fait bien mieux: l'état est un sous-ensemble de sommets visités associé à l'extrémité courante, soit 2 puissance V fois V états, et chaque transition coûte O(V), pour un total en O(V au carré fois 2 puissance V) en temps et O(V fois 2 puissance V) en mémoire. C'est praticable jusqu'à une vingtaine de sommets, où 2 puissance 20 fois 20 représente environ 20 millions d'états. Le problème est NP-complet, aucun algorithme polynomial n'est donc attendu; le retour sur trace élagué termine néanmoins souvent vite sur les graphes creux réels.
Confirme quel problème tu as réellement avant de sortir la machinerie exponentielle, car deux d'entre eux sont faciles.
| Alternative | À préférer quand | Coût |
|---|---|---|
| Chemin eulérien | Tu as besoin de chaque ARÊTE une fois plutôt que de chaque sommet. Temps linéaire par comptage des degrés. | O(V + E) |
| PD de Held-Karp | Moins d'une vingtaine de sommets et tu veux un oui ou un non définitif. | O(V^2·2^V) |
| Heuristiques de TSP | Le graphe est complet et pondéré, et tu veux un bon circuit plutôt qu'une preuve d'existence. | O(n^2) par passe de 2-opt |
| Conditions suffisantes de Dirac et Ore | Tu dois seulement prouver qu'un cycle existe. Si tout degré vaut au moins V/2, il en existe un, sans aucune recherche. | O(V) |
| Tri topologique | Le graphe est un DAG. Un chemin hamiltonien existe exactement lorsque les sommets consécutifs de l'unique ordre topologique sont adjacents. | O(V + E) |
Lire l'article complet: Eulerian Paths and Circuits
Algorithmes associés: Chemin Eulérien (Graphe Non Dirigé), Problème du Voyageur de Commerce, Recherche en Profondeur (DFS)