# Algorithme de Ford-Fulkerson

En informatique, l'algorithme de Ford-Fulkerson est un algorithme pour le problème de flot maximum, un problème d'optimisation classique dans le domaine de la recherche opérationnelle. Il est dû à Lester Randolph Ford junior et D. R. Fulkerson et c'est une variante de l'algorithme de Busacker et Gowen.

## Problème du flot maximum
### Définition du problème

Ce problème d'optimisation peut être représenté par un graphe comportant une entrée (à gauche) et une sortie (à droite). Le flot représente la circulation de l'entrée vers la sortie d'où l'utilisation de cet algorithme dans les problèmes de réseaux. Les applications sont multiples : problèmes informatiques, routiers, ferroviaires, etc. Il s'applique également à tous les autres problèmes de transferts comme les importations/exportations, les flux migratoires, démographiques mais aussi sur des flux purement numériques tels que les transferts financiers. Pour les données de très grande taille, il existe plusieurs algorithmes plus performants pour résoudre le problème de flot maximum.

### Exemple d'application

Une société de fret dispose de trois centres : un à Paris, le deuxième à Lyon, le troisième à Marseille. Trois destinations sont possibles : la Pologne, la Suède, la Grèce. Chacun des centres de fret a un stock initial de marchandises (Paris : 100 ; Lyon : 80 ; Marseille : 150). De même, chaque pays d'arrivée a une demande maximale pour les importations (Pologne : 120 ; Suède : 140 ; Grèce : 50).
L'algorithme de Ford-Fulkerson va permettre d'optimiser ces flux à l'aide d'un outil de modélisation mathématique. La structure sous-jacente est représentée par un graphe orienté dont le sommet de gauche symbolise le stock initial. Trois arcs en partent, chacun menant à un sommet représentant un centre de fret. Le sommet final symbolise la fin de la livraison, auquel mènent trois arcs venant de sommets représentant une destination de livraison.
Dans l'exemple présent, la matrice d'adjacence porte donc dans sa première ligne les valeurs desdits stocks. Inversement, à l'extrémité de la chaîne, la matrice associée comprendra dans sa dernière colonne les demandes respectives des pays cités. Entre les sommets « centre de fret » et les sommets « destination » peuvent se trouver des sommets et des arcs intermédiaires, les capacités de ces arcs correspondant au fret maximal d'un point à l'autre.
Le problème peut être généralisé à une circulation dans un réseau (véhicules, fluides, monnaie, etc.), les grandeurs mathématiques remplaçant indistinctement les faits réels qu'elles sont censées représenter.

### Formalisation
#### Réseau

Soit un réseau $G=(S,A,c,s,t)$ avec :
* $(S,A)$ un graphe orienté irréflexif ;
* une capacité $c:A\rightarrow \mathbb {N} ^{\star }$ avec pour convention : si l'arc $(u,v)$ n'existe pas, $c(u,v)=0$ ;
* un sommet source s sans arcs entrants ;
* un sommet puits t sans arcs sortants.
On suppose qu'il n'y a pas d'arcs anti-parallèles, c'est-à-dire que l'existence d'un arc $(u,v)$ exclut l'existence d'un arc $(v,u)$.

#### Flot

Le flot d'un réseau est une fonction $f:S^{2}\rightarrow \mathbb {R} ^{+}$ qui vérifie :
* pour tous sommets $(u,v)\in S\times S$, on a $0\leq f(u,v)\leq c(u,v)$ ;
* pour tout sommet $u\in S$ tel que $u\neq s$ et $u\neq t$ : $\sum _{v\in S}f(v,u)=\sum _{w\in S}f(u,w)$ (le flot entrant est égal au flot sortant : propriété de conservation).
La valeur d'un flot f est $|f|=\sum _{v\in S}f(s,v)$.

## Algorithme

