Aller au contenu principal

Flots et couplages

Ce que ce chapitre apporte 6 points
  • Définir un réseau de transport, un flot, sa valeur, et une coupe.
  • Comprendre le graphe résiduel et la nécessité des arcs inverses.
  • Dérouler Ford-Fulkerson sur un petit réseau.
  • Énoncer le théorème flot-max coupe-min et s'en servir pour prouver une optimalité.
  • Modéliser la recherche d'un couplage biparti maximum comme un problème de flot.
  • Appliquer le théorème de Hall pour justifier qu'aucun couplage ne place tous les candidats.
Deux questions restent, et elles se ressemblent plus qu'il n'y paraît. Combien peut-on faire passer dans un réseau dont chaque conduite a une capacité ? Et : peut-on apparier tous les candidats à un poste, chacun n'acceptant que certains postes ? La première est un problème de flot, la seconde un problème de couplage, et le même algorithme résout les deux. C'est aussi l'occasion de voir un théorème qui relie un maximum à un minimum, forme de résultat rare et puissante.

Le réseau de transport

Définitions

Un réseau de transport est un graphe orienté où chaque arc porte une capacité positive, avec deux sommets distingués : une source ss et un puits tt.

Un flot associe à chaque arc une valeur comprise entre 0 et sa capacité, telle qu'en tout sommet autre que ss et tt, ce qui entre égale ce qui sort.

La valeur du flot est ce qui sort de la source, moins ce qui y entre éventuellement ; c'est aussi ce qui arrive au puits.

Dans les réseaux de ce chapitre, la source n'a aucun arc entrant et le puits aucun arc sortant : ce sont une source et un puits au sens du chapitre sur les représentations, une colonne vide et une ligne vide dans la matrice d'adjacence.

Les deux contraintes, en une phrase chacune
Capacité : on ne fait pas passer plus qu'une conduite ne peut porter.
Conservation : rien ne se perd ni ne se crée en cours de route, sauf à la source et au puits.
Toute la théorie découle de ces deux règles, et toute erreur de modélisation vient d'en avoir oublié une.
Graphe orienté et pondéré6 sommets, 8 arcs
1082510746SACTDB
Le réseau du chapitre. Chaque arc porte sa capacité ; S est la source, en haut, T le puits, en bas.

Chemins augmentants et graphe résiduel

L'idée naïve consiste à chercher un chemin de la source au puits, à y pousser autant que possible, puis à recommencer. Elle fonctionne presque : il lui manque la possibilité de revenir sur une décision.

Graphe résiduel

Le graphe résiduel contient, pour chaque arc u→vu \to v de capacité cc portant un flot ff :

un arc direct u→vu \to v de capacité résiduelle c−fc - f, ce qu'on peut encore ajouter ;

un arc inverse v→uv \to u de capacité ff, ce qu'on peut annuler.

Pourquoi l'arc inverse est indispensable. Sans lui, un premier chemin mal choisi bloque définitivement une partie du réseau, et l'algorithme s'arrête sur un flot qui n'est pas maximal.
L'arc inverse permet à un chemin ultérieur d'emprunter la conduite à l'envers, ce qui revient à dire : « ce que j'avais envoyé par là, je le réoriente ». Le flot reste valide à chaque étape, et l'algorithme peut corriger ses propres choix.
C'est le détail qui fait passer d'une heuristique à un algorithme exact.

Le plus petit réseau où l'on voit le problème

Cinq arcs, tous de capacité 1. Le flot maximal vaut 2 : une unité par s→a→ts \to a \to t, une autre par s→b→ts \to b \to t. Voici pourtant ce que fait l'idée naïve si elle tombe d'abord sur le chemin du milieu, s→a→b→ts \to a \to b \to t. La figure s'ouvre après ce premier envoi, arcs inverses désactivés.

Flot dans un réseausource s, puits t, 5 arcs
1/10/11/10/11/1satb

Chaque arc porte flot / capacité, et s'épaissit avec son flot. Cliquer un arc pour changer sa capacité.

Déjà poussé : s → a → b → t (1).

