0% ont trouvé ce document utile (0 vote)
61 vues50 pages

Cours SsSol

Cours de théorie des graphes

Transféré par

S4ul Yaniv
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
61 vues50 pages

Cours SsSol

Cours de théorie des graphes

Transféré par

S4ul Yaniv
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
Vous êtes sur la page 1/ 50

Outils de modélisation-

Graphes et recherche opérationnelle

Support de cours UPSSITECH - 1ère année


(F. Bannay/M.-C. Lagasquie-Schiex - Année 2023-2024)

September 25, 2023


Contents

1 Structures de données 5
I Structures linéaires . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
I.1 Liste . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
I.2 Pile (stack) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
I.3 File (queue) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
II Structures arborescentes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
II.1 Arbre binaire de recherche (search binary tree) . . . . . . . . . . . . . . . . 10
II.2 Graphe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

2 Graphes orientés et non-orientés 12


I Concepts orientés : définitions et terminologie . . . . . . . . . . . . . . . . . . . . . 12
II Concepts non orientés : définitions . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
III Parcours . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
IV Forte-Connexité, graphe réduit (concepts orientés) . . . . . . . . . . . . . . . . . . 19

3 Les circuits, les cycles et les arbres 22


I Partition en niveaux des sommets d’un graphe sans circuit . . . . . . . . . . . . . . 22
II Arbre (notion non orientée) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
III Arbre couvrant de poids minimum . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

4 Algorithmes de plus court chemin 28


I Définitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
II Graphe orienté pondéré positivement: algorithme de Dijkstra . . . . . . . . . . . . 29
III Matrice de routage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
IV L’algorithme de Bellman . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
V Problèmes d’ordonnancement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

5 Flots et réseaux de transport 40


I Flux et flots . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
II Réseau de transport, Flot compatible, Problème du flot maximum dans un réseau . 43
II.1 Théorème du flot maximum et de la coupe minimum . . . . . . . . . . . . . 44
II.2 Algorithme de Ford-Fulkerson . . . . . . . . . . . . . . . . . . . . . . . . . . 45

1
Introduction
La théorie des graphes et la recherche opérationnelle font à la fois partie des mathématiques
dites “discrètes”1 et de l’informatique théorique (Dijkstra était informaticien). Cependant
cette matière est peu enseignée en mathématiques et fait systématiquement partie de
l’enseignement en informatique, bien que la recherche fasse intervenir des laboratoires
rattachés aux deux disciplines. Informellement, la théorie des graphes permet de raisonner
sur des dessins dans lesquels apparaissent des sommets et des arcs. La recherche opérationnelle
propose des méthodes rationnelles pour élaborer de meilleures décisions dans les problèmes
d’organisation. La recherche opérationnelle tire son nom des applications militaires dont
elle est issue. Elle s’attaque à trois types de problèmes (voir [18]) :

pb combinatoire (trouver une solution optimale parmi un grand nombre de solutions2 ),

pb aléatoire (trouver une solution optimale en présence d’incertitude 3 ),

pb concurrentiel (trouver une solution optimale en prenant en compte les agissements


d’autres décideurs4 ).

Les thèmes abordés dans ce cours sont au confluent de la théorie des graphes et de
l’optimisation combinatoire :

• connexité, coloration

• arbre partiel de poids minimum

• plus court chemin

• problèmes de flots

• ordonnancement de tâches.
1
Dans le sens où la notion de continuité n’intervient pas. Les objets étudiés en mathématiques
discrètes sont des ensembles dénombrables comme celui des entiers. Les mathématiques discrètes incluent
habituellement la logique (et l’étude du raisonnement), la théorie des ensembles, la théorie des nombres,
la combinatoire, la théorie des graphes, la théorie de l’information, la théorie de la calculabilité et de la
complexité.
2
Exemple typique : déterminer où installer 5 centres de distribution parmi 30 sites d’implantation
possibles, de sorte que les coûts de transport entre ces centres et les clients soient minimum. L’énumération
des solutions 30 x 29 x 28 x 27 x 26 / (5 x 4 x 3 x 2) = 142 506 doit être évitée. Pour info, il s’agit de
l’ensemble des combinaisons Cnp = p!(n−p)!n!
avec n = 30 et p = 5 (donc nb de façons de choisir un nombre
p d’objets dans un ensemble de taille n, lorsque les objets sont discernables et que l’on ne se soucie pas de
l’ordre dans lequel les objets sont placés ou énumérés).
3
Exemple typique : connaissant la distribution aléatoire du nombre de personnes entrant dans une
administration en une minute et la distribution aléatoire de la durée de traitement pour une personne,
déterminer le nombre minimum de guichets à ouvrir pour qu’une personne ait moins de 5% de chances de
devoir attendre plus de 15 minutes.
4
Exemple typique : fixer une politique de prix de vente, sachant que les résultats d’une telle politique
dépendent de la politique que les concurrents adopteront.

2
D’autre part, les graphes sont un outil pour représenter et modéliser des connaissances (ce
sont donc des structures de données) mais ce ne sont pas les seuls. En introduction de ce
cours, un panorama des différents types de structures de données sera fait afin de voir les
avantages et les inconvénients de chacun.
Les principaux documents qui ont servi à réaliser ce cours sont le support de cours de
Serge Nogarède [15], celui de Mme Laudet[13] et celui d’Annie Astié-Vidal [1], les livres
[2, 5, 9, 14, 12] et l’encyclopédie en ligne wikipedia [19, 18].

Historique
(wikipedia [19], Patrice Ossona de Mendez [6], Alexander Schrijver [17])

Les premiers travaux sur la théorie des graphes sont en général attribués au mathématicien
suisse Leonhard Euler (1707-1783) qui en 1736 réussit à formaliser mathématiquement et
résoudre le problème des ponts de Koenigsberg D’autres problèmes datant du XIXieme
siècle sont posés en termes de graphes :

• le problème du voyageur de commerce (“traveling salesman”) formulé dans un manuel


allemand pour voyageurs de commerce de 18325 . Il s’agit de trouver un circuit de
longueur minimale permettant de parcourir toutes les villes d’un réseau.

• le problème des quatre couleurs : en 1852, l’anglais Francis Guthrie (élève de Augustus
De Morgan) conjecture que n’importe quelle carte géographique peut être coloriée en
utilisant uniquement quatre couleurs de telle façon que deux pays qui présentent une
frontière commune soient de couleur distincte. Ce problème a été résolu par Kenneth
Appel et Wolfgang Haken en 1976 en faisant appel à une preuve informatique, soit
un siècle après son énonciation. En 2006, Georges Gonthier a proposé une nouvelle
preuve basée elle aussi sur une démonstration par ordinateur mais plus robuste. De
nombreux termes et concepts théoriques fondamentaux de la théorie des graphes ont
découlé des tentatives de résolution de ce problème.

La formalisation de la théorie des graphes commence vraiment dans les années 1940 : un
des premiers ouvrages est écrit par König en 1936 (théorie des graphes orientés et non
orientés). Et connait un essort particulier dans les années 1960 avec notamment Claude
Berge [2], père de la théorie “moderne” des graphes.
Parallèlement les années 1960 permettent la découverte d’algorithmes fondamentaux:

• plus court chemin (Bellman-Ford 1958, Dijkstra 1959)


5
“Der Handlungsreisende - wie er sein soll und was er zu thun hat, um Aufträge zu erhalten und eines
glücklichen Erfolgs in seinen Geschäften gewiB zu sein- von einem alten Commis-Voyageur” (Le voyageur
de commerce - comment il doit être et ce qu’il doit faire pour obtenir des commandes et être sûr du succès
de ses affaires - par un ancien Commis-Voyageur).

3
• arbre couvrant de poids minimum (Kruskal 1956, Prim 1957, Norman-Rabin 1959)

• flot maximal (Ford-Fulkerson 1956)

• coloration (Welsh-Powell 1967)

• recherche de chemin (“pathfinding”) : Branch and bound (Land-Doig 1960) et A⋆


(Hart-Nilsson-Raphael 1968).

De nos jours, la recherche opérationnelle et la théorie des graphes continuent leur évolution
en particulier en terme de performance. Deux exemples (Philippe Chrétienne [4]):

• le problème du voyageur de commerce (années 1960: 20 villes, années 1980: 1000


villes, années 2000 : 1 000 000 villes). Cette évolution est due à des progrès théoriques
(approche polyédrique), des progrès algorithmiques (programmation linéaire continue,
structure de données) et au progrès technologique.

• les problèmes d’ordonnancement : un problème concernant 10 machines et 10 pièces


(nombre de solutions (10!)10 ) était non résolu jusqu’en 1995. Il est maintenant
résolu exactement pour plusieurs dizaines de machines et de pièces grace aux progrès
théoriques et algorithmiques (approches par contraintes).

4
Chapter 1

Structures de données

(voir Froidevaux et al. [3], Cormen [5], Xuong [20])

En Informatique, les structures de données sont essentiellement destinées à rassembler un


ensemble de données. Ces données peuvent être :

hétérogènes (de nature différente) : par exemple une chaı̂ne de caractères et 3 entiers
pour représenter le nom et la date de naissance d’une personne. Pour faire cela, on
pourra utiliser des structures de données de type “enregistrement” (struct en C,
par exemple). Dans ce cas-là, ce qui importe est de rassembler quelques données
de nature différente pour en faire un tout manipulable facilement. Le nombre de
données est ici en général peu élevé.

homogènes (de même nature) : par exemple un ensemble de personnes. Il s’agit là
aussi de rassembler ces données pour en faire un tout manipulable mais ici on va
faire face à un problème d’efficacité puisque le nombre de ces données peut être très
grand. Les opérations à réaliser sont alors des ajouts ou suppressions de donnée, des
recherches de donnée (pour un simple accès ou une modification).

D’autre part, on doit se poser aussi la question de l’évolution de ces données car cela a un
impact fort sur la matière dont on va utiliser la structure de données et sur l’efficacité des
programmes. Les données peuvent être :

statiques : leur taille est fixée au départ du programme et ne peut plus évoluer ;

dynamiques : leur taille évolue au cours du programme.

Cette section est destinée à récapituler les principales structures de données utilisées
généralement en informatique pour traiter le cas des données homogènes et en général
dynamiques. Elles sont de 2 types possibles avec différents sous-cas :

structures linéaires avec au moins 3 sous-cas : listes (triées ou pas), piles, files,

5
structures arborescentes avec au moins 2 sous-cas : arbres, graphes.

Pour chaque cas, on donnera les opérations possibles avec leur complexité temporelle et les
limites ou contraintes d’utilisation de ces structures.

Remarque sur la complexité temporelle des opérations On utilisera la notation


de Landau O(f (n)) qui majore le temps d’exécution d’un programme quand le nombre de
données n tend vers l’infini :

T (n) = O(f (n)) si ∃c, n0 tels que ∀n > n0 , T (n) ≤ c × f (n)

c et n0 sont des constantes et T (n) représente le temps d’exécution pour n données.

I Structures linéaires
I.1 Liste
Une liste permet de stocker les données sous la forme d’une séquence. Elle peut être
dynamique ou statique et elle peut être triée ou pas.
Si elle est statique, cela implique des limites pour l’opération d’ajout : pas possible de
dépasser un nombre maximum de données stockées. Par contre, un avantage important
est l’accès direct à chaque donnée si on connaı̂t son indice (sa clé d’accès). Dans ce cas,
un moyen simple d’implémenter ce type de structure est d’utiliser un tableau :

• soit non trié : les données sont stockées dans n’importe quel ordre dans le tableau,

• soit trié : les données sont stockées dans un ordre fixé par le programmeur dans le
tableau ; on va donc pouvoir utiliser une méthode dichotomique pour accéder aux
valeurs.

6
Attention, l’existence d’un tri influence fortement le temps d’exécution des opérations (N
étant le nombre de données dans le tableau) :

ajout suppression recherche/modification


(avec limite !)
Tableau non trié O(1) O(N ) O(N )
Tableau trié O(log(N ) + N ) O(log(N ) + N ) O(log(N ))

