L'algorithme de Dijkstra
1 Les données du problème
On se donne un graphe ni, orienté, pondéré ;Sest l'ensemble des sommets du graphe ; on notenson cardinal ;a∈S est le sommet de départ.
w(x, y)∈R+est le poids de l'arc(x, y)s'il existe dans le graphe ; sans l'hypothèsew≥0, l'algorithme ne s'applique pas.
On cherche un plus court chemin dans le graphe entre a et les autres sommets.
Représentation
On utilise une matrice carréeW ;w[i, j]est la longueur, ou le poids de l'arc (i, j) ; par convention,w[i, j]<0 s'il n'y a pas d'arc(i, j)dans le graphe.
Cette représentation est peu satisfaisante sinest grand, et le nombre d'arcs N est tel queN n2.
Une autre possibilité de représentation est de dénir pour chaque sommet la liste de ses voisins.
2 L'algorithme
2.1 Principe
On détermined(x), longueur du (ou des) chemin le plus court deaàx, pour tout sommetx, et ce du sommet le plus proche deaau plus éloigné :
les valeurs ded(x)calculées sont donc dans l'ordre croissant.
Variables
On utilise trois variables :
-T, l'ensemble des sommets déjà traités.
-R, l'ensemble des sommets restant à traiter.
-dp, la distance provisoire, est dénie surS=T∪R. Quand l'algorithme se termine :
d=dp
L'ensemble T
T ⊂S est l'ensemble des sommets déjà traités : ceux pour lesquels on a déjà déterminéd(x), distance minimale deaàx.
Si x∈T, le plus court chemin deaà xest dans T, et il est de longueur d(x) =dp(x).
L'ensemble R
Rest l'ensemble des sommets restant à traiter.
Six∈R,dp(x)est la longueur du plus court chemin deaàxdontxest le seul sommet dansR.
2.2 Initialisation
Si cedp(x)est inni, c'est terminé ; sinon : b)
T ←T∪ {x}, R←R\ {x}
c) pour touty∈R, sidp(x) +w(x, y)< dp(y): dp(y)←dp(x) +w(x, y)
Terminaison
L'algorithme se termine car ... ? Complexité
On notenle nombre de sommets etmle nombre d'arêtes.
- complexité enO n2
pour cette représentation élémentaire par tableau.
- si on utilise un tas pour manipuler les sommets, et des listes pour représenter les arêtes, on arrive àO(m.lnn).
3 Justication rapide
Les invariants de boucle
1. Six∈T, le plus court chemin deaàxest dansT, et il est de longueur d(x) =dp(x).
2. Six∈R,dp(x)est la longueur du plus court chemin deaàxdontx est le seul sommet dansR.
3. ∀x∈T,∀y∈R, d(x)≤dp(y).
On montre qu'à chaque étape, les invariants de boucle sont con- servés
On choisitxdans R=S\T tel quedp(x) soit minimal ; soitl la longueur d'un chemin c = (a, ..., y) quelconque (pas nécessairement dans T) dont l'extrémitéy ∈R ; soit z le premier sommet dans ce chemin qui n'est pas dansT ; soit l0 la longueur de la partie dec entreaetz.
On constate que
dp(x)≤dp(z)≤l0 ≤l
Cedp(x)est donc la longueur d'un plus court chemin issu dea, dont l'ex- trêmité est quelconque dansR.
Il en découle que
∀y∈R, dp(x)≤d(y) Deux conséquences :
-d(x) =dp(x)
-∀y∈R, d(x)≤d(y): lesd(x)sont obtenus dans l'ordre croissant.
De même, on montre que la propriété suivante est convervée Pour touty∈R,dp(y)est la longueur du plus court chemin deaà y dont yest le seul sommet dansR.
4 Programme
2
import random as rd
nb_sommets, n_Max = 3, 10**6
graphe = [[rd.randint(-3, 5) for j in range(nb_sommets)] for i in range(nb_sommets)]
R, T = [k for k in range(nb_sommets)], []
dp = [0] + [n_Max for k in range(1,nb_sommets)]
def prochain_sommet(): # choisit le sommet suivant prochain = -1 # et renvoie -1 à défaut minimum = n_Max
for sommet in R:
if dp[sommet] < minimum:
prochain = sommet minimum = dp[sommet]
return prochain
x = prochain_sommet()
while x != -1: # cas où il n'y a plus de sommet T.append(x) # accessible dans r
R.remove(x) for y in R:
if graphe[x][y] >= 0 and dp[x] + graphe[x][y] < dp[y]:
dp[y] = dp[x] + graphe[x][y]
x = prochain_sommet()
par
pred(y) =x
A tout instant, pred(x) permet de reconstituer un chemin de a à x de longueurdp(x).
Quandxentre dansT,d(x)etpred(x)sont déjà dénitifs.
4