Vous êtes sur la page 1sur 16

Universit du Qubec

cole de technologie suprieure


Dpartement de gnie de la production automatise

Auteur : Tony Wong Ph.D., ing. Dpartement de gnie de production automatise cole de technologie suprieure Courriel : wong.wong@ etsmtl.ca

Algorithme de Dijsktra
Chemins minimaux partir dune source

Section

Algorithme de Dijsktra
Les chemins minimaux partir dune seule source
Prsentation partir dun graphe, lalgorithme de Dijsktra utilise le parcours en largeur dabord et lapproche gourmande (greedy) pour trouver les chemins les plus courts entre une source et toutes les destinations du graphe. Puisquun graphe est compos de nuds et dartes, lalgorithme de Dijsktra peut trouver les chemins les plus courts liant un nud quelconque tous les autres noeuds du graphe en une seule excution.

Conditions dapplicabilit Lalgorithme de Dijsktra sopre dans lunivers des graphes. Les graphes accepts peuvent tre orients ou non. La figure 1a) montre un graphe non orient alors que la figure 1b) montre un graphe orient.

1a)

1b)
Figure 1 Graphe non orient (a), graphe orient (b).

Un graphe peut galement tre pondr. Dans ce cas, la valeur de pondration est indique sur les artes du graphe. La figure 2 montre un graphe orient et pondr.
1 700 400 2 700 3 1700 6 700 1200
Figure 2 Graphe orient et pondr.

4 700

300

600

De cette faon, nous pouvons reprsenter un nombre de situations relles par des graphes. Par exemple, le trafic arien o les nuds sont des villes et les pondrations sont le cot des billets dembarquement reliant deux villes. Dans le domaine de la production industrielle, les nuds peuvent reprsenter diffrentes tapes dun processus de fabrication alors que les pondrations peuvent reprsenter le temps requis pour passer dune tape lautre. Lapplication de lalgorithme de Dijsktra exige un graphe dont les caractristiques sont : Orient ou non orient. Pondr ou non pondr. Valeur de la pondration non ngative (cest dire, 0). Enfin, il doit exister au moins un chemin partant du nud de dpart vers tous les autres nuds du graphe. videmment, cette condition ne sapplique pas pour le nud de dpart. Il est donc important de sassurer que les valeurs inscrites sur les artes des graphes soient non ngatives. Nature des graphes Cette section est une brve introduction, pour les non initis, de la thorie des graphes. Les lecteurs qui ne sintressent quaux applications de lalgorithme de Dijkstra sont pris de passer la section suivante. Un graphe G est reprsent par la notation
3

G = (N, A)

(1)

o N est lensemble des nuds et A est lensemble des artes et chaque arte est un pair (u, v) o u, v N. Si lordre des nuds dans le pair (u, v) est important alors le graphe est orient. Dans le cas contraire, le graphe est non orient. Dans un graphe orient, on dit quun nud v est adjacent au nud u si et seulement si le pair (u, v) A. Cest--dire, larte (u, v) existe dans le graphe. Pour exprimer la mme notion dans un graphe non orient, on dit quun nud v est adjacent au nud u (et par le fait mme u est adjacent v) si (u, v) A et (v, u) A. Lorsquun graphe est pondr, on ajoute un troisime composant dans lquation (1). Cest--dire, G = (N, A, c) (2)

