Aller au contenu principal

Théorie des graphes : parcours, coloration et ordonnancement

Ce que ce chapitre apporte 8 points
  • Reconnaître dans une situation ce que sont les sommets et les arêtes, et décider si le graphe est orienté.
  • Employer le vocabulaire de base : degré, chemin, cycle, circuit, connexité, sous-graphe, clique, graphe complet, biparti, arbre.
  • Écrire un graphe sous ses trois formes, à la main et en Python, et choisir celle qui convient.
  • Dérouler un parcours en largeur et un parcours en profondeur, à la main et en Python, et dire ce que coûte chacun.
  • Colorier un graphe, encadrer son nombre chromatique entre une clique et une coloration, et dire ce que signifie « NP-complet ».
  • Appliquer l'algorithme glouton, et expliquer pourquoi son résultat dépend de l'ordre des sommets.
  • Reconnaître un graphe cordal, définir un graphe parfait, et dérouler LexBFS.
  • Situer la coloration parmi les problèmes d'ordonnancement.

Une usine couvre son site de huit bornes radio, notées A à H. Les rondes, les caristes et les capteurs leur parlent ; la borne A est celle du poste de garde. Deux bornes assez proches l'une de l'autre se relaient les messages, et ce sont les mêmes qui se brouillent si elles émettent sur le même canal. Deux questions se posent à l'équipe qui exploite ce réseau. Un message parti du poste de garde doit-il passer par beaucoup de bornes pour atteindre la plus lointaine, et que devient-il si une borne tombe en panne ? Combien de canaux faut-il au minimum pour que deux bornes voisines n'émettent jamais sur le même, et comment être sûr qu'on ne pourrait pas en utiliser un de moins ?

Ces deux questions ne parlent ni de distances en mètres, ni de puissance d'émission : seulement de bornes et de paires de bornes. C'est exactement ce qu'un graphe sait décrire. Le chapitre en pose les notions de base, apprend à l'écrire en Python, à le parcourir et à le colorier, et répond aux deux questions à la fin.

Le chapitre sur les codes correcteurs remplaçait une recherche par une lecture : trois parités au lieu d'une comparaison à tous les mots de code. Celui-ci fait le même constat sur un problème réputé difficile, la coloration, qui devient facile dès que le graphe a la bonne structure.

Ce chapitre et le parcours Graphes

Ce chapitre est une initiation : il pose les notions qui servent à comprendre et à utiliser un graphe, sans viser l'exhaustivité. Le parcours Graphes reprend chacune en détail, avec d'autres figures, les arbres couvrants, les plus courts chemins pondérés, les flots et les couplages. Les sections y renvoient quand une idée mérite d'être creusée.

Travailler seul

Chaque quiz, chaque cadre de calcul et les questions à déplier sont précédés d'un rappel de cours : la notion, sa formule s'il y en a une, et un petit exemple résolu. Le lire avant de répondre. Les figures se manipulent, les blocs Python s'exécutent, et deux exercices demandent d'écrire une fonction dans la page.

Un graphe, c'est une relation

Le relevé fait sur le site dit quelles bornes sont à portée l'une de l'autre. Il compte onze paires : A et B, A et C, A et D, A et E, B et C, B et F, C et D, C et F, D et E, E et G, G et H. Rien d'autre n'est utile aux deux questions : ni la position exacte des bornes, ni la distance qui les sépare. Un point par borne, un trait par paire à portée, et le réseau tient dans un dessin.

Graphe non orienté8 sommets, 11 arêtes
AgardeBCDEFGH
AgardeBCDEFGH
Le graphe des bornes : huit sommets, onze arêtes. Une arête relie deux bornes à portée l'une de l'autre ; A est la borne du poste de garde.
Un graphe n'est pas le graphique d'une fonction

Le mot sert à deux objets sans rapport. Le graphique d'une fonction est une courbe tracée dans un repère : la position de chaque point y a un sens, c'est un couple de coordonnées. Un graphe est un ensemble de points et de liens entre eux, et seuls les liens comptent. Déplacer un sommet sur la figure ne change rien au graphe ; un trait plus long ne veut pas dire des bornes plus éloignées. Deux dessins très différents peuvent représenter le même graphe.

Définition

Un graphe G=(V,E)G = (V, E) est la donnée d'un ensemble fini de sommets VV et d'un ensemble EE de liens entre deux sommets. On note n=∣V∣n = |V| le nombre de sommets et m=∣E∣m = |E| le nombre de liens.

Si la relation est symétrique, un lien est une arête, sans sens, et le graphe est non orienté. Si elle ne l'est pas, un lien est un arc, qui va d'un sommet vers un autre, et le graphe est orienté.

Une boucle relie un sommet à lui-même ; des arêtes multiples relient plusieurs fois les mêmes sommets. Un graphe sans boucle ni arête multiple est dit simple : ce sont les seuls que ce chapitre emploie.

Quand chaque lien porte un nombre (une longueur, un débit, un coût), le graphe est pondéré.

Le graphe des bornes est simple et non orienté : n=8n = 8, m=11m = 11.

Arête ou arc : la question à se poser

La relation est-elle symétrique ? « A est à portée de B » l'est : si A est à portée de B, B est à portée de A, et c'est une arête. « Le câble doit être tiré avant que la borne soit fixée » ne l'est pas : l'inverse n'aurait aucun sens, et c'est un arc, du câble vers la borne. Poser cette question avant de dessiner évite de tout reprendre ensuite.

Rappel de cours : reconnaître un graphe

Modéliser, c'est dire en une phrase ce qu'est un sommet et ce qu'est un lien, puis décider si le lien a un sens.

Exemple résolu. Les salariés d'une entreprise, reliés quand l'un encadre l'autre : un sommet par salarié, un arc du responsable vers la personne encadrée. « Encadrer » n'est pas symétrique : le graphe est orienté.

Vérification rapideon peut se reprendre

1.Des pièces mécaniques, reliées quand l'une entre dans la fabrication de l'autre. Ce graphe est…

2.Les techniciens d'un service, reliés quand ils ont déjà travaillé ensemble sur un chantier. Ce graphe est…

3.Les carrefours d'une ville, reliés par les rues, dont certaines sont à sens unique. Le graphe qui convient pour calculer un itinéraire en voiture est…

