Calcul d`un arbre de recouvrement minimal

publicité
Calcul d’un arbre de recouvrement minimal
Ahmed Bouajjani
ENS Cachan, Magistère STIC, 2004-05
Problème de l’arbre de recouvrement minimal
• Soit G = (S, A) un graphe non orienté, et soit p : A → R une fonction de
pondération des arêtes.
• Problème : trouver un sous-ensemble T ⊆ A tel que
– T est acyclique (un arbre)
– T connecte tous les sommets de G
– T a un poids total
p(T ) =
X
(u,v)∈T
minimal
p(u, v)
Un algorithme générique
• Calculer progressivement un ensemble E d’arêtes en maintenant l’invariant
E est un sous-ensemble d’un arbre de recouvrement minimal
• ⇒ Ajouter à chaque itération une arête (u, v) admissible pour E :
E ∪ {(u, v)} satisfait toujours l’invariant
ARM-Gen(G, p) =
E←∅
tant que E n’est pas un ARM faire
Trouver une arête (u, v) admissible pour E
E ← E ∪ {(u, v)}
retourner E
Trouver un arc admissible
• Une coupure de G = (S, A) est une partition (U, S − U ) de S.
• Un arc (u, v) traverse une coupure (U, S − U ) si une des extrémités est dans
U et l’autre dans S − U .
• Une coupure respecte un ensemble d’arcs E si aucun des arcs de E ne
traverse la coupure.
• Un arc est léger pour une coupure (U, S − U ) s’il traverse la coupure, et si
son poids est le poids minimum parmi ceux des arcs traversant cette coupure.
Trouver un arc admissible
• Une coupure de G = (S, A) est une partition (U, S − U ) de S.
• Un arc (u, v) traverse une coupure (U, S − U ) si une des extrémités est dans
U et l’autre dans S − U .
• Une coupure respecte un ensemble d’arcs E si aucun des arcs de E ne
traverse la coupure.
• Un arc est léger pour une coupure (U, S − U ) s’il traverse la coupure, et si
son poids est le poids minimum parmi ceux des arcs traversant cette coupure.
Thm 1:
Soit G = (S, A) un graphe connexe non orienté, et soit p : A → R une
fonction de pondération. Soit E ⊆ A inclus dans un ARM de G, soit
(U, S − U ) une coupure de G qui respecte E, et soit (u, v) un arc léger
pour la coupure (U, S − U ). Alors, l’arc (u, v) est admissible pour E.
Trouver un arc admissible (suite)
Thm 1:
Soit G = (S, A) un graphe connexe non orienté, et soit p : A → R une fonction de
pondération. Soit E ⊆ A inclus dans un ARM de G, soit (U, S − U ) une coupure de
G qui respecte E, et soit (u, v) un arc léger pour la coupure (U, S − U ). Alors, l’arc
(u, v) est admissible pour E.
• Soit T un ARM contenant E, et supposons qu’il ne contient pas E ∪ {(u, v)},
• Soit c le chemin de u à v dans T . L’arc (u, v) forme un cycle avec c.
• (u, v) traverse (U, S − U ) ⇒ il existe un arc (x, y) de T qui traverse (U, S − U ),
• Soit T 0 = T − {(x, y)} ∪ {(u, v)},
• T 0 est un arbre de recouvrement
• T 0 est de poids minimal
– (u, v) est léger pour (U, S − U ) ⇒ p(u, v) ≤ p(x, y),
– p(T 0) = p(T ) − p(x, y) + p(u, v) ≤ p(T )
Algorithme de Kruskal (version abstraite)
• E est une forêt,
• E est étendue en connectant deux arbres différents par un des arcs de poids
min pouvant les relier.
Kruskal-Abst(G, p) =
E←∅
(initialement, la forêt représentée par E est constituée de l’ensemble des singletons
{s}, pour tout s ∈ S)
tant que E n’est pas réduit à un seul arbre faire
Trouver une arête (u, v) de poids min reliant deux arbres de E
E ← E ∪ {(u, v)}
retourner E
Algorithme de Kruskal
• E est implémenté comme une partition de S (structure union-find)
• Le choix des arcs admissibles : tri des arcs selon leur poids croissants.
Kruskal(G, p) =
E←∅
pout tout s ∈ S faire Créer-classe(s)
Trier les arcs de A dans l’ordre croissant de leurs poids p
pour tout (u, v) ∈ A pris dans l’ordre croissant du poids faire
si Trouver-classe(u) = Trouver-classe(v) alors
E ← E ∪ {(u, v)}
Union-classe(u, v)
retourner E
Algorithme de Kruskal (Complexité)
Kruskal(G, p) =
E←∅
pout tout s ∈ S faire Créer-classe(s)
Trier les arcs de A dans l’ordre croissant de leurs poids p
pour tout (u, v) ∈ A pris dans l’ordre croissant du poids faire
si Trouver-classe(u) = Trouver-classe(v) alors
E ← E ∪ {(u, v)}
Union-classe(u, v)
retourner E
• Tri des arcs : O(A log(A))
• S “Créer” + A “Trouver” et “Union” : O((S + A)α(S)), avec α(S) en
O(log(S)),
• G connexe ⇒ |A| ≥ |S − 1|
• |A| ≤ |S|2 ⇒ log(A) = O(log(S)
• Complexité : O(A log(S))
Algorithme de Prim
• On part d’un sommet fixé r.
• E est toujours un arbre.
Algorithme de Prim
• On part d’un sommet fixé r.
• E est toujours un arbre. π[u] désigne le père de u dans cet arbre
• E étendu par un arc de poids min vers un sommet isolé de (S, E)
• Pour chaque sommet u 6∈ E, d[u] désigne la distance min à un point de E
Prim(G, p, r) =
pout tout u ∈ S faire
d[u] = ∞
π[u] = nil
d[r] = 0
Q←S
tant que Q 6= ∅ faire
u ← Extraire-min(Q)
pout tout v ∈ Adj(u) faire
si v ∈ Q et p(u, v) < d[v] alors
π[v] ← u
d[v] ← p(u, v)
Algorithme de Prim (Complexité)
Prim(G, p, r) =
pout tout u ∈ S faire
d[u] = ∞ ; π[u] = nil
d[r] = 0
Q←S
tant que Q 6= ∅ faire
u ← Extraire-min(Q)
pout tout v ∈ Adj(u) faire
si v ∈ Q et p(u, v) < d[v] alors
π[v] ← u ; d[v] ← p(u, v)
retourner E
• Implémentation de Q par un tas binaire
– Initialisation (création d’un tas) : O(|S|)
– Opérations “Extraire-min” : S × log(S)
– Boucle “for” : 2|A| × log(S) (modification du tas)
– Compléxité : O(A log(S))
Algorithme de Prim (Complexité)
Prim(G, p, r) =
pout tout s ∈ S faire
d[u] = ∞ ; π[u] = nil
d[r] = 0
Q←S
tant que Q 6= ∅ faire
u ← Extraire-min(Q)
pout tout v ∈ Adj(u) faire
si v ∈ Q et p(u, v) < d[v] alors
π[v] ← u ; d[v] ← p(u, v)
retourner E
• Implémentation de Q par un tas binaire : O(A log(S))
• Implémentation de Q par un tas de Fibonacci :
– Initialisation (création d’un tas) : O(|S|)
– Opérations “Extraire-min” : S × log(S)
– Boucle “for” : 2|A| × 1 (modification du tas)
– Compléxité : O(S log(S) + A)
Téléchargement