Il s'agit d'un algorithme itératif. À chaque itération, la solution courante est un flot qui satisfait les contraintes de capacité (c'est donc un flot réalisable) et l'algorithme essaie d'augmenter la valeur de ce flot. Cela peut nécessiter d'annuler les mauvais choix. Pour ce faire, on définit le graphe résiduel de G et de f qui indique les modifications possibles (ajout ou annulation) : c'est un graphe pondéré $R_{f}=(S,A_{f},r_{f})$ où on a
$r_{f}(u,v)=\left\{{\begin{array}{cl}c(u,v)-f(u,v)&\mathrm {si} \ (u,v)\in A&\mathrm {(ajout)} \\f(v,u)&\mathrm {si} \ (v,u)\in A&\mathrm {(annulation)} \\0&\mathrm {sinon} \ \end{array}}\right.$
et $A_{f}=\{(u,v)\in S\times S|r_{f}(u,v)>0\}$.

### Pseudo-code

L'algorithme ne précise pas comment trouver chaque chemin $\gamma$. L'algorithme d'Edmonds-Karp, spécialisation de l'algorithme de Ford-Fulkerson, propose de faire un parcours en largeur.
Chaque chemin trouvé est garanti d’augmenter la valeur du flot, car il commence forcément par un arc sortant du sommet source et finit par un arc entrant dans le sommet puits.

### Exemple d'exécution

| On considère le réseau de flot $G=(S,A,c,s,t)$, consistant du graphe $(S,A)$ à quatre sommets $S=\{s,t,u,v\}$ et cinq arêtes $A=\{(s,u),(u,t),(s,v),(v,t),(u,v)\}$, de la source $s\in S$, du puits $t\in S$ et de la fonction de capacité $c\colon A\to \mathbb {R} _{\geq 0}$. On commence avec le flot vide $f$ qui attribue la valeur $0$ à chaque arête. Initialement, le graphe résiduel $G_{f}$et les capacités résiduelles $r_{f}$ correspondent alors exactement au réseau $G$ avec les capacités $c$. | Graphe $G$ (avec capacité $c$) | $e\in A$ $c(e)$ $(s,u)$4 $(u,t)$1 $(s,v)$2 $(v,t)$6 $(u,v)$3 |
| On considère le réseau de flot $G=(S,A,c,s,t)$, consistant du graphe $(S,A)$ à quatre sommets $S=\{s,t,u,v\}$ et cinq arêtes $A=\{(s,u),(u,t),(s,v),(v,t),(u,v)\}$, de la source $s\in S$, du puits $t\in S$ et de la fonction de capacité $c\colon A\to \mathbb {R} _{\geq 0}$. On commence avec le flot vide $f$ qui attribue la valeur $0$ à chaque arête. Initialement, le graphe résiduel $G_{f}$et les capacités résiduelles $r_{f}$ correspondent alors exactement au réseau $G$ avec les capacités $c$. | Flot $f$ | $e\in A$ $f(e)$ $(s,u)$0 $(u,t)$0 $(s,v)$0 $(v,t)$0 $(u,v)$0 |
| On considère le réseau de flot $G=(S,A,c,s,t)$, consistant du graphe $(S,A)$ à quatre sommets $S=\{s,t,u,v\}$ et cinq arêtes $A=\{(s,u),(u,t),(s,v),(v,t),(u,v)\}$, de la source $s\in S$, du puits $t\in S$ et de la fonction de capacité $c\colon A\to \mathbb {R} _{\geq 0}$. On commence avec le flot vide $f$ qui attribue la valeur $0$ à chaque arête. Initialement, le graphe résiduel $G_{f}$et les capacités résiduelles $r_{f}$ correspondent alors exactement au réseau $G$ avec les capacités $c$. | Graphe résiduel $G_{f}$ (avec capacité résiduelle $r_{f}$) | $e\in A$ $r_{f}(e)$ $r_{f}({\overleftarrow {e}})$ $(s,u)$40 $(u,t)$10 $(s,v)$20 $(v,t)$60 $(u,v)$30 |
| Supposons que l'algorithme choisisse d'abord le chemin $\gamma =\left((s,u),(u,v),(v,t)\right)$ (bleu). Le long de ce chemin, on peut augmenter le débit au maximum de $3$ puisque l'arête $(u,v)$ est limitante ($r_{f}((u,v))=3$). Il en résulte un nouveau flot (qu'on appellera toujours $f$) avec $f((s,u))=f((u,v))=f((v,t))=3$. L'arête $(s,u)$ a une capacité de $c((s,u))=4$. Elle est utilisée dans le flot : $f((s,u))=3$. Dans le graphe résiduel, sa capacité résiduelle sera donc $r_{f}((s,u))=c((s,u))-f((s,u))=1$. De même $r_{f}((u,v))=c((u,v))-f((u,v))=3-3=0$ et $r_{f}((v,t))=c((v,t))-f((v,t))=6-3=3$. Les trois arêtes $(s,u),(u,v),(v,t)$ sont strictement positives dans le flot. Ces poids dans le flot ne sont peut être pas les plus optimaux. Les nouvelles arêtes arrières $(t,v),(v,u),(u,s)$ (en rouge) dans le graphe résiduel marquent alors le fait que l'on pourra toujours diminuer le flot sur ces arêtes. | Chemin améliorant $\gamma$ (avec capacités résiduelles $r_{f}$) |
| Supposons que l'algorithme choisisse d'abord le chemin $\gamma =\left((s,u),(u,v),(v,t)\right)$ (bleu). Le long de ce chemin, on peut augmenter le débit au maximum de $3$ puisque l'arête $(u,v)$ est limitante ($r_{f}((u,v))=3$). Il en résulte un nouveau flot (qu'on appellera toujours $f$) avec $f((s,u))=f((u,v))=f((v,t))=3$. L'arête $(s,u)$ a une capacité de $c((s,u))=4$. Elle est utilisée dans le flot : $f((s,u))=3$. Dans le graphe résiduel, sa capacité résiduelle sera donc $r_{f}((s,u))=c((s,u))-f((s,u))=1$. De même $r_{f}((u,v))=c((u,v))-f((u,v))=3-3=0$ et $r_{f}((v,t))=c((v,t))-f((v,t))=6-3=3$. Les trois arêtes $(s,u),(u,v),(v,t)$ sont strictement positives dans le flot. Ces poids dans le flot ne sont peut être pas les plus optimaux. Les nouvelles arêtes arrières $(t,v),(v,u),(u,s)$ (en rouge) dans le graphe résiduel marquent alors le fait que l'on pourra toujours diminuer le flot sur ces arêtes. | Flot $f$ | $e\in A$ $f(e)$ $(s,u)$3 $(u,t)$0 $(s,v)$0 $(v,t)$3 $(u,v)$3 |
| Supposons que l'algorithme choisisse d'abord le chemin $\gamma =\left((s,u),(u,v),(v,t)\right)$ (bleu). Le long de ce chemin, on peut augmenter le débit au maximum de $3$ puisque l'arête $(u,v)$ est limitante ($r_{f}((u,v))=3$). Il en résulte un nouveau flot (qu'on appellera toujours $f$) avec $f((s,u))=f((u,v))=f((v,t))=3$. L'arête $(s,u)$ a une capacité de $c((s,u))=4$. Elle est utilisée dans le flot : $f((s,u))=3$. Dans le graphe résiduel, sa capacité résiduelle sera donc $r_{f}((s,u))=c((s,u))-f((s,u))=1$. De même $r_{f}((u,v))=c((u,v))-f((u,v))=3-3=0$ et $r_{f}((v,t))=c((v,t))-f((v,t))=6-3=3$. Les trois arêtes $(s,u),(u,v),(v,t)$ sont strictement positives dans le flot. Ces poids dans le flot ne sont peut être pas les plus optimaux. Les nouvelles arêtes arrières $(t,v),(v,u),(u,s)$ (en rouge) dans le graphe résiduel marquent alors le fait que l'on pourra toujours diminuer le flot sur ces arêtes. | Graphe résiduel $G_{f}$ résultant (avec les nouvelles capacités résiduelles $r_{f}$) | $e\in A$ $r_{f}(e)$ $r_{f}({\overleftarrow {e}})$ $(s,u)$13 $(u,t)$10 $(s,v)$20 $(v,t)$33 $(u,v)$03 |
| Supposons que l'algorithme sélectionne le chemin améliorant $\gamma =((s,v),(v,u),(u,t))$. L'augmentation maximale du débit est limitée par la capacité résiduelle $r_{f}((u,t))=c((u,t))-f((u,t))=1-0=1$. Pour la première fois, on passe par un arête arrière ($(v,u)$). Alors que le flot f augmente de 1 le long des arêtes (s,v) et (u,t), il diminue de 1 le long de (u,v). On peut remarquer que les capacités résiduelles des arêtes arrières sont toujours égales aux poids dans le flot. | Chemin améliorant $\gamma$ (avec capacités résiduelles $r_{f}$) |
| Supposons que l'algorithme sélectionne le chemin améliorant $\gamma =((s,v),(v,u),(u,t))$. L'augmentation maximale du débit est limitée par la capacité résiduelle $r_{f}((u,t))=c((u,t))-f((u,t))=1-0=1$. Pour la première fois, on passe par un arête arrière ($(v,u)$). Alors que le flot f augmente de 1 le long des arêtes (s,v) et (u,t), il diminue de 1 le long de (u,v). On peut remarquer que les capacités résiduelles des arêtes arrières sont toujours égales aux poids dans le flot. | Flot $f$ | $e\in A$ $f(e)$ $(s,u)$3 $(u,t)$1 $(s,v)$1 $(v,t)$3 $(u,v)$2 |
| Supposons que l'algorithme sélectionne le chemin améliorant $\gamma =((s,v),(v,u),(u,t))$. L'augmentation maximale du débit est limitée par la capacité résiduelle $r_{f}((u,t))=c((u,t))-f((u,t))=1-0=1$. Pour la première fois, on passe par un arête arrière ($(v,u)$). Alors que le flot f augmente de 1 le long des arêtes (s,v) et (u,t), il diminue de 1 le long de (u,v). On peut remarquer que les capacités résiduelles des arêtes arrières sont toujours égales aux poids dans le flot. | Graphe résiduel $G_{f}$ résultant (avec les nouvelles capacités résiduelles $r_{f}$) | $e\in A$ $r_{f}(e)$ $r_{f}({\overleftarrow {e}})$ $(s,u)$13 $(u,t)$01 $(s,v)$11 $(v,t)$33 $(u,v)$12 |
| Supposons que l'algorithme choisisse à nouveau le chemin $\gamma =\left((s,u),(u,v),(v,t)\right)$. Cette fois, le débit le long du chemin ne peut être augmenté que de 1. Cela correspond justement au montant par lequel on a diminué (u,v) à l'étape précédente. En effet, l'algorithme peut faire beaucoup de va-et-vient. | Chemin améliorant $\gamma$ (avec capacités résiduelles $r_{f}$) |
| Supposons que l'algorithme choisisse à nouveau le chemin $\gamma =\left((s,u),(u,v),(v,t)\right)$. Cette fois, le débit le long du chemin ne peut être augmenté que de 1. Cela correspond justement au montant par lequel on a diminué (u,v) à l'étape précédente. En effet, l'algorithme peut faire beaucoup de va-et-vient. | Flot $f$ | $e\in A$ $f(e)$ $(s,u)$ 4 $(u,t)$ 1 $(s,v)$ 1 $(v,t)$ 4 $(u,v)$ 3 |
| Supposons que l'algorithme choisisse à nouveau le chemin $\gamma =\left((s,u),(u,v),(v,t)\right)$. Cette fois, le débit le long du chemin ne peut être augmenté que de 1. Cela correspond justement au montant par lequel on a diminué (u,v) à l'étape précédente. En effet, l'algorithme peut faire beaucoup de va-et-vient. | Graphe résiduel $G_{f}$ résultant (avec les nouvelles capacités résiduelles $r_{f}$) | $e\in A$ $r_{f}(e)$ $r_{f}({\overleftarrow {e}})$ $(s,u)$04 $(u,t)$01 $(s,v)$11 $(v,t)$24 $(u,v)$03 |
| Ici, seul le chemin $\gamma =((s,v),(v,t))$ est possible. Cela augmente alors le débit de 1. Le flot a alors une valeur de $f((s,u))+f((s,v))=6$. Les arêtes sortantes de la source sont pleinement utilisées donc ce flot est un flot maximal. La coupure au niveau de (s,u) et (s,v) est donc une coupe minimale. On respecte donc bien le Théorème flot-max/coupe-min qui affirme qu'un flot maximal a la même valeur qu'une coupe minimale. L'algorithme se termine alors car aucun chemin de s à t n'existe dans le graphe résiduel obtenu. On a donc bien obtenu un flot maximal. | Chemin améliorant $\gamma$ (avec capacités résiduelles $r_{f}$) |
| Ici, seul le chemin $\gamma =((s,v),(v,t))$ est possible. Cela augmente alors le débit de 1. Le flot a alors une valeur de $f((s,u))+f((s,v))=6$. Les arêtes sortantes de la source sont pleinement utilisées donc ce flot est un flot maximal. La coupure au niveau de (s,u) et (s,v) est donc une coupe minimale. On respecte donc bien le Théorème flot-max/coupe-min qui affirme qu'un flot maximal a la même valeur qu'une coupe minimale. L'algorithme se termine alors car aucun chemin de s à t n'existe dans le graphe résiduel obtenu. On a donc bien obtenu un flot maximal. | Flot maximal $f$ | $e\in A$ $f(e)$ $(s,u)$4 $(u,t)$1 $(s,v)$2 $(v,t)$5 $(u,v)$3 |
| Ici, seul le chemin $\gamma =((s,v),(v,t))$ est possible. Cela augmente alors le débit de 1. Le flot a alors une valeur de $f((s,u))+f((s,v))=6$. Les arêtes sortantes de la source sont pleinement utilisées donc ce flot est un flot maximal. La coupure au niveau de (s,u) et (s,v) est donc une coupe minimale. On respecte donc bien le Théorème flot-max/coupe-min qui affirme qu'un flot maximal a la même valeur qu'une coupe minimale. L'algorithme se termine alors car aucun chemin de s à t n'existe dans le graphe résiduel obtenu. On a donc bien obtenu un flot maximal. | Graphe résiduel $G_{f}$ résultant (avec les nouvelles capacités résiduelles $r_{f}$) | $e\in A$ $r_{f}(e)$ $r_{f}({\overleftarrow {e}})$ $(s,u)$04 $(u,t)$01 $(s,v)$02 $(v,t)$15 $(u,v)$03 |