Valeur du flot : 1 (1 envoi)

Plus aucun chemin de s à t sans arc inverse. Ce que s atteint encore dans le graphe résiduel, côté 0 : s et b ; le reste, côté 1 : a et t.

Coupe : s → a (1) + b → t (1) = 2, pour un flot de 1. Elle ne certifie rien : a → b ramène du flot vers le côté de s. Réactiver les arcs inverses : un chemin reparaît.

Le premier chemin a poussé 1 unité. Trois arcs sont saturés, et plus aucun chemin de s à t ne subsiste : sans arc inverse, l'algorithme s'arrête ici, sur un flot de valeur 1.

Le graphe résiduel, lui, ne s'arrête pas là. Chaque arc saturé y laisse un arc inverse de capacité 1, celle du flot qu'il porte, et l'un d'eux rouvre un chemin.

À manipuler
Passer au graphe résiduel : sans arcs inverses, il ne reste que s→bs \to b et a→ta \to t, qui ne se rejoignent pas. Activer alors les arcs inverses : a→sa \to s, b→ab \to a et t→bt \to b apparaissent en tirets.
Cliquer b, puis a, puis t : le chemin s→b→a→ts \to b \to a \to t emprunte a→ba \to b à contresens. Le pousser : le flot passe à 2, et, de retour à la vue du réseau, a→ba \to b ne porte plus rien.
Ce que veut dire « emprunter un arc à l'envers »
Pousser une unité le long de s→b→a→ts \to b \to a \to t se traduit ainsi sur le vrai réseau : une unité de plus part par s→bs \to b, une unité de moins passe par a→ba \to b, et une unité de plus arrive par a→ta \to t.
Le flot final est donc 1 sur s→as \to a, 1 sur s→bs \to b, 0 sur a→ba \to b, 1 sur a→ta \to t et 1 sur b→tb \to t : valeur 2. L'algorithme n'a pas « ajouté du flot dans le mauvais sens », il a réorienté celui qu'il avait mal placé.
L'arc inverse n'existe pas dans le réseau
Il n'apparaît que dans le graphe résiduel, qui est une structure de calcul et non une description du réseau physique. Écrire un arc b→ab \to a dans le réseau de départ signifierait qu'une conduite existe dans ce sens ; l'arc inverse résiduel dit seulement « il y a une unité déjà envoyée par là, et on peut la reprendre ».
Vérification rapideon peut se reprendre

À quoi sert l'arc inverse du graphe résiduel ?

Ford-Fulkerson

Tant qu'il existe un chemin de ss à tt dans le graphe résiduel, y pousser le minimum des capacités résiduelles rencontrées, puis mettre à jour.

Quand il n'en existe plus, le flot est maximal.

Quand on choisit systématiquement le chemin le plus court, en nombre d'arcs, par un BFS, l'algorithme s'appelle Edmonds-Karp et sa complexité est bornée par O(n×m2)O(n \times m^2), indépendamment des capacités.

Le programme ci-dessous range les capacités dans un dictionnaire indexé par les arcs : la clé ("S", "A") désigne l'arc S→AS \to A. C'est plus commode ici que la liste d'adjacence du chapitre 2, parce que chaque arc inverse doit porter sa propre valeur. Le BFS examine les voisins dans l'ordre alphabétique : quand deux chemins ont la même longueur, c'est cet ordre qui décide lequel est retenu.

main.py
Sortie
>_ Prêt à exécuter…

Le théorème flot-max coupe-min

Coupe

Une coupe est une partition des sommets en deux parties, l'une contenant la source, l'autre le puits. Sa capacité est la somme des capacités des arcs allant du côté source vers le côté puits.

Toute quantité qui va de ss à tt doit traverser chaque coupe. Donc la valeur de tout flot est inférieure ou égale à la capacité de toute coupe. Le théorème dit que les deux valeurs se rejoignent.

Théorème flot-max coupe-min
max⁡flots∣f∣=min⁡coupes (X,Xˉ)c(X,Xˉ)\max_{\text{flots}} |f| = \min_{\text{coupes } (X, \bar X)} c(X, \bar X)

