efrei/theorie-graphes/main.tex

1378 lines
58 KiB
TeX

\documentclass[a4paper,french,12pt]{article}
\title{Théorie des graphes}
\author{}
\date{Dernière compilation~: \today{} à \currenttime}
\usepackage{styles}
\begin{document}
\maketitle
\tableofcontents
\clearpage
\section{Définitions}
Un graphe est un ensemble de sommets qui possèdent des relations.
Quand les relations sont symétriques, le graphe est \emph{non orienté}.
Les relations sont alors appelées des \emph{arrêtes}.
L'arrête $(x,y)$ est équivalente à l'arrête $(y,x)$.
Quand les relations sont non symétriques, la relation dépend d'une direction.
Le graphe est alors \emph{orienté} et les relations s'appelent des \emph{arcs}.
Un graphe peut contenir des arcs et des arrêtes, mais on dira quand même qu'il est soit \emph{orienté} soit \emph{non orienté}.
Dès qu'il existe des relations non symétriques, donc des arcs, on parle donc de graphe orienté.
On peut ajouter une valeur aux relations (par exemple pour le calcul d'un temps de trajet, ou un coût pour le calcul d'une route OSPF).
On parle alors de graphe \emph{valué}.
S'il n'y pas de valeur associée aux relations, le graphe est \emph{non valué}.
\subsection{Matrice d'un graphe orienté}
\begin{multicols}{2}
On peut passer d'une représentation graphique à un tableau~: \\\\
\begin{tabularx}{\linewidth}{YYYYY}
& A & B & C & D \\
A & 0 & 1 & 1 & 1 \\
B & 0 & 0 & 0 & 0 \\
C & 0 & 1 & 0 & 1 \\
D & 0 & 1 & 0 & 0 \\
\end{tabularx}
\begin{center}
\begin{tikzpicture}[-latex,auto,x=2cm,y=2cm]
\node(a)[state] at (0,0) {A};
\node(b)[state] at (2,0) {B};
\node(c)[state] at (2,-2) {C};
\node(d)[state] at (0,-2) {D};
\path
(a) edge (b)
(a) edge (c)
(a) edge (d)
(c) edge (b)
(c) edge (d)
(d) edge (b)
;
\end{tikzpicture}
\end{center}
\end{multicols}
\subsection{Types de graphes}
\subsubsection{Graphe Eulerien}
\begin{itemize}
\item Il existe un cycle passant par toutes les arrêtes.
\item Le degré de tous les sommets est \emph{pair}.
\end{itemize}
\subsubsection{Graphe semi-Eulerien}
\begin{itemize}
\item Il existe un chemin avec un départ et une arrivée différents, tel que l'on passe par toutes les arrêtes.
\item Seuls deux sommets sont de degrés \emph{impairs}.
Ce sont le départ et l'arrivée.
Les autres sommets sont de degré \emph{pair}.
\end{itemize}
\subsection{Fonction $\Gamma$}
\subsubsection{Extrémité, prédécesseur, successeur}
Soit $G=(S,A)$ un graphe.
Soient $x$ et $y$ deux sommets de $S$.
$a=(x,y)$ (arrête ou arc) étant un élément de l'ensemble $A$, $x$ et $y$ sont alors des \emph{extrémités} de $a$.
Si $a$ est un arc (donc orienté) allant de $x$ à $y$, alors $x$ est le \emph{prédécesseur} de $y$ et $y$ est le \emph{successeur} de $x$.
\subsubsection{Prédécesseurs et successeurs directs}
$\Gamma^{-1}(x)$ désigne l'ensemble des prédécesseurs de $x$. \\
$\Gamma^{+1}(x)$ désigne l'ensemble des successeurs de $x$.
\subsubsection{Prédécesseurs et successeurs indirects}
$\Gamma^{-n}(x)$ désigne l'ensemble des prédécesseurs de niveau $n$ de $x$. \\
$\Gamma^{+n}(x)$ désigne l'ensemble des successeurs de niveau $n$ de $x$.
On peut définir $\Gamma^{-n}(x)$ comme étant l'ensemble des prédécesseurs des $\Gamma^{-n+1}(x)$. \\
On peut définir $\Gamma^{+n}(x)$ comme étant l'ensemble des successeurs des $\Gamma^{+n-1}(x)$.
\subsubsection{Prédécesseurs et successeurs directs et/ou indirects}
Les ensembles des prédécesseurs et successeurs de $x$ de niveau quelconque sont notés respectivement $\Gamma^{-*}(x)$ et $\Gamma^{+*}(x)$.
On peut les calculer avec une somme infinie~:
\begin{equation*}
\Gamma^{+*}(x) = \Gamma^{+1}(x) \cup \Gamma^{+2}(x) \cup \Gamma^{+2}(x) \cup \cdots \cup \Gamma^{+n}(x)
\end{equation*}
Cette somme n'est pas infinie dans la mesure où le nombre de sommets est fini.
Quand on compte les prédécesseurs ou les successeurs, à chaque étape ajoutant aux ensembles précédents, au bout d'un moment on va trouver quelque chose de stable.
\subsection{Connexité}
Si pour tout $x$ et tout $y$ d'un graphe il existe un chemin allant de $x$ à $y$, le graphe est dit connexe.
Si le graphe est orienté, il est alors \emph{fortement connexe}.
\subsection{Incidence}
\begin{center}
\begin{tikzpicture}
\node(x)[state] at (0,0) {x};
\node(y)[state] at (2,0) {y};
\path [->] (x) edge (y);
\end{tikzpicture}
\end{center}
L'arc est incident de $x$ vers l'extérieur (parce qu'il sort de $x$) et de $y$ vers l'intérieur (parce qu'il entre dans $y$).
\subsection{Degré d'un sommet}
Le degré intérieur $d\text{°}^-(x)$ d'un sommet $x$ est le total d'incidents de $x$ vers l'intérieur. \\
Le degré extérieur $d\text{°}^+(x)$ d'un sommet $x$ est le total d'incidents de $x$ vers l'extérieur.
Le degré $d\text{°}(x)$ d'un sommet $x$ est la somme de $d\text{°}^-(x)$ et de $d\text{°}^+(x)$.
\subsection{Point d'entrée}
Un point d'entrée n'a pas de prédécesseur ($\Gamma^{-1}(x) = \emptyset$).
\subsection{Point de sortie}
Un point de sortie n'a pas de successeur ($\Gamma^{+1}(x) = \emptyset$).
\subsection{Point isolé}
Un point isolé est à la fois un point d'entrée et de sortie.
Il n'a pas de successeur ni de prédécesseur ($\Gamma^{-1}(x) \cup \Gamma^{+1}(x) = \emptyset$).
\subsection{Fermeture transitive}
Une fermeture transitive est un ``raccourci'' entre deux sommets.
Si un arc ou une arrête existe entre $x$ et $y$, la fermeture transitive de $x$ et $y$ est $(x,y)$.
\section{Représentation et algorithmes généraux}
On définit des matrices pour qu'une machine puisse avoir une représentation du graphe.
\subsection{Matrices d'adjacence et d'incidence}
\subsubsection{Matrice d'adjacence}
On code à 1 quand les sommets sont reliés.
\begin{center}
\begin{tabular}{cc|cccccc|c}
& & \multicolumn{6}{c}{sommets} & \\
& & A & B & C & D & E & F & $d^+$ \\
\hline
\multirow{6}{*}{sommets} & A & 0 & 1 & 1 & 0 & 0 & 0 & 2 \\
& B & 0 & 0 & 0 & 1 & 0 & 0 & \\
& C & 0 & 1 & 0 & 0 & 1 & 0 & \\
& D & 0 & 0 & 1 & 0 & 0 & 1 & \\
& E & 0 & 0 & 1 & 0 & 0 & 0 & \\
& F & 1 & 0 & 0 & 0 & 1 & 0 & \\
\hline
& $d^-$ & 1 & & & & & & \\
\end{tabular}
\end{center}
On peut ajouter le degré~: arcs entrants ($d^-$) ou arcs sortants ($d^+$).
\paragraph{Exemple}
\begin{multicols}{2}
Non orienté~:
\begin{tikzpicture}
\node (a)[state] at (0,0) {A};
\node (b)[state] at (2,0) {B};
\path
(a) edge [loop above] (a)
(a) edge (b)
;
\end{tikzpicture}
\begin{align*}
\begin{pmatrix}
1 & 1 \\
1 & 0 \\
\end{pmatrix}
\end{align*}
\columnbreak
Orienté~:
\begin{tikzpicture}[->]
\node (a)[state] at (0,0) {A};
\node (b)[state] at (2,0) {B};
\path
(a) edge [loop above] (a)
(a) edge (b)
;
\end{tikzpicture}
\begin{align*}
\begin{pmatrix}
1 & 1 \\
0 & 0 \\
\end{pmatrix}
\end{align*}
\end{multicols}
\subsubsection{Matrice d'incidence}
On note -1 pour une transition entrante et +1 pour une transition sortante.
Pour les boucles, on note 2.
\begin{center}
\begin{tabular}{cc|cccccc}
& & \multicolumn{6}{c}{nombre d'arcs} \\
& & 1 & 2 & 3 & 4 & 5 & 6 \\
\hline
\multirow{6}{*}{sommets} & A & -1 & 0 & 0 & 0 & 0 & 0 \\
& B & +1 & +1 & 0 & -1 & 0 & 0 \\
& C & 0 & 0 & 0 & 0 & 0 & 0 \\
& D & 0 & -1 & -1 & +1 & 0 & 0 \\
& E & 0 & 0 & 0 & 0 & 0 & 0 \\
& F & 0 & 0 & +1 & 0 & 0 & 2 \\
\end{tabular}
\end{center}
\subsection{Algorithmes généraux}
\subsubsection{Calcul de rang}
\paragraph{Méthode pour les humains}
Comme les humains peuvent avoir une vue globale sur tout le graphe d'un coup (pourvu que le nombre de sommets ne soit pas trop grand), il est possible d'identifier visuellement les sommets n'ayant aucun arc entrant.
L'algorithme consiste alors à retirer du graphe ces sommets, par itération.
À chaque itération, le rang augmente (le rang 0 étant le rang le plus fort).
\begin{multicols}{3}
\begin{center}
Graphe de départ~: \\
\begin{tikzpicture}[->,scale=0.6, transform shape]
\node (1) [state] at (0,0) {1};
\node (2) [state] at (-1,-8) {2};
\node (3) [state] at (-2,-5) {3};
\node (4) [state] at (1,-10) {4};
\node (5) [state] at (2,-1) {5};
\node (6) [state] at (-2,-1) {6};
\node (7) [state] at (1,-5) {7};
\node (8) [state] at (1,-8) {8};
\node (9) [state] at (-1,-3) {9};
\node (10) [state] at (2,-3) {10};
\node (11) [state] at (3,-7) {11};
\node (12) [state] at (4,-4) {12};
\path
(1) edge (5)
(2) edge (4)
(2) edge (7)
(2) edge (8)
(2) edge (12)
(3) edge (7)
(3) edge (10)
(3) edge (11)
(4) edge (8)
(4) edge (11)
(4) edge [bend right] (12)
(6) edge (1)
(6) edge (3)
(6) edge (10)
(7) edge (10)
(7) edge (12)
(8) edge (11)
(9) edge (5)
(9) edge (7)
(5) edge (12)
(10) edge (5)
(11) edge (12)
;
\end{tikzpicture}
\end{center}
\columnbreak
\begin{center}
Rang 0 (sommets 2--6--9)~: \\
\begin{tikzpicture}[->,scale=0.6, transform shape]
\node (1) [state] at (0,0) {1};
\node (3) [state] at (-2,-5) {3};
\node (4) [state] at (1,-10) {4};
\node (5) [state] at (2,-1) {5};
\node (7) [state] at (1,-5) {7};
\node (8) [state] at (1,-8) {8};
\node (10) [state] at (2,-3) {10};
\node (11) [state] at (3,-7) {11};
\node (12) [state] at (4,-4) {12};
\path
(1) edge (5)
(3) edge (7)
(3) edge (10)
(3) edge (11)
(4) edge (8)
(4) edge (11)
(4) edge [bend right] (12)
(7) edge (10)
(7) edge (12)
(8) edge (11)
(5) edge (12)
(10) edge (5)
(11) edge (12)
;
\end{tikzpicture}
\end{center}
\columnbreak
\begin{center}
Rang 1 (sommets 1--3--4)~: \\
\begin{tikzpicture}[->,scale=0.6, transform shape]
\node (5) [state] at (2,-1) {5};
\node (7) [state] at (1,-5) {7};
\node (8) [state] at (1,-8) {8};
\node (10) [state] at (2,-3) {10};
\node (11) [state] at (3,-7) {11};
\node (12) [state] at (4,-4) {12};
\path
(7) edge (10)
(7) edge (12)
(8) edge (11)
(5) edge (12)
(10) edge (5)
(11) edge (12)
;
\end{tikzpicture}
\end{center}
\end{multicols}
\begin{multicols}{3}
\begin{center}
Rang 2 (sommets 7--8)~: \\
\begin{tikzpicture}[->,scale=0.6, transform shape]
\node (5) [state] at (2,-1) {5};
\node (10) [state] at (2,-3) {10};
\node (11) [state] at (3,-7) {11};
\node (12) [state] at (4,-4) {12};
\path
(5) edge (12)
(10) edge (5)
(11) edge (12)
;
\end{tikzpicture}
\end{center}
\columnbreak
\begin{center}
Rang 3 (sommets 10--11)~: \\
\begin{tikzpicture}[->,scale=0.6, transform shape]
\node (5) [state] at (2,-1) {5};
\node (12) [state] at (4,-4) {12};
\path
(5) edge (12)
;
\end{tikzpicture}
\end{center}
\columnbreak
\begin{center}
Rang 4 (sommet 5)~: \\
\begin{tikzpicture}[->,scale=0.6, transform shape]
\node (12) [state] at (4,-4) {12};
\end{tikzpicture}
\end{center}
\end{multicols}
\ldots{} et donc le sommet 12 est de rang 5.
\paragraph{Méthode pour les ordinateurs}
Contrairement aux humains, un ordinateur ne comprend pas un graph.
Il a besoin d'une matrice d'adjacence.
Le graphe précédent donne la matrice suivante~:
\begin{center}
\begin{tabular}{c|cccccccccccc}
& 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 & 10 & 11 & 12 \\
\hline
1 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\
2 & 0 & 0 & 0 & 1 & 0 & 0 & 1 & 1 & 0 & 0 & 0 & 1 \\
3 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 1 & 1 & 0 \\
4 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 1 & 1 \\
5 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \\
6 & 1 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 \\
7 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 1 \\
8 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 \\
9 & 0 & 0 & 0 & 0 & 1 & 0 & 1 & 0 & 0 & 0 & 0 & 0 \\
10 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\
11 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \\
12 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\
\hline
$d^-$ & 1 & 0 & 1 & 1 & 3 & 0 & 3 & 2 & 0 & 3 & 3 & 5 \\
\end{tabular}
\end{center}
En calculant le $d^-$ à chaque étape, on peut trouver les sommets à enlever~: il s'agit de ceux pour lesquels le $d^-$ est égal à 0.
Il suffit alors d'enlever ces sommets de la matrice et de recommencer.
La boucle s'arrête quand aucun $d^-$ est à 0, ou au maximum après $n$ fois (avec $n$ étant le nombre de sommets).
\subsubsection{Détection de cycle (algorithme de Rosalind-Marimond)}
L'algorithme de Rosalind-Marimond supprime les $d^-$ (connexions entrantes) et les $d^+$ (connexions sortantes) à chaque étape.
Ce qui reste à la fin est forcément un cycle, puisque tous les sommets ont à la fois des arcs entrants et sortants.
\subsubsection{Parcours en largeur}
On \emph{enfile} à chaque n\oe{}ud ses enfants directs.
\begin{minipage}{\linewidth}
\begin{multicols}{2}
\begin{tikzpicture}[scale=0.6, transform shape]
\node (a) [state] at (0,0) {a};
\node (b) [state] at (-2,-2) {b};
\node (c) [state] at (2,-2) {c};
\node (d) [state] at (-3,-4) {d};
\node (e) [state] at (-1,-4) {e};
\node (f) [state] at (1,-4) {f};
\node (g) [state] at (3,-4) {g};
\node (h) [state] at (-1,-6) {h};
\node (i) [state] at (3,-6) {i};
\node at (3, -7) {non visité};
\path
(a) edge (b)
(a) edge (c)
(b) edge (d)
(b) edge (e)
(c) edge (f)
(c) edge (g)
(e) edge (h)
;
\end{tikzpicture}
\begin{itemize}
\item a
\item bc
\item cde
\item defg
\item efg
\item fgh
\item gh
\item h
\end{itemize}
\end{multicols}
\end{minipage}
\subsubsection{Parcours en longueur}
On \emph{empile} à chaque n\oe{}ud ses enfants directs.
\begin{minipage}{\linewidth}
\begin{multicols}{2}
\begin{tikzpicture}[scale=0.6, transform shape]
\node (a) [state] at (0,0) {a};
\node (b) [state] at (-2,-2) {b};
\node (c) [state] at (2,-2) {c};
\node (d) [state] at (-3,-4) {d};
\node (e) [state] at (-1,-4) {e};
\node (f) [state] at (1,-4) {f};
\node (g) [state] at (3,-4) {g};
\node (h) [state] at (-1,-6) {h};
\node (i) [state] at (3,-6) {i};
\node at (3, -7) {non visité};
\path
(a) edge (b)
(a) edge (c)
(b) edge (d)
(b) edge (e)
(c) edge (f)
(c) edge (g)
(e) edge (h)
;
\end{tikzpicture}
\begin{itemize}
\item a
\item bc
\item dec
\item ec
\item hc
\item c
\item fg
\item g
\end{itemize}
\end{multicols}
\end{minipage}
\section{Ordonnancement}
Il s'agit de se donner un \emph{ordre} dans les tâches à faire, lorsque celles-ci sont multiples.
Les tâches rapides à faire vont pouvoir être mises en attente, alors que les tâches très longues ne devront jamais subir de retard, sinon c'est toute la chaîne qui va être retardée.
\subsection{Construction d'un graphe}
\begin{tabular}{|c|c|c|}
\hline
tâche & durée & contraintes \\
\hline
A & 9 & --- \\
B & 2 & --- \\
C & 3 & B \\
D & 5 & A \\
E & 2 & AD \\
F & 2 & E \\
G & 2 & D \\
H & 4 & DE \\
I & 5 & D \\
J & 1 & BC \\
K & 2 & AEFGH \\
\hline
\end{tabular}
\begin{tikzpicture}[->,scale=0.8,transform shape,auto,baseline=(current bounding box.center)]
\node (alpha) [state] at (-2,0) {$\alpha$};
\node (A) [state] at (0,2) {A};
\node (B) [state] at (0,-3) {B};
\node (C) [state] at (2,-4) {C};
\node (D) [state] at (2,-1) {D};
\node (E) [state] at (2,1) {E};
\node (F) [state] at (4,2) {F};
\node (G) [state] at (5,-2) {G};
\node (H) [state] at (6,0) {H};
\node (I) [state] at (5,-4) {I};
\node (J) [state] at (1,-6) {J};
\node (K) [state] at (8,2) {K};
\node (omega) [state] at (8,-3) {$\omega$};
\path
(alpha) edge node {0} (A)
(alpha) edge node {0} (B)
(A) edge node {9} (D)
(A) edge node {9} (E)
(B) edge node {2} (C)
(B) edge node {2} (J)
(C) edge node {3} (J)
(D) edge node {5} (E)
(E) edge node {2} (F)
(D) edge node {5} (G)
(D) edge node {5} (H)
(D) edge node {5} (I)
(E) edge node {2} (H)
(A) edge [bend left] node {9} (K)
(E) edge node {2} (K)
(F) edge node {2} (K)
(G) edge [bend right] node {2} (K)
(H) edge node {4} (K)
(J) edge [bend right] node {1} (omega)
(I) edge node {5} (omega)
(K) edge node {2} (omega)
;
\end{tikzpicture}
Ensuite, on trouve les rangs~:
\begin{multicols}{3}
Rang 0~: $\alpha$ \\
\begin{tikzpicture}[->,scale=0.6, transform shape, auto]
\node (A) [state] at (0,2) {A};
\node (B) [state] at (0,-3) {B};
\node (C) [state] at (2,-4) {C};
\node (D) [state] at (2,-1) {D};
\node (E) [state] at (2,1) {E};
\node (F) [state] at (4,2) {F};
\node (G) [state] at (5,-2) {G};
\node (H) [state] at (6,0) {H};
\node (I) [state] at (5,-4) {I};
\node (J) [state] at (1,-6) {J};
\node (K) [state] at (8,2) {K};
\node (omega) [state] at (8,-3) {$\omega$};
\path
(A) edge node {9} (D)
(A) edge node {9} (E)
(B) edge node {2} (C)
(B) edge node {2} (J)
(C) edge node {3} (J)
(D) edge node {5} (E)
(E) edge node {2} (F)
(D) edge node {5} (G)
(D) edge node {5} (H)
(D) edge node {5} (I)
(E) edge node {2} (H)
(A) edge [bend left] node {9} (K)
(E) edge node {2} (K)
(F) edge node {2} (K)
(G) edge [bend right] node {2} (K)
(H) edge node {4} (K)
(J) edge [bend right] node {1} (omega)
(I) edge node {5} (omega)
(K) edge node {2} (omega)
;
\end{tikzpicture}
\columnbreak
Rang 1~: A, B \\
\begin{tikzpicture}[->,scale=0.6, transform shape, auto]
\node (C) [state] at (2,-4) {C};
\node (D) [state] at (2,-1) {D};
\node (E) [state] at (2,1) {E};
\node (F) [state] at (4,2) {F};
\node (G) [state] at (5,-2) {G};
\node (H) [state] at (6,0) {H};
\node (I) [state] at (5,-4) {I};
\node (J) [state] at (1,-6) {J};
\node (K) [state] at (8,2) {K};
\node (omega) [state] at (8,-3) {$\omega$};
\path
(C) edge node {3} (J)
(D) edge node {5} (E)
(E) edge node {2} (F)
(D) edge node {5} (G)
(D) edge node {5} (H)
(D) edge node {5} (I)
(E) edge node {2} (H)
(E) edge node {2} (K)
(F) edge node {2} (K)
(G) edge [bend right] node {2} (K)
(H) edge node {4} (K)
(J) edge [bend right] node {1} (omega)
(I) edge node {5} (omega)
(K) edge node {2} (omega)
;
\end{tikzpicture}
\columnbreak
Rang 2~: C, D \\
\begin{tikzpicture}[->,scale=0.6, transform shape, auto]
\node (E) [state] at (2,1) {E};
\node (F) [state] at (4,2) {F};
\node (G) [state] at (5,-2) {G};
\node (H) [state] at (6,0) {H};
\node (I) [state] at (5,-4) {I};
\node (J) [state] at (1,-6) {J};
\node (K) [state] at (8,2) {K};
\node (omega) [state] at (8,-3) {$\omega$};
\path
(E) edge node {2} (F)
(E) edge node {2} (H)
(E) edge node {2} (K)
(F) edge node {2} (K)
(G) edge [bend right] node {2} (K)
(H) edge node {4} (K)
(J) edge [bend right] node {1} (omega)
(I) edge node {5} (omega)
(K) edge node {2} (omega)
;
\end{tikzpicture}
\end{multicols}
\begin{multicols}{3}
Rang 3~: E, G, I, J \\
\begin{tikzpicture}[->,scale=0.6, transform shape, auto]
\node (F) [state] at (4,2) {F};
\node (H) [state] at (6,0) {H};
\node (K) [state] at (8,2) {K};
\node (omega) [state] at (8,-3) {$\omega$};
\path
(F) edge node {2} (K)
(H) edge node {4} (K)
(K) edge node {2} (omega)
;
\end{tikzpicture}
\columnbreak
Rang 4~: F, H \\
\begin{tikzpicture}[->,scale=0.6, transform shape, auto]
\node (K) [state] at (8,2) {K};
\node (omega) [state] at (8,-3) {$\omega$};
\path
(K) edge node {2} (omega)
;
\end{tikzpicture}
\columnbreak
Rang 5~: K \\
\begin{tikzpicture}[->,scale=0.6, transform shape, auto]
\node (omega) [state] at (8,-3) {$\omega$};
\end{tikzpicture}
Rang 6~: $\omega$
\end{multicols}
\begin{tabular}{|c|c|c|c|c|c|c|c|c|c|c|c|c|c|}
\hline
rang & 0 & \multicolumn{2}{c|}{1} & \multicolumn{2}{c|}{2} & \multicolumn{4}{c|}{3} & \multicolumn{2}{c|}{4} & 5 & 6 \\
\hline
tâche$_{\text{durée}}$ & $\alpha_0$ & $A_9$ & $B_2$ & $C_3$ & $D_5$ & $E_2$ & $G_2$ & $I_5$ & $J_1$ & $F_2$ & $H_4$ & $K_2$ & $\omega$ \\
\hline
prédécesseur & --- & $\alpha$ & $\alpha$ & B & A & AD & D & D & BC & E & DE & \parbox{0.6cm}{\centering A E F G H} & \parbox{0.6cm}{\centering I J K} \\
\hline
\makecell{dates\\$\rightarrow$} & 0 & 0 & 0 & $2_B$ & $9_A$ & \parbox{0.6cm}{\centering $9_A$ $14_D$} & $14_D$ & $14_D$ & \parbox{0.6cm}{\centering $2_B$ $5_C$} & $16_E$ & \parbox{0.6cm}{\centering $14_D$ $16_E$} & \parbox{0.6cm}{\centering $9_A$ $16_E$ $18_F$ $16_G$ $20_H$} & \parbox{0.6cm}{\centering $19_I$ $6_J$ $22_K$} \\
\hline
\parbox{2cm}{\centering max dates \\ plus tôt} & 0 & 0 & 0 & $2_B$ & $9_A$ & $14_D$ & $14_D$ & $14_D$ & $5_C$ & $16_E$ & $16_E$ & $20_H$ & $22_K$ \\
\hline
successeur & AB & DEK & CJ & J & \parbox{0.6cm}{E H G I} & FH & K & $\omega$ & $\omega$ & K & K & $\omega$ & --- \\
\hline
\makecell{dates\\$\leftarrow$} & \parbox{0.6cm}{\centering 0 16} & \parbox{0.6cm}{\centering 0 5 11} & \parbox{0.6cm}{\centering 16 19} & 18 & \parbox{0.6cm}{\centering 9 11 13 12} & \parbox{0.6cm}{\centering 16 14} & 18 & 17 & 21 & 18 & 16 & 20 & 22 \\
\hline
\parbox{2cm}{\centering min dates \\ plus tard} & 0 & 0 & 16 & 18 & 9 & 14 & 18 & 17 & 21 & 18 & 16 & 20 & 22 \\
\hline
marge & 0 & 0 & 16 & 16 & 0 & 0 & 4 & 3 & 16 & 2 & 0 & 0 & 0 \\
\hline
\end{tabular}
Le chemin le plus lent est donc celui qui nous amène à K.
Pour finir nos tâches (arriver à $\omega$), en parallèlisant les tâches qui peuvent l'être, on ne pourra jamais faire moins de 22 heures.
La marge est le retard autorisé pour ne pas retarder toute la chaîne.
Le chemin critique est le chemin à flux tendu où l'on ne doit pas prendre de retard.
C'est le chemin où la marge est nulle, ici $\alpha$ADEHK$\omega$.
\section{Chemin le plus court}
L'ordonnancement est relié au chemin \emph{le plus long}, c'est-à-dire le plus critique.
Pour trouver le chemin le plus court, on travaille avec des graphes \emph{valués}~: on attribue une valeur à chacun des arcs ou arrêtes.
Cette valeur est appelée \emph{poids} ou \emph{coût}.
On va utiliser deux algorithmes~:
\begin{enumerate}
\item \textbf{Dijkstra} ---
orienté ou non orienté, mais les coûts doivent être \emph{positifs}.
\item \textbf{Bellman} ---
\emph{orienté} avec des coûts positifs ou négatifs, mais pas de \emph{circuit absorbant}.
Quand on a un coût négatif, on peut obtenir des choses bizarres en empruntant le même chemin plusieurs fois.
On va donc préférer un graphe orienté.
Quand on a un circuit, et que la somme des coûts sur le circuit est négatif, on a un \emph{circuit absorbant}.
\begin{center}
Circuit non absorbant~: \\
\begin{tikzpicture}[->,auto,scale=1, transform shape]
\node (a)[state] at (0,0) {A};
\node (b)[state] at (2.4,0) {B};
\node (c)[state] at (1.2,-2) {C};
\path
(a) edge node {-2} (b)
(b) edge node {1} (c)
(c) edge node {4} (a)
;
\end{tikzpicture}
\hspace{2cm}
Circuit absorbant~: \\
\begin{tikzpicture}[->,auto,scale=1, transform shape]
\node (a)[state] at (0,0) {A};
\node (b)[state] at (2.4,0) {B};
\node (c)[state] at (1.2,-2) {C};
\path
(a) edge node {-4} (b)
(b) edge node {-2} (c)
(c) edge node {1} (a)
;
\end{tikzpicture}
\end{center}
La notion de chemin le plus court n'a alors plus de sens parce que tous les chemins font $-\infty$.
\end{enumerate}
\subsection{Algorithme de Dijkstra}
On décide de regarder tous les chemins les plus courts partant de 1.
\begin{multicols}{2}
\begin{tikzpicture}[->,auto,scale=0.8, transform shape]
\node (1)[state] at (0,0) {1};
\node (2)[state] at (2,2) {2};
\node (3)[state] at (2,-2) {3};
\node (4)[state] at (6,2) {4};
\node (5)[state] at (8,0) {5};
\node (6)[state] at (4,0) {6};
\path
(1) edge node {1} (3)
(1) edge node {7} (2)
(3) edge node {5} (2)
(3) edge node {7} (6)
(2) edge node {2} (6)
(2) edge node {4} (4)
(6) edge node {3} (5)
(3) edge node {2} (5)
(5) edge node {5} (4)
;
\end{tikzpicture}
\columnbreak
\begin{tabular}{|c|c|ccccc|}
\hline
Sommet & \multicolumn{1}{c}{1} & 2 & 3 & 4 & 5 & 6 \\
\hline
1 & \color{red}{$0_1$} & & & & & \\
\cline{2-7}
& & $7_1$ & \color{red}{$1_1$} & & & \\
\cline{3-7}
& & $6_3$ & & & \color{red}{$3_3$} & $8_3$ \\
\cline{3-7}
& & \color{red}{$6_3$} & & $8_5$ & & \\
\cline{3-7}
& & & & \color{red}{$8_5$} & & $8_{3,2}$ \\
\cline{3-7}
& & & & & & \color{red}{$8_{3,2}$} \\
\cline{2-7}
& \color{red}{$0_1$} & \color{red}{$6_3$} & \color{red}{$1_1$} & \color{red}{$8_5$} & \color{red}{$3_3$} & \color{red}{$8_{3,2}$} \\
\hline
\end{tabular}
\end{multicols}
\subsection{Algorithme de Bellman}
Quand on a des coûts négatifs, on n'a pas le choix, il faut prendre cet algorithme.
Il faut aussi savoir s'il y a un circuit absorbant.
Ici, non car pas de circuit.
\begin{tikzpicture}[->,auto,scale=0.8, transform shape]
\node (1)[state] at (0,0) {1};
\node (2)[state] at (2,0) {2};
\node (3)[state] at (0,-2) {3};
\node (5)[state] at (2,-2) {5};
\node (6)[state] at (2,-4) {6};
\node (4)[state] at (4,-2) {4};
\path
(1) edge node {7} (2)
(1) edge node {8} (3)
(2) edge node {1} (5)
(5) edge node {-2} (3)
(2) edge node {4} (4)
(5) edge node {2} (4)
(3) edge node {1} (6)
(4) edge node {-2} (6)
;
\end{tikzpicture}
\hfill
\begin{tabular}{c|c|ccccc|l}
\cline{2-7}
& \multicolumn{1}{c}{1} & 2 & 3 & 4 & 5 & 6 & \\
\cline{2-7}
$k=1$ & & $7_1$ & $8_1$ & & & & successeurs de 1~: 2 et 3 \\
\cline{2-7}
$k=2$ & & & & $11_2$ & $8_2$ & $9_3$ & successeurs de 2 et 3~: 4, 5, 6 \\
\cline{2-7}
$k=3$ & & & $6_5$ & $10_5$ & & $9_{3,4}$ & successeurs de 4, 5, 6~: 6, 3, 4 \\
\cline{2-7}
$k=4$ & & & & & & $7_3$ & successeur de 6, 3, 4~: 6\\
\cline{2-7}
$k=5$ & & \multicolumn{5}{c|}{pas de changement} & successeur de 6~: $\emptyset$\\
\cline{2-7}
& & $7_1$ & $6_5$ & $10_5$ & $8_2$ & $7_3$ & résumé \\
\cline{2-7}
\end{tabular}
Chemin le plus court de 1 à 6~: coût 7, prédécesseur 3. \\
$\rightarrow 1-2-5-3-6$
\subsubsection{Algorithme de Bellman avec un circuit absorbant}
Voyons ce qu'il se passe si l'on applique l'algorithme de Bellman sur un graphe comportant un circuit absorbant~:
\begin{tikzpicture}[->,auto,scale=0.8, transform shape]
\node (a)[state] at (0,0) {A};
\node (b)[state] at (2,2) {B};
\node (c)[state] at (0,-2) {C};
\node (d)[state] at (2,-4) {D};
\node (e)[state] at (4,-1) {E};
\path
(a) edge node {5} (b)
(a) edge node {1} (c)
(b) edge [bend left] node {5} (e)
(e) edge [bend left] node {20} (b)
(e) edge node {-5} (a)
(c) edge node {1} (d)
(d) edge [bend left] node {1} (e)
(e) edge [bend left] node {-1} (d)
;
\end{tikzpicture}
\begin{tabular}{c|c|cccc|}
\cline{2-6}
& A & B & C & D & E \\
\cline{2-6}
$k=0$ & $0_A$ & & & & \\
\cline{2-6}
$k=1$ & & $5_A$ & $1_A$ & & \\
\cline{2-6}
$k=2$ & & & & $2_C$ & $10_B$ \\
\cline{2-6}
$k=3$ & & & & & $3_D$ \\
\cline{2-6}
$k=4$ & \color{red}{$-2_A$} & & & & \\
\cline{2-6}
\end{tabular}
À $k=4$ ($n-1$), on détecte la présence d'un cycle~: modification d'un élément déjà vu.
\subsection{Arbre couvrant}
\subsubsection{Définitions}
Un arbre est un graphe non orienté, connexe, simple et sans cycle.
\begin{tikzpicture}[scale=1, transform shape]
\node (a)[state] at (0,0) {A};
\node (b)[state] at (2.4,0) {B};
\node (c)[state] at (1.2,-2) {C};
\path
(a) edge (b)
(b) edge (c)
(c) edge (a)
;
\end{tikzpicture}
Pas un arbre car cycle.
\begin{tikzpicture}[scale=1, transform shape]
\node (a)[state] at (0,0) {A};
\node (b)[state] at (2.4,0) {B};
\node (c)[state] at (1.2,-2) {C};
\path
(a) edge (b)
(c) edge (a)
;
\end{tikzpicture}
Arbre.
\begin{tikzpicture}[scale=1, transform shape]
\node (a)[state] at (0,0) {A};
\node (b)[state] at (2.4,0) {B};
\node (c)[state] at (1.2,-2) {C};
\path
(a) edge [bend left] (b)
(b) edge [bend left] (a)
(c) edge (a)
;
\end{tikzpicture}
Pas un arbre car pas simple.
\begin{tikzpicture}[scale=1, transform shape]
\node (a)[state] at (0,0) {A};
\node (b)[state] at (2.4,0) {B};
\node (c)[state] at (1.2,-2) {C};
\node (d)[state] at (4.2,-1) {D};
\path
(a) edge (b)
(c) edge (a)
;
\end{tikzpicture}
Pas un arbre car non connexe.
On va affecter un coût sur chaque arrête.
On détaillera trois algorithmes pour donner l'arbre couvrant tous les sommets de coût total minimum.
\subsubsection{Algorithme de Kruskall}
Sur un graphe non orienté, valué, connexe.
\begin{center}
\begin{tikzpicture}[scale=0.7,transform shape,auto]
\node (1)[state] at (0,0) {1};
\node (2)[state] at (4,0) {2};
\node (3)[state] at (5,-2) {3};
\node (4)[state] at (4,-4) {4};
\node (5)[state] at (0,-4) {5};
\node (6)[state] at (-2,-2) {6};
\path
(1) edge node {7} (2)
(2) edge node {4} (3)
(3) edge node {1} (4)
(4) edge node {3} (5)
(5) edge node {1} (6)
(6) edge node {2} (1)
(1) edge node {6} (5)
(2) edge node {5} (5)
(3) edge node {2} (5)
;
\end{tikzpicture}
\end{center}
\begin{itemize}
\item coût 1~:
\begin{tikzpicture}[scale=0.5,transform shape,baseline=(current bounding box.center)]
\node (5)[state] at (0,0) {5};
\node (6)[state] at (2,0) {6};
\path (5) edge (6);
\end{tikzpicture}
\begin{tikzpicture}[scale=0.5,transform shape,baseline=(current bounding box.center)]
\node (3)[state] at (0,0) {3};
\node (4)[state] at (2,0) {4};
\path (3) edge (4);
\end{tikzpicture}
\item coût 2~:
\begin{tikzpicture}[scale=0.5,transform shape,baseline=(current bounding box.center)]
\node (1)[state] at (0,0) {1};
\node (6)[state] at (2,0) {6};
\path (1) edge (6);
\end{tikzpicture}
\begin{tikzpicture}[scale=0.5,transform shape,baseline=(current bounding box.center)]
\node (3)[state] at (0,0) {3};
\node (5)[state] at (2,0) {5};
\path (3) edge (5);
\end{tikzpicture}
\item coût 3~:
\begin{tikzpicture}[scale=0.5,transform shape,baseline=(current bounding box.center)]
\node (4)[state] at (0,0) {4};
\node (5)[state] at (2,0) {5};
\path (4) edge (5);
\end{tikzpicture}
\item coût 4~:
\begin{tikzpicture}[scale=0.5,transform shape,baseline=(current bounding box.center)]
\node (2)[state] at (0,0) {2};
\node (3)[state] at (2,0) {3};
\path (2) edge (3);
\end{tikzpicture}
\item coût 5~:
\begin{tikzpicture}[scale=0.5,transform shape,baseline=(current bounding box.center)]
\node (2)[state] at (0,0) {2};
\node (5)[state] at (2,0) {5};
\path (2) edge (5);
\end{tikzpicture}
\item coût 6~:
\begin{tikzpicture}[scale=0.5,transform shape,baseline=(current bounding box.center)]
\node (1)[state] at (0,0) {1};
\node (5)[state] at (2,0) {5};
\path (1) edge (5);
\end{tikzpicture}
\item coût 7~:
\begin{tikzpicture}[scale=0.5,transform shape,baseline=(current bounding box.center)]
\node (1)[state] at (0,0) {1};
\node (2)[state] at (2,0) {2};
\path (1) edge (2);
\end{tikzpicture}
\end{itemize}
\paragraph{Constructif}
On sélectionne les arrêtes de coût minimum à condition de ne pas former de cycle.
Ordre de sélection des arrêtes~:
\begin{multicols}{2}
\begin{enumerate}
\item
\begin{tikzpicture}[scale=0.7,transform shape,auto,baseline=(current bounding box.center)]
\node (5)[state] at (0,-4) {5};
\node (6)[state] at (-2,-2) {6};
\path
(5) edge node {1} (6)
;
\end{tikzpicture}
\item
\begin{tikzpicture}[scale=0.7,transform shape,auto,baseline=(current bounding box.center)]
\node (3)[state] at (5,-2) {3};
\node (4)[state] at (4,-4) {4};
\node (5)[state] at (0,-4) {5};
\node (6)[state] at (-2,-2) {6};
\path
(3) edge node {1} (4)
(5) edge node {1} (6)
;
\end{tikzpicture}
\item
\begin{tikzpicture}[scale=0.7,transform shape,auto,baseline=(current bounding box.center)]
\node (1)[state] at (0,0) {1};
\node (3)[state] at (5,-2) {3};
\node (4)[state] at (4,-4) {4};
\node (5)[state] at (0,-4) {5};
\node (6)[state] at (-2,-2) {6};
\path
(3) edge node {1} (4)
(5) edge node {1} (6)
(6) edge node {2} (1)
;
\end{tikzpicture}
\item
\begin{tikzpicture}[scale=0.7,transform shape,auto,baseline=(current bounding box.center)]
\node (1)[state] at (0,0) {1};
\node (3)[state] at (5,-2) {3};
\node (4)[state] at (4,-4) {4};
\node (5)[state] at (0,-4) {5};
\node (6)[state] at (-2,-2) {6};
\path
(3) edge node {1} (4)
(5) edge node {1} (6)
(6) edge node {2} (1)
(3) edge node {2} (5)
;
\end{tikzpicture}
\item $\{4,5\}$ non sélectionné car il créerait un cycle.
\item
\begin{tikzpicture}[scale=0.7,transform shape,auto,baseline=(current bounding box.center)]
\node (1)[state] at (0,0) {1};
\node (2)[state] at (4,0) {2};
\node (3)[state] at (5,-2) {3};
\node (4)[state] at (4,-4) {4};
\node (5)[state] at (0,-4) {5};
\node (6)[state] at (-2,-2) {6};
\path
(2) edge node {4} (3)
(3) edge node {1} (4)
(5) edge node {1} (6)
(6) edge node {2} (1)
(3) edge node {2} (5)
;
\end{tikzpicture}
\end{enumerate}
\end{multicols}
On a couvert tous les sommets, on peut s'arrêter.
\paragraph{Destructif}
On sélectionne les arrêtes de coût maximum en les enlevant, à condition de ne pas isoler de sommet.
Ordre de destruction des arrêtes~:
\begin{multicols}{2}
\begin{enumerate}
\item $\{1,2\}$
\begin{tikzpicture}[scale=0.7,transform shape,auto,baseline=(current bounding box.center)]
\node (1)[state] at (0,0) {1};
\node (2)[state] at (4,0) {2};
\node (3)[state] at (5,-2) {3};
\node (4)[state] at (4,-4) {4};
\node (5)[state] at (0,-4) {5};
\node (6)[state] at (-2,-2) {6};
\path
(2) edge node {4} (3)
(3) edge node {1} (4)
(4) edge node {3} (5)
(5) edge node {1} (6)
(6) edge node {2} (1)
(1) edge node {6} (5)
(2) edge node {5} (5)
(3) edge node {2} (5)
;
\end{tikzpicture}
\item $\{1,5\}$
\begin{tikzpicture}[scale=0.7,transform shape,auto,baseline=(current bounding box.center)]
\node (1)[state] at (0,0) {1};
\node (2)[state] at (4,0) {2};
\node (3)[state] at (5,-2) {3};
\node (4)[state] at (4,-4) {4};
\node (5)[state] at (0,-4) {5};
\node (6)[state] at (-2,-2) {6};
\path
(2) edge node {4} (3)
(3) edge node {1} (4)
(4) edge node {3} (5)
(5) edge node {1} (6)
(6) edge node {2} (1)
(2) edge node {5} (5)
(3) edge node {2} (5)
;
\end{tikzpicture}
\item $\{2,5\}$
\begin{tikzpicture}[scale=0.7,transform shape,auto,baseline=(current bounding box.center)]
\node (1)[state] at (0,0) {1};
\node (2)[state] at (4,0) {2};
\node (3)[state] at (5,-2) {3};
\node (4)[state] at (4,-4) {4};
\node (5)[state] at (0,-4) {5};
\node (6)[state] at (-2,-2) {6};
\path
(2) edge node {4} (3)
(3) edge node {1} (4)
(4) edge node {3} (5)
(5) edge node {1} (6)
(6) edge node {2} (1)
(3) edge node {2} (5)
;
\end{tikzpicture}
\item $\{2,3\}$ non sélectionné car il isole un sommet.
\item $\{4,5\}$
\begin{tikzpicture}[scale=0.7,transform shape,auto,baseline=(current bounding box.center)]
\node (1)[state] at (0,0) {1};
\node (2)[state] at (4,0) {2};
\node (3)[state] at (5,-2) {3};
\node (4)[state] at (4,-4) {4};
\node (5)[state] at (0,-4) {5};
\node (6)[state] at (-2,-2) {6};
\path
(2) edge node {4} (3)
(3) edge node {1} (4)
(5) edge node {1} (6)
(6) edge node {2} (1)
(3) edge node {2} (5)
;
\end{tikzpicture}
\end{enumerate}
\end{multicols}
Il n'y a plus de cycle, on peut s'arrêter.
\subsubsection{Algorithme de PRIM}
Sur un graphe non orienté, valué, connexe.
Pour un sommet donné, on fait pousser un arbre en prenant à chaque fois l'arrête disponible la moins valuée.
Partons par exemple du sommet 2.
% TODO: finish
\begin{tikzpicture}[scale=0.7,transform shape,auto,baseline=(current bounding box.center)]
\node (2)[state] at (4,0) {2};
\path
(1) edge node {7} (2)
(2) edge node {4} (3)
(2) edge node {5} (5)
;
\end{tikzpicture}
On pousse sur l'arrête $\{2,3\}$ car 4 est la valeur la plus faible.
\begin{tikzpicture}[scale=0.7,transform shape,auto,baseline=(current bounding box.center)]
\node (2)[state] at (4,0) {2};
\node (3)[state] at (5,-2) {3};
\path
(1) edge node {7} (2)
(2) edge node {4} (3)
(3) edge node {1} (4)
(2) edge node {5} (5)
(3) edge node {2} (5)
;
\end{tikzpicture}
On pousse sur l'arrête $\{3,4\}$ car 1 est la valeur la plus faible.
\begin{tikzpicture}[scale=0.7,transform shape,auto,baseline=(current bounding box.center)]
\node (2)[state] at (4,0) {2};
\node (3)[state] at (5,-2) {3};
\node (4)[state] at (4,-4) {4};
\path
(1) edge node {7} (2)
(2) edge node {4} (3)
(3) edge node {1} (4)
(4) edge node {3} (5)
(2) edge node {5} (5)
(3) edge node {2} (5)
;
\end{tikzpicture}
On pousse sur l'arrête $\{3,5\}$.
\begin{tikzpicture}[scale=0.7,transform shape,auto,baseline=(current bounding box.center)]
\node (2)[state] at (4,0) {2};
\node (3)[state] at (5,-2) {3};
\node (4)[state] at (4,-4) {4};
\node (5)[state] at (0,-4) {5};
\path
(1) edge node {7} (2)
(2) edge node {4} (3)
(3) edge node {1} (4)
(4) edge node {3} (5)
(5) edge node {1} (6)
(1) edge node {6} (5)
(2) edge node {5} (5)
(3) edge node {2} (5)
;
\end{tikzpicture}
On pousse sur l'arrête $\{5,6\}$.
\begin{tikzpicture}[scale=0.7,transform shape,auto,baseline=(current bounding box.center)]
\node (1)[state] at (0,0) {1};
\node (2)[state] at (4,0) {2};
\node (3)[state] at (5,-2) {3};
\node (4)[state] at (4,-4) {4};
\node (5)[state] at (0,-4) {5};
\node (6)[state] at (-2,-2) {6};
\path
(1) edge node {7} (2)
(2) edge node {4} (3)
(3) edge node {1} (4)
(4) edge node {3} (5)
(5) edge node {1} (6)
(6) edge node {2} (1)
(1) edge node {6} (5)
(2) edge node {5} (5)
(3) edge node {2} (5)
;
\end{tikzpicture}
On pousse sur l'arrête $\{6,1\}$.
\begin{tikzpicture}[scale=0.7,transform shape,auto,baseline=(current bounding box.center)]
\node (1)[state] at (0,0) {1};
\node (2)[state] at (4,0) {2};
\node (3)[state] at (5,-2) {3};
\node (4)[state] at (4,-4) {4};
\node (5)[state] at (0,-4) {5};
\node (6)[state] at (-2,-2) {6};
\path
(1) edge node {7} (2)
(2) edge node {4} (3)
(3) edge node {1} (4)
(4) edge node {3} (5)
(5) edge node {1} (6)
(6) edge node {2} (1)
(1) edge node {6} (5)
(2) edge node {5} (5)
(3) edge node {2} (5)
;
\end{tikzpicture}
Tous les sommets ont été visités, on a terminé.
\end{document}