o c : N N + est une fonction donnant le cot de larte reliant deux nuds. Le domaine de la fonction c( ) est lensemble des nuds do le produit cartsien N N. Rappelons que le cot doit tre non ngative pour permettre lapplication de lalgorithme de Dijsktra, cest pour cette raison que limage de la fonction est +. Un chemin dans un graphe est une squence de nuds u1, u2, , uW tel que (ui , ui+1) A pour 1 i W 1. La longueur dun chemin est alors simplement W 1. galement, un nud u peut avoir un chemin vers lui-mme. Si ce chemin na pas dartes alors la longueur de ce chemin est nulle (zro). Par contre, si ce chemin possde une arte (u, u) alors le chemin joignant le nud u est appel une boucle et sa longueur demeure nulle (zro). Un chemin est un chemin simple si tous les nuds du chemin sont distincts except le nud de dpart et le nud darrive. Soit un nud de dpart u1 et un nud darrive uW. Dans un graphe orient, un chemin de longueur 1 avec u1 = uW est appel un cycle. Un cycle est un cycle simple si le chemin composant le cycle est un chemin simple. Dans un graphe non orient, on impose une contrainte supplmentaire dans la formation dun cycle : il faut que les nuds du chemin soient tous des nuds distincts. La raison de cette contrainte supplmentaire est vidente si lon considre que le chemin u1, u2, u1 dans un graphe non orient est en fait la mme arte. Cest--dire (u1, u2) = (u2, u1) pour un graphe non orient. Donc, nous avons la nomenclature suivante : Graphe orient Cycle simple Cycle non simple o les nuds du chemin ne sont pas tous distincts Cycle N/A Graphe non orient

Un graphe orient sans cycle est un graphe acyclique. Ces graphes ont beaucoup dapplications dans la pratique. Notamment dans la reprsentation et lanalyse des

programmes parallles. Nous les avons donns un nom particulier, le DAG. Lacronyme DAG signifie tout simplement Direct Acyclic Graphs . Sil existe un chemin reliant tous les nuds du graphe, ce dernier est appel un graphe connect pour un graphe non orient. Pour un graphe orient, il est appel graphe fortement connect. Si on enlve la direction des artes dun graphe orient et que le graphe non orient rsultant est connect alors on appel le graphe orient, un graphe orient faiblement connect. Le tableau suivant rsume cette proprit des graphes. Graphe orient Fortement connect Faiblement connect liminer lorientation des artes. Le graphe rsultant est connect. Graphe non orient Connect Connect

Enfin, sil existe au moins une arte reliant tous les pairs de nuds dans le graphe, le graphe est un graphe complet. On peut constater que ce type de graphes peut reprsenter un grand nombre de situations. Par exemple, un ordinateur parallle mmoire commune, les chemins de communication entre ordinateurs relis par un rseau Ethernet. Lorsquun graphe est pondr (voir quation 2), nous pouvons associer un cot aux diffrents chemins contenus dans le graphe. Ainsi, le cot du chemin u1, u2, , uW tel que (ui , ui+1) A pour 1 i W 1 est donn par
C = c(ui , ui +1 ).
i =1 W 1

(3)

Un grand nombre de problmes consistent trouver un chemin entre u1 et uW et en mme temps minimiser le cot associ. Dans la thorie des graphes, nous faisons souvent labstraction de la faon dont les graphes sont reprsents. En informatique, dont le but consiste trouver des solutions aux problmes mathmatiques, la reprsentation des graphes est une question primordiale. Lune des reprsentation la plus utilise est la liste des nuds adjacents. Dans cette reprsentation, nous dressons une liste de nuds contenus dans le graphe et on les lie dautres listes numrant les nuds adjacents. La figure 3 est une reprsentation figurative dune liste de nuds adjacents du graphe orient de la est utilis ici pour reprsenter le vide ou la fin dune liste. figure 2. Le symbole Lavantage de cette reprsentation rside dans sa simplicit et dans lconomie de son implantation. En fait, lespace mmoire ncessaire pour emmagasiner la liste de nuds adjacents est proportionnel au nombre des nuds et au nombre dartes du graphe (Cest--dire, | N | + | A | o | | est le nombre cardinal de lensemble).

1 2 3 4 5 6 7 8

2 4 3 5 7 6 3 8 8

1 700

4 700

300

600

6 700

1200

Figure 3 a) Liste des nuds adjacents. (b) Graphe orient de la figure 2.

