Contenus
Capacités attendues
Commentaires
Contenus
Capacités attendues
Commentaires
Un graphe simple est un couple comprenant
Une arête est un couple de sommets.

Lorsque les arêtes ont une direction (flèche), elles sont orientées
Une arête orientée ne se parcourt que dans le sens de la flèche. Dans ce cas on note généralement les arêtes avec des parenthèses pour désigner des couples.
Si c’est un réseau de transport, on peut se rendre de 1 vers 2, mais pas dans l’autre sens (sens interdit)

Toutes les arêtes ne sont pas équivalentes (type de route par exemple)
On attribue un poids (weight) aux arêtes.

Lors qu’il y a un arc d’un sommet s à un sommet t, on dit que t est adjacent à s. Le voisinage d’un sommet est l’ensemble de ses sommets adjacents.
Dans un graphe non orienté, si il y a un chemin de u vers v, il y a aussi un chemin de v vers u, mais ce n’est pas forcément le cas dans un graphe orienté.
Donner le voisinage de chacun des sommets du graphe orienté ci-dessous.

Dans un graphe donné, un chemin reliant un sommet u à un sommet v est une séquence finie de sommets reliés deux à deux par des arcs et menant de u à v
Donnez 3 chemins reliant 1 à 4 dans le graphe ci-dessous. Y a t’il un chemin entre 5 et 1 ?

Un chemin est dit simple si il n’emprunte pas deux fois le même arc, et élémentaire si il ne passe pas deux fois par le même sommet.
Un chemin simple reliant un sommet à lui-même et contenant au moins un arc est appelé un cycle.
Dans le graphe suivant :

La longueur d’un chemin est définie comme le nombre d’arcs qui constituent ce chemin. La distance entre deux sommets est la longueur du plus court chemin reliant ces deux sommets. Si aucun chemin n’existe entre deux sommets, la distance n’est pas définie.
La distance d’un sommet à lui-même vaut zéro. Dans un graphe non orienté, la distance d’un sommet u vers un sommet v est la même que la distance entre v et u. Ce n’est pas forcément le cas dans un graphe orienté.
Dans le graphe ci-dessous, donnez la distance entre :

On dit qu’un graphe non orienté est connexe si, pour toute paire u,v de sommets, il existe un chemin de u à v.
Pour un graphe orienté, on dit qu’il est connexe si le graphe non orienté obtenu en oubliant le sens des flèches est connexe. On dit qu’il est fortement connexe si il existe un chemin de u vers v sans oublier le sense des flèches.
Graphe non orienté non connexe, graphe orienté fortement connexe, graphe orienté connexe.

L’idée du parcours en profondeur est basée sur le principe suivant, appliquable par exemple à la recherche de la sortie dans un labyrinthe :
Il y a beaucoup de manières de représenter un graphe; la seule chose
dont on ait besoin pour le parcours en profondeur, c’est de pouvoir
trouver tous les voisins d’un noeud donné (ce qui est indiqué
voisins_de_s dans le code ci-après
def parcours(graphe, vus, sommet):
""" Parcours en profondeur du graphe depuis le sommet s
:param graphe: graphe
:param vus: liste des sommets déjà vus
:param s: sommet de départ
"""
if s not in vus:
vus.append(s)
for v in voisins_de_s:
parcours(graphe, vus, v)Comment peut-on s’assurer que le parcours s’arrêtera un jour ?
Pour un graphe avec N sommets, quel est le coût du parcours en profondeur ?
Effectuer à la main toutes les étapes du parcours en profondeur de l’arbre suivant

0,1,0,1,0,0
0,0,0,0,0,1
1,0,0,1,0,1
0,0,1,0,0,0
0,1,0,1,0,1
1,0,1,0,1,0
voisin_de(graphe, s) qui utilise la
matrice d’adjacence pour renvoyer tous les voisins u somme sVous pouvez vérifier vos résultats sur https://graphonline.ru/fr/
Si un graphe comporte trop de sommets, on peut dépasser la profondeur de récursion maximale (environ 1000 ou 2000 en python)
Comme pour les arbres, on peut aussi faire un parcours en profondeur en utilisant une pile.
def parcours(graphe, vus, s):
pile = Pile()
pile.empile(s)
while not pile.est_vide():
s = pile.depile()
if s in vus:
continue
vus.append(s)
for v in voisins_de_s:
pile.empile(v)Un utilisant la classe Pile réalisée plus tôt dans
l’année, implémentez le parcours de l’arbre de l’exercice précédent.
Le parcours en profondeur permet de détecter la présence d’un cycle dans un graphe orienté. En effet, quand on tombe sur un sommet déjà visité, il peut s’agir d’un cycle.

Dans le premier graphe, le parcours fait d’abord 1 2 3
puis 1 4 et détecte qu’il est déjà passé sur 3, mais ce
n’est pas un cycle.
Dans le deuxième graphe, le parcours fait 1 2 3 4 puis
détecte qu’il est déjà passé par 2; et dans ce cas c’est un cycle
Pour savoir si un noeud déjà atteint est marqué à cause d’un parcours multiple ou d’un cycle, on va “colorier” les noeuds avec différentes couleurs :
Ceci permet de savoir si un noeud déjà rencontré est dû à un cycle ou bien à un chemin multiple :
Coloriez et détectez les cycles dans les graphes suivants

On a besoin de la liste des sommets du graphe
sommets_du_graphe et des voisins de chaque sommet (comme
précédemment).
On utilise un dictionnaire avec comme clef chaque sommet et comme valeur la couleur de chaque sommet.
BLANC, GRIS, NOIR = 1, 2, 3
def parcours_cycle(graphe, couleurs, s):
# Détection de cycle ou chemin multiple
if couleurs[s] == GRIS:
return True
if couleurs[s] == NOIR:
return False # Sommet nouveau, on le colorie en gris
couleur[s] = GRIS
# On parcourt ses voisins (et on quitte si on a trouvé un cycle)
for v in voisins_de_s:
if parcours_cycle(graphe, couleurs, v):
return True
# On a fini toute l'exploration de ce sommet => colorié en noir
couleurs[s] = NOIR
return Falsedef cycle(graphe):
# On prépare la peinture
couleur = {}
for s in sommets_du_graphe:
couleur[s] = BLANC # On teste l'existence de cycle pour tous les sommets
for s in sommets_du_graphe:
if parcours_cycle(graphe, couleur, s):
return True
return FalseComment peut-on s’assurer que la recherche de cycle s’arrêtera un jour ?
Pour un graphe avec N sommets, quel est le coût de la recherche de cycle ?
Implémenter et lancer la recherche de cycle sur les 3 exemples de graphes de l’exercice précédent.
On a souvent besoin de chercher le chemin le plus “court” entre deux sommets d’un graphe :
Pour des graphes avec des poids positifs, on utilise fréquemment l’algorithme de Dijkstra (parcours en largeur)
https://fr.wikipedia.org/wiki/Algorithme_de_Dijkstra