Notons qu’il existe des algorithmes de tri permettant de trier un tableau qui ne le serait
pas (l’un des plus efficaces est le tri rapide de complexité O(N × log(N ))).
Si la liste est dynamique, alors on n’a pas de contrainte sur les ajouts (moyennant la place
mémoire disponible sur la machine). Par contre, il n’y a plus d’accès direct à chaque
donnée. On a alors les complexités suivantes montrant que l’existence du tri n’a plus
d’impact :

ajout suppression recherche/modification


(sans limite !)
Liste dynamique non triée O(N ) O(N ) O(N )
Liste dynamique triée O(N ) O(N ) O(N )

I.2 Pile (stack)


La pile permet aussi de stocker des données sous la forme d’une séquence mais avec un
comportement d’ajout, d’accès et de suppression très particulier :

la dernière donnée ajoutée joue un rôle essentiel car c’est la seule donnée
directement accessible et supprimable directement ; pour accéder à une autre
donnée il faut la retirer de la structure.

On ajoute et on supprime donc toujours depuis le sommet de la pile. L’opération de


suppression est donc contrainte par le fait que c’est toujours la dernière donnée ajoutée
qui sera supprimée (contrairement à ce qu’on peut faire dans une liste, où l’on peut choisir
de supprimer la donnée que l’on veut).
On peut faire l’analogie avec une pile d’assiettes : on ajoute sur le sommet de la pile et on
enlève depuis le sommet de la pile.
On ne peut donc pas faire de tri, ni accéder directement à n’importe quelle donnée.
C’est une structure en général dynamique1 . En théorie, la pile n’a donc pas de limite en
nombre de données stockables.
Le temps d’exécution des opérations est le suivant (N étant le nombre de données dans la
pile) :
1
Notons qu’on peut quand même la simuler à l’aide d’un tableau.

7
ajout suppression recherche/modification
(avec contrainte !)
Pile O(1) O(1) non applicable

Notons qu’on peut toujours faire une recherche dans une pile mais qu’il s’agit là d’une
opération destructrice : on déconstruit la pile jusqu’à trouver ce que l’on cherche. C’est
pour cela qu’on considère qu’une pile n’est pas faite pour faire de la recherche ou de la
modification de données. C’est juste un moyen de stocker des données sachant qu’on les
utilisera dans l’ordre inverse de celui du stockage (la plus récente d’abord).

I.3 File (queue)


La file permet aussi de stocker des données sous la forme d’une séquence mais avec un
comportement d’ajout, d’accès et de suppression très particulier (différent de celui de la
pile) :
il n’y a que 2 données directement accessibles :
• la dernière donnée ajoutée à partir de laquelle on peut faire un nouvel
ajout,
• la donnée la plus ancienne ajoutée qui est la seule donnée supprimable
directement ; pour accéder à une autre donnée il faut la retirer de la
structure.
Donc pour accéder à une autre donnée de la file, il faut partir de la donnée la
plus ancienne et la retirer de la structure.
Les ajouts se font donc en fin de file et la suppression en début de file. Ainsi, l’opération
de suppression est contrainte par le fait que c’est toujours la donnée ajoutée depuis le plus
longtemps qui sera supprimée (contrairement à ce qu’on peut faire dans une liste où l’on
peut choisir de supprimer la donnée que l’on veut et contrairement à ce qu’on peut faire
dans une pile où c’est la donnée la plus récente qui sera supprimée).
On peut faire l’analogie avec une file d’attente : on ajoute à la fin de la file et on enlève
depuis le début de la file.
On ne peut donc pas faire de tri, ni accéder directement à n’importe quelle donnée.
C’est une structure en général dynamique2 donc pas de limite en nombre de données
stockables.
Le temps d’exécution des opérations est le suivant (N étant le nombre de données dans la
file) :
ajout suppression recherche/modification
(avec contrainte !)
File O(1) O(1) non applicable
2
Notons qu’on peut quand même la simuler à l’aide d’un tableau.

8
Ici aussi, notons qu’on peut toujours faire une recherche dans une file mais qu’il s’agit là
d’une opération destructrice : on déconstruit la file jusqu’à trouver ce que l’on cherche.
C’est pour cela qu’on considère qu’une file n’est pas faite pour faire de la recherche ou de
la modification de données. C’est juste un moyen de stocker des données sachant qu’on les
utilisera dans le même ordre que celui du stockage (la plus ancienne d’abord).
Remarque : la pile et la file sont très similaires de par le type des contraintes imposées (pas
de tri, pas d’accès direct, recherche uniquement par déconstruction). Elles ne diffèrent que
par leur point d’accès :

• 1 seul point d’accès pour la pile, le “dernier élément ajouté”, à partir duquel on fait
les ajouts et les suppressions ;

• 2 points d’accès pour la file, le “plus ancien élément ajouté” pour la suppression et
le “dernier élément ajouté” pour l’ajout.

II Structures arborescentes
Ce sont des structures qui permettent un stockage “organisé” des données : à partir d’une
donnée on peut accéder à certaines autres données mais pas forcément à toutes. On n’a
donc plus une séquence de données, mais plutôt une notion de “relation entre les données”
puisque des données sont liées à certaines données et pas à d’autres. On dit que chaque
donnée correspond à un nœud de la structure et la relation correspond aux liens entre les
nœuds.
Cette relation se définit avec des contraintes et ces contraintes peuvent être de nature
différente :

contraintes purement structurelles : à partir d’une donnée a, on peut accéder uniquement


à des données b1 , . . . , bn ; on dit que a est le père de b1 , . . . , bn et que b1 , . . . , bn sont
les fils de a ;

contraintes sémantiques : elles s’ajoutent aux contraintes structurelles en imposant


qu’il existe une règle liant la donnée a et les données b1 , . . . , bn (par exemple, a
doit être inférieure à chaque bi ).

Ces structures sont en général dynamiques3 donc sans limite en nombre de données stockables.
Sur ces structures, on retrouve les opérations vues précédemment (ajout, suppression,
recherche et modification d’une donnée), mais on peut aussi avoir de nouvelles opérations
(voir l’exemple en section II.2).
Sachant que les contraintes structurelles et sémantiques sont extrêmement nombreuses, il
est impossible de toutes les décrire ici. On va juste donner deux exemples génériques.
3
Même si, dans certains cas très particuliers, on peut les simuler à l’aide d’un tableau.

9
II.1 Arbre binaire de recherche (search binary tree)
Un arbre binaire de recherche est une structure qui permet de faire du tri de données. Il
a deux contraintes à satisfaire :
contrainte structurelle : à partir d’une donnée a, on peut accéder au plus à deux
données b1 et b2 ; on dit que la structure est un arbre binaire ; b1 est appelé le
sous-arbre gauche et b2 le sous-arbre droit ;

contrainte sémantique : pour chaque nœud, toutes les valeurs stockées dans le sous-
arbre gauche du nœud sont inférieures [ou égales] à la valeur du nœud et toutes les
valeurs stockées dans le sous-arbre droit du nœud sont strictement supérieures à la
valeur du nœud ; on dit que la structure est un arbre de recherche.
Le respect de la contrainte sémantique donne le moyen d’obtenir un tri des valeurs
stockées par simple parcours de tout l’arbre.
Par contre, il n’y a pas d’accès direct aux données (il faut partir du premier nœud de
l’arbre et parcourir l’arbre en suivant les liens entre les nœuds). Contrairement à la pile
ou à la file, ce parcours n’est pas destructif. On peut donc supprimer la donnée de notre
choix.
Il existe tout un vocabulaire lié à la notion d’arbre :
racine : premier nœud de l’arbre (c’est le point d’accès aux données)

feuille : nœud de l’arbre n’ayant pas de fils

branche : séquence de nœuds de l’arbre allant de la racine à une feuille

hauteur : longueur de la plus longue branche en nombre de liens entre les nœuds
Le temps d’exécution des opérations est le suivant (N étant le nombre de données dans
l’arbre et h la hauteur de l’arbre) :

ajout suppression recherche/modification


Arbre binaire de recherche O(h) O(h) O(h)
avec la contrainte suivante : 1 ≤ h ≤ N et
dans le meilleur des cas (arbre équilibré4 ) h ≈ log(N )

II.2 Graphe
Un graphe est une structure de données qui permet de stocker des données et de modéliser
une relation binaire R entre ces données. Il a deux contraintes à satisfaire :
contrainte structurelle : à partir d’une donnée a, on peut accéder au plus à n données
b1 , . . . , bn , n étant fini et appelé le facteur de branchement du graphe ;
4
le delta max de longueur entre les branches est de 1

10
contrainte sémantique : un nœud contenant une donnée a est lié à une donnée bi si et
seulement si le couple (a, bi ) appartient à la relation binaire R.

Il n’y a pas d’accès direct aux données (il faut partir d’un nœud du graphe – et parcourir le
graphe jusqu’à atteindre les données qui nous intéressent). Ce parcours n’est pas destructif.
Comme la structure de données graphe permet à la fois de stocker des données mais
aussi une relation R entre ces données, il y a de nouvelles opérations possibles : ajout,
suppression, recherche et modification d’un couple de R.
Le temps d’exécution des opérations est le suivant (N étant le nombre de données dans le
graphe et M le nombre de couples dans la relation R) :

ajout suppression recherche/modification


donnée relation donnée relation donnée relation
Graphe O(N ) O(N + M ) O(N + M ) O(M ) O(N ) O(M )

Le reste de ce cours va être consacré à l’étude plus approfondie des graphes.

Bilan :

• nature variable des données manipulées par les programmes :


hétérogènes/homogènes, statiques/dynamiques

• beaucoup de données ⇒ besoin de gestion/d’organisation de ces


données

• les structures de données permettent cette gestion

• 2 types de structures avec des sous-types :

– linéaires (liste, file et pile)


– arborescentes (arbre et graphe)

• à chaque type, correspond un ensemble d’opérations possibles

• à chaque type+opération, correspondent une complexité (temps de


calcul et parfois mémoire) et des contraintes

Avant de coder, il faut identifier les structures les mieux adaptées avec
leurs avantages et inconvénients !

11
Chapter 2

Graphes orientés et non-orientés

Préliminaire : Il existe deux types de graphes (orientés ou pas). Ce chapitre va donner


les principales définitions et la terminologie à utiliser qui sont très souvent liées au type de
graphe.

I Concepts orientés : définitions et terminologie


Définition 1 (graphe orienté) Un graphe orienté G est un couple (X, U ) où
• X est un ensemble fini de sommets X = {xi , i = 1..n}, n fini (le nombre de sommets
n est appelé l’ ordre du graphe)
• U est un ensemble de couples de sommets de X × X, appelés arcs .
Étant donné un arc u = (xi , xj ) ∈ U , xi est appelée origine de u (ou extrémité initiale )
et xj est l’ extremité terminale de u.
Si xi = xj alors l’arc est une boucle .
Deux sommets reliés par un arc sont dits adjacents .
Notons que U représente donc une relation binaire liant un sommet à un autre sommet.
Exemple 1 G = (X, U ) avec
X = {a, b, c, d, e, f, g},
U = {(a, b), (a, d), (b, d), (d, b), (b, b), (e, e), (e, f ), (g, f )}
u5

b u6 f
u1 u7
a u4 u3 e u8
u2

d c g

12
Plusieurs types de graphe peuvent être définis suivant les contraintes sur l’ensemble des
arcs.

Le premier type de graphe correspond au cas où aucun sommet n’est adjacent à lui-même
(donc la relation U est irréflexive1 ) :

Définition 2 (Graphe simple) Un graphe orienté est simple s’il ne contient pas de
boucles.

Le second type de graphe correspond au cas où tout sommet est adjacent à tout autre
sommet excepté lui-même :

Définition 3 (Graphe complet) Un graphe orienté simple G = (X, U ) est dit complet
si ∀x, y ∈ X, si x ̸= y et (x, y) ̸∈ U alors (y, x) ∈ U .

On peut aussi construire d’autres graphes à partir d’un graphe existant.


La première possibilité consiste à garder les sommets existants mais à réduire l’ensemble
des arcs :

Définition 4 (Graphe partiel (strict)) Soit G = (X, U ) un graphe, le graphe G′ =


(X, U ′ ) avec U ′ ⊂ U est un graphe partiel de G.