où XX est le côté de la coupe qui contient la source, Xˉ\bar X celui qui contient le puits, et c(X,Xˉ)c(X, \bar X) la capacité de la coupe.

Ce que ce genre de théorème apporte. Il donne un certificat vérifiable. Pour convaincre quelqu'un qu'un flot est maximal, on n'a pas à raconter le déroulement de l'algorithme : il suffit d'exhiber une coupe de même capacité.
L'interlocuteur vérifie deux choses simples, que le flot est valide et que la coupe a bien cette capacité, et la conclusion s'impose. C'est la même structure de preuve qu'au chapitre 7, où une clique minore et une coloration majore, et c'est une forme d'argument qu'il faut savoir reconnaître.
La coupe minimale s'obtient gratuitement à la fin de l'algorithme : ce sont les arcs saturés qui séparent les sommets encore atteignables depuis la source, dans le graphe résiduel, de tous les autres.

La coupe, sur le réseau du chapitre

Le flot maximal du réseau dessiné plus haut vaut 13. Voici une répartition qui l'atteint, celle que trouve le programme ci-dessus en trois chemins, chaque arc portant flot / capacité. Il en existe d'autres (7 sur S→AS \to A, 2 sur A→BA \to B, 6 sur S→BS \to B, le reste inchangé, vaut aussi 13), mais toutes saturent les deux arcs de la coupe.

Flot dans un réseausource S, puits T, 8 arcs
5/108/80/25/58/107/72/46/6SACTDB

Chaque arc porte flot / capacité, et s'épaissit avec son flot. Cliquer un arc pour changer sa capacité.

Déjà poussé : S → A → C → T (5), S → B → D → T (6), S → B → D → C → T (2).

Valeur du flot : 13 (3 envois)

Plus aucun chemin de S à T. Ce que S atteint encore dans le graphe résiduel, côté 0 : S, A, C, D et B ; le reste, côté 1 : T.

Coupe : C → T (7) + D → T (6) = 13, égale à la valeur du flot. Aucun flot ne dépasse une coupe, aucune coupe ne descend sous un flot : les deux sont optimaux, et la coupe en est le certificat.

Le flot maximal, de valeur 13. Les sommets encore atteignables depuis S dans le graphe résiduel portent la couleur 0, les autres la couleur 1 : ici, T tout seul. Les deux arcs épaissis, qui les séparent et sont saturés tous les deux, forment la coupe minimale.
À manipuler
Revenir au flot nul, puis avancer d'un chemin à la fois avec Edmonds-Karp : S→A→C→TS \to A \to C \to T pousse 5, S→B→D→TS \to B \to D \to T pousse 6, S→B→D→C→TS \to B \to D \to C \to T pousse 2. Au troisième, plus aucun chemin : la coupe apparaît, et sa capacité égale la valeur du flot. On peut aussi choisir ses chemins soi-même dans le graphe résiduel : l'ordre change, pas le total.
Cliquer ensuite l'arc S→AS \to A et porter sa capacité à 20 : aucun chemin n'apparaît, le flot reste 13. Porter plutôt C→TC \to T de 7 à 8 : un chemin reparaît, S→A→B→D→C→TS \to A \to B \to D \to C \to T, qui pousse 1, et le flot passe à 14.

C'est l'égalité qui certifie, et non le seul fait de s'arrêter. La petite figure du début s'arrêtait elle aussi faute de chemin, arcs inverses désactivés ; mais la coupe qu'elle affichait valait 2 pour un flot de 1, et le flot n'était pas maximal.