Il est vident que la liste des nuds adjacents peut avoir des nuds non distincts pour les graphes orients (exemple : dans la figure 3, le nud 8 apparat deux fois parmi les nuds adjacents). Pour les graphes non orients, les nuds de la liste peuvent tre tous distincts. Il arrive que deux nuds soient relis entre eux par plus dune arte pour indiquer diffrentes situations concrtes. Un graphe admet ce genre de liens condition quil existe des caractristiques diffrentes. Dans le cas des graphes orients et pondrs, on peut lier deux nuds par plus dune arte si la direction ou la pondration est diffrente. Par exemple, le graphe de la figure 4 montre un petit quadrilatre des rues du centre-ville de Montral. Certaines de ces rues sont de sens unique alors dautres sont de double sens de circulation.
1 700 2 3 1700 1 Ste-Catherine - Mansfield 2 Ste-Catherine - McGill 3 Ste-Catherine - Universit 4 Cathcart - Mansfield 5 Cathcart - McGill 6 Cathcart - Universit 7 Ren Lvesque - Mansfield 8 Ren Lvesque - Universit

400

700

4 700

300

600

6 700

1200

Figure 4 reprsentation particulire d'un graphe orient.

On constate dans le graphe orient de la figure 4 que les rues double sens de circulation sont simplement reprsentes par deux artes dorientation oppose. La figure 5 donne la liste des nuds adjacents du graphe de la figure 4.

1700

400

700

1 2 3 4 5 6 7 8

2 4 1 3 2 1 5 7 4 6 5 3 8 4 8 7

1 700

4 700

300

600

6 700

1200

Figure 5 Liste des nuds adjacents du graphe de la figure 4.

Attention : Certains algorithmes de graphe nacceptent pas ce genre de modification. Vous devez alors ajouter des nuds au graphe de base pour permettre lajout des liens (ou des pondrations) supplmentaires. Application de lalgorithme de Dijsktra Cet algorithme accepte un graphe de nature illustr dans les figures 1, 2 et 4. Pour les besoins de ce document, nous appliquerons lalgorithme de Dijsktra aux graphes de type illustr dans la figure 4. Lalgorithme de Dijsktra ncessite galement une table pour mmoriser les nuds visits. Cette table peut tre ralise de multiple faon (liste de priorit, heaps, etc.). La figure 6 donne le contenu de cette table. Nud Trait Cot Chemin

Figure 6 Table utilise par l'algorithme de Dijkstra pour mmoriser les informations utiles.

La colonne Nud sert identifier les nuds du graphe. La colonne Trait indique si le nud correspondant est trait (ou non). La colonne Cot indique le cot minimal du chemin passant par ce nud. Enfin, la colonne Chemin donne le nud prdcesseur du nud identifi dans la colonne Nud . Par exemple, dans le graphe de la figure 4, le nud 3 peut avoir comme nuds prdcesseurs le nud 2 ou le nud 6.
7

1700

400

700

Voici lalgorithme de Dijsktra donn sous forme de pseudo-code. En pratique, cet algorithme comprend trois parties : i) rglage initial de la table des donnes; ii) parcours de la table pour la formation des chemins cots minimaux; iii) la fouille des chemins minimaux.
Dfinition des paramtres de lalgorithme
typedef int NUD; // un nud const int MARQUEUR_ARRT = -1; // marqueur spcial LISTE_NUD_ADJACENT lna; // liste des nuds adjacents typedef struct _TABLE { // Table des donnes (voir figure 6) bool trait; int cot; NUD chemin; } TABLE // MAX_NUD est le nombre de nuds dans le graphe TABLE table[MAX_NUD];

Rglage initial de la table


// source est le nud de dpart void InitTable(NUD source, TABLE T[]) { // construire la liste des nuds adjacents partir du // graphe Construire(lna); // Rglage initial de la table for (i=0; i<MAX_NUD; i++) { T[i].trait = false; T[i].cot = ; // infini T[i].chemin = MARQUEUR_ARRT; // pas de prdcesseur } // Le cot pour atteindre le nud de dpart est toujours zro // Ici on indique le nud de dpart pour la fouille des chemins // cot minimaux T[source].cot = 0; }