La seconde possibilité consiste à réduire l’ensemble des sommets existants mais en gardant
tous les arcs entre les sommets choisis :

Définition 5 (Sous-graphe (strict)) Soit G = (X, U ) un graphe, le graphe GX ′ =


(X ′ , UX ′ ) avec X ′ ⊂ X et UX ′ = {(xi , xj ) ∈ U |xi , xj ∈ X ′ } est un sous-graphe de G
engendré par X ′ .

Exercice 1 Transformer le dessin ci-après pour qu’il devienne un graphe simple.

b f

a e

d c g

Puis construisez un graphe complet à partir du sous-graphe engendré par l’ensemble de


sommets {c, e, f, g} en ajoutant le moins d’arcs possible.

On peut également définir un sous-graphe partiel (sous-graphe dans lequel on élimine des
arcs).
1
∀x ∈ X, ∄(x, x) ∈ U .

13
Définition 6 (Voisinage dans un graphe. Dictionnaire d’un graphe)
On appelle successeur d’un sommet x, tout sommet y tel que (x, y) ∈ U .
Le prédecesseur d’un sommet x est un sommet y tel que (y, x) ∈ U .
L’ensemble des successeurs d’un sommet x est noté Γ+ (x), l’ensemble de ses prédecesseurs
Γ− (x). Γ(x) = Γ+ (x) ∪ Γ− (x) est l’ensemble des voisins de x.
Un sommet qui n’a pas de voisin est un sommet isolé .
Le degré sortant d+ (x) (resp. degré entrant d− (x)) de x est le nombre d’arcs d’origine
x (resp d’extrémité). Le degré de x est d(x) = d+ (x) + d− (x).
Les sources d’un graphe sont les sommets de degré entrant nul (d− (x) = 0), les puits
sont ceux de degré sortant nul (d+ (x) = 0).
Le dictionnaire d’un graphe est :

xi Γ+ (xi )
• soit un tableau qui à chaque sommet fait correspondre ses successeurs :

xi Γ− (xi )
• soit un tableau qui à chaque sommet fait correspondre ses prédecesseurs :

Exercice 2 Quel est le dictionnaire du graphe de l’exemple 1 ? Quels sont les sources, les
puits, le degré de b ?

Propriété 1 Soit G = (X, U ) un graphe orienté, d(x) = 2 × |U |.


P
x∈X

La preuve de la propriété précédente repose sur le fait que tout arc entrant sur un sommet
sort d’un autre sommet. Il est donc comptabilisé deux fois dans le calcul des degrés.

Définition 7 (Matrice d’adjacence) La matrice d’adjacence associée à un graphe (pas


forcément simple) ou matrice booléenne est une matrice n × n (n étant le nombre de
1 si (xi , xj ) ∈ U
(
sommets) dont les termes sont aij =
0 sinon

Exercice 3 Donner la matrice d’adjacence de l’exemple 1.

Définition 8 (Chemin-Circuit) Soit G = (X, U ) un graphe orienté. Un chemin reliant


deux sommets (pas forcément distincts) a (origine) et b (extrémité) est une séquence d’arcs
(u1 , . . . up ) avec p ≥ 1 tel qu’il existe une suite de sommets (s1 , . . . sp+1 ) avec s1 = a et
sp+1 = b de façon à ce qu’un sommet extrémité d’un arc soit l’origine du suivant, c’est à
dire ∀i ∈ J1, pK, (si , si+1 ) = ui .
Un chemin est dit simple si ses arcs sont tous différents. La longueur ou cardinalité
d’un chemin est son nombre d’arcs (p, par définition, un chemin de longueur 0 n’existe
pas.)
Un circuit est un chemin simple dont les deux extrémités coincident.
Un chemin est élémentaire si tous les sommets sont distincts (sauf eventuellement s1 =
sp+1 (circuit élémentaire)).

14
Exemple 2 Dans l’exemple 1, la séquence (u1, u3, u4, u3, u4) est un chemin non simple.
(u1, u3, u4) est un chemin simple mais non élémentaire. (u1, u3) est un chemin élémentaire.
(u3, u4) est un circuit (il correspond à plusieurs chemins (u3, u4) et (u4, u3)).

Remarque Un chemin élémentaire est simple (mais pas l’inverse).

Exercice 4 Quelle est la cardinalité maximale d’un chemin élémentaire entre deux sommets
distincts dans un graphe d’ordre n?

II Concepts non orientés : définitions


Définition 9 (Graphe non orienté) Un graphe non orienté G est un couple (X, U ),
où

• X est un ensemble fini de sommets X = {xi , i = 1..n},

• U est un ensemble d’ arêtes de G, une arête u ∈ U symbolise un lien non dirigé entre
deux sommets. Soit xi et xj deux sommets, les couples (xi , xj ) et (xj , xi ) représentent
la même arête dont xi et xj sont les extrémités .

On peut réutiliser la notion de “graphe simple” (pas de boucle) adaptée au cas non orienté.
De même, les notions de sous-graphe et de graphe partiel peuvent être réexploitées dans le
cas non-orienté.

Exemple 3 Graphe non-orienté et simple.

b d f
a h
c e g

L’ensemble des sommets {c, d, e, g} permet de définir un sous-graphe (voir en rouge).

La notion de “graphe complet” (chaque sommet est relié à tous les autres sauf lui-même
par une arête) peut aussi être adaptée facilement au cas non orienté et elle conduit aux
notions de “clique” et “stable”.

Définition 10 (Graphe non orienté complet, Clique et Stable) Un graphe simple


non orienté est complet s’il existe une arête entre deux sommets quelconques.
Une clique est un sous-graphe complet.
Un stable est un ensemble de sommets tel que deux sommets distincts ne sont pas adjacents.

15
Notons qu’il existe un lien direct entre clique et stable : dans le cas d’un graphe simple,
trouver un stable d’ordre k revient à trouver une clique d’ordre k dans le graphe simple
inverse, c’est-à-dire qu’il possède une arête si elle n’existe pas dans le graphe d’origine, et
inversement.

Exercice 5 Dessinez un graphe simple non-orienté complet à 4 sommets, 5 sommets.

Exercice 6 Sur le graphe non orienté associé à l’exemple 3 trouver le cardinal de la plus
grande clique, celui du plus grand stable.

Attention les concepts non-orientés s’appliquent dans des graphes orientés ou non-orientés
:

• chaque fois qu’on applique un concept non-orienté à un graphe orienté on l’applique


en omettant les orientations des arcs.

• certains concepts orientés peuvent s’appliquer à un graphe non-orienté en ajoutant


une orientation dans les deux sens aux arêtes.

Définition 11 (Chaı̂ne et cycle) Soit G = (X, U ) un graphe orienté ou non. Une


chaı̂ne est une séquence d’arcs ou d’arêtes (u1 , . . . up−1 ) de U reliant deux sommets (pas
forcément distincts) s1 (origine) et sp (extrémité) avec p > 1 tel qu’il existe une suite de
sommets (s1 , . . . sp ) avec ∀i ∈ J1, p − 1K, si et si+1 sont reliés dans U par ui (sans tenir
compte de son orientation si G est orienté) par un arc de cette chaı̂ne.
Une chaı̂ne est simple si elle ne contient pas deux fois le même arc.
Un cycle est défini par l’ensemble des arcs d’une chaı̂ne simple dont les extrémités coı̈ncident.
Une chaı̂ne est élémentaire si elle ne contient pas deux fois le même sommet (sauf
eventuellement x = y (cycle élémentaire)).

Exemple 4 Notez bien : graphe orienté!!

a
u1 u4
u5
b c
u2 u6
d
u3 u7
u8 u9

La séquence (u1, u4, u6, u5, u1) est une chaı̂ne non simple, (u1, u4, u6, u5) est une chaı̂ne
simple mais pas élémentaire, (u1, u4, u6, u8) est une chaı̂ne élémentaire. (u2, u3, u8) est
un cycle.

16
Exercice 7 Donner un exemple de chaı̂ne et de cycle dans le graphe de l’exemple 3.

Remarque Un chemin est une chaı̂ne dont tous les arcs sont orientés dans le même sens.

Remarque Attention la notion de chemin ou de circuit n’existe pas dans un graphe non-
orienté.

Définition 12 (Coloration et Nombre chromatique) Une coloration de G est une


fonction associant à tout sommet de G une couleur, généralement un élément de l’ensemble
d’indices des couleurs {1, 2, ..., n}, telle que deux sommets adjacents n’ont pas la même
couleur (où n est le nombre de sommets du graphe). Le nombre minimum de couleurs pour
obtenir une coloration de G est appelé le nombre chromatique de G.

Remarque Une coloration de G correspond à une partition de ses sommets en stables.

Exemple 5 Avec l’exemple 3. Comme il existe une clique de 4, il faudra au moins 4


couleurs pour colorer ce graphe. Par exemple :

b d f
a h
c e g

Définition 13 (Composantes connexes ou s-connexes) Soit G = (X, U ) un graphe


orienté ou non. La relation binaire( R sur X (dite relation de connexité) est définie par:
x = y ou
(x, y) ∈ R ⇔
il existe une chaı̂ne entre x et y
R est une relation d’équivalence (réflexive, symétrique et transitive).
Les classes d’équivalence X1 , . . . Xp (1 ≤ p ≤ |X|) de la relation de connexité sont les
composantes connexes de G.

On appelle également composantes connexes de G les sous-graphes GXi engendrés par les
ensembles de sommets Xi .
Un graphe est dit connexe s’il ne possède qu’une composante connexe, c’est-à-dire que
deux sommets distincts quelconques sont reliés par une chaı̂ne ; par définition, les sous-
graphes GXi sont connexes.

Exercice 8 Quelles sont les composantes connexes du graphe suivant ?

17
b h
u10
u1 u4
u5 u11 u13
a c f
u2 u6 u12
d g
u3 u7
u8 u9

III Parcours
Définition 14 (Descendants et ascendants) On dit que y est un descendant de x s’il
existe un chemin de x à y ou si x = y. On dit que y est un ascendant de x s’il existe un
chemin de y à x ou y = x. On note D(x) et A(x) les ensembles respectifs de descendants
et d’ascendants du sommet x.
Définition 15 (racine) Un sommet x est racine d’un graphe G = (X, U ) ssi tous les
sommets du graphe (sauf éventuellement x) sont des descendants de x (il existe un chemin
de x vers tout autre sommet)
Remarque Γ+ (x) ⊆ D(x) et Γ− (x) ⊆ A(x).
La liste des descendants d’un sommet i0 dans un graphe G = (X, U ) peut être obtenue par
un parcours en largeur ou en profondeur d’abord.
Le parcours en largeur consiste à explorer les “frères”2 d’un nœud avant d’explorer ses fils.
Définition 16 (parcours en largeur d’abord (BFS))
Algorithme 1 : Parcours en largeur d’abord (BFS)
Données : G : un graphe connexe orienté. i0 : sommet de G à partir duquel on fait le parcours
Variables : La liste OUVERT : sommets en attente d’être traités
La liste FERMÉ : sommets déjà traités
i : sommet courant
OUVERT ← (i0 ); FERMÉ ← ()
tant que OUVERT n’est pas vide faire
soit i le premier élément d’OUVERT
si i n’est pas dans FERMÉ alors
mettre les successeurs de i qui ̸∈ FERMÉ en fin d’OUVERT (en mémorisant que i est
leur père et en supprimant les répétitions)
effectuer le traitement pour i
mettre i dans FERMÉ
supprimer i d’OUVERT

2
Donc ceux qui ont le même père.

18
Notons que, dans l’algo 1 pour le parcours BFS, la liste OUVERT est gérée comme une
file : on ajoute à la fin de la liste et on supprime au début de la liste.
Le parcours en profondeur consiste à explorer les fils d’un nœud avant d’explorer ses frères.
On selectionne donc le premier descendant puis on réitére le processus sur son premier
descendant . . . jusqu’à ce qu’il n’y ait plus de descendants ; à ce moment-là on considère
le deuxième descendant de l’avant-dernier sommet . . . .

Définition 17 (parcours en profondeur d’abord (DFS)) La liste des sommets obtenus


par un parcours en profondeur d’abord à partir d’un sommet i0 d’un graphe G = (X, U )
est obtenue par le même algorithme en remplaçant “fin” par “tête” (“mettre les successeurs
en tête d’OUVERT”).
On ajoute les informations3 date de pré-visite d(x) (ou début de traitement) et post-visite
f (x) (ou fin de traitement) à chaque sommet. d(x) est la date à laquelle on a découvert
x pour la première fois, f (x) est la date à laquelle on a fini d’explorer tous les descendants
de x (c’est-à-dire quand on le supprime d’OUVERT).

Notons que, dans l’algo pour le parcours DFS, la liste OUVERT est gérée comme une pile :
on ajoute et on supprime au début de la liste.
Notons aussi que la gestion des répétitions est un peu différente entre BFS et DFS :

• dans BFS, on ne rajoute pas dans OUVERT les successeurs qui y sont déjà ;

• dans DFS, on rajoute dans OUVERT les successeurs vérifiant la condition et s’ils y
étaient déjà, on supprime l’ancienne occurrence qui était dans OUVERT.

Exercice 9 Donnez les descendants du sommet b par un parcours en largeur d’abord/profondeur


d’abord pour le graphe suivant:

b d f
a h
c e g

IV Forte-Connexité, graphe réduit (concepts orientés)


Définition 18 (Composantes fortement connexes ou f-connexes) Soit G = (X, U )
un graphe orienté. La relation binaire Rf sur X est définie par:
3
Si le graphe est sans-circuit, le classement des sommets selon les dates de post-visite croissant donne
un tri topologique du graphe (en le dessinant linéairement dans cet ordre, alors tous les arcs sont orientés
de gauche à droite).

19
x = y ou
(
(x, y) ∈ Rf ⇔
il existe une chemin de x vers y et un chemin de y vers x
Rf est une relation d’équivalence (réflexive, symétrique et transitive).
Les classes d’équivalence X1 , . . . Xp (1 ≤ p ≤ |X|) de la relation de forte connexité sont les
composantes fortement connexes de G.

Un graphe est fortement connexe s’il n’a qu’une seule composante fortement connexe,
c’est-à-dire qu’il existe un chemin entre deux sommets distincts quelconques.

Exemple 6 Composantes f-connexes de l’exercice 8 : {a}, {b}, {c, d, e}, {f, h}, {g}.

Définition 19 (Graphe réduit) Soit G = (X, U ) un graphe orienté, le graphe réduit


GR = (XR , UR ) est défini par
• XR = {Xi , i = 1...p|Xi est une composante f-connexe de G} et

• UR = {(Xi , Xj )|Xi , Xj ∈ XR , Xi ̸= Xj et ∃x ∈ Xi , ∃y ∈ Xj , (x, y) ∈ U }

Propriété 2 ∀x ∈ X, la composante fortement-connexe x de x est telle que x = D(x) ∩


A(x).

Propriété 3 Soit G un graphe, l’algorithme de Kosaraju permet de calculer les composantes


fortement-connexes en seulement deux parcours en profondeur.
L’algorithme opère en deux étapes :
1. exécuter l’algorithme de parcours en profondeur des successeurs sur G (en recommençant
depuis un sommet non atteint tant qu’il en reste et en notant les dates post-fixes);

2. exécuter l’algorithme de parcours en profondeur des prédécesseurs sur G, en explorant


les sommets dans l’ordre décroissant des dates post-fixes données par le premier
parcours en profondeur.
Les graphes produits par le 2ème parcours sont les composantes f-connexes de G.
Démonstration : Si C et C ′ des composantes f-connexes distinctes et arc de C vers
C ′ alors fin de traitement de C > fin de traitement de C ′ (P1). Dans le deuxième parcours
en profondeur on commence par la composante f-connexe C dont la date de post-visite est
maximale. Donc, d’après P1, il ne peut pas y avoir d’arc entrant dans C depuis une autre
composante connexe, donc la recherche en profondeur sur les prédecesseurs ne donnera que
des sommets de C (et tous les sommets de C). Ensuite l’opération est réitérée sur une autre
composante C ′ dont fin de traitement maximale dans le graphe sans C (on ne considère plus
les sommets de C puisqu’ils ont des dates de fin de traitement ultérieures) donc les seuls
arcs entrants viennent d’une comp f-connexe déjà traitée ainsi le parcours en profondeur des
prédécesseurs ne donnera que les sommets de C ′ etc. C’est pour cela que chaque arborescence
du parcours en profondeur des prédécesseurs correspond à une et une seule comp.f-connexe
(cf. [5]). ⊔

Propriété 4 Un graphe réduit est sans-circuit.

20
Exercice 10 Calculez les composantes f-connexes du graphe de l’exemple 8 par l’algorithme
de Kosaraju puis donnez son graphe réduit.

Bilan :

• beaucoup de vocabulaire !-)

• 2 types de graphes (orienté ou pas)

• des notions communes aux deux types (sommet, dictionnaire,


graphe simple, graphe complet, degré, ordre d’un graphe, parcours,
connexité, coloration)

• des notions propres à chaque type (arc ou arête, chemin ou chaı̂ne,


circuit ou cycle, degré entrant/sortant, f-connexité)

• différentes catégories de sous-graphes

• premiers algos (BFS, DFS, Kosaraju)

21
Chapter 3

Les circuits, les cycles et les arbres

I Partition en niveaux des sommets d’un graphe sans


circuit
Comment déceler l’absence de circuit dans un graphe? Procédure de mise en niveau et
détection des circuits dans un graphe G = (X, U ):

Définition 1 (partition en niveaux)

a) On trace le dictionnaire sommets/prédécesseurs du graphe.

b) On cherche dans le dictionnaire les sommets sans prédécesseur (les sources). Les
sources constituent le niveau 0 (ou rang 0): soit N0 l’ensemble de ces sommets. On
passe ensuite au niveau k = 1.