## Propriétés de l'algorithme
### Complexité

Le flot maximal est atteint quand plus aucun chemin améliorant ne peut être trouvé. Cependant, il n'y a aucune certitude que cette situation soit atteinte, mais la réponse sera correcte si l'algorithme se termine. Dans le cas où l'algorithme s'exécute indéfiniment, le flot peut même ne pas converger vers le flot maximum. Néanmoins, cette situation ne se produit qu'avec des valeurs de flot irrationnelles. Lorsque les capacités sont des entiers, le temps d'exécution de l'algorithme de Ford-Fulkerson est borné par $O(Af)$ (voir les notations de Landau), où $A$ est le nombre d'arêtes dans le réseau de flot et $f$ est la valeur du flot maximal. En effet, chaque chemin augmentant peut être trouvé en $O(A)$ et augmente le débit d'une quantité entière d'au moins $1$ avec $f$ comme borne supérieure.
Une variante de l'algorithme de Ford-Fulkerson avec terminaison garantie et un temps d'exécution indépendant de la valeur de flot maximal est l' algorithme d'Edmonds-Karp, qui a une complexité temporelle en $O(SA^{2})$.

### Terminaison

Si les capacités des arêtes sont des entiers, l'algorithme se termine. En effet, la suite des flots calculés est à valeurs entières. strictement croissante, et majorée par la valeur du flot maximal. Elle ne peut donc pas être infinie, et l'algorithme se termine.

