§2. Graphes A. Définitions DÉFINITION 2.1 (Graphe orienté). — C

§2. Graphes
A. Définitions
DÉFINITION 2.1 (Graphe orienté). C’est la donnée d’un ensemble V de sommets (an-
glais : vertex, vertices), d’un ensemble E d’arêtes orientées (anglais : edges) et de deux
applications origine et terme de E dans V .
Il peut y avoir une arête d’un sommet vers lui-même, plusieurs arêtes entre deux
sommets, une arête d’un sommet uvers un sommet vet une arête du sommet vvers
le sommet u.
Dessin.
Cas simple : il y a au plus une arête d’un sommet vers un autre ; alors, on peut iden-
tifier une arête au couple de sommets (source, but) ; Eest alors une partie de E×E.
Cette structure combinatoire modélise de nombreux phénomènes : réseau ferro-
viaire (les sommets sont les gares, les arêtes les lignes de train) ; jeux symétriques (les
sommets sont les positions possibles, les arêtes représentent les mouvements permis
d’une position à une autre) ; ordonnancement d’une liste de tâches (les sommets sont
les tâches, les arêtes représentent la priorité d’une tâche sur une autre).
DÉFINITION 2.2 (Graphe non-orienté). C’est un graphe orienté dont on néglige le
sens des flèches. qu’on peut parcourir dans les deux sens.
Quand il n’y a au plus une arête entre deux sommets, on peut définir un graphe non
orienté en disant que l’ensemble d’arêtes non orientées est une partie de l’ensemble
des parties de cardinal 1 ou 2 de V.
Pour des raisons compliquées à expliquer ici, la définition mathématique générale
est un peu subtile. Elle définit un graphe non orienté comme la donnée d’un graphe
orienté (V,E) et d’une involution e7→ ¯
esans point fixe sur l’ensemble des arêtes qui
échange source et but. Autrement dit, on double toutes les arêtes en en renversant le
sens. Une arête est un couple d’arêtes {e,¯
e}. Une orientation d’un graphe non-orienté
(V,E,¯·) est un graphe orienté (V,E0) où E0est une partie de Etelle que E0¯
E0=et
E0¯
E0=E; autrement dit, le choix pour chaque arête d’une des deux arêtes orientées
correspondantes.
On peut aussi pondérer les graphes et se donner une fonction w:ER(anglais :
weight). Cette fonction peut représenter la longueur de l’arête, le coût du transport le
long de cette arête, sa résistance,...
B. Représentations
Comment représenter un graphe ? On le suppose fini, càd que Vet Esont des en-
sembles finis. Le plus souvent, Vet Esont identifiés à des ensembles d’entiers entre
1 et |V|, et 1 et |E|(on pourrait commencer à 0, plein de variantes sont possibles...).
On rappelle que coder un entier 6nrequiert en gros logncases mémoire ; si |V|est
inférieur à un mot mémoire, négliger les logarithmes et les remplacer par 1.
1
2
a) brutalement : on se donne les applications source et but de [1,|E|] dans [1,|V|] ;
Taille : 2|E|log|V|.
b) liste d’adjacence : pour chaque sommet, on fait la liste des arêtes issues de ce
sommet, et le sommet but. La taille de cette représentation est |E|log|E| + |V|; dans le
cas où il n’y a au plus qu’une arête d’un sommet vers u autre, on a plutôt |V|+|E|log|V|.
c) matrice d’adjacence : on donne la matrice carrée de taille |V|dont le terme (i,j)
est 1 s’il y a une arête de ivers jet 0 sinon. Taille : |V|2;
d) matrice d’incidence : matrice rectangulaire de taille |V| × |E|, dont le terme (v,e)
est 1 si l’arête eest de but v,1 si elle est de source v, et 0 sinon (on suppose qu’il n’y
a pas d’arête d’un sommet vers lui-même).
Ces diverses représentations ont toutes leur intérêt (sauf peut-être la première). Pro-
grammer le passage de l’une à l’autre. Pour chacune de ces représentations, program-
mer les fonctions suivantes :
nombre d’arêtes issues d’un sommet donné ;
nombre d’arêtes de terme un sommet donné ;
nombre d’arêtes du graphe ;
y a-t-il une arête entre deux sommets donnés ?
La valence (sortante) d’un sommet est le nombre d’arêtes issues de ce sommet ; la
valence (entrante) est le nombre d’arêtes de terme ce sommet ; la valence tout court
est la somme des deux valences entrante et sortante.
La matrice d’incidence d’un graphe non orienté est symétrique.
Un chemin reliant un sommet uà un sommet vdans un graphe est une suite d’arêtes
(e1,...,em) telles que o(e1)=u,t(e1)=o(e2), etc., t(em)=v; on dit qu’il est de lon-
gueur m. On dit qu’il est simple si les sommets o(e1),...,o(em) sont tous distincts ; que
c’est un cycle si u=v.
Si Aest la matrice d’incidence d’un graphe, le terme d’indice (u,v) de la matrice Am
est le nombre de chemins de longueur md’origine uet de terme v.
C. Connexité
Soit G=(V,E) un graphe orienté. On introduit la relation d’équivalence dans l’en-
semble des sommets engendrée par uvs’il existe une arête d’origine uet de terme v.
Les classes d’équivalences sont appelées les composantes connexes du graphe. On dit
que le graphe est connexe s’il a au plus une composante connexe.
Dans ce contexte, il est plus simple de supposer Gnon orienté. Alors, deux sommets
sont dans la même composante connexe si et seulement s’ils sont reliés par un chemin.
Les deux algorithmes (BFS et DFS) ci-dessous parcourent un graphe orienté Get
déterminent l’ensemble des sommets accessibles depuis un sommet donné. Dans ces
algorithmes, seul compte l’existence pour tout couple (u,v) de sommets de Gd’une
arête d’origine uet de terme v. On identifiera ainsi les arêtes au couple formé de leur
origine et de leur terme.
§2. GRAPHES 3
Algorithme BFS (anglais : breadth-first search ; recherche en largeur).
On se donne un sommet ud’un graphe orienté. On va construire la fonction d:V
N{} telle que d(v) est la longueur du plus petit chemin de uàv. On initialise la
fonction dàd0(u)=0 et d0(v)= ∞ si v6= u; on pose m=0.
Récurrence mm+1. Pour chaque sommet v, on définit dm+1comme suit :
si dm(v)6m, on pose dm+1(v)=m;
si dm(v)= +∞ et qu’il existe une arête ereliant và un sommet v0tel que
dm(v0)6= +∞, on a nécessairement dm(v0)=met on pose dm+1(v)=m+1.
sinon, on pose dm+1(v)= +∞.
Au bout d’un nombre fini d’étapes, dm=dm+1(le graphe est fini et si dm(v)6= dm+1(v),
alors dn(v)= ∞ pour n6m, et dn(v)=dm+1(v) pour n>m+1). On pose d=dm.
Alors, les sommets accessibles depuis usont les sommets vtels que d(v)6= ∞.
Si le graphe est représenté par une liste d’adjacence, l’étape cruciale consistant à
modifier dmcompte tenu des sommets tels que dm(v)=mest assez facile à effectuer.
Pour ne pas reparcourir la liste des sommets à chaque étape, il est commode de
conserver de l’étape m1 la liste des sommets vtels que dm(v)=m: pour chacun de
ces sommets, on étudie la liste des arêtes issues de v; ceux, v0, pour lesquels dm(v0)=
sont stockés dans la liste de l’étape met on pose dm+1(v0)=m+1.
L’algorithme construit un arbre de racine udont les sommets sont les sommets ac-
cessibles depuis u, et dont les fils d’un sommet vsont ceux pour lesquels le plus court
chemin depuis upasse par và l’avant-dernier pas.
Complexité. De chaque sommet, on explore le graphe depuis toutes les arêtes qui en
sortent ; si le graphe est codé par sa liste d’adjacence, la complexité est alors O(|V|+|E|).
S’il était représenté par sa matrice d’adjacence, elle serait pire O(|V|2).
Algorithme DFS (anglais : depth-first search, recherche en profondeur).
On part d’un sommet u, on va le plus loin possible sans revenir sur un sommet déjà
visité. Quand on ne peut plus, on remonte d’une étape et on recommence. On garde
en mémoire, pour chaque sommet visité, son prédécesseur.
L’algorithme suppose que l’ensemble des arêtes issues d’un sommet est ordonné.
Il parcourt tout le graphe à la manière de Thésée faisant une « main gauche » dans le
labyrinthe de Minos.
On initialise m=0, d0(v)=f0(v)= ∞ si v6= u;d0(u)=f0(u)=0 ; π0(v)= ∞ pour
tout v;u0=u.
Les fonctions det findiquent le temps auquel l’algorithme visite pour la première
et la dernière fois un sommet. La fonction πcontient le prédécesseur d’un sommet v
c’est-à-dire le sommet par lequel l’algorithme est arrivé en vpour la première fois.
Étape m. S’il en existe, on considère la première arête ede Gissue de umtelle que
dm(t(e)) = ∞ (le terme de eest un sommet pas encore visité) ; on pose alors dm+1(v)=
dm(v) et πm+1(v)=πm(v) si v6= t(e), dm+1(t(e)) =m+1, πm+1(t(e)) =um,fm+1=fm, et
um+1=t(e). S’il n’y a pas de telle arête, il y a deux cas. Si πm(um)6= ∞, on pose dm+1=
dm,πm+1=πm,fm+1(v)=fm(v) pour v6= um,fm+1(um)=m+1 et um+1=πm(um) (le
prédécesseur de um). Si πm(um)= ∞, on prend pour um+1le premier sommet utel que
4
dm(u)= ; on pose dm+1(v)=dm(v) pour v6= um+1,dm+1(um+1)=m+1, fm+1=fm.
S’il n’existe pas de tel sommet, l’algorithme s’arrête.
Quand l’algorithme est achevé, on pose alors π=πm+1,d=dm+1,f=fm+1.
Notons que les sommets accessibles depuis le sommet initial usont ceux que l’on
visite jusqu’au moment mtel que um=uet où on calcule πm(u)= ; si c’est tout ce
dont on a besoin, on peut arrêter l’algorithme là.
L’algorithme construit un arbre de recherche (en fait, une forêt), codé via la fonction
prédécesseur. On définit par récurrence qu’un sommet uest un ancêtre d’un sommet v
si u=vou si va un prédécesseur dont uest un ancêtre.
LEMME 2.3. — Si u est un ancêtre de v, l’intervalle [d(u), f(u)] contient l’intervalle
[d(v), f(v)] ; Si v est un ancêtre de u,... Sinon, les intervalles [d(u), f(u)] et [d(v), f(v)]
sont disjoints.
Démonstration. Dans l’algorithme, si on a atteint un sommet ven suivant une arête, on ne
peut y revenir qu’en remontant une arête déjà descendue. Ainsi, si on va de uvers v, on ne peut
le faire qu’une fois : on ne peut revenir à uqu’une fois avoir terminé d’explorer les arêtes issues
de v.
LEMME 2.4. Pour quun graphe orienté soit acyclique, il faut et il suffit qu’il n’existe
pas d’arête (u,v)telle que v soit un ancêtre de u.
Démonstration. Si vest un ancêtre de u, il y a un chemin de vàu. S’il existe une arête de u
àv, le graphe possède donc un cycle. Inversement, considérons un cycle (v1,v2,...,vn,v1) dont
v1soit le premier sommet visité par l’algorithme. Alors, v1est le prédécesseur de v2, etc., donc
v1est un ancêtre de vnet il existe une arête (vn,v1).
LEMME 2.5. — Soit G un graphe orienté ; soit (u0,u1,...,un)un chemin dans G. Si
d(u0)<d(ui)pour tout i {1,...,n}, alors u0est un ancêtre de un.
Remarquons que l’hypothèse signifie que lorsque le sommet u0est découvert, les
autres sommets du chemin sont encore vierges.
Démonstration. Raisonnons par l’absurde en supposant que u0n’est pas un ancêtre de un
et soit mle plus petit entier de {1,...,n} tel que umne soit pas un descendant de u0. On a
d(u0)6d(um1)<f(um1)<f(u0). Comme il y a une arête de um1vers um,umest décou-
vert avant que um1soit terminé : d(u0)<d(um)<f(um1). D’après le lemme 1.3, l’intervalle
[d(um), f(um)] est contenu dans l’intervalle [d(u0), f(u0)] (ils ne sont pas disjoints, donc l’un
est inclus dans l’autre, et la seule inclusion possible est celle-ci), donc u0est un ancêtre de um,
contradiction.
Complexité. De chaque sommet, on explore récursivement toutes les arêtes sor-
tantes. La complexité est donc O(|V| + |E|) lorsque le graphe est représenté par sa liste
d’adjacence.
Multiplication matricielle.
Soit Ala matrice d’adjacence d’un graphe (orienté ou non). On remarque que la ma-
trice Ama pour terme (u,v) le nombre de chemins de longueur exactement mqui sont
d’origine uet de terme v. La matrice (I+A)ma pour terme d’indice (u,v) le nombre de
§2. GRAPHES 5
chemins de longueur au plus m; rajouter la matrice identité Isignifie qu’on rajoute au
graphe des boucles de longueur 1 qu’on ne compte pas.
Par ailleurs, s’il y a un chemin de uvers v, il y en a un de longueur 6|V| 1. Il suffit
donc de calculer (I+A)|V|. Par exponentiation rapide, on doit faire log|V|multiplica-
tions de matrices de taille |V|, soit une complexité O(|V|3log|V|), voire O(|V|αlog|V|),
avec αl’exposant de la complexité de la multiplication matricielle (Strassen).
S’il y a beaucoup de chemins, les coefficients des matrices (I+A)mexplosent rapi-
dement On peut simplifier les calculs en ne retenant que la possibilité d’un chemin
de longueur au plus m. Cela revient à remplacer l’addition par la fonction max et à
calculer ce « produit » dans l’espèce d’anneau {0,1} où l’addition est donnée par la
fonction max (la fonction logique OU inclusif) et la multiplication par le produit (la
fonction logique ET). De la sorte, la taille des coefficients des matrices calculées est
constante.
D. Tri topologique
Imaginons un ensemble de tâches à effectuer et une relation binaire entre ces tâches
qui précise de deux tâches laquelle doit être effectuée avant l’autre.
Par exemple, les tâches peuvent être la liste des habits à enfiler (slip, chaussettes,
pantalon, chaussures, chemise, ceinture, pantalon, cravate, veste, manteau, montre,
lunettes) et la relation prescrit qu’on met ses chaussettes avant ses chaussures, etc.
Le problème du tri topologique consiste à déterminer un ordre complet dans lequel
effectuer toutes ces tâches.
Il y a une condition nécessaire évidente pour que ce problème soit résoluble : qu’il
n’existe pas une suite de tâches t1,..., tntelles que tidoit être effectuée avant ti+1pour
i{1,...,n1} et tndoit être effectuée avant t1.
Ces données conduisent naturellement à un graphe orienté dont les sommets sont
les tâches et les arêtes sont les couples (t,t0) de tâches distinctes telles que tdoit être
faite avant t0. La condition nécessaire de faisabilité est l’absence de cycle dans ce
graphe.
Si l’on effectue un DFS complet sur ce graphe, à partir d’un sommet arbitraire, on
obtient le tri voulu : les tâches peuvent en effet être effectuées dans l’ordre inverse du
dernier temps de visite f(v) des sommets. Prouvons ce fait. Considérons deux som-
mets uet vtels qu’il y a une arête de uvers vet démontrons que f(u)>f(v). Trois cas
sont a priori possibles :
– si uest un ancêtre de v, alors [d(u), f(u)] contient [d(v), f(v)] d’après le
lemme 1.3 ; en particulier, f(u)>f(v).
si vest un ancêtre de v, le graphe est acyclique en vertu du lemme 1.4.
enfin, si ni uni vn’est un ancêtre de v, les intervalles [d(u), f(u)] et [d(v), f(v)]
sont disjoints ; comme il y a une arête de uvers v, si uétait découvert avant v,u
serait un ancêtre de v, contradiction. Donc uest découvert après v, donc d(v)6
f(v)<d(u)6f(v), cqfd.
E. Composantes fortement connexes
On considère encore un graphe orienté G.
1 / 9 100%
La catégorie de ce document est-elle correcte?
Merci pour votre participation!

Faire une suggestion

Avez-vous trouvé des erreurs dans linterface ou les textes ? Ou savez-vous comment améliorer linterface utilisateur de StudyLib ? Nhésitez pas à envoyer vos suggestions. Cest très important pour nous !