c) Le niveau k, Nk , est l’ensemble des sommets sans prédécesseurs dans le sous-graphe


issu des sommets de X \ (N0 ∪ ... ∪ Nk−1 ) (c’est-à-dire sans les sommets des niveaux
inférieurs). On passe au niveau k + 1.

d) On arrête quand un niveau est vide.

Propriété 1 G peut être entièrement décomposé en niveau (partitionné) ⇔ G est sans


circuit.

Donc si en appliquant la définition 1 on s’arrête alors qu’il reste des sommets qui n’ont pas
encore été placés dans un niveau alors le graphe possède un circuit.

Exercice 11 Représentez le graphe suivant par niveaux.

22
a b c

g h

d e f

Définition 2 Un tri topologique d’un graphe orienté sans circuit G = (X, U ) est un
ordre1 linéaire2 des sommets de G tel que si G contient l’arc (u, v), u apparaı̂t avant v
dans la liste.
Remarque Un tri topologique se déduit facilement de la mise en niveaux.

a g d b e c f h

Notons qu’il peut exister plusieurs tris pour un même graphe. Par exemple ici on pourrait
mettre g avant a.
Propriété 2 Si G est sans circuit et si l’arc (x, y) ∈ U alors niv(x) < niv(y)
Démonstration : y étant de niveau niv(y) est un sommet sans prédécesseur
dans X \ (N0 ∪ N1 ∪ . . . ∪ Nniv(y)−1 ) donc x appartient à N0 ∪ N1 ∪ . . . ∪ Nniv(y)−1
donc est d’un niveau entre 0 et niv(y) − 1. ⊔

Propriété 3 Si G est sans circuit et si un sommet x est de rang r > 0 alors il admet au
moins un prédécesseur de rang r − 1.
Démonstration : Par définition si x est de rang r alors tous ses prédécesseurs
sont de rang ≤ r − 1. donc si x n’avait pas de prédécesseur de rang r − 1 alors,
par construction, il aurait obtenu un rang ≤ r − 1. ⊔

Propriété 4 Si G est sans circuit alors le rang d’un sommet est la longueur du plus long
chemin d’une source vers ce sommet.
Démonstration : Si x est de rang r d’après la propriété 2 il admet un
prédécesseur de rang r − 1 on peut ainsi construire un chemin d’un sommet de
rang 0 jusqu’à x, ce chemin possède r arcs. De plus, pour tout sommet y il ne
peut pas y avoir de prédécesseur de y du même rang (car d’après la propriété 2,
si y a un prédécesseur alors ce prédécesseur est de rang strictement inférieur).
Entre chaque niveau on ne peut donc pas construire de chemin plus long qu’un
arc. Il n’y a pas de prédécesseur des sommets du niveau 0 donc le plus long
chemin d’extrémité x contient r arcs. ⊔

1
Une relation d’ordre est une relation binaire réflexive, antisymétrique et transitive.
2
Donc sous la forme d’une liste

23
Notons qu’il peut exister plusieurs chemins menant à x (voir par exemple dans l’exercice 11
le cas du sommet h : il y a plusieurs chemins de longueur 5 qui mènent à h mais aussi des
chemins de longueur inférieure, 3).

II Arbre (notion non orientée)


Propriété 5 Pour tout graphe non orienté G d’ordre n avec m arêtes,
• G sans cycle ⇒ G a au plus de n-1 arêtes : m ≤ n − 1
• G connexe ⇒ G a au moins de n-1 arêtes : m ≥ n − 1
Démonstration : preuve basée sur le nombre cyclomatique= nombre de cycles
linéairement indépendants3 = m − n + p où p est le nombre de composantes
connexes, m le nombre d’arcs et n le nombre de sommets. ⊔

Définition 3 (Arbre) Un arbre est un graphe connexe et sans cycle.
Propriété 6 (Propriétés caractéristiques) Les propositions suivantes sont équivalentes
et caractérisent un arbre H :
1. H est connexe et sans cycle.
2. H est sans cycle et a (n-1) arêtes.
3. H est connexe et a (n-1) arêtes.
4. H est sans cycle et toute arête ajoutée crée un cycle.
5. H est connexe et toute arête supprimée le rend non connexe.
6. tout couple de sommet est relié par une chaı̂ne unique.

Remarque Le concept d’arbre est défini pour un graphe non orienté. Dans le cas orienté,
on considère le graphe associé à G en ne tenant pas compte de l’orientation des arcs.
Exercice 12 Transformer le graphe de l’exercice 11 en arbre.
3
Ce sont des cycles élémentaires tels que l’un n’est pas inclus dans l’autre. Par exemple dans le graphe
suivant, avec p = 1, m = 9, n = 7, il y a 3 cycles linéairement indépendants (A − B − D − C − A,
C − D − F − C et D − E − F − D) :

B E

A D G

C F

Notons qu’il existe bien-sûr d’autres cycles composés à partir de ces cycles indépendants. Par exemple,
A − B − D − F − C − A ou A − B − D − E − F − C − A.

24
III Arbre couvrant de poids minimum
Définition 4 (Arbre couvrant) Un arbre couvrant (ou arbre partiel) d’un graphe G
(orienté ou non) est un graphe partiel de G connexe et sans cycle.

Exemple 7
2
G = (X, V ) et H = (X, V′ ). H est bien un arbre connexe et
1 3
sans cycle (connexe et 4 arêtes).
5 4

Théorème 1 Un graphe admet un arbre couvrant si et seulement s’il est connexe.

Démonstration :

• Si G n’est pas connexe alors a fortiori aucun graphe partiel de G n’est


connexe.
• Réciproque : Soit G un graphe connexe. Si, quelle que soit l’arête qu’on
enlève, G n’est plus connexe alors G est un arbre (propriété 6 item 5)
sinon on peut supprimer au moins une arête sans que G ne perde sa
connexité. On enlève cette arête et l’on réitère le raisonnement, on arrive
nécessairement à un graphe partiel connexe tel que, quelle que soit l’arête
qu’on enlève, il ne l’est plus. Ce graphe partiel est donc un arbre.

Définition 5 (problème de l’arbre couvrant de poids minimum)


Soit G = (X, U ) un graphe connexe pondéré positivement par une fonction poids (ou coût)
p : U → R+ . Le problème de l’ arbre couvrant de poids minimum ou ACPM (ou juste
APM ) consiste à trouver un graphe partiel (X, U ′ ⊆ U ) de G qui soit connexe et de poids
P
u∈U ′ p(u) minimum parmi tous les graphes partiels de G.