Le vocabulaire, sur le graphe des bornes

Degré

Le degré d(v)d(v) d'un sommet est son nombre de voisins. Sur le graphe des bornes : A et C ont 4 voisins, B, D et E en ont 3, F et G 2, et H un seul.

Lemme des poignées de main

∑d(v)=2m\sum d(v) = 2m

La somme des degrés vaut deux fois le nombre d'arêtes, puisque chaque arête est comptée à ses deux extrémités.

Sur le graphe des bornes, 4+3+4+3+3+2+2+1=22=2×114 + 3 + 4 + 3 + 3 + 2 + 2 + 1 = 22 = 2 \times 11. Conséquence immédiate : la somme des degrés étant paire, le nombre de sommets de degré impair est pair. Ils sont quatre ici, B, D, E et H. C'est le premier outil pour prouver qu'un graphe ne peut pas exister : cinq sommets de degré 3 donneraient une somme de 15, impaire.

Chemins, cycles, circuits

Définitions

Un chemin est une suite de sommets dont chacun est relié au suivant. Sa longueur est son nombre d'arêtes. Il est élémentaire s'il ne repasse par aucun sommet.

Un cycle est un chemin d'au moins trois sommets qui revient à son point de départ sans emprunter deux fois la même arête.

Dans un graphe orienté, un chemin doit suivre le sens des arcs, et un chemin qui revient à son point de départ en les suivant s'appelle un circuit.

Certains ouvrages disent chaîne dans un graphe non orienté et réservent « chemin » aux graphes orientés. Ce site dit chemin dans les deux cas, et précise quand le sens compte.

Graphe non orienté8 sommets, 11 arêteschemin mis en évidence
ABCDEFGH
ABCDEFGH
Le chemin A, E, G, H, de longueur 3 : un message du poste de garde vers H passe par E puis par G. A, B, C, A est un cycle de longueur 3, un triangle.

Connexité

Un graphe est connexe si deux sommets quelconques sont reliés par un chemin. Sinon, il se décompose en composantes connexes, ses morceaux d'un seul tenant. Le graphe des bornes est connexe ; il cesse de l'être si la borne E tombe en panne.

Graphe non orienté7 sommets, 8 arêtes
ABCDFGH
La borne E en panne : G et H ne sont plus joignables depuis le poste de garde. Le graphe restant a deux composantes connexes, A, B, C, D, F d'un côté, G et H de l'autre.

Sous-graphes et cliques

Un sous-graphe s'obtient en gardant une partie des sommets et une partie des arêtes qui les relient. Le sous-graphe induit par un ensemble de sommets garde toutes les arêtes entre eux : on choisit les sommets, les arêtes viennent avec. Sur les bornes A, B, C et F, le sous-graphe induit a cinq arêtes, A-B, A-C, B-C, B-F et C-F ; ne garder que A-B et B-F donne un sous-graphe, qui n'est pas induit.

Clique, graphe complet

Une clique est un ensemble de sommets deux à deux adjacents. On note ω(G)\omega(G) la taille de la plus grande clique de GG.

Un graphe où chaque sommet est relié à tous les autres est complet ; à nn sommets, on le note KnK_n. Il compte une arête par paire de sommets, soit n(n−1)/2n(n - 1)/2, et le graphe entier est une clique : ω(Kn)=n\omega(K_n) = n.

Le graphe des bornes contient quatre triangles, A, B, C ; A, C, D ; A, D, E ; B, C, F. Aucun groupe de quatre bornes n'est relié deux à deux : ω=3\omega = 3.

Graphe non orienté8 sommets, 11 arêtesclique de taille 3
ABCDEFGH
ABCDEFGH
A, B et C sont deux à deux à portée : une clique de taille 3. A, E, G et H se suivent de proche en proche, mais ne forment pas une clique : A et G ne sont pas reliés.
Clique et composante, deux choses différentes

Une composante connexe demande que les sommets soient reliés de proche en proche, par des chemins. Une clique demande bien plus : que chaque paire soit reliée directement. Le graphe des bornes est d'un seul tenant, et sa plus grande clique n'a pourtant que trois sommets.

Quelques familles

Familles de graphes

Un graphe est biparti si ses sommets se répartissent en deux groupes sans aucune arête à l'intérieur d'un groupe.

Un arbre est un graphe connexe sans cycle. Un arbre à nn sommets a exactement n−1n - 1 arêtes : c'est le plus petit réseau qui relie tout.

Le graphe complet KnK_n et le graphe pondéré ont été définis plus haut.

Rappel de cours : poignées de main et cliques

La somme des degrés vaut 2m2m. Le graphe complet KnK_n a n(n−1)/2n(n - 1)/2 arêtes, soit (n2)\binom{n}{2}. Une clique se cherche parmi les sommets deux à deux reliés.

Exemple résolu, sur K4K_4 : chaque sommet a 3 voisins, la somme des degrés vaut 4×3=124 \times 3 = 12, donc le graphe a 6 arêtes, et c'est bien (42)=6\binom{4}{2} = 6. Ses quatre sommets forment une clique : ω(K4)=4\omega(K_4) = 4.

Une neuvième borne

  • 1.

    Une borne I est ajoutée, à portée de G et de H seulement. Combien d'arêtes compte maintenant le graphe ?

  • 2.

    Quelle est la somme des degrés du nouveau graphe ?

  • 3.

    Combien de bornes ont maintenant un degré impair ?

  • 4.

    Quelle est la taille de la plus grande clique du nouveau graphe ?

  • 5.

    Combien d'arêtes faudrait-il pour que six bornes soient toutes à portée les unes des autres ?

Représenter un graphe en machine

Les trois écritures

Liste d'adjacence : pour chaque sommet, la liste de ses voisins. En Python, un dictionnaire de listes.

Matrice d'adjacence : un tableau n×nn \times n dont la case (i,j)(i, j) vaut 1 si l'arête existe, 0 sinon. En Python, une liste de listes.

Liste d'arêtes : la simple liste des paires, comme le relevé du site.

Écrire avant de lire

Avant de regarder la figure, écrire à la main, à partir des onze paires du relevé, la liste des voisins de B, de E et de H. Chaque paire se range deux fois : la paire B et F met F chez B, et B chez F. Comparer ensuite avec la figure.

