Laboratoire de Programmation Système de renseignements automatiques pour voyageurs de la SNCB - Algorithme de Moore-Dijkstra - Info BAC 2 - Volvert Sylvain Février 2012 Table des matières 1. Représentation des données (rappel) .................................................................................. 3 2. Code de l'algorithme ........................................................................................................... 4 3. Spécification de l'algorithme de Moore-Dijkstra ................................................................ 4 4. Organigramme de l'algorithme ........................................................................................... 5 5. Invariant de l'algorithme ..................................................................................................... 6 6. Preuve de la correction de l'algorithme de Moore-Dijkstra ................................................ 6 7. 6.1. Correction partielle ...................................................................................................... 6 6.2. Correction totale de l'algorithme ............................................................................... 10 Adaptation de l'algorithme de Moore-Dijstra ................................................................... 11 1. Représentation des données (rappel) tab_horaire = array [1..2 , 1..40] of string ; l_gare = cel_gare = ↑cal_gare; record gare_prec : l_gare; nom_gare : string; gare_suiv : l_gare; end; l_train = cel_train = ↑cel_train ; record num_train : string ; horaire : tab_horaire ; train_suiv : l_train ; end ; l_liaison = ↑cel_liaison ; cel_liaison = record nom_li : string ; début : l_gare ; fin : l_gare ; train : l_train ; liaison_suiv : l_liaison ; end ; l_gare : gare : l_liaison : liai : l_train : train : gare_prec nom_gare nom_li début num_train fin horaire train liaison_suiv gare_prec … nom_li … train_suiv 1 tab_horaire : … gare_suiv (la) num_train 2 1 (lb) Arrêt 40 Page 3 sur 11 début heure nom_gare fin train horaire 2. Code de l'algorithme D := {d}; π(d) := 0; foreach x ∈ X \ D do begin π(x) := π(d) + p(d,x); prec(x) := d end while D ≠ X do begin choose c ∈ X \ D such that π(c) = min{ π(y) : y ∈ X \ D}; D := D ∪ {c}; foreach x ∈ X \ D do if π(c) + p(c,x) < π(x) then begin π(c) := π(c) + p(c,x); prec(x) :=c end end rappel : - On partitionne l'ensemble X en deux ensembles : D et X \ D Un tableau π relève pour chaque point le poids du meilleur chemin connu jusqu'à présent Un autre tableau prec détermine pour chaque point son prédécesseur sur le chemin extrémal qui mène à lui 3. Spécification de l'algorithme de Moore-Dijkstra Pré : Post : 1 p initialisé ˄ X⊇{d} ∈X π in ∑ 1 "x-1" représente le prec(x) Page 4 sur 11 4. Organigramme de l'algorithme MooreDijkstra Initialisation des poids Selection d'un point p de poids minimum Mise à jour du poids π(x) au vu d'un arc possible (p,x) Et voici la représentation de l'algorithme sous forme d'ordinogramme : Page 5 sur 11 5. Invariant de l'algorithme ∈ ∈ { {∑ 6. Preuve de la correction de l'algorithme de Moore-Dijkstra 6.1. Correction partielle Rappels des étapes clefs de la correction partielle : 1) {PRE} Init {INV} 2) {INV ˄¬B} Iter {INV} 3) {INV ˄ B} Clot {POST} 1) {PRE} INIT {INV} Init : D := {d}; π(d) := 0; foreach x ∈ X \ D do begin π(x) := π(d) + p(d,x); prec(x) := d end Page 6 sur 11 wp (D = {d}; π(d) = 0; π(x) = π(d) + p(d,x); prec(x) = d { π(x) = min{∑ x∈X: ∈ { ˄ prec [x] = c }) x∈X: = wp (D = {d}; π(d) = 0; π(x) = π(d) + p(d,x) { ˄ prec [ ] c }) min{∑ = wp (D = {d}; π(d) = 0 { x∈X: ∈ ={ π(x) = [prec(x) / d] ∈ = {d} : π(x)= min{∑ ˄d c }) [π(x) / π(d) + p(d,x)] = wp( D={d} { x∈X: ∈ { π(d)+p(d,x) = min{∑ ˄d c }) [ π(d) / 0 ] ={ x∈X: d ∈ D : D={d} : p(d,x) = min{∑ ˄ d = c} C'est bien correct car la précondition => { x ∈ X : ∈ { ˄d p(d,x) = min{∑ 2) {INV ˄¬B} Iter {INV} Inv : ∈ ∈ { {∑ ¬B : X ≠ D Iter : Q choose c ∈ X \ D such that π(c) = min{ π(y) : y ∈ X \ D}; D := D ∪ {c}; foreach x ∈ X \ D do if π(c) + p(c,x) < π(x) B then begin π(c) := π(c) + p(c,x); I1 prec(x) :=c end I2: / Page 7 sur 11 c} /!\ A wp (if B then I1 else I2; Q) = (B ∧ wp (I1;Q)) ∨ (¬B ∧ wp (I2;Q)) (π(c) + p(c,x) < π prec(x):=c { ˄ wp (π(c) = min{ π (y) : y ∈ \D}; D := D ∪ {c} ; π(x):= π(c) +p(c,x); x∈X: ∈ { π(x) = min{∑ ˄ prec [x]= c}) ) ˅ B ( π(c) + p c, { ≥π ˄ wp (π(c) = min{ π (y) : y ∈ \D}; D := D ∪{c} { π(x) = min{∑ x∈X: ∈D: ˄ prec [x]= c})) ------------------------------------------------------- A: (π(c) + p(c,x) < π prec(x):=c { ˄ wp (π(c) = min{ π (y) : y ∈ \D}; D := D ∪ {c} ; π(x):= π(c) +p(c,x) ; x∈X: =(π(c) + p(c,x) < π { x∈X: ∈ =(π(c) + p(c,x) < π { ∈ { { π(x) = min{∑ ˄ prec [x]= c })) [prec(x) / c ] ˄ wp π(c) = min{ π (y) : y ∈ \D}; D := D ∪ {c} { x ∈ X : ∈D: ˄ c = c })) [π(x)/ π(c) +p(c,x) ] ˄ wp (π(c) = min{ π (y) : y ∈ \D}{ x ∈ X : π(c) +p(c,x) = min{∑ =(π(c) + p(c,x) < π ˄ prec [x]= c})) ˄ wp (π(c) = min{ π (y) : y ∈ \D}; D := D ∪ {c} ; π(x):= π(c) +p(c,x) π(x) = min{∑ = (π(c) + p(c,x) < π π(x) = min{∑ ∈ { })) [D / D ∪ {c}] ˄{ x∈X: ∈ D ∪ {c} : D ∪ {c} { min{∑ ˄ c = c }) [π(c) / min{ π (y) : y ∈ X\D] =(π(c) + p(c,x) < π ˄{ x∈X: min{∑ }) ∈D:D { Page 8 sur 11 π(c) +p(c,x) = min{ π (y) : y ∈ \D +p(c,x) = B: ( π(c) + p c, { ≥π ˄ wp (π(c) = min{ π (y) : y ∈ \D}; D := D ∪ {c} { π(x) = min{∑ = ( π(c) + p c, ≥π x∈X: ∈ { ˄ prec [ ] c})) [D / D ∪ {c} ] ≥π ˄{ x∈X: ∈ D∪{c} : D∪{c} { ˄ prec [x]= c}) min{∑ = ( π(c) + p c, ∈ ˄ prec [x]= c})) ˄ wp (π(c) = min{ π (y) : y ∈ \D} { π(x) = min{∑ = ( π(c) + p c, x∈X: ≥π ˄{ x∈X: π(x) = [π(c) / min{ π (y) : y ∈ X\D ] ∈D:D { π(x) = min{∑ ˄ prec [x]= c})) En combinant A et B, nous obtenons : (π(c) + p(c,x) < π min{∑ ˄{ x∈X: }) ∈D:D { min{ π (y) : y ∈ \D +p(c,x) = ˅ ( π(c) + p c, [x]= c})) ≥π ˄{ x∈X: ∈D:D { INV ˄¬B => le résultat de la wp ci-dessus. C'est bien correct. Page 9 sur 11 π(x) = min{∑ ˄ prec 3) {INV ˄ B} Clot {POST} B: X= D Clot : / Inv : x∈X: Sp ( x ∈ X : = x∈X: c∈D D c∈D D c∈D D d … c} π(x) = min{∑ ˄ prec [x]= c d … c} π(x) = min{∑ d … c} π(x) = min{∑ ˄ prec [x]= c ; D = X) ˄ prec [x]= c ˄ D = X On remarque que cela implique la post-condition et donc que cela est correct. 6.2. Correction totale de l'algorithme Rappels pour obtenir la correction totale : 1) Trouver un ensemble bien fondé 2) Trouver une fonction sur cet ensemble 3) Montrer que l'on sort bien de la boucle (élément minimal) 4) Montrer que la fonction décroit à chaque itération 1) Trouver un ensemble bien fondé (N, <) 2) Déterminer une fonction sur cet ensemble f (D) = X - D 3) Montrer que l'on sort bien de la boucle (élément minimal) X-D=0 X=D on sort bien de la boucle. 4) Montrer que la fonction décroit à chaque itération sp (D = D ∪{c} ; { f0 = X - D }) = { f0 = X - D ˄ D = D ∪ {c}} [D / D’] = {f0 = X - D’ ˄ D D’ ∪ {c}} D’ D / c} = {f0 = X - (D / {c}) } = {f0 = X - D + 1 } = { f0 = f1 + 1 } Cela prouve la décroissance à chaque itération. Page 10 sur 11 7. Adaptation de l'algorithme de Moore-Dijstra (Bonus) Page 11 sur 11