Ce graphe partiel de poids minimum est bien un arbre car il est par définition connexe
et nécessairement sans cycle puisque sinon on pourrait diminuer son poids en supprimant
une arête du cycle sans perdre la connexité du graphe.
Il existe deux algorithmes classique pour la recherche de l’ACPM : celui de PRIM 1957 [16]
et celui de KRUSKAL 1956 [11] avec des complexités en o(n3 ) pour Prim et o(m2 ) pour
Kruskal.

Exemple 8

25
A 4 B
7 2 5

C 5 1 D
1 2 3

E 7 F

On ne tient pas compte de l’orientation des arcs.

Algorithme de PRIM [16] :

• soit G0 = (X0 , ∅) où on place dans X0 un seul sommet x0 quelconque de X.

• étape courante : à partir de Gk = (Xk , Vk ) sélectionner l’arête (x, y) de poids


minimum telle qu’une de ses extrémités
( ∈ Xk alors que l’autre ̸∈ Xk d’où Gk+1 =
x si x ̸∈ Xk
(Xk ∪ {xk }, Vk ∪ {(x, y)}) (avec xk = ).
y sinon

• fin de l’algorithme quand k = n − 1.

Algorithme de KRUSKAL croissant : On classe préalablement les arêtes dans l’ordre de


leurs poids croissants : p(u1 ) ≤ p(u2 ) ≤ . . . ≤ p(um )

• au départ G1 = (X, V1 ), V1 = {u1 } où u1 est l’arête de poids minimum dans G

• étape courante Gk+1 = (X, Vk+1 ) obtenu à partir de Gk en ajoutant la première arête
(dans l’ordre des poids) dont l’adjonction à Vk ne crée pas de cycle.

• fin de l’algorithme quand |Vk | = n − 1

Exercice 13 Appliquer Prim sur le graphe de l’exemple 8.

Exercice 14 Appliquer Kruskal sur le graphe de l’exemple 8.

Il existe aussi Kruskal décroissant (on classe les arêtes en poids décroissant et on les élimine
tant qu’on reste connexe).

26
Bilan :

• un graphe sans cicuit peut être mis en niveau


⇒ permet un tri topologique sur les sommets
⇒ outil pour des parcours de graphe plus efficaces

• un arbre est un graphe connexe sans cycle (l’orientation des arcs


n’a pas d’importance)

• un cas particulier d’arbre induit par un graphe pondéré sur les arcs :
les ACPM (arbres couvrant de poids minimum)

• deux algo permettant de calculer les ACPM (Kruskal et Prim)

27
Chapter 4

Algorithmes de plus court chemin

I Définitions
Rappel: Un sommet x est racine d’un graphe G, ssi pour tout sommet y ̸= x, il existe au
moins un chemin dans G allant de x à y.

Définition 1 (arborescence) Une arborescence est un arbre qui admet une racine.

Donc dans une arborescence, on prend en compte l’orientation des arcs.

Exemple 9 Le graphe suivant admet une arborescence de racine c (en rouge sur le schéma).
Ce n’est pas la seule (voir le cas de l’arborescence en bleu).

a b a b

c d c d

e f e f

Définition 2 (poids d’un chemin, chemin ij-minimal) Soit G = (X = J1, nK, U ) un


graphe orienté pondéré, c’est-à-dire que chaque arc (i, j) est affecté d’un poids pij , le poids
(ou “coût”) d’un chemin c dans G est égal à la somme du poids de ses arcs sera noté p(c)).
Un chemin ij-minimal est un chemin de i à j de poids minimum parmi tous les chemins
de i à j.

Par abus, on dira souvent “plus court chemin” et on parlera de “longueur” du chemin au
lieu de parler de chemin de poids minimum.
On suppose que x est racine de G, et on s’intéresse à déterminer pour tout sommet y ̸= x,
un plus court chemin de x à y, c’est-à-dire un chemin de poids minimum, ou encore chemin
xy-minimal.

28
Propriété 1 Si les pi,j sont positifs alors tout chemin ij-minimal est soit élémentaire (ne
passant pas deux fois par le même sommet), soit contient un circuit de poids nul.

II Graphe orienté pondéré positivement: algorithme


de Dijkstra
Les chemins mis en évidence par les algorithmes proposés ci-dessous sont élémentaires.
L’ algorithme de Dijkstra (1971) [7] (aussi appelé Moore-Dijkstra) permet d’obtenir une
arborescence partielle H = (X, V ) de G de racine i0 (c’est-à-dire que H est un graphe sans
cycle de racine i0 (et donc connexe) avec V ⊆ U ) dans laquelle, pour tout sommet i de
X \ {i0 }, l’unique chemin allant de i0 à i est un chemin i0 i-minimal de G.
Algorithme 2 : Moore-Dijkstra
Données : G : un graphe connexe orienté pondéré positivement
i0 : un sommet racine de G
Résultat : pour chaque sommet i ̸= i0 , λi distance du plus court chemin de i0 à i et vi arc
d’extrémité terminale i sur ce plus court chemin
Variables : S : sommets explorés, i : sommet courant, j : successeur de i non encore exploré
λi0 ← 0
pour i = 1 à n, i ̸= i0 faire λi ← ∞
S←∅
tant que S ̸= X faire
sélectionner i dans X \ S tel que λi = minj∈X\S λj
S ← S ∪ {i}
pour tout j de Γ+ (i) ∩ (X \ S) faire
si λi + pij < λj alors
/* ajustement de j à partir de i et m.à.j. de l’arc d’extrémité j */
λj ← λi + pij
vj ← (i, j)

Exemple 10 Soit G = (X = J1, 6K, U ) le graphe orienté suivant de racine c.

Sommets Sommets
a 4 b sélectionnés a b c d e f
Initialisation ∞ ∞ 0 ∞ ∞
⃝ ∞
7 2 5
c 7 ∞ / ∞ ⃝ 1 ∞
c 5 1 d e 6 ∞ / ⃝3 / 8
d 5
⃝ 8
⃝ / / / 8
1 2 3
a / 8 / / / 6

e 7 f f / 8 / / / /
b / / / / / /

Normalement, on doit noter les arcs vj à chaque fois que l’on change le λj mais avec une
représentation sur un tableau on peut s’en passer : les nombres entourés dans la colonne
d’un sommet j correspondent à la valeur définitive λj (distance du chemin minimal depuis

29
i0 , ici c, à j). On a entouré ce nombre sur la ligne où cette valeur apparaı̂t pour la première
fois pour ce sommet. Ainsi ce nombre se trouve sur la ligne du sommet i à partir duquel
la marque λj a été ajustée à cette valeur. Cette convention permet de connaı̂tre l’arc dont
l’extrémité terminale est j dans l’arborescence de chemin i0 j-minimaux.
Ainsi le sommet a a obtenu sa valeur définitive à partir du sommet d, ce qui signifie que
l’arc (d, a) appartient à l’arborescence. On obtient finalement l’arborescence suivante:

a b
2 5

c 1 d
1 2

e f

Complexité de l’algorithme O(n2 ). Chaque étape de l’algorithme de Dijkstra nous fournit


la valeur définitive d’un sommet, et on le sait. Si on s’intéresse aux chemins de valeur
minimale entre le sommet de départ A et un sommet particulier B, on peut arrêter le
calcul dès que B est calculé, même si tous les sommets ne sont pas calculés. La stratégie
est donc gloutonne.

Justification de la validité de l’algorithme de Dijkstra


Montrons que l’arborescence H donnée par l’algorithme est telle que pour tout sommet j,
l’unique chemin dans H de i0 à j est un chemin i0 j-minimal de G.

1. Montrons que les sommets sont sélectionnés dans l’ordre des λ croissant. Au moment
où le sommet i est sélectionné, d’après le critère de sélection, λi est plus petit que
tous les lambda des sommets restants. Soit j le sommet qui sera selectionné juste
après i. Avant l’ajustement on a λi ≤ λj , après la phase d’ajustement à partir de
i, soit λj reste inchangée si j n’est pas un successeur de i, soit λj prend la valeur
λi + pij , compte tenu de la positivité des poids, cette valeur reste supérieure à λi . Ce
raisonnement est vrai à chaque étape.

2. Montrons que le graphe H = (X, V = ∪j∈X\{i0 } vj ) donnée par l’algorithme est une
arborescence de racine i0 telle que pour tout sommet j, il existe un unique chemin
dans H de i0 à j de poids λj .
Démonstration par récurrence en montrant qu’à toute étape, le graphe HS = (S, VS =
∪j∈X\{i0 } vj ) est une arborescence de racine i0 dans laquelle pour tout sommet j de
S \ {i0 } il existe un unique chemin de i0 à j de poids λj .

• Au départ, considérons H0 = ({i0 }, V = ∅) la propriété est vraie car il n’y a


pas de sommet dans S \ {i0 }.

30
• Supposons que cette propriété soit vraie après avoir sélectionné p sommets dans
Sp . Montrons qu’elle est vraie après avoir sélectionné le sommet suivant. Soit
Hp = (Sp , Vp ) le graphe contenant les arcs entrants donnés par l’algorithme
après avoir sélectionné p sommets. Soit i le sommet non encore sélectionné de
λi minimal, Hp+1 = (Sp ∪ {i}, Vp ∪ {vi }), l’arc vi par construction est égal à (k, i)
tel que k est un sommet déjà exploré donc de Sp à i et λi = λk + pki . Puisque
k appartient à Hp , il existe un chemin de io à k de longueur λk (par hypothèse
de récurrence). Donc il existe un chemin de i0 à i de longueur λk + pki = λi .
Hp était une arborescence de racine i0 à laquelle on a ajouté un sommet et un
arc vers ce sommet, on n’a donc pas créé de cycle (puisque ce sommet n’existait
pas dans Hp , il n’y avait donc pas de chemin partant de lui), Hp+1 est donc sans
cycle et de racine i0 (puisqu’il existe un chemin de i0 au nouveau sommet).
A chaque étape la propriété est vérifiée, elle l’est à la première étape donc elle l’est
à la fin de l’algorithme.
3. Montrons que pour tout arc (i, j) de G, λi et λj donnés par l’algorithme de Dijkstra
vérifient λj − λi ≤ pij .
• Si j est entré dans S après i alors après la phase d’ajustement à partir de i, soit
λj = λi + pij soit λj ≤ λi + pij . Ensuite λj n’a pu que diminuer. Donc à la fin
de l’algorithme, λj ≤ λi + pij .
• Si i est entré dans S après j alors λj ≤ λi (puisque les sommets sont examinés
dans l’ordre croissant des λ). Donc a fortiori λj ≤ λi + pij .
4. Montrons que pour tout sommet j ̸= i0 , et tout chemin non vide µ = [x1 , . . . xp ] de G
tel que x1 = i0 et xp = j, λj ≤ l(µ), avec l(µ) la somme des poids des arcs composant
le chemin µ.
Calculons l(µ) = p−1 k=1 pxk xk+1 .
P

D’après l’item précédent, l(µ) ≥ p−1


k=1 λxk+1 − λxk = λj − λ0 = λj .
P

Remarque Dans le cas où i0 n’est pas racine de G l’algorithme se termine avec des
sommets dont la marque reste infinie, ces sommets ne sont pas des descendants de i0 .
Dans le cas d’un graphe non orienté, l’algorithme fonctionne en considérant qu’une arête
équivaut à avoir un arc dans chaque sens. On obtient donc des chaı̂nes i0 j-minimales.

III Matrice de routage


Définition 3 (matrice des poids des chemins ij-minimaux)
La matrice des poids des chemins ij-minimaux ( matrice des longueurs ) associée à un
graphe orienté valué d’ordre n est une matrice de dimension n × n telle que chaque case
en ligne i et colonne j soit définie par
λij = longueur du chemin ij-minimal

31
Dans le cas non-orienté on considère les chaı̂nes ij-minimales.
Définition 4 (matrice de routage) La matrice de routage associée à un graphe orienté
valué d’ordre n est une matrice de dimension n×n telle que chaque case en ligne i et colonne
j soit définie par
mij = sommet adjacent à i sur le chemin ij-minimal
Dans le cas non-orienté on considère les chaı̂nes ij-minimales.
Exemple 11 Soit le graphe suivant avec l’arborescence des chemins cj-minimaux en rouge :