Vérifier le certificat en trois lignes
La coupe. D'un côté {S,A,B,C,D}\{S, A, B, C, D\}, de l'autre {T}\{T\}. Les arcs qui la traversent sont C→TC \to T et D→TD \to T, de capacités 7 et 6 : la coupe vaut 13.
Le flot. Ce qui sort de SS vaut 5+8=135 + 8 = 13, et ce qui entre dans TT vaut 7+6=137 + 6 = 13. La conservation se vérifie sommet par sommet : en DD, il entre 8 et il sort 6+2=86 + 2 = 8.
La conclusion. Les deux nombres coïncident, donc aucun flot ne peut dépasser 13 et aucune coupe ne peut descendre en dessous. Les deux sont optimaux, et il n'a pas fallu parler de l'algorithme une seule fois.
Où couper, en pratique
Les arcs de la coupe minimale sont les goulots du réseau : élargir un autre arc ne change strictement rien, comme S→AS \to A, qui ne porte que 5 sur 10.
Élargir un goulot fait monter le débit, mais seulement jusqu'à la coupe suivante : porter C→TC \to T de 7 à 8 donne 14, mais le porter à 107 ne donne que 15, et non 113, parce que trois autres coupes valent 15.
Et quand plusieurs coupes minimales existent, l'élargissement doit toucher chacune d'elles : élargir un arc d'une seule laisse l'autre en place, et le débit ne bouge pas.
C'est la lecture qui rend le théorème utile en dehors des mathématiques : il ne dit pas seulement combien on peut faire passer, il dit où se trouve la limite.
Vérification rapideon peut se reprendre

Comment convaincre quelqu'un qu'un flot est maximal, sans lui faire refaire l'algorithme ?

Couplages

Définitions

Un couplage est un ensemble d'arêtes deux à deux sans extrémité commune.

Il est maximum s'il contient le plus grand nombre possible d'arêtes, parfait s'il couvre tous les sommets.

Le cas biparti est celui qu'on rencontre : des candidats d'un côté, des postes de l'autre, une arête quand la candidature est recevable. Ici, Bruno n'accepte que Base, et Ana comme Chloe la convoitent aussi. La figure s'ouvre sur une affectation faite au fil de l'eau : Ana sur Base, puis Chloe sur Web.

Couplage biparti3 candidats, 3 postes, 5 candidatures
AnaBrunoChloeReseauBaseWeb

Trait épais : le couplage. Contour tireté : sans affectation. Cliquer une arête pour la prendre ou la rendre.

Compléter le couplage à la main, puis demander un chemin augmentant.

Couplage de taille 2 : Ana-Base, Chloe-Web.

Sans poste : Bruno. Vacant : Reseau.

Les candidats à gauche, les postes à droite, une arête par candidature recevable. Le couplage, en trait épais, a été construit au fil de l'eau : Ana sur Base, puis Chloe sur Web.
À manipuler
Chercher une place pour Bruno en cliquant son arête : Base est déjà pourvue, la figure refuse, et Bruno n'a pas d'autre choix. Demander alors un chemin augmentant : Bruno, Base, Ana, Reseau. Ses arêtes alternent, marquées + (à prendre), − (à rendre), + : Bruno prend Base, qu'Ana rend pour passer sur Reseau. Échanger : le couplage passe de 2 à 3, et personne n'a perdu de poste.
Vider ensuite le couplage, le reconstruire autrement, et redemander un chemin : tant qu'un candidat reste sans poste, la figure en trouve un ; quand tous sont placés, il n'y en a plus.

Un couplage de taille 3 existe donc : Ana-Reseau, Bruno-Base, Chloe-Web.

Bloqué n'est pas maximum
Un couplage auquel on ne peut plus ajouter d'arête n'est pas forcément maximum. Placer Ana sur Base, puis Chloe sur Web, bloque Bruno : ce couplage de taille 2 ne peut plus grandir sans rien défaire, alors qu'il en existe un de taille 3.
C'est l'erreur de qui affecte au fil de l'eau. Pour aller plus loin, il faut défaire une affectation, exactement comme l'arc inverse défait un envoi.
Un couplage biparti est un flot
Ajouter une source reliée à tous les sommets de gauche, un puits relié à tous ceux de droite, orienter les arêtes de gauche à droite, et donner la capacité 1 à tous les arcs.
Avec des capacités entières, Ford-Fulkerson ne pousse que des quantités entières : chaque arc porte 0 ou 1, et un flot de valeur kk correspond exactement à un couplage de taille kk. La capacité 1 sur les arcs de la source garantit qu'un candidat n'est pris qu'une fois, et celle sur les arcs du puits qu'un poste n'est pourvu qu'une fois.
Le flot maximal donne donc le couplage maximum, sans écrire un algorithme de plus.

