Introduction Kruskal Prim IFT 436 - Algorithmes et structures de données Algorithmes sur les Graphes - MST Rachid Kadouche Université de Sherbrooke 23 juillet 2013 1 Introduction Kruskal Prim L’arbre couvrant de poids minimum (Minimum Spanning Tree) 2 Introduction Kruskal Prim Le problème Soit un graphe non orienté G = (S, A) Une fonction de pondération w : A → R : w (u, v ) le poids de chaque arête (u, v ) ∈ A Trouver T ⊆ A tel que 1 2 T connecte P tous les sommets w (T ) = (u,v )∈T w (u, v ) est minimisé. L’arbre couvrant dont le poids est le plus petit de tous les arbres couvrants est appelé l’arbre couvrant de poids minimum. (Minimum Spanning Tree) 3 Introduction Kruskal Prim MST - Algo général : explication On veut construire un ens. E d’arêtes. Initialement E est vide. Nous ajoutons des arêtes à E en maintenant la propriété suivante : E est un sous ens. d’un MST. On ajout seulement des arêtes qui maintiennent cette propriété . Si E est un sous-ens. d’un MST, une arêtes (u, v ) est sûre pour E ssi E ∪ {(u, v )} est aussi un sous-ens. de MST. 4 Introduction Kruskal Prim MST - Algo général : pseudo Algorithme : GENERIC-MST(G, w) 4 E ← ∅; while E ne forme pas un MST do trouver une arête (u, v ) que l’on peut ajouter à E ; E ← E ∪ {(u, v )}; 5 return E 1 2 3 5 Introduction Kruskal Prim MST - Une coupe Soit un graphe G = (S, A), -V ⊂ S -T un MST et E ⊂ T . (V , S − V ) est une coupe l’arête(f , d) ∈ A traverse la coupe (V , S − V ) et l’arête(c, d) est minimale (V , S − V ) une coupe qui respecte E 6 Introduction Kruskal Prim MST - Théorème Posons : G = (S, A) un graphe connexe, non-orienté et pondéré, E un sous-ens d’un MST, (V , S − V ) une coupe qui respecte E , (u, v ) une arête minimale qui traverse (V , S − V ) alors (u, v ) est une arête sûre pour E . 7 Introduction Kruskal Prim Algo de Kruskal : l’idée Mettre chaque sommet dans un ens. disjoint. Trier les arêtes de A en ordre croissant de poids. Pour chaque arête : Si les sommets ne sont pas dans le même ens., les joindre. (Union) 8 Introduction Kruskal Prim Kruskal - Exemple 9 Introduction Kruskal Prim Kruskal - Exemple 10 Introduction Kruskal Prim Kruskal - Exemple 11 Introduction Kruskal Prim MST - Kruskal Algorithme : MST-Kruskal(G) 1 2 3 8 Trier A en ordre croissant de poids; foreach (u, v ) ∈ A trié do if Find-Set(u) 6= Find-Set(v) then E ← E ∪ {(u, v )}; Union(u,v); 9 return E 4 5 6 7 12 E ← ∅; foreach v ∈ S do Make-Set(v); Introduction Kruskal Prim Analyse du MST - Kruskal Algorithme : MST-Kruskal(G) 1 2 3 8 Trier A en ordre croissant de poids; foreach (u, v ) ∈ A trié do if Find-Set(u) 6= Find-Set(v) then E ← E ∪ {(u, v )}; Union(u,v); 9 return E 4 5 6 7 13 E ← ∅; foreach v ∈ S do Make-Set(v); Introduction Kruskal Prim Analyse du MST - Kruskal Algorithme : MST-Kruskal(G) 1 2 3 8 Trier A en ordre croissant de poids; foreach (u, v ) ∈ A trié do if Find-Set(u) 6= Find-Set(v) then E ← E ∪ {(u, v )}; Union(u,v); 9 return E 4 5 6 7 14 E ← ∅; foreach v ∈ S do Make-Set(v); En utilisant l’implémentation des forêts d’ensembles disjoints (voir chapitre 21 du manuel) Introduction Kruskal Prim Analyse du MST - Kruskal Algorithme : MST-Kruskal(G) 1 2 3 8 Trier A en ordre croissant de poids; foreach (u, v ) ∈ A trié do if Find-Set(u) 6= Find-Set(v) then E ← E ∪ {(u, v )}; Union(u,v); 9 return E 4 5 6 7 15 E ← ∅; foreach v ∈ S do Make-Set(v); En utilisant l’implémentation des forêts d’ensembles disjoints (voir chapitre 21 du manuel) Ligne 3 : O(S lg S) Introduction Kruskal Prim Analyse du MST - Kruskal Algorithme : MST-Kruskal(G) 1 2 3 8 Trier A en ordre croissant de poids; foreach (u, v ) ∈ A trié do if Find-Set(u) 6= Find-Set(v) then E ← E ∪ {(u, v )}; Union(u,v); 9 return E 4 5 6 7 16 E ← ∅; foreach v ∈ S do Make-Set(v); En utilisant l’implémentation des forêts d’ensembles disjoints (voir chapitre 21 du manuel) Ligne 3 : O(S lg S) Ligne 4 : O(A lg A) Introduction Kruskal Prim Analyse du MST - Kruskal Algorithme : MST-Kruskal(G) 1 2 3 8 Trier A en ordre croissant de poids; foreach (u, v ) ∈ A trié do if Find-Set(u) 6= Find-Set(v) then E ← E ∪ {(u, v )}; Union(u,v); 9 return E 4 5 6 7 17 E ← ∅; foreach v ∈ S do Make-Set(v); En utilisant l’implémentation des forêts d’ensembles disjoints (voir chapitre 21 du manuel) Ligne 3 : O(S lg S) Ligne 4 : O(A lg A) Ligne 6,7 et 8 : O(A lg S) Introduction Kruskal Prim Analyse du MST - Kruskal Algorithme : MST-Kruskal(G) 1 2 3 8 Trier A en ordre croissant de poids; foreach (u, v ) ∈ A trié do if Find-Set(u) 6= Find-Set(v) then E ← E ∪ {(u, v )}; Union(u,v); 9 return E 4 5 6 7 18 E ← ∅; foreach v ∈ S do Make-Set(v); En utilisant l’implémentation des forêts d’ensembles disjoints (voir chapitre 21 du manuel) Ligne 3 : O(S lg S) Ligne 4 : O(A lg A) Ligne 6,7 et 8 : O(A lg S) T (S, A) = O((S + A)lgS + A lg A) Introduction Kruskal Prim Analyse du MST - Kruskal Algorithme : MST-Kruskal(G) 1 2 3 8 Trier A en ordre croissant de poids; foreach (u, v ) ∈ A trié do if Find-Set(u) 6= Find-Set(v) then E ← E ∪ {(u, v )}; Union(u,v); 9 return E 4 5 6 7 19 E ← ∅; foreach v ∈ S do Make-Set(v); En utilisant l’implémentation des forêts d’ensembles disjoints (voir chapitre 21 du manuel) Ligne 3 : O(S lg S) Ligne 4 : O(A lg A) Ligne 6,7 et 8 : O(A lg S) T (S, A) = O((S + A)lgS + A lg A) Si G est connexe et simple : |A| ≥ |S| − 1 ⇒ O((S + A) lg S) = O(A lg S) A = O(S 2 ) ⇒ lg A = O(lg S) Introduction Kruskal Prim Analyse du MST - Kruskal Algorithme : MST-Kruskal(G) 1 2 3 8 Trier A en ordre croissant de poids; foreach (u, v ) ∈ A trié do if Find-Set(u) 6= Find-Set(v) then E ← E ∪ {(u, v )}; Union(u,v); 9 return E 4 5 6 7 20 E ← ∅; foreach v ∈ S do Make-Set(v); En utilisant l’implémentation des forêts d’ensembles disjoints (voir chapitre 21 du manuel) Ligne 3 : O(S lg S) Ligne 4 : O(A lg A) Ligne 6,7 et 8 : O(A lg S) T (S, A) = O((S + A)lgS + A lg A) Si G est connexe et simple : |A| ≥ |S| − 1 ⇒ O((S + A) lg S) = O(A lg S) A = O(S 2 ) ⇒ lg A = O(lg S) T (S, A) = O(A lg S) Introduction Kruskal Prim Algo de Prim : l’idée Plutôt que de joindre des arbres, on va en faire croı̂tre un seul. On choisit arbitrairement une racine. À chaque étape, on choisit une arête minimale qui traverse la coupe (V , S − V ). 21 Introduction Kruskal Prim Prim - Exemple 22 Introduction Kruskal Prim Prim - Exemple 23 Introduction Kruskal Prim Comment trouver une arête minimale rapidement Utilise une queue à priorité minimum (Q). Les éléments de Q sont les sommets de S − V . Un sommet v retourné par Extract-Min est tel que ∃u ∈ S pour lequel (u, v ) est une arête minimale traversant (V , S − V ) La clé de v est ∞ si v n’est pas adjacent à aucun sommets de V . 24 Introduction Kruskal Prim MST - Algo Prim Algorithme : Prim(G, r) 1 2 3 4 5 6 7 8 9 10 11 12 25 Q ← ∅; foreach u ∈ S do key [u] ← ∞; π[u] ← NIL; Insert(Q, u); Decrease-Key(Q, r, 0) ; while Q 6= ∅ do u ← Extract-Min(Q); foreach v ∈ Adj[u] do if v ∈ Q et w (u, v ) < key [v ] then π[v ] ← u; Decrease-Key(Q, v, w(u,v)); /* key [r ] ← 0 */ Introduction Kruskal Prim Analyse de MST - Algo Prim Algorithme : Prim(G, r) 1 2 3 4 5 6 7 8 9 10 11 12 26 Q ← ∅; foreach u ∈ S do key [u] ← ∞; π[u] ← NIL; Insert(Q, u); Decrease-Key(Q, r, 0); while Q 6= ∅ do u ← Extract-Min(Q); foreach v ∈ Adj[u] do if v ∈ Q et w (u, v ) < key [v ] then π[v ] ← u; Decrease-Key(Q, v, w(u,v)); Q est stocké dans un tableau de 1 à S, key [v ] est stocké dans le vème elmt Les opérations sur Q sont : Insert(Q ← S) (ligne 5) Extract-Min(Q) (ligne 8) Decrease-Key (ligne 12) Introduction Kruskal Prim Analyse de MST - Algo Prim Algorithme : Prim(G, r) 1 2 3 4 5 6 7 8 9 10 11 12 27 Q ← ∅; foreach u ∈ S do key [u] ← ∞; π[u] ← NIL; Insert(Q, u); Decrease-Key(Q, r, 0); while Q 6= ∅ do u ← Extract-Min(Q); foreach v ∈ Adj[u] do if v ∈ Q et w (u, v ) < key [v ] then π[v ] ← u; Decrease-Key(Q, v, w(u,v)); Q est stocké dans un tableau de 1 à S, key [v ] est stocké dans le vème elmt Les opérations sur Q sont : Insert(Q ← S) (ligne 5) Θ(S) Extract-Min(Q) (ligne 8) O(S) (S fois) Decrease-Key (ligne 12) Θ(1)(au plus A fois) Introduction Kruskal Prim Analyse de MST - Algo Prim Algorithme : Prim(G, r) 1 2 3 4 5 6 7 8 9 10 11 12 28 Q ← ∅; foreach u ∈ S do key [u] ← ∞; π[u] ← NIL; Insert(Q, u); Decrease-Key(Q, r, 0); while Q 6= ∅ do u ← Extract-Min(Q); foreach v ∈ Adj[u] do if v ∈ Q et w (u, v ) < key [v ] then π[v ] ← u; Decrease-Key(Q, v, w(u,v)); Q est stocké dans un tableau de 1 à S, key [v ] est stocké dans le vème elmt Les opérations sur Q sont : Insert(Q ← S) (ligne 5) Θ(S) Extract-Min(Q) (ligne 8) O(S) (S fois) Decrease-Key (ligne 12) Θ(1)(au plus A fois) T (A, S) = O(S 2 + A) Introduction Kruskal Prim Analyse de MST - Algo Prim Algorithme : Prim(G, r) 1 2 3 4 5 6 7 8 9 10 11 12 29 Q ← ∅; foreach u ∈ S do key [u] ← ∞; π[u] ← NIL; Insert(Q, u); Decrease-Key(Q, r, 0); while Q 6= ∅ do u ← Extract-Min(Q); foreach v ∈ Adj[u] do if v ∈ Q et w (u, v ) < key [v ] then π[v ] ← u; Decrease-Key(Q, v, w(u,v)); Q est stocké dans un tas min binaire Les opérations sur Q sont : Insert(Q ← S) (ligne 5) Extract-Min(Q) (ligne 8) Decrease-Key (ligne 12) Introduction Kruskal Prim Analyse de MST - Algo Prim Algorithme : Prim(G, r) 1 2 3 4 5 6 7 8 9 10 11 12 30 Q ← ∅; foreach u ∈ S do key [u] ← ∞; π[u] ← NIL; Insert(Q, u); Decrease-Key(Q, r, 0); while Q 6= ∅ do u ← Extract-Min(Q); foreach v ∈ Adj[u] do if v ∈ Q et w (u, v ) < key [v ] then π[v ] ← u; Decrease-Key(Q, v, w(u,v)); Q est stocké dans un tas min binaire Les opérations sur Q sont : Insert(Q ← S) (ligne 5) Θ(S) Extract-Min(Q) (ligne 8) O(lgS) (S fois) Decrease-Key (ligne 12) O(lgS) (au plus A fois) Introduction Kruskal Prim Analyse de MST - Algo Prim Algorithme : Prim(G, r) 1 2 3 4 5 6 7 8 9 10 11 12 31 Q ← ∅; foreach u ∈ S do key [u] ← ∞; π[u] ← NIL; Insert(Q, u); Decrease-Key(Q, r, 0); while Q 6= ∅ do u ← Extract-Min(Q); foreach v ∈ Adj[u] do if v ∈ Q et w (u, v ) < key [v ] then π[v ] ← u; Decrease-Key(Q, v, w(u,v)); Q est stocké dans un tas min binaire Les opérations sur Q sont : Insert(Q ← S) (ligne 5) Θ(S) Extract-Min(Q) (ligne 8) O(lgS) (S fois) Decrease-Key (ligne 12) O(lgS) (au plus A fois) T (A, S) = O((S + A)lgS) Introduction Kruskal Prim Analyse de MST - Algo Prim Algorithme : Prim(G, r) 1 2 3 4 5 6 7 8 9 10 11 12 32 Q ← ∅; foreach u ∈ S do key [u] ← ∞; π[u] ← NIL; Insert(Q, u); Decrease-Key(Q, r, 0); while Q 6= ∅ do u ← Extract-Min(Q); foreach v ∈ Adj[u] do if v ∈ Q et w (u, v ) < key [v ] then π[v ] ← u; Decrease-Key(Q, v, w(u,v)); Q est stocké dans un tas min binaire Les opérations sur Q sont : Insert(Q ← S) (ligne 5) Θ(S) Extract-Min(Q) (ligne 8) O(lgS) (S fois) Decrease-Key (ligne 12) O(lgS) (au plus A fois) T (A, S) = O((S + A)lgS) T (A, S) = O(SlgS + A) en utilisant un tas de Fibonacci (voir chapitre 20 du manuel)