a 4 b
7 2 5
c 5 1 d
1 2 3
e 7 f

Cette arborescence permet de pré-remplir les matrices des longueurs et de routage de la


façon suivante :

longueurs cas orienté routage cas orienté


× ? ? ? ? 1 × ? ? ? ? f
   

 ? × ? ? ? ? 


 ? × ? ? ? ? 

5 8 × 3 1 6 e e × e e e
   
   
2 5 ? ? 3 a b ? × ? a
   

 × 





4 7 ? 2 × 5 d d ? d × d
   
   
? ? ? ? ? × ? ? ? ? ? ×
Pour traiter le cas “non-orienté”, et seulement si l’arborescence des chaı̂nes ij-minimales
est identique à celle des chemins ij-minimaux, on peut partir du cas “orienté” et compléter
certains des “?” pour traiter les chemins inverses (ceux en remontant les flèches1 ). On
obtient alors le pré-remplissage suivant :
longueurs cas non-orienté routage cas non-orienté
× ? 5 2 4 1 × ?
   
d d d f
 ? × 8 5 7 ?   ? × d d d ? 
  

 5 8 × 3 1 6   e e × e e e 
   
 2 5 3 × 2 3 
   
 
 a b
 e × e a  
 4 7 1 2 × 5   d d c d × d 
   

1 ? 6 3 5 × a ? a a a ×
1
Attention, il faut suivre les chemins de l’arborescence de la source vers le sommet ou l’inverse. On ne
peut pas emprunter un chemin dans un sens puis repartir dans un autre sens dans un autre chemin. Voir
l’exercice 15.

32
Dans le cas non-orienté, la matrice des longueurs est symétrique mais pas la matrice de
routage.

Dans les deux cas, il reste à finaliser en mettant à jour si possible les “?” restants. Par
exemple il existe un chemin ab-minimal qui n’est pas dans l’aborescence. On pourra donc
mettre à jour la case ab pour la matrice des longueurs avec 4 et pour la matrice de routage
avec b.

Si l’arborescence des chaı̂nes ij-minimales n’est pas identique à celle des chemins ij-
minimaux, il faut alors calculer l’arborescence des chaı̂nes ij-minimales puis calculer directement
les matrices dans le cas non-orienté sans passer par les versions pour le cas orienté.

Exercice 15 Soit le graphe suivant avec l’arborescence des chemins cj-minimaux en rouge :

a 4 b
7 2 5
c 1 1 d
1 2 3
e 7 f

Calculer l’arborescence des chaı̂nes ij-minimales et celle des chemins ij-minimaux en


partant de c. En déduire le pré-remplissage des matrices des longueurs et de routage pour
chaque cas (orienté et pas orienté).
Attention, le graphe de cet exemple est très similaire mais différent de celui de l’exemple 11.

IV L’algorithme de Bellman
Théorème 2 (Principe d’optimalité de Bellman) Si le chemin minimum de A à B
passe par le sommet C alors la portion de A à C est elle-même minimale.

L’ algorithme de Bellman-Kalaba 1958 calcule la longueur d’un plus court chemin à partir
d’un sommet i0 d’un graphe valué quelconque.
Le principe de l’algorithme est de considérer d’abord les chemins de 1 arc (longueur λ1 )
entre i0 et tous les autres sommets puis 2 arcs (longueur λ2 ) et ainsi de suite.
Pour ce faire,