Parcours de la table
// Cette fonction imprime le chemin cot minimal partir // du nud de dpart vers un nud quelconque du graphe // v est le nud de destination void ParcoureTable(NUD v, Table T[]) { if (T[v].chemin != MARQUEUR_ARRT) { ParcoureTable(T[v].chemin, T); cout << " "; } printf(" %d : cot du chemin %d", v, T[v].cot); }
8

Identification des chemins minimaux


void Dijkstra(LISTE_NUD_ADJACENT lna, TABLE T[]) { 1 NUD u, v; 2 while ( true) { 3 // cherche le nud traiter 4 u = nud avec le plus petit cot et non trait dans la 5 table T 6 ou 7 MARQUEUR_ARRT si ce nud nexiste pas 8 if (u == MARQUEUR_ARRT) 9 return; 10 T[u].trait = true; 11 // pour chaque nud adjacent de u faire 12 while ((v = adjacent(u, lna)) != vide) { 13 if (!T[v].trait) 14 // Est-ce un cot minimal ? 15 // c(u, v) est la valeur de larte reliant les 16 // les nuds u et v 17 if (T[u].cot + c(u, v) < T[v].cot) { 18 // ajuster le cot et indique le nud prdcesseur 19 T[v].cot = T[u].cot + c(u, v); 20 T[v].chemin = u; 21 } 22 } 23 } }

Le rglage initial de la table des donnes ne doit pas poser de problme. Le seul point important est dassigner au nud de dpart un cot zro et pour tous les autres nuds un cot infini (ou trs grand). La fonction ParcoureTable() est simplement une fonction rcursive qui imprime un chemin cot minimal partir des nuds prdcesseurs contenus dans la table. Cette fonction est utilise une fois tous les chemins minimaux auront t identifis par lalgorithme de Dijsktra. Lalgorithme de Dijsktra consiste en une boucle infinie (ligne 2). On doit toujours traiter le nud dont le cot (estim) est le plus petit et qui nest pas encore trait (ligne 4 7). Le nud slectionn est marqu comme trait (ligne 10). Sil ny a pas de nuds de cette nature alors lalgorithme doit terminer son excution puisque tous les chemins cots minimaux ont t identifis. Lalgorithme utilise le parcours systmatique en largeur dabord dun graphe pour identifier tous les chemins dont le cot est minimal. Le parcours en largeur dabord consiste traiter tous les nuds adjacents dun nud avant de traiter les nuds adjacents des nuds adjacents (et ainsi de suite). Les chemins cots minimaux sont donc construits en ajoutant les artes bouts bouts partir du nud de dpart (source). Durant ce parcours systmatique du graphe (ligne 12), lalgorithme prend note du cot du chemin de chacun des nuds rencontrs. Il est galement
9

gourmand puisque chaque rencontre dun nud, lalgorithme slectionne toujours larte qui donne le plus petit cot au chemin courant (ligne 4). Le reste des tapes de lalgorithme consiste rajuster, au besoin, le cot des chemins et les nuds prdcesseurs (lignes 17 20). Nous allons prsenter un exemple montrant le principe dopration de lalgorithme de Dijkstra. Cet exemple utilise le graphe de la figure 4 et la liste de nuds adjacents de la figure 5. Rappelons que ce graphe reprsente un petit quadrilatre centre-ville.
1 2 3 4 5 6 7 8 2 4 1 3 2 1 5 7 4 6 5 3 8 4 8 7 1 700 2 3 1700 6 700 1200 8
10

400

700

4 700

300

600

1 Ste-Catherine - Mansfield 2 Ste-Catherine - McGill 3 Ste-Catherine - Universit 4 Cathcart - Mansfield

5 Cathcart - McGill 6 Cathcart - Universit 7 Ren Lvesque - Mansfield 8 Ren Lvesque - Universit

Figure 7 Quadrilatre des rues utiliss pour cet exemple.

Lobjectif ici est dobtenir les chemins minimaux entre le nud 1 qui joue le rle du nud de dpart et les nuds 5 et 8. Dabord initialisons la table des donnes. 1) Rglage initial de la table : Nud Trait Cot Chemin MARQUEUR_ARRT 1 false 0 MARQUEUR_ARRT 2 false MARQUEUR_ARRT 3 false MARQUEUR_ARRT 4 false MARQUEUR_ARRT 5 false MARQUEUR_ARRT 6 false MARQUEUR_ARRT 7 false MARQUEUR_ARRT 8 false Note : ltat initial seulement le nud de dpart a un cot initial de zro.

2) Excution de lalgorithme de Dijkstra : i) Slectionner le nud 1, u = 1 puisque son cot est le plus petit parmi les nuds pas encore traits. T[1].cot est 0.
T[1].trait = true