Matrice d'adjacence
ABCDEFGHd
A011110004
B101001003
C110101004
D101010003
E100100103
F011000002
G000010012
H000000101
Liste d'adjacence
A
: {B, C, D, E}
B
: {A, C, F}
C
: {A, B, D, F}
D
: {A, C, E}
E
: {A, D, G}
F
: {B, C}
G
: {E, H}
H
: {G}
Liste d'arêtes
  • (A, B)
  • (A, C)
  • (A, D)
  • (A, E)
  • (B, C)
  • (B, F)
  • (C, D)
  • (C, F)
  • (D, E)
  • (E, G)
  • (G, H)
Les trois écritures du graphe des bornes, calculées à partir des mêmes arêtes que le dessin : elles ne peuvent pas se contredire. La matrice est symétrique, parce que le graphe n'est pas orienté. Sa diagonale est nulle, parce qu'aucun sommet n'est son propre voisin. La somme d'une ligne donne le degré du sommet correspondant.

Trois lectures du même objet, et trois usages. La matrice répond en une case à « ces deux bornes sont-elles voisines ? », et elle est symétrique, puisqu'une arête allume les cases (i,j)(i, j) et (j,i)(j, i). La liste donne d'un coup tous les voisins d'une borne, ce que la matrice ne fait qu'en lisant une ligne entière. La liste d'arêtes est la plus compacte, et c'est celle qu'on écrit dans un fichier.

Le bloc ci-dessous construit la matrice à partir de la liste d'arêtes, et en tire deux réponses.

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

La liste d'adjacence, elle, est à écrire.

Exercice : écrire puis vérifier

Du relevé à la liste d'adjacence

Écrire liste_adjacence(aretes), qui reçoit une liste de paires et renvoie un dictionnaire donnant, pour chaque sommet, la liste de ses voisins, dans l'ordre où les paires les donnent.

À compléter

Écrire la fonction, puis « Vérifier » : 4 vérifications sur des cas qu'on sait faire de tête.

Une bibliothèque fait tout cela d'un coup. networkx construit le graphe à partir de la liste d'arêtes, et sait ensuite en donner les voisins, les degrés, la matrice, les distances ou les composantes. Pour un très grand graphe, scipy.sparse range une matrice en ne gardant que ses cases non nulles.

main.py
Sortie
>_ Prêt à exécuter…
Rappel de cours : la place qu'occupe chaque écriture

Pour un graphe de nn sommets et mm arêtes, la matrice compte n2n^2 cases, quel que soit le nombre d'arêtes, dont 2m2m valent 1 ; la liste d'adjacence range 2m2m noms de voisins ; la liste d'arêtes, mm paires. Avec la notation du chapitre sur la complexité, la matrice occupe O(n2)O(n^2), la liste d'adjacence O(n+m)O(n + m).

Exemple résolu, sur le graphe des bornes : la matrice a 8×8=648 \times 8 = 64 cases, dont 22 valent 1 ; la liste d'adjacence range 22 noms, la liste d'arêtes 11 paires.

Vérification rapideon peut se reprendre

Une matrice d'adjacence sur un graphe de 10 000 sommets et 30 000 arêtes occupe…

Comment choisir. Un graphe est creux quand mm est de l'ordre de nn, dense quand il approche n(n−1)/2n(n - 1)/2. Les grands graphes réels sont presque toujours creux : un réseau routier, un réseau social, les liaisons d'un réseau de capteurs. Pour eux, la liste d'adjacence gagne sur tous les tableaux, en mémoire et en temps : trouver les voisins d'un sommet y coûte son degré, quand la matrice oblige à lire ses nn cases. La matrice se justifie sur un graphe dense, ou pour répondre très souvent à « ces deux sommets sont-ils voisins ? ».

Parcourir un graphe

Première question du chapitre : un message parti du poste de garde passe-t-il par beaucoup de bornes avant d'atteindre la plus lointaine ? Y répondre demande de visiter les bornes dans un ordre réfléchi, en partant de A. C'est ce que fait un parcours.

Deux parcours, une seule différence

Un parcours part d'un sommet et visite tous ceux qu'il peut atteindre, chacun une fois. Il tient une réserve de sommets découverts mais pas encore traités.

Le parcours en largeur range la réserve dans une file, où le premier entré est le premier sorti : il explore les sommets par distances croissantes au départ, d'abord tous les voisins, puis les voisins des voisins.

Le parcours en profondeur la range dans une pile, où le dernier entré est le premier sorti : il s'enfonce aussi loin que possible avant de revenir en arrière.

Le parcours en largeur, déroulé depuis le poste de garde.

Graphe non orienté8 sommets, 11 arêtes
0 / 8
ABCDEFGH
ABCDEFGH
Rien n'est encore visité.
Parcours en largeur depuis A, qui se déroule en boucle. Les arêtes s'allument quand elles font découvrir un sommet neuf ; les autres restent éteintes. Toucher une commande arrête la boucle, pour avancer pas à pas.

Les bornes s'allument par vagues, et chaque vague est à une arête de plus de A : B, C, D et E à un relais, F et G à deux, H à trois. Le rang de la vague où une borne s'allume est sa distance au poste de garde, en nombre de relais, et c'est pourquoi le parcours en largeur donne les plus courts chemins. La réponse à la première moitié de la question est là : trois relais suffisent pour atteindre H, et aucun chemin plus court n'existe.

Le même graphe, parcouru par une figure qui calcule elle-même le parcours ; la réserve s'y affiche en jetons à chaque pas.

Parcours avec une file, depuis A8 sommets, 11 arêtes
0 / 8
Réserve
Marque
Voisins
Cliquer un sommet pour en faire le départ.
Adist 0BCDEFGH
Adist 0BCDEFGH

Sommets rangés par distance au départ. Plein : traité, avec son rang. Contour tireté : marqué, en attente dans la réserve. En gras : l'arête par laquelle chaque sommet a été découvert.

Voisins, dans l'ordre où le parcours les prend (alphabétique) :

  • A : B, C, D, E
  • B : A, C, F
  • C : A, B, D, F
  • D : A, C, E
  • E : A, D, G
  • F : B, C
  • G : E, H
  • H : G
