Le plus court chemin d`un graphe

publicité
Le plus court chemin : PCC Exemple d’un graphe non pondéré, non valué Formalisation : I : G = (V,E), S ∈ V (depart), t (arrivé) S : {path (S,t)G } F : | path (S,t)G | Opt : min Voici un algorithme de bases pour tracer le plus court chemin de ce graphe, en partant de s pour arriver à t R = [] u = t While u != s : R.insert(0,u) u = P[u] Return R.insert(0,s) L’arbre des distances de ce graphe : On en déduit un tableau des parents, par exemple 4 a pour père 6, donc à la case 4, on mettra 6 au dessus 2 2 2 6 3 2 1 2 3 4 5 6 Problème du plan du métro paris On cherche à trouver le plus court chemin entre 2 stations données (s station de départ, t d’arriver). Formalisation : 𝐼 ∶ 𝐿 = 𝐿! , … 𝐿!" 𝑡, 𝑠 𝑠𝑡𝑎𝑡𝑖𝑜𝑛 𝑆 ∶ { 𝑆! , 𝑆! , … 𝑆!" / ∀ 𝑖 1 ≤ 𝑖 < 𝑘 − 2 ∃ 𝜆 𝑡𝑞 𝑠! ∈ 𝐿! ∧ 𝑠!!! ∈ 𝐿! ∧ 𝑠!!! ∉ 𝐿! f : k opt : min G= (V,E) 𝑉 = { 𝑆𝑡! , … , 𝑆𝑡!"# } 𝐸 = { 𝑥, 𝑦 / ∃ 𝑖 𝑥 ∈ 𝐿! 𝑒𝑡 𝑦 ∈ 𝐿! } TD partie 1 Exemple d’un graph à cycle : On a un cycle négatif, ex ici en calculant les distances si on fait 3 tours : s-­‐> ((5 + 2 – 8 + 1 + 4 = 4) + 2 – 8 + 1 + 4 = 3) + 2 – 8 + 1 + 4 = 2 -­‐>t On fait -­‐1 à chaque fois que l’ont a fait un tour complet On obtient une loi tel que : 𝑒
𝑒
𝑒
𝑒
𝑠 ≡ 𝑆! ! 𝑆! ! 𝑆! ! … 𝑆!!! ! 𝑆! ≡ 𝑡 → → →
→
min
𝑤(𝑒) ! ∈!"#! !,! !
Exemple d’estimation : Estimation : on donne un chemin le plus cours provisoire En partant de s, si on cherche à passer par z pour atteindre x plus vite, si on met entre z et x la valeur 55, on a pas améliorer le chemin provisoire, car 50+55 > 100, mais si on met 35 entre z et x, on l’a améliore, le chemin provisoire w(z,x) + le chemin de s à z est plus court que celui de s à x. On dit alors que w(z,x) est tense car dist[x] > dist[z] + w(z,x) Arrête tense : Arrête qui contribue a changer un schéma provisoire (ici w(z,x)) lorsqu’on trouve une arrête tense satisfaisable, on a trouvé le plus cours chemin ici on a donc choisis 35 comme valeur à w(z,x) car 100 > 50 + 35, on attribue donc à x une nouvelle distance : dist[x] <-­‐ 85 Algorithme noyau(G,u) dist = [∞ 𝑓𝑜𝑟 𝑢 𝑖𝑛 𝐺] Q={s} while Q : z = Q.delese() -­‐> on prends un élément, on le choisis et on le vide for x in adj[z] if 𝑀!! is tense dist[x] <-­‐ dist[z] + w(z,x) Q.add(x) Nota bene : 𝑀!! le chemin de x à z Cet algorithme est une adaptation de l’algorithme de ford en 1956, ainsi que celui de Dijkstra
On a calculé pour chaque sommet, la valeur du plus court chemin en partant de a (notre point de départ s), et on l’a noté en bleu à coté de chaque sommet (sauf d, qui est égal à 4 évidement) Algorithme du schéma : la plus petite distance entre un point et un autre sommet quelconque dist = [∞ 𝑓𝑜𝑟 𝑣 𝑖𝑛 𝐺] dist[s] = 0 O(v) P[s] = s Q = v while Q : z = Q.delete-­‐min() //on supprime le sommet avec le plus petit chemin provisoire : O(v) for x in adj [z] if dist[x] > dist[z] + w(z,x) dist[x] = dist[z] + w(z,x) P[x] = z -­‐> pere de x = z On calcule la complexité de l’algorithme : [𝑂 𝑣 + 𝑂(𝐸)] = 𝑂 𝑣 + 𝑣 ! + 𝐸 = 𝑂(𝑣 ! + 𝐸) 𝑂 𝑣 + ! !" !
Algorithme DIJKSTRA(G,u) Dist = [infinity for u in G] Dist[s] = 0 P[s] = s Q = V While Q : z = Q.delete_min() for x in adj[z] : Relax(z,x) … return < P, dist > Méthodes pour les tris par tas (heap = tas) Heap_push (heap, item) Heap_pop(heap) TD partie 2 Algorithme de Dijsktra Exemple d’un autre graphique 
Téléchargement