## Exemple pour lequel l'algorithme ne termine pas

On s'intéresse au graphe suivant, qui a pour sommet source $s$, pour sommet puits $t$. Les arêtes $e_{1}$, $e_{2}$ et $e_{3}$ ont pour capacités respectives $1$, $r=({\sqrt {5}}-1)/2$ et $1$. La capacité des autres arêtes est fixée à $10$. On a choisi la constante $r$ de sorte que $r^{2}=1-r$. On considère l'exécution de l'algorithme choisissant les chemins suivants, où on note $p_{1}=\{s,v_{4},v_{3},v_{2},v_{1},t\}$, $p_{2}=\{s,v_{2},v_{3},v_{4},t\}$ et $p_{3}=\{s,v_{1},v_{2},v_{3},t\}$.
| Étape | Chemin choisi | Augmentation du flot | Capacité résiduelle | Capacité résiduelle | Capacité résiduelle |
| Étape | Chemin choisi | Augmentation du flot | $e_{1}$ | $e_{2}$ | $e_{3}$ |
| 0 | | | $r^{0}=1$ | $r$ | $1$ |
| 1 | $\{s,v_{2},v_{3},t\}$ | $1$ | $r^{0}$ | $r^{1}$ | $0$ |
| 2 | $p_{1}$ | $r^{1}$ | $r^{2}$ | $0$ | $r^{1}$ |
| 3 | $p_{2}$ | $r^{1}$ | $r^{2}$ | $r^{1}$ | $0$ |
| 4 | $p_{1}$ | $r^{2}$ | $0$ | $r^{3}$ | $r^{2}$ |
| 5 | $p_{3}$ | $r^{2}$ | $r^{2}$ | $r^{3}$ | $0$ |
On remarque qu'après les étapes 1 et 5, les capacités résiduelles des arêtes $e_{1}$, $e_{2}$ et $e_{3}$ sont respectivement de la forme $r^{n}$, $r^{n+1}$ et $0$ et le flot ajouté est $r^{n}$ où $n\in \mathbb {N}$. Ainsi, par récurrence on pourra toujours répéter la boucle de chemins $p_{1}$, $p_{2}$, $p_{1}$ et $p_{3}$ tout en ajoutant un flot strictement positif car les capacités résiduelles resteront toujours de la forme $r^{n}$, $r^{n+1}$ et $0$ à la fin de l'exécution sur les chemins. L'algorithme ne termine donc pas sur cette entrée. Le fait que l'on ait une capacité irrationnelle par rapport aux autres capacités entières est cruciale car elle permet d'avoir une suite de taille de flot infinie strictement croissante et majorée.