FileEntrées dans la file : 1 pour 8 sommets
sort ←
  1. Adépart
← entre
Ordre de visite : aucun sommet encore
Départ : A entre dans la file et est marqué aussitôt. Rien n'est encore traité.
Le graphe des bornes, parcouru depuis A. Basculer la réserve de la file à la pile : l'ordre passe de A, B, C, D, E, F, G, H à A, B, C, D, E, G, H, F.

Avec la pile, le parcours file de B vers C, puis D, E, G et H, et ne revient chercher F qu'à la fin : il suit chaque branche jusqu'au bout. C'est ce qui le rend commode pour délimiter un morceau du graphe. Pour la seconde moitié de la question, il suffit de retirer la borne en panne et de lancer un parcours depuis A : les bornes qu'il atteint restent joignables, les autres sont coupées. Sur ce réseau, seules deux pannes coupent quelque chose : celle de E, qui isole G et H, et celle de G, qui isole H. E et G sont des points de passage obligés.

Marquer à l'enfilement, pas au défilement

En largeur, un sommet doit être marqué « vu » au moment où il entre dans la file. Si on attend qu'il en sorte, plusieurs voisins peuvent l'ajouter chacun à leur tour : la file se remplit de doublons, et une distance notée à chaque ajout peut être écrasée par une plus grande. Dans le parcours depuis A, F serait mis deux fois dans la file, par B puis par C.

Les deux parcours visitent chaque sommet une fois et examinent chaque arête deux fois, depuis chacune de ses extrémités : avec des listes d'adjacence, leur temps est en O(n+m)O(n + m). Avec une matrice, il passe à O(n2)O(n^2), puisqu'il faut lire toute une ligne pour trouver les voisins d'un sommet.

Le parcours en largeur, écrit en Python sur la liste d'adjacence. Le second appel répond à la question de la panne.

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

Remplacer deque et popleft par une liste et pop() change la file en pile : le même code devient un parcours en profondeur, à un détail près, que le chapitre sur les parcours explique avec les composantes connexes et la détection de cycle.

Rappel de cours : file, pile et distance

Une file rend les sommets dans l'ordre où ils y sont entrés ; une pile rend d'abord le dernier entré. Avec une file, tous les sommets à distance 1 du départ entrent avant le premier sommet à distance 2, et sortent donc avant lui.

Exemple résolu, sur les arêtes X-Y, X-Z et Y-T, depuis X. On sort X et on enfile Y et Z : file = [Y, Z]. On sort Y, on enfile T : file = [Z, T]. On sort Z, puis T. Y et Z sont à distance 1, T à distance 2. Avec une pile, T sortirait avant Z, alors qu'il est plus loin du départ.

Vérification rapideon peut se reprendre

1.Le parcours en largeur donne les plus courts chemins, pas le parcours en profondeur. Pourquoi ?

2.Les liaisons d'un réseau de câbles portent leur longueur en mètres. Le parcours en largeur depuis une armoire donne-t-il le trajet de câble le plus court vers chaque point ?

Quand les arêtes portent un poids : Dijkstra et Prim. Deux algorithmes célèbres sont des parcours dont la réserve est une file de priorité, qui rend à chaque pas le sommet le plus avantageux plutôt que le plus ancien.

L'algorithme de Dijkstra calcule les plus courts chemins dans un graphe pondéré, aux poids positifs : il sort à chaque pas le sommet le plus proche du départ parmi ceux qu'il a déjà atteints. C'est le parcours en largeur, quand les arêtes n'ont plus toutes la même longueur. Voir le chapitre sur les plus courts chemins.

L'algorithme de Prim construit un arbre couvrant de poids minimal : relier toutes les bornes par des câbles, de longueur totale la plus petite possible. Il part d'un sommet, et ajoute à chaque pas la liaison la moins chère qui atteint un sommet neuf. Voir le chapitre sur les arbres.

Colorier un graphe

Seconde question du chapitre. Deux bornes à portée l'une de l'autre se brouillent si elles émettent sur le même canal, et chaque canal supplémentaire est une fréquence de plus à réserver. Attribuer un canal à chaque borne, c'est donner une couleur à chaque sommet, avec une seule règle : deux sommets reliés n'ont jamais la même couleur.

Colorier d'abord, on expliquera après

Le graphe des bornes, à colorier : deux bornes reliées ne peuvent pas porter la même teinte. Combien de teintes au minimum ?
PinceauRecliquer un sommet de la même couleur l'efface.
ABCDEFGH
Couleurs utilisées : 0Sommets à colorier : 8
Choisir une couleur, puis cliquer les sommets. La règle tient en une ligne : deux sommets reliés par une arête ne peuvent pas porter la même couleur. Chercher à en employer le moins possible, et relever combien il en a fallu au premier essai : c'est ce nombre-là que la suite du chapitre explique.
À manipuler
Colorier en suivant une règle fixe : prendre les bornes dans l'ordre alphabétique, de A à H, et donner à chacune la première teinte de la palette qu'aucune de ses voisines déjà coloriées ne porte. Noter le nombre de teintes employées.
Effacer, puis recommencer avec la même règle dans l'ordre B, E, C, D, A, F, G, H. B et E, qui ne sont pas voisines, prennent la même teinte ; C en prend une deuxième, D une troisième, et A, voisine de B, C, D et E, se retrouve devant trois teintes déjà prises.

Deux choses se remarquent en jouant. L'ordre change le résultat : trois teintes dans l'ordre alphabétique, quatre dans le second, sur le même graphe et avec la même règle. Et une fois trois teintes trouvées, rien ne dit encore qu'on ne peut pas descendre à deux. Avoir réussi avec trois prouve qu'il en suffit trois, pas qu'il en faut trois.

Définitions

Une coloration attribue une couleur à chaque sommet de sorte que deux sommets adjacents n'aient jamais la même. Une coloration qui emploie au plus kk couleurs est une kk-coloration.

Le nombre chromatique χ(G)\chi(G) est le plus petit nombre de couleurs d'une coloration de GG.

La clique donne le minimum

Rappel de cours : la minoration par la clique

χ(G)≥ω(G)\chi(G) \geq \omega(G)