Un quatrième candidat, David, ne vise lui aussi que Base, et un quatrième poste, Support, s'ouvre, qu'Ana accepterait. Quatre candidats pour quatre postes : le compte global ne dit rien, et pourtant le couplage maximum ne dépasse pas 3. On peut le prouver.

Couplage biparti4 candidats, 4 postes, 7 candidatures
AnaBrunoDavidChloeSupportReseauBaseWeb

Trait épais : le couplage. Contour tireté : sans affectation. Cliquer une arête pour la prendre ou la rendre.

Compléter le couplage à la main, puis demander un chemin augmentant.

Couplage de taille 3 : Ana-Reseau, Bruno-Base, Chloe-Web.

Sans poste : David. Vacant : Support.

Quatre candidats, quatre postes : le compte global ne décide rien. Le couplage en trait épais, de taille 3, est celui que trouve le programme plus bas ; David y reste sans poste.
Théorème de Hall

Dans un graphe biparti de parts LL (les candidats) et RR (les postes), il existe un couplage qui place tous les candidats si et seulement si, pour tout sous-ensemble X⊆LX \subseteq L, les candidats de XX visent ensemble au moins ∣X∣|X| postes différents.

Ici X={Bruno,David}X = \{Bruno, David\} donne ∣X∣=2|X| = 2 et un seul poste visé, Base. La condition est violée, donc aucun couplage ne place les quatre. Le sens facile du théorème se comprend tout de suite : si un groupe vise moins de postes qu'il ne compte de personnes, quelqu'un restera sans poste. Le théorème dit que c'est le seul obstacle possible.

À manipuler
Demander un chemin augmentant : il n'y en a pas, et la figure désigne à la place Bruno et David, qui visent en tout un seul poste, Base. Ajouter ensuite une candidature, Bruno sur Reseau : un chemin de cinq arêtes apparaît, David, Base, Bruno, Reseau, Ana, Support, et l'échange place les quatre candidats.
Revenir au départ et donner plutôt Web à David : le certificat à deux candidats tombe, et la figure en trouve un autre, Bruno, David et Chloe, trois candidats pour deux postes, Base et Web.
Un certificat, encore, et de la même famille
Ce sous-ensemble XX est une preuve d'impossibilité, courte et vérifiable : il n'y a pas à énumérer les affectations, il suffit de compter deux candidats et un poste.
C'est la troisième fois que le parcours rencontre cette forme d'argument, après « clique et coloration » et « flot et coupe ». À chaque fois, une borne d'un côté, un objet qui l'atteint de l'autre, et la question est close.

Le programme ci-dessous n'est pas un algorithme de plus : c'est Ford-Fulkerson, écrit directement sur les candidatures. Chercher un poste pour un candidat, quitte à déplacer l'occupant vers un autre poste qu'il accepte, c'est chercher un chemin augmentant dans le réseau à capacités 1 ; déplacer l'occupant, c'est emprunter un arc inverse. On lui donne parfois, à tort, le nom d'algorithme hongrois : la méthode hongroise (Kuhn, 1955) résout une autre question, l'affectation où chaque paire candidat-poste a un coût, et où l'on cherche le couplage parfait le moins cher.

Comme la coupe à la fin du flot, le témoin de Hall sort de l'algorithme sans rien énumérer. Depuis un candidat resté sans poste, on regarde les postes qu'il vise, puis les candidats qui les occupent, puis les postes que visent ces derniers, et ainsi de suite. Tous ces postes sont occupés : un poste libre atteint de cette façon donnerait un chemin augmentant, et le couplage, qui est maximum, aurait pu grandir. Chacun l'est par un candidat du groupe : le groupe compte donc un candidat de plus que de postes visés.