ii)

prendre un nud v qui est adjacent u. v = 2. a) T[1].cot + c(1, 2) < T[2].cot ? 0 + 400 < vrai alors T[2].cot = 400, T[2].chemin = 1. prendre un nud v qui est adjacent u. v = 4 b) T[1].cot + c(1, 4) < T[4].cot ? 0 + 700 < vrai alors T[4].cot = 700, T[4].chemin = 1.

iii)

Ltat actuel de la table des donnes Nud 1 2 3 4 5 6 7 8 Trait true false false false false false false false Cot 0 400 700 Chemin
MARQUEUR_ARRT 1 MARQUEUR_ARRT 1 MARQUEUR_ARRT MARQUEUR_ARRT MARQUEUR_ARRT MARQUEUR_ARRT

i) Slectionner le nud 2, u = 2 puisque son cot est le plus petit parmi les nuds pas encore traits. T[2].cot est 400.
T[2].trait = true

ii)

prendre un nud v qui est adjacent u. v = 1. a) nud 1 est dj trait passe au nud adjacent suivant. prendre un nud v qui est adjacent u. v = 3.
11

b) T[2].cot + c(2, 3) < T[3].cot ? 400 + 700 < vrai alors T[3].cot = 1100, T[3].chemin = 2. iii) Ltat actuel de la table des donnes Nud 1 2 3 4 5 6 7 8 i) Slectionner le nud 4, u = 4 puisque son cot est le plus petit parmi les nuds pas encore traits. T[4].cot est 700.
T[4].trait = true

Trait true true false false false false false false

Cot 0 400 1100 700

Chemin
MARQUEUR_ARRT 1 2 1 MARQUEUR_ARRT MARQUEUR_ARRT MARQUEUR_ARRT MARQUEUR_ARRT

ii)

prendre un nud v qui est adjacent u. v = 1. a) nud 1 est dj trait. prendre un nud v qui est adjacent u. v = 5. b) T[4].cot + c(4, 5) < T[5].cot ? 700 + 300 < vrai alors T[5].cot = 1000, T[5].chemin = 4. prendre un nud v qui est adjacent u. v = 7. b) T[4].cot + c(4, 7) < T[7].cot ? 700 + 700 < vrai alors T[7].cot = 1400, T[7].chemin = 4.

iii)

Ltat actuel de la table des donnes Nud 1 2 3 4 5 Trait true true false true false
12

Cot 0 400 1100 700 1000

Chemin
MARQUEUR_ARRT 1 2 1 4

6 7 8 i)

false false false

1400

MARQUEUR_ARRT 4 MARQUEUR_ARRT

Slectionner le nud 5, u = 5 puisque son cot est le plus petit parmi les nuds pas encore traits. T[5].cot est 1000.
T[5].trait = true

ii)