Dans une clique de taille kk, chaque sommet est relié à tous les autres : il leur faut kk couleurs distinctes, donc au moins autant au graphe entier. Sur le graphe complet, la borne est atteinte : χ(Kn)=n\chi(K_n) = n.

Exemple résolu. A, B et C sont deux à deux à portée : ils forment un triangle, et il leur faut trois canaux distincts. Le réseau entier demande donc au moins trois canaux.

Comment on prouve qu'une coloration est optimale. En deux temps :

  1. Exhiber une clique de taille kk : cela prouve χ≥k\chi \geq k ;
  2. Exhiber une coloration à kk couleurs : cela prouve χ≤k\chi \leq k.

Les deux ensemble donnent χ=k\chi = k. Une coloration seule ne prouve jamais l'optimalité : elle ne fournit qu'une majoration.

Graphe non orienté8 sommets, 11 arêtesclique de taille 3
ABCDEFGH
ABCDEFGH
Trois canaux, et aucune arête entre deux bornes du même canal : trois suffisent. Le triangle A, B, C surligné en exige trois à lui seul : trois sont nécessaires. Donc χ = 3.

Un problème réputé difficile

Rappel de cours : ce que veut dire « NP-complet »

Un problème est dans la classe NP si l'on sait vérifier une solution proposée en temps polynomial, c'est-à-dire en un temps qui reste une puissance de la taille des données, comme n2n^2 ou n3n^3. Le sigle signifie « non déterministe polynomial », et non « non polynomial ». Décider si un graphe se colore avec kk couleurs est dans NP : pour vérifier une coloration, il suffit de parcourir les mm arêtes.

Un problème de NP est NP-complet si tout problème de NP s'y ramène par une réduction polynomiale, une transformation de coût polynomial. Le résoudre vite permettrait donc de résoudre vite tous les problèmes de NP. Décider si un graphe se colore avec 3 couleurs est NP-complet, et aucun algorithme connu ne trouve χ(G)\chi(G) sur un graphe quelconque sans risquer un temps qui croît exponentiellement.

Exemple. Vérifier qu'une attribution de canaux aux huit bornes est valide demande de regarder les onze arêtes. Essayer toutes les colorations en trois couleurs d'un graphe de 50 sommets en demanderait jusqu'à 3503^{50}, soit plus de 7×10237 \times 10^{23}.

NP-complet ne veut pas dire « insoluble »

Cela veut dire qu'aucune méthode générale et rapide n'est connue. Trois issues bien réelles : un graphe assez petit pour tout essayer ; une solution approchée, que l'algorithme glouton fournit immédiatement ; une famille de graphes particulière, où le problème redevient facile. La dernière section de ce chapitre en montre une.

Vérifier, justement, s'écrit en quelques lignes.

Exercice : écrire puis vérifier

Vérifier une coloration

Écrire est_coloration(aretes, couleur), qui renvoie True si aucune arête ne relie deux sommets de même couleur, et False sinon. couleur est un dictionnaire qui donne la couleur de chaque sommet.

À compléter

Écrire la fonction, puis « Vérifier » : 5 vérifications sur des cas qu'on sait faire de tête.

Une seule boucle sur les arêtes : la vérification est en O(m)O(m), ce qui place la coloration dans NP.

L'algorithme glouton

Principe

Un algorithme glouton fait à chaque étape le choix qui paraît le meilleur sur le moment, sans jamais revenir en arrière.

Pour la coloration, les couleurs sont numérotées 0, 1, 2, et ainsi de suite. On prend les sommets dans un ordre choisi à l'avance, et chacun reçoit la première couleur qu'aucun de ses voisins déjà coloriés ne porte.

Algorithme
Entrée : un graphe, et un ordre de ses sommets
Sortie : un numéro de couleur pour chaque sommet
Pour chaque sommet v, pris dans l'ordre choisi Faire
noter les couleurs que portent les voisins de v déjà coloriés
donner à v la première couleur 0, 1, 2… qui n'a pas été notée
FinPour

La première ligne de la boucle relève les couleurs interdites ; la seconde prend la première qui reste. Les voisins pas encore coloriés n'y figurent pas : l'algorithme décide sans rien savoir de ce qui vient après. Il est en O(n+m)O(n + m) et produit toujours une coloration valide, mais pas forcément optimale.

Le glouton sur le graphe des bornes, dans l'ordre alphabétique : chaque couleur apparaît à l'étape qui la donne.

Graphe non orienté8 sommets, 11 arêtes
0 / 8
ABCDEFGH
ABCDEFGH
Rien n'est encore visité.
La coloration gloutonne dans l'ordre alphabétique, qui se déroule en boucle. À chaque étape, la borne traitée prend la première couleur que ses voisines déjà coloriées laissent libre.

L'ordre décide de tout

Le plus petit exemple tient en quatre sommets alignés, A-B-C-D. Deux couleurs suffisent : il n'y a aucun triangle, et l'alternance 0, 1, 0, 1 convient. La figure propose deux ordres ; on peut aussi composer le sien en cliquant les sommets.

Coloration gloutonne4 sommets, 3 arêtes
Ordre :
  1. A
  2. B
  3. C
  4. D
0 / 4
ABCD
Rien n'est encore coloré : avancer d'une étape, ou cliquer un sommet pour choisir soi-même le suivant.
Quatre sommets alignés. Dans l'ordre A, B, C, D, le glouton alterne et emploie deux couleurs ; dans l'ordre A, D, B, C, il en emploie trois, sur le même graphe.

Dans le second ordre, A et D, qui ne sont pas voisins, prennent tous deux la couleur 0. B, voisin de A, prend la 1. C arrive enfin entre B, en 1, et D, en 0 : il lui faut une troisième couleur. Aucune décision n'était fausse sur le moment ; c'est leur enchaînement qui coûte.

Le même effet, sur le graphe des bornes. Choisir un ordre, le dérouler pas à pas, puis comparer le nombre de couleurs à celui de la plus grande clique ; ou cliquer les bornes dans l'ordre de son choix.

Coloration gloutonne8 sommets, 11 arêtes
Ordre :
  1. A
  2. B
  3. C
  4. D
  5. E
  6. F
  7. G
  8. H