main.py
Sortie
>_ Prêt à exécuter…
La bonne façon de prouver que tous ne peuvent pas être placés
« J'ai essayé et je n'y arrive pas » ne prouve rien. Exhiber un sous-ensemble violant la condition : ici Bruno et David, qui ne visent que Base, ou encore Bruno, Chloe et David, trois candidats qui ne visent que deux postes.
C'est court, vérifiable, et définitif. C'est encore la même structure d'argument : un certificat plutôt qu'une exploration.
Vérification rapideon peut se reprendre

Quatre candidats ne visent que deux postes. Que conclure ?

Mettre en pratique

Pourquoi le graphe résiduel contient-il des arcs inverses ?

Pour permettre à l'algorithme de revenir sur une décision antérieure.

Sans arc inverse, un premier chemin augmentant mal choisi peut saturer une conduite dont une autre route aurait eu davantage besoin, et l'algorithme s'arrête sur un flot non maximal.

L'arc inverse, de capacité égale au flot déjà passé, permet à un chemin ultérieur de « rendre » ce flot pour le réorienter. Le flot reste valide à chaque étape, et la correction de l'algorithme en dépend entièrement.

Comment prouver qu'un flot est maximal, sans refaire tourner l'algorithme ?

En exhibant une coupe de capacité égale à la valeur du flot.

Toute quantité allant de la source au puits traverse toute coupe, donc la valeur d'un flot est toujours inférieure ou égale à la capacité de toute coupe. Si les deux nombres coïncident, aucun des deux ne peut être amélioré.

C'est le théorème flot-max coupe-min, et c'est un certificat vérifiable en quelques additions.

Comment ramener un couplage biparti à un problème de flot ?

On ajoute une source reliée à tous les sommets de gauche, un puits relié à tous ceux de droite, on oriente les arêtes existantes de gauche à droite, et l'on met la capacité 1 partout.

Les capacités unitaires sur les arcs de la source empêchent un candidat d'être pris deux fois, celles sur les arcs du puits empêchent un poste d'être pourvu deux fois.

Avec des capacités entières, Ford-Fulkerson ne pousse que des quantités entières : chaque arc porte 0 ou 1, un flot de valeur kk correspond alors exactement à un couplage de kk arêtes, et le flot maximal donne le couplage maximum.

Quatre candidats ne visent que deux postes. Que peut-on conclure ?

Qu'aucun couplage ne peut les placer tous les quatre, par le théorème de Hall : un sous-ensemble de 4 candidats n'a que 2 voisins, ce qui viole la condition.

Au mieux, deux d'entre eux obtiendront un poste.

Ce sous-ensemble est le certificat : il prouve l'impossibilité en une phrase, là où énumérer les affectations possibles serait long et peu convaincant.

Pourquoi choisir le plus court chemin augmentant ?

Pour garantir la terminaison et une bonne complexité.

Ford-Fulkerson avec un choix quelconque peut, sur des capacités mal choisies, effectuer un nombre d'itérations proportionnel à la valeur du flot, donc dépendant des nombres et non de la taille du graphe. Avec des capacités irrationnelles, il peut même ne pas terminer.

En prenant systématiquement le plus court chemin par un BFS, variante Edmonds-Karp, le nombre d'itérations est borné par O(n×m)O(n \times m), indépendamment des capacités.

Quel rapport entre ce chapitre et le chapitre sur la coloration ?

La structure de preuve.

Dans les deux cas, on encadre une quantité par deux côtés : une clique, ou à défaut un cycle impair, minore le nombre chromatique, une coloration le majore ; une coupe majore le flot, un flot la minore.

Quand les deux se rejoignent, l'optimalité est démontrée, et la preuve tient en un objet exhibé plutôt qu'en un raisonnement sur l'algorithme.

C'est une forme d'argument, la dualité, qui dépasse largement la théorie des graphes : on la retrouve en programmation linéaire, dont le théorème flot-max coupe-min est un cas particulier. Du côté de la coloration, l'égalité n'est d'ailleurs pas garantie : C5C_5 n'a aucune clique de taille 3, et il faut pourtant trois couleurs.

Chapitre révisé en octobre 2026 · Une erreur dans ce chapitre ?

Dans la bibliothèque d'exercices