• il se base sur le principe d’optimalité (donc pour trouver un plus court chemin de k
arcs, de i0 vers i on compare tous les chemins de k − 1 arcs de i0 vers un prédécesseur
de i + longueur de l’arc (prédé,i) et on prend le meilleur.

33
• il utilise aussi l’astuce d’ajouter un arc fictif (i0 , i0 ) de longueur 0 afin que l’ensemble
des chemins de i0 vers i ayant k −1 arcs dans le graphe avec l’arc fictif, correspondent
dans le vrai graphe à tous les chemins de i0 vers i possédant entre 0 et k-1 arcs. (Ce qui
permet à l’item précédent d’être sûr d’avoir pu comparer tous les meilleurs chemins
possédant entre 0 et k − 1 arcs (donc choisir le meilleur parmi (les chemins entre i0
et i qui passe par un autre sommet et le chemin direct (arc) entre i0 et i)).

Si le graphe ne contient pas de circuit de longueur négative il existe un plus court chemin
qui est élémentaire qui a donc au plus n − 1 arcs. Si G n’a pas de circuit de longueur
négative λn−1 (j) est la longueur du plus court chemin de i0 à j.
Ce principe de l’algorithme de Bellman est à l’origine de la programmation dynamique (le
fait de ne pas faire de calculs inutiles donc de stocker les calculs pour l’étape i afin de s’en
resservir pour l’étape i + 1.)
Algorithme 3 : Bellman-Kalaba
Données : G : un graphe connexe orienté pondéré par l (pij : poids de l’arc (i, j))
i0 : sommet de G, on ajoute un arc fictif (i0 , i0 ) de poids 0.
Résultat : Si G a un circuit de longueur négative pas de solution sinon pour chaque sommet
i ̸= i0 , distance du plus court[long] chemin de i0 à i ou ∞
Variables : j : sommet courant, k : étape courante
λ0 (i0 ) ← 0
pour tout sommet i ̸= i0 faire λ0 (i) = ∞ [−∞]

k←1
tant que k ≤ n faire
pour tout sommet j faire λk (j) = min[max]i∈Γ− (j) (λk−1 (i) + pij )

si λk = λk−1 alors STOP


sinon k ← k + 1

fin
si k = n + 1 alors G admet un circuit < 0 [> 0]
sinon ∀j ∈ X \ {i0 }, λk (j) est la longueur d’un chemin i0 j-minimal [maximal]

Exemple 12 Soit G = (X = J1, 7K, U ) le graphe orienté suivant, on désire connaı̂tre les
1 :
plus courts chemins d’origine ⃝

Sommets
k λk 1 2 3 4 5 6 7
2 1 3 2 4 0 λ0 0 ∞ ∞ ∞ ∞ ∞ ∞
2 1 λ1 0 2 ∞ ∞ ∞ ∞ 4
1 1 2 -2 1 -2 2 λ2 0 2 3 ∞ ∞ 4 4
4 3 λ3 0 2 3 5 4 1 4
7 1 6 5 5 4 λ4 0 2 3 5 3 1 2
5 λ5 0 2 3 5 3 1 2
STOP

34
Le principe de lecture du tableau est similaire à celui utilisé pour Dijkstra mais plus
compliqué à mettre en œuvre. Par ex, considérons le sommet 5. La valeur du plus court
chemin depuis 1 est 3 ; cette valeur 3 a été obtenue par l’utilisation de λ3 , donc lorsque
les sommets 4, 5 et 6 ont changé de valeur. Le sommet 5 n’est pas incident à lui-même
donc le chgt de valeur ne vient pas de lui. Les sommets 4 et 6 sont tous les deux des
prédécesseurs de 5, le chgt vient donc de l’un d’entre eux. Il faut retrouver celui qui a
produit la valeur 3 pour 5. Dans notre cas, il s’agit de 4 et donc c’est l’arc (4,5) qui
est dans l’arborescence des plus courts chemins. Une amélioration possible de l’algorithme
serait donc de mémoriser aussi le sommet i ayant produit le min. Cela donnerait alors le
tableau suivant (pour le sommet 1, on utilise l’existence de l’arc fictif (1,1) et dans chaque
case on met : λk (i)/pere(i)) :
Sommets
k λk 1 2 3 4 5 6 7
0 λ0 0/1 ∞ ∞ ∞ ∞ ∞ ∞
1 λ1 0/1 2/1 ∞ ∞ ∞ ∞ 4/1
2 λ2 0/1 2/1 3/2 ∞ ∞ 4/2 4/1
3 λ3 0/1 2/1 3/2 5/3 4/3 1/3 4/1
4 λ4 0/1 2/1 3/2 5/3 3/4 1/3 2/6
5 λ5 0/1 2/1 3/2 5/3 3/4 1/3 2/6
STOP

Ce qui permet ensuite d’obtenir plus facilement l’arborescence des chemins minimaux :

2 1 3 2 4
2
1 1 2 -2 1 -2
4
7 1 6 5 5

La complexité de l’algorithme de Bellman-Kalaba est de l’ordre de n3 puisqu’elle est en


O(nm): au pire, on regarde tous les prédecesseurs de tous les sommets (m arcs), et ceci
n fois. Lorsque le graphe est sans circuit, on peut diminuer grandement sa complexité.
L’ algorithme de Bellman pour les graphes sans circuit se sert des niveaux pour calculer
les plus courts chemins en une seule passe sa complexité est en O(m).
Algorithme 4 : Bellman pour les graphes sans circuits
Données : G graphe orienté pondéré sans circuit (poids de signe quelconque),
les sommets étant numérotés de 1 à n en accord avec les niveaux de G (donc
en utilisant le tri topologique décrit au chapitre 3)
Résultat : pour chaque sommet i ̸= 1, λ(i) distance du plus court[long] chemin du sommet 1
aux autres sommets.
λ(1) ← 0
pour tout sommet j ∈ J2, nK faire λ(j) = min[max]i∈Γ− (j) (λ(i) + pij )

Exercice 16 Soit G = (X = J1, 7K, U ) le graphe orienté sans circuit suivant, on désire
1
connaı̂tre les plus courts chemins d’origine ⃝

35
2 1 3 2 4
2
1 2 -2 1 -2
4
7 1 6 5 5

Ici, grace à la mise à niveau, et comme pour l’algorithme de Dijkstra, chaque étape nous
fournit la valeur définitive d’un sommet, et on le sait. Si on s’intéresse aux chemins de
valeur minimale entre le sommet de départ A et un sommet particulier B, on peut arrêter
le calcul dès que B est calculé, même si tous les sommets ne sont pas calculés. On dit que
la stratégie est gloutonne, ce qui signifie que certains résultats ne seront plus remis en
question (un glouton est quelqu’un qui avale et ne peut pas revenir en arrière, c’est-à-dire
ne peut pas remettre en cause ce qu’il vient de faire).

Remarque L’algorithme de Bellman-Kalaba permet aussi de calculer les plus longs chemins,
il admet les valuations négatives et les circuits.

Il en existe une variante un peu plus efficace appelée Bellman-Ford ou Bellman ou Ford
(cf. feuille d’algo).

Petit focus sur les problèmes de recherche de plus court chemin Ce type de
problèmes apparaı̂t beaucoup quand on cherche à exploiter des graphes pour trouver une
meilleure solution à un jeu donné. Par contre, on se heurte très vite au fait que ces graphes
sont énormes puisque, en général, les sommets sont les différents états du jeu et les arcs
donnent les passage possibles entre deux états en jouant un coup. La recherche de plus
courts chemins d’un sommet donné vers un sommet intéressant (représentant une solution)
revient à rechercher une stratégie gagnante. Vu l’énormité des graphes, on ne génère pas
forcément tout le graphe. C’est pourquoi on utilise plutot des algorithmes de type A∗ [10]
qui est une variante de Dijkstra utilisant une fonction appelée heuristique qui estime la
valeur d’un plus court chemin d’un sommet donné à la solution et une fonction qui donne
les successeurs d’un sommet.

En résumé les principaux algorithmes de recherche de plus court chemin sont

• Bellman-Kalaba pour les graphes pondérés de poids quelconque (cet algorithme est
aussi utilisable pour trouver les chemins maximaux contrairement à Dijkstra).

• et Bellman pour les graphes sans-circuit.

• Dijkstra qui est plus efficace que Bellman-Kalaba mais ne s’applique qu’à des graphes
pondérés positivement,

• l’algorithme de Moore est une variante non-gloutonne de Dijkstra permettant de


traiter des graphes pondérés quelconques.

36
• Si l’on désire connaı̂tre tous les plus courts chemins possibles à partir de tous les
sommets du graphe vers tous les autres sommets, il existe l’algorithme de Roy-Floyd-
Warshall (1959) qui travaille sur une matrice d’adjacence. Sa complexité étant en
O(n3 ), il est en général moins couteux en mémoire d’utiliser Dijkstra (ou ses variantes
utilisant une structure spéciale pour stocker les sommets non-encore explorés en O(n×
log(n))) en considérant chaque sommet successivement comme source du graphe.

• Si la pondération des arcs est uniforme (tous les arcs ont le même poids) alors le plus
court chemin est le plus court en nombre d’arcs et un algorithme d’exploration en
largeur d’abord est le plus efficace O(m).

Remarque Les algorithmes de plus courts/longs chemins peuvent s’utiliser sur des graphes
non-orientés en considérant qu’une arête représente deux arcs de sens opposés avec le même
coût sur les deux arcs que sur l’arête.

V Problèmes d’ordonnancement
Résoudre un problème d’ordonnancement consiste à déterminer un calendrier d’exécution
des différentes tâches d’un projet (ou ordonnancement) qui minimise la durée de ce projet.

Exemple 13 La réalisation d’un projet nécessite l’exécution de huit tâches A, B, C, D,


E, F , G, H. Les durées de ces tâches et les contraintes de postériorité auxquelles elles
sont soumises sont données dans le tableau suivant :

Tâches A B C D E F G H
Durées 30 5 12 17 4 3 14 8
Tâches pré-requises A A A B,C C E,F D

Définition 5 (début au plus tôt, au plus tard, tâche critique, marge totale)
La date de début au plus tôt d’une tâche , c’est la date minimum à laquelle peut commencer
une tâche.
La date de début au plus tard est la date maximale à laquelle la tâche peut commencer si
l’on veut que la durée minimale du projet ne soit pas modifiée.
Une tâche est critique ssi tout retard dans l’exécution de cette tâche allonge d’autant la
durée minimale du projet.
La marge totale (MT) est le temps maximal dont cette tache peut être différée ou allongée
sans retarder la fin des travaux.
On appelle marge libre (ml) d’une tâche le délai pouvant être accordé au commencement
d’une tâche sans modifier les marges totales des tâches suivantes.

Il existe deux méthodes de modélisation de ce problème :

• la méthode potentiels-tâches et

37
• la méthode potentiels-étapes (PERT2 ).

La modélisation par un graphe potentiels-tâches (tâches = sommets) est assez intuitive et


n’admet qu’un seul graphe pour modéliser un problème donné. Toutefois elle était moins
utilisée que la modélisation PERT. En effet, la modélisation PERT (tâches = arcs) était
préférée par les praticiens car elle utilise des graphes comportant moins d’arcs. Cependant
la modélisation PERT ne donne pas nécessairement un graphe unique.
Les deux modélisations permettent de faire le calcul de diverses métriques :

• Le calcul des débuts au plus tôt tv d’une tâche v revient à appliquer Bellman sans-
circuit pour calculer les plus longs chemins : tv = maxx∈Γ− (v) (tx + durée(x)) .

• Le calcul des débuts au plus tard t∗v se ramène aussi à un Bellman sans-circuit sur le
graphe transposé (en partant de la fin du projet) : t∗v = minx∈Γ+ (v) (t∗x − durée(v)) .

• La marge totale MT se calcule en faisant M Tv = t∗v − tv .

• La marge libre mlv = minx∈Γ+ (v) tx − fv où fv est la fin au plus tôt de v c’est-à-dire
fv = tv + durée(v).

Exemple 14 Représentation du problème d’ordonnancement de l’exemple 13 en utilisant


la modélisation par potentiel-tâches :

B
30 5
α 0 A 30 C 12 E 4 G 14 ω
12 3
30 F 8

D 17 H

Résultats numériques :

Tâches v α A B C D E F G H ω
début au plus tôt tv 0 0 30 30 30 42 42 46 47 60
début au plus tard t∗v 0 0 37 30 35 42 43 46 52 60
fin au plus tot fv 0 30 35 42 47 46 45 60 55 60
marges totales M Tv 0 0 7 0 5 0 1 0 5 0
marges libres mlv 0 0 7 0 0 0 1 0 5 0
2
1956. Program evaluation and review technik (technique d’évaluation et de remise à jour de
programmes/projets)

38
Les tâches critiques A, C, E, G sont caractérisées par l’égalité entre leur date de début au
plus tôt et leur date de début au plus tard ( t∗v − tv = 0).
D a une marge libre de 0 alors qu’il a une marge total de 5, car un retard dans l’exécution
de D entraı̂nerait une diminution dans la marge de H.

Bilan :

• Un problème classique : chercher des plus courts chemins dans des


graphes pondérés (poids sur les arcs).

– Les chemins les plus courts en venant d’un sommet donné


forment une arborescence (arbre admettant une racine).
– Quand les pondérations sont positives, on peut utiliser l’algo
de Dijkstra pour trouver cette arborescence.
– D’autres algos existent qui n’imposent pas de contrainte sur
les pondérations (positives ou négatives) : Bellman-Kalaba,
Bellman pour les graphes sans circuit, . . .
– Certains algos permettent aussi de trouver les plus longs
chemins (Bellman-Kalaba).
– Cette arborescence permet un pré-remplissage de matrices
spécifiques (longueurs et routage).

• Un autre problème classique utilisant aussi des poids mais avec des
contraintes de précédence en plus : ordonnancement de tâches dans
un projet

– deux méthodes principales (potentiel-tâches ou PERT)


– ds les 2 cas, calcul de diverses métriques (durée minimale du
projet, date de début au plus tôt/tard de chaque tâche, tâches
critiques, marges totales/libres des tâches)

39
Chapter 5

Flots et réseaux de transport

Les problèmes que l’on va aborder dans ce chapitre consistent à organiser de façon optimale
sous diverses contraintes, les mouvements de certaines quantités d’un bien dans un réseau.
Étant donné un réseau aux arcs valués par des capacités, le problème du flot maximal
consiste à faire circuler la plus grande quantité possible entre deux points du réseau sans
excéder les capacités des arcs.
(La théorie à l’origine était développée pour gérer la circulation du courant dans des circuits
électriques1 .) Beaucoup d’applications : quelques exemples

• création d’itinéraires de délestage. Connaissant les capacités des tronçons routiers


en véhicules par heure, l’organisation d’itinéraires de délestage entre deux villes
permettant de supporter le plus grand nombre de véhicules par heure est un problème
de flot maximal. Ce problème est similaire à celui des taxis de la Marne: faire arriver
le plus de véhicules à un endroit donné en une période de temps donnée, étant donné
les stocks de taxis en différentes villes, les capacités des routes, les capacités de
stationnement en chaque ville, le réseau routier, la vitesse possible. Ce problème fait
intervenir en plus la configuration du réseau routier et le temps de parcours entre
chaque ville.

• organisation du traffic maritime : étant donné des ports de départ ayant chacun des
stocks d’une marchandise donnée et des ports d’arrivés ayant chacun des demandes
1

• Euler 1736 : pb des ponts de Konigsberg


• Kirchhof 1835 : lois des circuits electriques, tension, courant,
• Koenig 1914 : graphe biparti et couplage parfait
• Ford-Fulkerson 1956 : Théorème du flot-max/coupe min ⇒ prog linéaire algo simplexe
• Edmonds 1965 : naissance de la théorie de la complexité, Edmonds, en recherchant l’efficacité
d’un algo de recherche de couplage maximum par chaı̂ne augmentante, a défini le concept d’algo
polynomial ⇒ Cook 1971 : exhibe le premer problème NP-complet (SAT)

40
pour cette marchandise, trouver un déplacement de ces marchandises permettant de
faire arriver le maximum de marchandises.

• structuration et dimensionnement optimal d’un réseau de communication : permettre


un flot maximum de données pour un coût minimum de réalisation des jonctions entre
les différents points du réseau (le coût étant fonction des capacités de ces jonctions).

I Flux et flots
Soit G = ({x1 , . . . xn }, {u1 , . . . um }) un graphe orienté.

Définition 1 (Flot) Un flot sur un graphe est un vecteur φ = (φ1 , . . . , φm ) de Rm qui


vérifie en chaque sommet du graphe la loi de Kirchhoff définie par :
φ(u) =
X X
∀x ∈ X, φ(u) (loi de Kirchhoff)
u∈ω − ({x}) u∈ω + ({x})
où pour tout A ⊆ X, ω (A) est l’ensemble des arcs sortants de A ω + (A) = {(x, y) ∈ U |
+

x ∈ A et y ̸∈ A}, et ω − (A) l’ensemble des arcs entrants en A: ω − (A) = {(x, y) ∈ U | x ̸∈ A


et y ∈ A}.
Le nombre φi = φ(ui ) est appelé flux dans l’arc ui . Et du coup, la loi de Kirchhoff est
aussi appelée loi de conservation du flux .

Le flux φi dans l’arc ui peut être assimilé à la quantité de données (véhicules, liquide,
information, . . . ) parcourant l’arc ui dans le sens de son orientation si φi > 0 ou dans le
sens inverse si φi < 0. La loi de Kirchhoff impose qu’en tout sommet le flux entrant
soit égal au flux sortant.

Exemple 15 Donnez des exemples de flots sur le graphe suivant

b
u1 u4 u1 u2 u3 u4 u5 u6
φ1 = ( 3 , 0 , 3 , 2 , −2 , 1 )
a u6 d φ0 = ( 0 , 0 , 0 , 0 , 0 , 0 )
u2
φ2 = ( 1 , 0 , 1 , 0 , 0 , 0 )
u3 u5 φ3 = ( 3 , 1 , 4 , 1 , −1 , 2 )
c

Exercice 17 En considérant que φ2 et φ3 sont des flots, prouvez que φ = −φ2 + 5φ3 est
aussi un flot.

Propriété 1

• Toute combinaison linéaire de flot sur G définit un flot sur G

41
• Le vecteur nul de Rm est un flot sur tout graphe G (dit “flot nul”)

• Tout vecteur cycle de G est un flot sur G

Démonstration : Les 2 premières propriétés sont évidentes. Montrons la


troisième en donnant d’abord la définition du vecteur cycle :

Soit C un sous-ensemble d’arcs de G représentant un cycle dans G.


On note C + (resp. C − ) le sous-ensemble de C correspondant aux arcs
orientés dans le sens (resp. sens inverse) du parcours2 . Le vecteur-

cycle correspondant à C est alors défini par C = (c1 , . . . , cm ), m étant
le nb d’arcs dans G avec :
1 si ui ∈ C +



ci = −1 si ui ∈ C −
0 si ui ̸∈ C

Soit µ de Rm un vecteur cycle quelconque sur G montrons que c’est un flot. Si


le cycle µ est élémentaire alors soit x un sommet quelconque,

• soit le cycle ne passe par x alors tous les arcs incidents à x ont un flux nul
donc la conservation du flux est vérifiée en x
• soit il existe deux arcs incidents à x appartenant au cycle µ, il y a alors
quatre cas possibles et dans tous les cas le flux entrant en x est égal au
flux sortant
2 arcs sortants 2 arcs entrants un arc entrant un arc entrant
et un sortant et un sortant
(sens parcours) (sens inverse)
1

1
-1

-1
+

x x x x
+

+
-1

-1
1

flux entrant = 0 flux entrant=1-1 flux entrant=+1 flux entrant=-1


flux sortant = 1-1 flux sortant=0 flux sortant=+1 flux sortant=-1

Si le cycle n’est pas élémentaire alors on considère chacun des cycles élémentaires
qui le constituent ; comme on vient de le voir, chacun d’eux est un flot et leur
somme est encore un flot. La propriété est donc vérifiée pour n’importe quel
cycle. ⊔

2
Ce sens est choisi de manière arbitraire.

42
II Réseau de transport, Flot compatible, Problème
du flot maximum dans un réseau
Définition 2 (réseau de transport) Un réseau de transport est un graphe orienté con-
nexe R = (X, U = {u1 , . . . um }) avec

• un sommet sans prédecesseur appelé entrée du réseau (ou source) noté s (Γ− (s) =
∅)

• et un sommet sans suivant appelé sortie du réseau (ou puits) noté t (Γ+ (t) = ∅)

• et une application c : U → R+ ∪{∞} qui à chaque arc u associe sa capacité c(u) ≥ 0.

On y adjoint un arc u0 (fictif) u0 = (t, s) de capacité infinie qui sera appelé arc de retour .

Exemple 16 Le réseau suivant avec les capacités indiquées entre parenthèses, muni de
l’arc de retour (t,s) de capacité infinie est un réseau de transport.

1 (4) 3
(5) (7)

s (3) (2) (5) t


(8) (9)

2 (6) 4

Définition 3 (flot compatible) Un flot compatible ou encore réalisable est un vecteur


φ de Rm+1 (en comptant l’arc de retour) tel que:

• φ est un flot sur (X, U ∪ {u0 }) : ∀x ∈ X, φ(u) =


P P
u∈ω + ({x}) u∈ω − ({x}) φ(u)

• φ est compatible avec les capacités : ∀u ∈ U ∪ {u0 }, 0 ≤ φ(u) ≤ c(u)

La valeur du flot , notée v(φ), est le flux qui traverse l’arc de retour ou encore le flux
sortant de la source ou encore le flux arrivant à la sortie :

v(φ) = φ(u0 ) = φ(u) =


X X
φ(u)
u∈ω + (s) u∈ω − (t)

Si φ(u) = c(u) on dit que l’arc u est saturé . Un flot est dit de valeur maximale s’il
maximise cette valeur v(φ) dans l’ensemble de tous les flots réalisables (un tel flot n’est
pas nécessairement unique).

Remarque Un tel flot existe toujours, un algorithme permettant d’obtenir un tel flot
lorsque les capacités sont des rationnels est décrit ci-après.

43
II.1 Théorème du flot maximum et de la coupe minimum
Définition 4 (coupe) Une coupe séparant s et t notée (A, B) est une partition de l’ensemble
des sommets en deux sous-ensembles A et B = X \ A telle que s ∈ A, t ̸∈ A.
L’ensemble des arcs d’une coupe (A, B) est l’ensemble ω + (A) (arcs sortant de A). Par
définition, ω + (A) = {(i, j) ∈ U | i ∈ A, j ̸∈ A}).
La capacité de la coupe , notée C, est la somme des capacités des arcs de la coupe :
C(ω + (A)) = u∈ω+ (A) c(u).
P

Remarque Une coupe (A, B) est aussi dénotée par son ensemble d’arcs, donc ω + (A).

Exercice 18 Soit le réseau suivant avec les capacités indiquées entre parenthèses, donnez
des exemples de coupe avec leur capacité.

1 (4) 3
(5) (7)

s (3) (2) (5) t


(8) (9)

2 (6) 4

Remarque Le retrait dans un réseau R de tous les arcs d’une coupe supprime tous les
chemins de s à t.

Propriété 2 (Théorème de la coupe) Pour tout flot φ compatible sur un réseau R et


pour toute coupe ω + (A) séparant s et t, la valeur du flot est inférieure à la capacité de
cette coupe :
φ(u0 ) ≤ C(ω + (A)) =
X
c(u)
u∈ω + (A)

Démonstration : Soit φ un flot compatible sur R et soit ω + (A) une coupe.


D’après la loi de conservation du flux généralisée, on a

φ(u) =
X X
φ(u)
u∈ω + (A) u∈ω − (A)

Or u0 est un arc entrant dans A, donc:

φ(u) = φ(u) + φ(u0 )


X X

u∈ω + (A) u∈ω − (A),u̸=u0

φ étant un flot compatible, ∀u ∈ U , 0 ≤ φ(u) ≤ c(u). Donc, en particulier,


φ(u) ≥ 0 et u∈ω+ (A) φ(u) ≤ u∈ω+ (A) c(u). D’où, φ(u0 ) ≤
P P P

Pu∈ω (A),u̸=u0
u∈ω + (A) c(u) = C(ω (A)).
+

44
Ceci est vrai pour toute coupe donc même quand on considère une coupe de capacité
minimale. Puisque c’est vrai aussi pour tout flot compatible, c’est vrai pour un flot
de valeur maximum. Ce résultat fournit donc une borne max pour la valeur du flot
maximal. Mais il existe en fait un résultat encore plus puissant (voir la démonstration
dans [5]) :

Propriété 3 (Théorème Flot Maximal/Coupe Minimale) La valeur d’un flot maximal


est égal à la valeur d’une coupe minimale.
De plus, si (A, B) est une coupe minimale, et que u est un arc ayant son départ dans A et
son extrémité dans B, alors u est saturé par tout flot maximal.

II.2 Algorithme de Ford-Fulkerson


L’algorithme de Ford-Fulkerson (1955) [8] utilise un principe de marquage relatif à un flot
compatible φ. On peut prendre comme flot compatible de départ le flot nul si on n’a pas
mieux.

Définition 5 (Principe de marquage de Ford-Fulkerson) On marque l’entrée s du


réseau, puis
x étant un sommet marqué , y est marquable à partir de x ssi
∃u = (x, y) ∈ R et φ(u) < c(u)
(
marquage direct
y n’est pas marqué et
∃u = (y, x) ̸= u0 ∈ R et φ(u) > 0 marquage indirect

Propriété 4 Si à la fin de la procédure de marquage

1. on parvient à marquer la sortie t du réseau alors on peut augmenter la valeur du


flot d’une valeur ε calculée comme suit : Soit ν la chaı̂ne (de s à t) ayant permis
de marquer t, et soit ν + , les arcs de ν participant aux marquages directs et ν − aux
marquages indirects. ε = min(minu∈ν + (c(u) − φ(u)), minu∈ν − φ(u)). Le nouveau flot
est obtenu en augmentant les flux des arcs de ν + et en diminuant les flux des arcs de
ν − de ε.

2. on ne parvient pas à marquer la sortie alors le flot est maximum et l’ensemble A des
sommets marqués permet de définir une coupe (A,X \ A) de capacité minimum.

Démonstration :(de la propriété 4)

1. Dans le premier cas, cela signifie qu’il existe une chaı̂ne reliant s à t dont
les arcs dans le sens s t vérifient φ(u) < c(u) et les arcs dans l’autre sens
vérifient φ(u) > 0. Considérons le cycle µ formé par cette chaı̂ne et l’arc
de retour u0 dans le sens de parcours donné par u0 .
Soit ε = minu∈µ r(u) où r(u) est la capacité résiduelle dans l’arc u. (ε =
min(ε1 , ε2 ) où ε1 = minu∈µ+ c(u) − φ(u) > 0 et ε2 = minu∈µ− φ(u) > 0
avec min∅ = ∞, notons que µ+ est toujours non vide car u0 ∈ µ+ ).

45
On a ε > 0, soit φ′ = φ + ε.µ. φ′ est une combinaison linéaire de flots car
tout vecteur cycle est un flot. Ce flot est compatible (conséquence du choix
de ε). Sa valeur est supérieure à φ puisque φ′ (u0 ) = φ(u0 ) + ε.µ(u0 ) =
φ(u0 ) + 1 × ε.
2. Dans le deuxième cas, on ne parvient pas à marquer la sortie. Notons A
l’ensemble des sommets marqués. Soit u = (x, y) un arc de ω + (A) c’est à
dire que x est marqué et y non marqué, alors φ(u) = c(u) (puisque φ est
un flot compatible et si φ(u) < c(u) on aurait pu marquer y par marquage
direct). Soit u = (y, x) un arc de ω − (A) c’est à dire que x est marqué et y
ne l’est pas, cela signifie que φ(u) = 0 ou que u = u0 (sinon soit le flot ne
serait pas compatible soit on aurait pu marquer y par marquage indirect).
Calculons u∈ω+ (A) φ(u) = C(ω + (A)). D’autre part, u∈ω− (A) φ(u) = 0 +
P P

φ(u0 ). La loi de conservation du flux sur A donne donc :φ(u0 ) = C(ω + (A)).
Ce qui signifie d’après le théorème de la coupe que le flot est maximum.

Exercice 19 Trouver un flot maximum de s à t dans le réseau suivant et indiquer une


coupe de capacité minimum. Sur chaque arc, les flux d’un flot initial sont indiqués suivis
par les capacités indiquées entre parenthèses.

2(4)
1 3
4(5) 4(7)

s 2(3) 2(2) 0(5) t

1(8) 1(9)
2 4
1(6)

46
Bilan :

• Un graphe peut représenter un réseau de transport avec une entrée


et une sortie et des capacités sur chaque arc.

• Un flot est un vecteur représentant les données qui transitent par les
arcs du réseau avec une contrainte : le respect de la loi de Kirchhoff
(sur chaque sommet, tout ce qui entre sort).

• Un flot est compatible si toutes ses composante sont positives et


respectent les capacités du réseau.

• Un problème classique : trouver un flot maximal dans ce réseau (ce


qui correspond aussi à trouver une coupe minimale).

• Un algo pour résoudre ce pb : algo de Ford-Fulkerson.

47
Bibliography

[1] A. Astié-Vidal. Support du cours mathématiques pour l’informatique, Licence


Informatique L3, 2004.

[2] C. Berge. Graphes et Hypergraphes. Dunod, Paris, 1969.

[3] Froidevaux Christine, Gaudel Marie-Claude, and Soria Michèle. Types de données et
algorithmes. Collection Informatique. Ediscience international, Paris, 1994.

[4] P. Chrétienne. La recherche opérationnelle, la science pour mieux comprendre et mieux


résoudre les problèmes de décision. In 2ème rencontres des Sciences et Technologies
de l’Information (ASTI’05), Clermont-Ferrand, France, October 2005. ISIMA.

[5] T. Cormen, C. Leiserson, R. Rivest, and C. Stein. Algorithmique. Dunod, 2010.

[6] P. Ossona de Mendez. Théorie des graphes: Epopée et aventures. http://madezhi.


free.fr/langfr/biblio.html, 1996.

[7] E. W. Dijkstra. A short introduction to the art of programming. Technical Report


EWD316, T. H. Eindhoven, The Netherlands, August 1971.

[8] L. Ford and D. Fulkerson. A simplex algorithm finding maximal networks flows and
an application to the hitchock problem. Rand Report Rand Corporation, dec 1955.

[9] M. Gondran and M. Minoux. Graphes et Algorithmes. Eyrolles, 1985.

[10] P. Hart, N. Nilsson, and B. Raphael. A formal basis for the heuristic determination
of minimum cost paths. IEEE Transactions on Systems Science and Cybernetics,
SSC-4(2):100–107, July 1968.

[11] J.B. Kruskal. On the shortest spanning sub-tree and the traveling salesman problem.
In Proceedings of the American Mathematical Society, volume 7, pages 48–50, 1956.

[12] P. Lacomme, C. Prins, and M. Servaux. Algorithmes de graphes. Eyrolles, 2003.

[13] R. Laudet. Support du cours de graphes, Licence Informatique, Université Paul


Sabatier, 1989.

[14] J. McHugh. Algorithmic graph theory. Prentice-Hall International Editions, 1990.

48
[15] S. Nogarède. Support du cours de recherche opérationnelle, Licence 3, IUP STRI,
2007.

[16] R.C. Prim. Shortest connection networks and some generalisations. Bell System
Technical Journal, 36:1389–1401, 1957.

[17] A. Schrijver. On the history of combinatorial optimization (till 1960). In K. Aardal,


G.L. Nemhauser, and R. Weismantel, editors, Handbook of Discrete Optimization,
pages 1–68. Elsevier, Amsterdam, 2005.

[18] Wikipédia. Recherche opérationnelle. Wikipédia, l’encyclopédie libre,


page http://fr.wikipedia.org/w/index.php?title=Recherche_op%C3%
A9rationnelle&oldid=17837831, 2007. [En ligne; Page disponible le 14-août-
2007].

[19] Wikipédia. Théorie des graphes. Wikipédia, l’encyclopédie libre, page


http://fr.wikipedia.org/w/index.php?title=Th%C3%A9orie_des_graphes&
oldid=19614031, 2007. [En ligne; Page disponible le 14-août-2007].

[20] N.H. Xuong. Mathématiques discrètes et informatique. Masson, 1992.

49

Vous aimerez peut-être aussi