0 / 8
ABCDEFGH
ABCDEFGH
Rien n'est encore coloré : avancer d'une étape, ou cliquer un sommet pour choisir soi-même le suivant.
Le graphe des bornes, colorié par le glouton dans l'ordre choisi. L'ordre alphabétique, Welsh-Powell et LexBFS emploient trois couleurs ; l'ordre défavorable en emploie quatre : B et E, éloignées, prennent la même couleur, et A se retrouve face à trois couleurs prises.

L'écart n'est pas toujours d'une seule couleur. Il existe des graphes bipartis, colorables en deux couleurs, sur lesquels un ordre défavorable fait employer au glouton autant de couleurs que la moitié du nombre de sommets.

Rappel de cours : ce que le glouton garantit, et ce qu'il ne garantit pas
  1. Il n'emploie jamais plus de Δ+1\Delta + 1 couleurs, où Δ\Delta est le degré maximal : un sommet a au plus Δ\Delta voisins, donc au plus Δ\Delta couleurs interdites, et l'une des couleurs 0 à Δ\Delta reste libre. C'est une borne supérieure : elle dit ce qui suffit toujours, pas ce qui est nécessaire.
  2. Il existe toujours un ordre pour lequel il trouve l'optimum ; le trouver est aussi difficile que le problème de départ.
  3. D'où les heuristiques d'ordre. Welsh-Powell trie les sommets par degré décroissant, pour servir les plus contraints quand il reste des couleurs libres : souvent meilleur qu'un ordre arbitraire, sans aucune garantie.

Exemple résolu. Sur le graphe des bornes, Δ=4\Delta = 4 : le glouton n'y emploie jamais plus de cinq couleurs, quel que soit l'ordre. Il en a employé trois ou quatre selon l'ordre ; le triangle A, B, C montre qu'il en faut au moins trois.

Vérification rapideon peut se reprendre

1.Quatre bornes d'un autre site sont deux à deux à portée. Que peut-on en conclure ?

2.« Colorier un graphe en 3 couleurs est NP-complet » signifie…

3.Un graphe a pour degré maximal 6. Que peut-on en conclure sur son nombre chromatique ?

Graphes cordaux, graphes parfaits et LexBFS

Un second niveau

Cette section va plus loin que les précédentes. Ce qu'il faut en retenir tient en deux phrases. Sur certains graphes, les graphes cordaux, la borne de la clique est toujours atteinte : χ=ω\chi = \omega. Et un parcours particulier, LexBFS, donne un ordre dans lequel le glouton trouve à coup sûr cet optimum, en temps linéaire. La suite explique comment les reconnaître, et pourquoi cela marche.

Graphe cordal

Corde, graphe cordal

Une corde d'un cycle est une arête qui relie deux sommets du cycle sans être une de ses arêtes, c'est-à-dire deux sommets non consécutifs.

Un graphe est cordal quand chacun de ses cycles de quatre sommets ou plus a au moins une corde. Un triangle n'a jamais de corde, et n'en a pas besoin : dans un graphe cordal, les seuls cycles sans corde sont des triangles.

Le carré est le plus petit graphe qui ne soit pas cordal : un cycle de quatre sommets, sans corde. Ajouter une diagonale le coupe en deux triangles, et le rend cordal.

Graphe non orienté4 sommets, 4 arêteschemin mis en évidence
ABCD
Le carré A, B, C, D : un cycle de quatre sommets, dont les cordes possibles, A-C et B-D, manquent toutes les deux. Ce graphe n'est pas cordal.

Le graphe des bornes est cordal. Le cycle A, B, F, C, A a la corde B-C ; le cycle A, B, C, D, E, A a les cordes A-C et A-D ; et ainsi de suite pour chacun. Vérifier cycle par cycle serait long, et LexBFS, plus bas, fera ce contrôle d'un seul passage. Deux familles sont cordales d'office : les arbres, qui n'ont aucun cycle, et les graphes d'intervalles, obtenus en posant des segments sur une droite et en reliant deux segments qui se recouvrent.

Graphe parfait

Graphe parfait

Un graphe est parfait quand, pour lui et pour chacun de ses sous-graphes induits, le nombre chromatique égale la taille de la plus grande clique : χ=ω\chi = \omega.

Les sous-graphes induits ne sont pas un détail. Le cycle de cinq sommets n'a aucun triangle, ω=2\omega = 2, mais demande trois couleurs, χ=3\chi = 3 : il n'est pas parfait. Le coller à côté d'un triangle donne un graphe où χ=3\chi = 3 et ω=3\omega = 3, égalité trompeuse : le sous-graphe induit par le cycle garde son écart, et le graphe entier n'est pas parfait non plus.

Graphe non orienté8 sommets, 8 arêtes
PQRSTXYZ
Un cycle de cinq sommets à côté d'un triangle. Sur le graphe entier, χ = ω = 3 ; sur le sous-graphe induit par P, Q, R, S, T, χ = 3 et ω = 2. Il n'est donc pas parfait.

Pourquoi un graphe cordal est parfait

Le raisonnement tient en trois temps, et il n'admet qu'un résultat.

Ordre parfait d'élimination

Un sommet est simplicial quand ses voisins forment une clique. Un ordre parfait d'élimination range les sommets de sorte que chacun soit simplicial dans le graphe formé de lui et des sommets qui le suivent : on peut retirer les sommets un à un en ne retirant chaque fois qu'un sommet dont les voisins restants sont deux à deux reliés.

Résultat admis, démontré dans le chapitre sur les familles remarquables : un graphe est cordal si et seulement s'il possède un ordre parfait d'élimination.

  1. Le glouton atteint ω\omega. Colorier dans l'ordre inverse d'un ordre parfait d'élimination : quand vient le tour d'un sommet, ses voisins déjà coloriés sont ceux qui le suivaient dans l'ordre d'élimination, donc deux à deux reliés. Avec lui, ils forment une clique, de taille au plus ω\omega : ils sont au plus ω−1\omega - 1, ne lui interdisent qu'au plus ω−1\omega - 1 couleurs, et le glouton n'emploie jamais plus de ω\omega couleurs. Comme il en faut au moins ω\omega, χ=ω\chi = \omega.
  2. Un sous-graphe induit d'un graphe cordal est cordal. Un cycle sans corde dans le sous-graphe serait aussi sans corde dans le graphe entier, puisque le sous-graphe induit garde toutes les arêtes entre ses sommets.
  3. Donc l'égalité χ=ω\chi = \omega vaut pour le graphe et pour chacun de ses sous-graphes induits : le graphe est parfait.

