Vous êtes sur la page 1sur 5

L'algorithme de Dijkstra

1 Les données du problème


On se donne un graphe ni, orienté, pondéré ; S est l'ensemble des sommets
du graphe ; on note n son 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èse w ≥ 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ée W ; 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 si n est grand, et le nombre d'arcs
N est tel que N  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étermine d (x), longueur du (ou des) chemin le plus court de a à x, pour


tout sommet x, et ce du sommet le plus proche de a au plus éloigné :
les valeurs de d (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 sur S = 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 de a à x.
Si x ∈ T , le plus court chemin de a à x est dans T , et il est de longueur
d (x) = dp (x).

L'ensemble R
R est l'ensemble des sommets restant à traiter.
Si x ∈ R, dp (x) est la longueur du plus court chemin de a à x dont x est
le seul sommet dans R.

2.2 Initialisation

T = {a} ; dp (a) = 0 ; dp (x) = w (a, x) si l'arc entre a et x existe, ∞ sinon.

1
Variante

T = {} ; dp (a) = 0 ; dp (x) = ∞ si x 6= a sinon.

2.3 L'algorithme

a) on choisit x dans R = S\T tel que dp (x) soit minimal.


Si ce dp (x) est inni, c'est terminé ; sinon :
b)
T ← T ∪ {x} , R ← R \ {x}
c) pour tout y ∈ R, si dp (x) + w (x, y) < dp (y) :
dp (y) ← dp (x) + w (x, y)

Terminaison

L'algorithme se termine car ... ?

Complexité

On note n le nombre de sommets et m le nombre d'arêtes.


- complexité en O 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. Si x ∈ T , le plus court chemin de a à x est dans T , et il est de longueur


d (x) = dp (x).
2. Si x ∈ R, dp (x) est la longueur du plus court chemin de a à x dont x
est le seul sommet dans R.
3. ∀x ∈ T, ∀y ∈ R, d (x) ≤ dp (y).

On montre qu'à chaque étape, les invariants de boucle sont con-


servés

On choisit x dans R = S\T tel que dp (x) soit minimal ; soit l 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
dans T ; soit l0 la longueur de la partie de c entre a et z .
On constate que
dp (x) ≤ dp (z) ≤ l0 ≤ l
Ce dp (x) est donc la longueur d'un plus court chemin issu de a, dont l'ex-
trêmité est quelconque dans R.
Il en découle que
∀y ∈ R, dp (x) ≤ d (y)
Deux conséquences :
- d (x) = dp (x)
- ∀y ∈ R, d (x) ≤ d (y) : les d (x) sont obtenus dans l'ordre croissant.

De même, on montre que la propriété suivante est convervée

Pour tout y ∈ R, dp (y) est la longueur du plus court chemin de a à y dont


y est le seul sommet dans R.

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()

1
5 Reconstitution du chemin optimal
On dénit un tableau prédécesseur qui donne pour chaque sommet le précé-
dent dans un chemin optimal.
Dans l'algorithme précédent, étape c : si d (x) + w (x, y) < d (y)..., on
note qu'il faut passer par x pour atteindre y ; prédécesseur est mis à jour
par
pred (y) = x
A tout instant, pred (x) permet de reconstituer un chemin de a à x de
longueur dp (x).
Quand x entre dans T , d (x) et pred (x) sont déjà dénitifs.

4
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)]
precedent = nb_sommets*[-1]
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]
precedent[y] = x
x = prochain_sommet()

Vous aimerez peut-être aussi