prendre un nud v qui est adjacent u. v = 4. a) nud 4 est dj trait. prendre un nud v qui est adjacent u. v = 6. b) T[5].cot + c(5, 6) < T[6].cot ? 5. 1000 + 600 < vrai alors T[6].cot = 1600, T[6].chemin =

iii)

Ltat actuel de la table des donnes Nud 1 2 3 4 5 6 7 8 Trait true true false true true false false false Cot 0 400 1100 700 1000 1600 1400 Chemin
MARQUEUR_ARRT 1 2 1 4 5 4 MARQUEUR_ARRT

i) Slectionner le nud 3, u = 3 puisque son cot est le plus petit parmi les nuds pas encore traits. T[3].cot est 1100.
T[3].trait = true

ii)

prendre un nud v qui est adjacent u. v = 2. a) nud 2 est dj trait.

iii)

Ltat actuel de la table des donnes


13

Nud 1 2 3 4 5 6 7 8 i)

Trait true true true true true false false false

Cot 0 400 1100 700 1000 1600 1400

Chemin
MARQUEUR_ARRT 1 2 1 4 5 4 MARQUEUR_ARRT

Slectionner le nud 7, u = 7 puisque son cot est le plus petit parmi les nuds pas encore trait. T[7].cot est 1400.
T[7].trait = true

ii)

prendre un nud v qui est adjacent u. v = 4. a) nud 4 est dj trait. prendre un nud v qui est adjacent u. v = 8. b) T[7].cot + c(7, 8) < T[8].cot ? 7. 1400 + 1200 < vrai alors T[8].cot = 2600, T[8].chemin =

iii)

Ltat actuel de la table des donnes Nud 1 2 3 4 5 6 7 8 Trait true true true true true false true false Cot 0 400 1100 700 1000 1600 1400 2600 Chemin
MARQUEUR_ARRT 1 2 1 4 5 4 7

i) Slectionner le nud 6, u = 6 puisque son cot est le plus petit parmi les nuds pas encore traits. T[6].cot est 1600.
T[6].trait = true
14

ii)

prendre un nud v qui est adjacent u. v = 3. b) nud 3 est dj trait. prendre un nud v qui est adjacent u. v = 8. b) T[6].cot + c(6, 8) < T[8].cot ? 1600 + 700 < 2600 vrai alors T[8].cot = 2300, T[8].chemin = 6.

iii)

Ltat actuel de la table des donnes Nud 1 2 3 4 5 6 7 8 Trait true true true true true true true false Cot 0 400 1100 700 1000 1600 1400 2300 Chemin
MARQUEUR_ARRT 1 2 1 4 5 4 6

i) Slectionner le nud 8, u = 8 puisque son cot est le plus petit parmi les nuds pas encore traits. T[8].cot est 2300.
T[8].trait = true

ii)

prendre un nud v qui est adjacent u. v = 7 a) nud 7 est dj trait.

iii)

Ltat actuel de la table des donnes Nud 1 2 3 4 5 6 7 8 Trait true true true true true true true true Cot 0 400 1100 700 1000 1600 1400 2300 Chemin
MARQUEUR_ARRT 1 2 1 4 5 4 6

15

i) Il ny a plus de nud non trait. Lalgorithme doit terminer son excution.

Note : La dernire table des donnes donne le rsultat de lalgorithme de Dijsktra.

3) Affichage des chemins minimaux : Nud de dpart 1, nuds darrive 5 et 8.


ParcoureTable(5, T[]);

T[5].chemin nud 4 cot 1000 T[4].chemin nud 1 T[1].chemin MARQUEUR_ARRT

Affichage :
1 4 5 : cot du chemin 1000

ParcoureTable(8, T[]);

T[8].chemin nud 6 cot 2300 T[6].chemin nud 5 T[5].chemin nud 4 T[4].chemin nud 1 T[1].chemin MARQUEUR_ARRT

Affichage :
1 4 5 6 8 : cot du chemin 2300

16