La chaîne à retenir : cordal ⟹ parfait ⟹ χ=ω\chi = \omega, et un ordre d'élimination rend le glouton optimal. Reste à trouver cet ordre.

LexBFS

Le parcours en largeur lexicographique

LexBFS choisit les sommets un à un et les numérote à rebours : le premier choisi reçoit le numéro nn, le dernier le numéro 1. Chaque sommet porte une étiquette, la suite des numéros déjà inscrits chez lui, vide au départ.

À chaque étape, on choisit le sommet dont l'étiquette est la plus grande, puis il inscrit son numéro à la fin de l'étiquette de ses voisins non encore choisis. En cas d'égalité, n'importe quel choix convient ; ici, le nom le plus loin dans l'alphabet départage.

Sur un graphe cordal, l'ordre de choix obtenu a la propriété cherchée : chaque sommet forme une clique avec ceux de ses voisins choisis avant lui. Lu à l'envers, c'est un ordre parfait d'élimination, et le glouton appliqué dans l'ordre de choix est optimal.

Les étiquettes se comparent comme les mots d'un dictionnaire, numéro par numéro, et non comme des nombres. On compare les premiers numéros ; en cas d'égalité, les suivants. Ainsi (4)(4) l'emporte sur (3,2,1)(3, 2, 1), puisque 4 dépasse 3 dès le premier numéro, et (3,2)(3, 2) l'emporte sur (3)(3), qu'elle prolonge. Additionner les numéros, ou lire (3,2)(3, 2) comme « 32 », donnerait d'autres choix.

La mise à jour des étiquettes se suit sur quatre sommets : un triangle A, B, C, et un sommet D accroché à C.

Graphe non orienté4 sommets, 4 arêtes
0 / 4
ABCD
Rien n'est encore visité.
LexBFS sur un triangle et un sommet pendant, en boucle. L'ordre de choix est D, C, B, A.

Sur le graphe des bornes, le même déroulé donne ceci.

ChoixNuméroÉtiquettes juste avant le choix
H8toutes vides : l'alphabet départage
G7G (8), les autres vides
E6E (7)
D5A (6), D (6) : égalité, l'alphabet départage
A4A (6, 5), C (5)
C3C (5, 4), B (4)
B2B (4, 3), F (3)
F1F (3, 2)

L'ordre de choix est H, G, E, D, A, C, B, F. Le contrôle se lit sur cet ordre : pour chaque sommet, ses voisins choisis avant lui sont-ils deux à deux reliés ? Pour A, ce sont E et D, reliés ; pour C, A et D, reliés ; pour B, A et C ; pour F, C et B ; les autres n'en ont qu'un. Le contrôle passe : le graphe des bornes est cordal. Le glouton dans cet ordre donne H 0, G 1, E 0, D 1, A 2, C 0, B 1, F 2, soit trois couleurs, et le triangle A, B, C prouve que c'est le minimum. Le bouton « LexBFS » de la figure du glouton, plus haut, déroule exactement cet ordre.

La garantie ne vaut que sur un graphe cordal

Sur un graphe qui n'est pas cordal, LexBFS rend encore un ordre, sans plus aucune garantie, et c'est le contrôle qui le dit. Sur le carré, LexBFS rend D, C, A, B : B a pour voisins choisis avant lui A et C, qui ne sont pas reliés. Le contrôle échoue, le carré n'est pas cordal, et une coloration obtenue dans cet ordre ne serait qu'une majoration.

Bien programmé, LexBFS est en O(n+m)O(n + m), comme le glouton : sur un graphe cordal, une coloration optimale s'obtient donc en temps linéaire, alors que le problème est NP-complet sur un graphe quelconque. C'est la structure du graphe, et non la puissance de calcul, qui fait la différence.

Vérification rapideon peut se reprendre

1.Quatre bornes installées aux coins d'un hangar ne portent qu'à leurs deux voisines de coin : A et B, B et C, C et D, D et A. Ce graphe est-il cordal ?

2.Un graphe est parfait quand…

Ordonnancer : quand les couleurs sont des créneaux

L'ordonnancement

L'ordonnancement est un domaine de la recherche opérationnelle : organiser dans le temps l'exécution d'un ensemble de tâches, en tenant compte de contraintes de temps (durées, dates imposées, tâches qui doivent en précéder d'autres) et de contraintes de ressources (machines, personnes, matériel disponibles en quantité limitée). Il faut le plus souvent à la fois affecter les ressources aux tâches et ordonner leur exécution, pour optimiser un critère : la durée totale, le respect des échéances, l'usage des ressources.

Deux sortes de contraintes reviennent sans cesse, et elles ne donnent pas le même graphe.

  • L'incompatibilité : deux tâches ne peuvent pas avoir lieu en même temps. La relation est symétrique : ce sont des arêtes, et choisir les créneaux revient à colorier, une couleur par créneau.
  • La précédence : une tâche doit être finie avant qu'une autre commence. La relation a un sens : ce sont des arcs, et le graphe est orienté.

Sur le réseau du chapitre, la première sorte se rencontre à la maintenance. Chaque borne doit être arrêtée une demi-journée pour sa révision, et deux bornes à portée l'une de l'autre ne peuvent pas l'être ensemble : la zone qu'elles se partagent ne serait plus couverte. Combien de demi-journées faut-il au minimum ? C'est le même graphe, et la même réponse : χ=3\chi = 3. La coloration de la figure donne le planning, A, F et G la première demi-journée, B, D et H la deuxième, C et E la troisième, et le triangle A, B, C prouve qu'on ne peut pas faire en deux.

La seconde sorte se rencontre à l'installation d'une nouvelle borne.

Graphe orienté6 sommets, 5 arcs
CommanderPoserTirerFixerConfigurerTester
CommanderPoserTirerFixerConfigurerTester
L'installation d'une borne : commander la borne, tirer le câble, fixer le support, poser, configurer, tester. Un arc va de la tâche qui doit être finie vers celle qui l'attend.

