Probleme – Biparti si et seulement si aucun cycle impair
Exercice · niveau 3 (difficile) · informatique (MP2I/MPI), chapitre 13 — Le modèle des graphes
Énoncé
Le chapitre ne démontre que le sens direct.
- Démontrer la réciproque : un graphe sans cycle de longueur impaire est biparti.
- En tirer un algorithme, et donner sa complexité.
- Que rend l'algorithme quand le graphe n'est pas biparti ?
- Mettre à l'épreuve sur des graphes de référence.
Corrigé
1. La réciproque. Supposons sans cycle impair. Il suffit de traiter une composante connexe, puis de réunir les parties obtenues.
Soit donc connexe, et un sommet quelconque. Notons la distance de à — le nombre minimal d'arêtes d'un chemin de à —, définie pour tout par connexité. Posons
Ces deux ensembles partagent . Montrons que toute arête relie à .
Soit une arête. D'abord : un chemin optimal vers prolongé par l'arête donne un chemin vers , donc , et symétriquement. Il reste à écarter .
Supposons . Prenons un chemin optimal de à et un chemin optimal de à . Le long d'un chemin optimal, la distance croît strictement de à chaque pas : le -ième sommet de est à distance . Soit alors le sommet commun aux deux chemins de plus grande distance — il en existe, étant commun.
Les portions de et de allant de à et de à ne se rencontrent qu'en : un autre sommet commun serait à distance strictement supérieure à , contredisant le choix de . Leurs longueurs valent chacune, un sous-chemin d'un chemin optimal étant optimal, et car entraînerait , donc . En concaténant les deux portions et l'arête , on obtient un cycle de longueur
qui est impair — et c'est bien un cycle, sans répétition d'arête, les deux portions étant disjointes hors de . Contradiction. Donc , d'où et les deux extrémités sont de parités différentes : l'arête relie à .
2. L'algorithme. La démonstration est effective : elle donne la bipartition, se calcule par un parcours en largeur, et la contradiction est un test.
(* Renvoie Some couleur si g est biparti (couleur.(u) vaut 0 ou 1),
None sinon. n sommets, listes d'adjacence g. Complexité : Theta(n + m). *)
let bicolorer n g =
let couleur = Array.make n (-1) in
let biparti = ref true in
for s = 0 to n - 1 do
if couleur.(s) = -1 then begin (* une composante non encore vue *)
couleur.(s) <- 0;
let f = Queue.create () in
Queue.push s f;
while not (Queue.is_empty f) do
let u = Queue.pop f in
List.iter (fun v ->
if couleur.(v) = -1 then begin
couleur.(v) <- 1 - couleur.(u); (* on ALTERNE *)
Queue.push v f
end
else if couleur.(v) = couleur.(u) then biparti := false) g.(u)
done
end
done;
if !biparti then Some couleur else None
Correction : l'invariant du parcours est couleur.(u) pour tout sommet colorié — vrai à l'initialisation, et conservé puisqu'on colorie chaque nouveau sommet de la couleur opposée à celle de son découvreur, et que le parcours en largeur découvre chaque sommet par un chemin optimal. Le test couleur.(v) = couleur.(u) détecte donc exactement une arête entre deux sommets de même parité, c'est-à-dire, par la démonstration ci-dessus, un cycle impair.
Complexité : chaque sommet est empilé une fois et chaque arête examinée deux fois — une par extrémité —, soit en temps et en mémoire. C'est le coût d'un simple parcours, et il faut le mesurer à l'aune de l'alternative : chercher un cycle impair en énumérant les cycles serait exponentiel. Une caractérisation combinatoire ne donne pas toujours un algorithme ; celle-ci, si, et c'est ce qui la rend précieuse.
3. Ce que l'algorithme rend en cas d'échec. L'arête fautive est un certificat : en remontant les arbres du parcours depuis et depuis jusqu'à leur ancêtre commun, on reconstruit un cycle impair explicite. C'est une qualité qu'il faut exiger d'un algorithme de décision : répondre « non » sans preuve oblige l'utilisateur à faire confiance ; répondre « non, voici pourquoi » se vérifie en .
4. Les mises à l'épreuve. Mesuré, chaque réponse confrontée à une recherche indépendante de cycle impair :
| graphe | biparti ? | cycle impair ? | résultat | ||
|---|---|---|---|---|---|
| , le carré | oui | non | parts | ||
| , le pentagone | non | oui | arête fautive | ||
| oui | non | parts | |||
| non | oui | arête fautive | |||
| arbre à sommets | oui | non | parts | ||
| cube | oui | non | parts |
Les deux colonnes centrales sont toujours opposées : la caractérisation est confirmée sur les six cas. Deux remarques que ce tableau suggère. Tout arbre est biparti — il n'a aucun cycle, donc aucun cycle impair, et la bipartition est le partage par la parité de la profondeur. Et les cycles pairs , , … sont bipartis tandis que , , … ne le sont pas : ce sont les exemples minimaux des deux côtés.
À quoi cela sert. La bipartition est le modèle de tout appariement : étudiants et stages, tâches et machines, offres et demandes. Savoir en si un graphe est biparti, c'est savoir si le problème d'appariement s'y pose — et le programme cite la bicolorabilité au chapitre chap:parcours précisément à ce titre.
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.