Un tel graphe se lit autrement qu'un graphe de conflits. La durée minimale du chantier est la longueur du plus long chemin, en additionnant les durées : c'est le chemin critique de la méthode PERT, que le chapitre sur les graphes orientés calcule avec les dates au plus tôt et au plus tard. Et un circuit y signale une erreur de planification : si « tester » devait aussi précéder « tirer », aucune tâche du circuit ne pourrait commencer la première.

Les grandes familles de problèmes d'ordonnancement.

  • La gestion de projet : des tâches liées par des précédences, et une date de fin à rendre la plus proche possible (méthode PERT, chemin critique).
  • Les problèmes d'atelier, où des pièces passent sur plusieurs machines. Dans un flow-shop, toutes les pièces suivent la même séquence de machines ; dans un job-shop, chaque pièce a sa propre séquence, imposée ; dans un open-shop, l'ordre de passage sur les machines est libre.
  • L'ordonnancement des processus d'un système d'exploitation : un processeur, ressource unique, partagé entre les programmes qui veulent s'exécuter. Voir le chapitre sur le multitâche.

Avant de colorier, se demander si les contraintes sont des incompatibilités ou des précédences : un planning de chantier où « les fondations avant les murs » se traduit par des arcs, pas par des couleurs.

Ce que le réseau décide

Les deux questions du début ont maintenant leur réponse.

Un message du poste de garde atteint toute borne en trois relais au plus, et H, la plus lointaine, exige bien ces trois relais : le parcours en largeur l'a montré par vagues. Deux pannes seulement coupent le réseau, celle de E, qui isole G et H, et celle de G, qui isole H. Ce sont les deux bornes à doubler, si la couverture doit résister à une panne.

Trois canaux suffisent, et il en faut trois. A, F et G sur le premier, B, D et H sur le deuxième, C et E sur le troisième : aucune paire à portée ne partage un canal. Et le triangle A, B, C prouve qu'on ne pourrait pas faire avec deux. Le réseau étant cordal, LexBFS et le glouton auraient trouvé ce minimum seuls, sans essai ; et le même raisonnement donne, sans rien changer, le planning de maintenance en trois demi-journées.

La méthode

  1. Dire ce que sont les sommets et ce que sont les liens, en français, avant tout dessin : « un sommet = une borne ; une arête = deux bornes à portée ».
  2. Décider orienté ou non en testant si la relation est symétrique.
  3. Choisir l'écriture selon la densité : liste d'adjacence pour un graphe creux, matrice pour un graphe dense.
  4. Vérifier le lemme des poignées de main : la somme des degrés doit valoir 2m2m.
  5. Pour des distances en nombre de liens, un parcours en largeur ; pour les morceaux du graphe, n'importe quel parcours, souvent en profondeur ; pour des liens pondérés, Dijkstra.
  6. Pour colorier, chercher d'abord une clique : elle donne la borne inférieure, et souvent la réponse.
  7. Encadrer χ\chi : une clique de taille kk puis une coloration à kk couleurs. Les deux, sinon rien n'est prouvé.
  8. Regarder la structure : un graphe cordal se colore de façon optimale dans l'ordre de LexBFS, un graphe biparti en deux couleurs ; sinon, le glouton ne donne qu'une majoration.

Mettre en pratique

Rappel de cours : poignées de main, place en mémoire, familles

La somme des degrés vaut 2m2m, elle est donc toujours paire. Une matrice d'adjacence a n2n^2 cases ; une liste d'adjacence range 2m2m identifiants de voisins. Un graphe cordal a tous ses cycles de quatre sommets ou plus munis d'une corde ; un graphe parfait vérifie χ=ω\chi = \omega sur chacun de ses sous-graphes induits.

Exemple résolu. Quatre sommets de degré 2 donnent une somme de 8, donc 4 arêtes : c'est le carré. Pour 1 000 sommets ayant chacun 10 voisins, la matrice a 10610^6 cases, la liste 10410^4 identifiants, cent fois moins.

Un graphe a 6 sommets de degré 3. Combien d'arêtes ? Un graphe à 5 sommets de degré 3 existe-t-il ?

Par le lemme des poignées de main, 6×3=18=2m6 \times 3 = 18 = 2m, donc m=9m = 9.

Pour 5 sommets de degré 3 : 5×3=155 \times 3 = 15, qui devrait valoir 2m2m, or 15 est impair. Un tel graphe n'existe pas.

Quelle structure de données pour un réseau social de 10⁹ utilisateurs ayant chacun environ 200 amis ?

La liste d'adjacence, sans hésitation.

La matrice demanderait (109)2=1018(10^9)^2 = 10^{18} cases, soit 125 pétaoctets même à un bit par case : matériellement impossible.

La liste stocke m=109×200/2=1011m = 10^9 \times 200 / 2 = 10^{11} arêtes, chacune chez ses deux extrémités, soit 2×10112 \times 10^{11} identifiants ; à 8 octets l'identifiant, 1,6 téraoctet : grand, mais réel. Le graphe est extrêmement creux, comme tous les grands graphes réels.

Des bornes forment un arbre : un réseau connexe, sans aucun cycle. Combien de canaux faut-il ?

Deux, dès qu'il y a au moins une arête. Un arbre n'a aucun cycle, donc aucun cycle impair : il est biparti. Partir d'une borne quelconque et alterner les canaux selon la parité de la distance à cette borne ne crée jamais de conflit, puisque deux bornes voisines sont à des distances qui diffèrent d'exactement 1.

C'est aussi un graphe cordal : il n'a aucun cycle, donc aucun cycle sans corde. Et en effet χ=ω=2\chi = \omega = 2.

Cinq bornes en anneau, chacune à portée de ses deux voisines et d'aucune autre. Ce graphe est-il cordal ? parfait ?

Ni l'un ni l'autre. C'est un cycle de cinq sommets sans aucune corde : il n'est pas cordal.

Il n'a pas de triangle, donc ω=2\omega = 2, mais c'est un cycle impair, donc χ=3\chi = 3. Le graphe lui-même est l'un de ses sous-graphes induits, et l'égalité χ=ω\chi = \omega y échoue : il n'est pas parfait. C'est le plus petit graphe qui ne le soit pas.

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

Dans la bibliothèque d'exercices