Algoritme van Prim

advertisement
Minimum Spanning Tree
Wat is MST?
• Minimum spanning tree
• De meest efficiënte manier vinden om een verbonden
netwerk op te bouwen
Wat is een tree/boom?
• Graaf 𝐺:
– een verzameling knopen (vertices): 𝑉
– een verzameling kanten (edges): 𝐸 ⊆ 𝑉 × 𝑉
• Een boom is een graaf 𝐺 waarin er één uniek simpel pad is
tussen elk paar knopen
• Een boom is verbonden (connected): je kunt vanuit iedere
knoop in iedere andere knoop komen
• Een boom bevat geen cykels: je kan niet in een rondje
lopen
Hoeveel kanten heeft een boom?
• Een boom op 𝑛 knopen heeft 𝑛 − 1 kanten
• Basisgeval: triviale boom met 1 knoop heeft 0 kanten
• Inductiestap: stel iedere boom met 𝑛 < 𝑚 knopen heeft 𝑛 −
1 kanten. Voor een boom met 𝑚 knopen geldt dan dat…
𝑙 knopen
𝑙 − 1 kanten
𝑚 − 𝑙 knopen
𝑚 − 𝑙 − 1 kanten
Hoeveel kanten heeft een boom?
• Een boom op 𝑛 knopen heeft 𝑛 − 1 kanten
• Basisgeval: triviale boom met 1 knoop heeft 0 kanten
• Inductiestap: stel iedere boom met 𝑛 < 𝑚 knopen heeft 𝑛 −
1 kanten. Voor een boom met 𝑚 knopen geldt dan dat…
…hij bestaat uit een kant die twee losse bomen verbindt, één
met 𝑙 knopen, de ander met 𝑚 − 𝑙 knopen. Met de IH hebben
ze 𝑙 − 1 en 𝑚 − 𝑙 − 1 knopen.
De boom heeft dus 𝑙 − 1 + 𝑚 − 𝑙 − 1 + 1 = 𝑚 − 1 knopen 
𝑙 knopen
𝑙 − 1 kanten
𝑚 − 𝑙 knopen
𝑚 − 𝑙 − 1 kanten
Definitie MST
• “Bepaal de boom met het minste aantal kanten” is dus niet
zo spannend…
• Gewogen graaf: 𝐺 = 𝑉, 𝐸 samen met een wegingsfunctie
𝑤: 𝐸 → ℝ kent aan iedere kant een gewicht toe (“lengte”)
• Minimum spanning tree 𝑇 van een verbonden, gewogen
graaf 𝐺 = 𝑉, 𝐸 is een deelverzameling 𝑇 ⊆ 𝐸 zodat (𝑉, 𝑇) een
boom is en 𝑒∈𝑇 𝑤(𝑒) minimaal is
Voorbeeld MST
Gewicht: 35
MST als optimaliseringsprobleem
• Invoer: verbonden, gewogen graaf (𝑉, 𝐸, 𝑤)
• Zoekruimte: alle deelverzamelingen van 𝐸: 𝒫(𝐸)
• Toelaatbaarheid: het moet een boom zijn
• Doelfunctie: 𝑤 𝑇 =
𝑒∈𝑇 𝑊(𝑒)
Bomen bouwen 1
• Je kunt een bestaande boom aanpassen:
– Voeg een kant toe → cykel dus geen boom meer
– Haal een kant van de cykel weg → het is weer een boom
Bomen bouwen 2
• Iedere verbonden graaf (𝑉, 𝐸) heeft een deelverzameling
𝑇 ⊆ 𝐸 zodat (𝑉, 𝑇) een boom is
• Als (𝑉, 𝐸) verbonden maar geen boom is dan bevat (𝑉, 𝐸)
een cykel
• Gooi willekeurig een kant van die cykel weg
• Is het resultaat een nog geen boom? Herhaal!
• Gevolg: graaf 𝐺 verbonden en 𝑛 − 1 kanten → 𝐺 is boom
Als 𝐺 geen boom zou zijn zou er een deelverzameling zijn
van minder dan 𝑛 − 1 kanten die een boom zou zijn ↯
Hoe bepaal je een MST?
• Algoritmische trukendoos:
– Divide & Conquer
• Verdeel de graaf in twee deelgraven?
• Verbind de deel-MST’s met de lichtste kant?
• Fail…
– Dynamisch Programmeren
Hoe bepaal je een MST?
• Algoritmische trukendoos:
– Divide & Conquer
• Verdeel de graaf in twee deelgraven?
• Verbind de deel-MST’s met de lichtste kant?
• Fail…
– Dynamisch Programmeren
• Optimal Substructure: een optimale oplossing bevat
een optimale deeloplossing
• Een MST bestaat uit 2 MST’s verbonden door 1 edge
Hoe bepaal je een MST?
• DP heeft naast OSS ook overlapping subproblems nodig
• Het kan wél, maar…
• Het probleem heeft een greedy choice property!
Algoritme van Prim
• Bouw de boom op door steeds 1 kant toe te voegen
• Kies een beginknoop
• Bekijk de knopen die je in 1 stap kunt bereiken
• Kies de lichtste van de uitgaande kant
• Je kiest steeds de lichtste boomverlatende kant
Algoritme van Prim
Algoritme van Prim
Algoritme van Prim
Algoritme van Prim
Algoritme van Prim
Algoritme van Prim
Algoritme van Prim
Algoritme van Prim
Algoritme van Prim
Implementatie van Prim
• Hoe kun je snel de lichtste kant vinden? Priority Queue!
• Representatie van het resultaat? Parent Pointers
Pseudocode van Prim
foreach(Vertex v in graph.Vertices) v.Key = ∞;
root.Key = 0;
PQ = new PriorityQueue(graph.Vertices);
while(!PQ.Empty)
u = PQ.ExtractMin();
foreach(Vertex v in u.Neighbors)
if(PQ.Contains(v) && w(u,v) < v.Key)
v.Parent = u;
PQ.DecreaseKey(v, w(u,v));
Algoritme van Prim
Priority Queue
B: 4
H: 8
Algoritme van Prim
Priority Queue
B: 4
C: 8
H: 8
Algoritme van Prim
Priority Queue
C: 8
I: 2
F: 4
D: 7
H: 8
Algoritme van Prim
Priority Queue
I: 2
F: 4
G: 6
D: 7
H: 8 H: 7
Algoritme van Prim
Pseudocode van Prim
foreach(Vertex v in graph.Vertices) v.Key = ∞;
root.Key = 0;
PQ = new PriorityQueue(graph.Vertices);
O(n)
while(!PQ.Empty)
u = PQ.ExtractMin();
foreach(Vertex v in u.Neighbors)
if(PQ.Contains(v) && w(u,v) < v.Key)
v.Parent = u;
PQ.DecreaseKey(v, w(u,v));
O(n)
O(log n)
totaal O(m)
O(log n)
Looptijd is dus 𝑂 𝑚 log 𝑛 . Het kan nog sneller in 𝑂(𝑚 + 𝑛 log 𝑛)
met een Fibbonacciheap – die doet decreasekey in 𝑂(1) .
Pseudocode van Prim Dijkstra
foreach(Vertex v in graph.Vertices) v.Key = ∞;
root.Key = 0;
PQ = new PriorityQueue(graph.Vertices);
O(n)
while(!PQ.Empty)
u = PQ.ExtractMin();
foreach(Vertex v in u.Neighbors)
if(PQ.Contains(v) && w(u,v) + u.Key <
v.Parent = u;
PQ.DecreaseKey(v, w(u,v) + u.Key);
O(n)
O(log n)
totaal O(m)
v.Key)
O(log n)
Looptijd is dus 𝑂 𝑚 log 𝑛 . Het kan nog sneller in 𝑂(𝑚 + 𝑛 log 𝑛)
met een Fibbonacciheap – die doet decreasekey in 𝑂(1) .
Bewijs van Prim
• We moeten de GCP bewijzen
• GCP: Zij 𝑇 een MST van (𝑉, 𝐸) en stel dat 𝐴 ⊆ 𝑇. Als 𝑒 een
lichtste kant is die een knoop in 𝐴 met een knoop niet in 𝐴
verbindt (𝑒 is 𝐴-verlatend), dan is 𝐴 ∪ {𝑒} deelverzameling
van een MST 𝑇′.
•
•
•
•
Als 𝑒 ∈ 𝑇 dan is het goed. Stel dus dat 𝑒 ∉ 𝑇.
Dan bevat 𝑇 ∪ {𝑒} een cykel. Bekijk de kanten van die cykel.
De cykel bevat naast 𝑒 nog een 𝐴-verlatende kant 𝑓.
𝑤 𝑓 ≥ 𝑤(𝑒) dus T ′ = 𝑒 ∪ 𝑇\ 𝑓 is een minimale(re) spanning
tree (𝑤 𝑇 ′ = 𝑤 𝑇 + 𝑤 𝑒 − 𝑤 𝑓 ≤ 𝑤(𝑇))
Algoritme van Kruskal
• Prim: laat één boom steeds verder groeien
• Kruskal: werkt met een woud met allemaal losse stukjes
boom
• Iedere verbonden graaf heeft een deelgraaf die boom is:
– Herhaald kanten van cykels weglaten
• Kan ook andersom: maak een boom door steeds toe te
voegen:
A = ∅;
foreach(Edge e in graph)
if(A ∪ e bevat geen cykel)
A = A ∪ {e};
• Het resultaat hangt af van de volgorde!
Algoritme van Kruskal
• Bekijk de kanten van licht naar zwaar
• Voeg steeds de kant toe als hij geen cykel introduceert
• Cykels testen: Union-Find!
Sort(edges);
foreach(Vertex v) MakeSet(v);
foreach(Edge e)
if(FindRep(e.A) ≠ FindRep(e.B))
resultaat.Add(e);
Union(e.A, e.B);
Algoritme van Kruskal
• Bekijk de kanten van licht naar zwaar
• Voeg steeds de kant toe als hij geen cykel introduceert
• Cykels testen: Union-Find!
Sort(edges);
foreach(Vertex v) MakeSet(v);
foreach(Edge e)
if(FindRep(e.A) ≠ FindRep(e.B))
resultaat.Add(e);
Union(e.A, e.B);
Sort is 𝑂 𝑚 log 𝑚 . 𝑂(𝑚) union find-operaties kosten 𝑂 𝑚 𝛼 𝑚 .
Sorteren domineert. Totaal: 𝑂 𝑚 log 𝑚 = 𝑂(𝑚 log 𝑛)
Voorbeeld Kruskal
HG
IC
GF
AB
CF
IG
CD
HI
AH
BC
DE
FE
Voorbeeld Kruskal
HG: A B C D E F GH I
IC
GF
AB
CF
IG
CD
HI
AH
BC
DE
FE
Voorbeeld Kruskal
HG: A B C D E F GH I
IC: A B CI D E F GH
GF
AB
CF
IG
CD
HI
AH
BC
DE
FE
Voorbeeld Kruskal
HG: A B C D E F GH I
IC: A B CI D E F GH
GF: A B CI D E FGH
AB
CF
IG
CD
HI
AH
BC
DE
FE
Voorbeeld Kruskal
HG:
IC:
GF:
AB:
CF
IG
CD
HI
AH
BC
DE
FE
A B C D E F GH I
A B CI D E F GH
A B CI D E FGH
AB CI D E FGH
Voorbeeld Kruskal
HG:
IC:
GF:
AB:
CF:
IG
CD
HI
AH
BC
DE
FE
A B C D E F GH I
A B CI D E F GH
A B CI D E FGH
AB CI D E FGH
AB CFGHI D E
Voorbeeld Kruskal
HG:
IC:
GF:
AB:
CF:
IG:
CD
HI
AH
BC
DE
FE
A B C D E F GH I
A B CI D E F GH
A B CI D E FGH
AB CI D E FGH
AB CFGHI D E
niks
Voorbeeld Kruskal
HG:
IC:
GF:
AB:
CF:
IG:
CD:
HI
AH
BC
DE
FE
A B C D E F GH I
A B CI D E F GH
A B CI D E FGH
AB CI D E FGH
AB CFGHI D E
niks
AB CDFGHI E
Voorbeeld Kruskal
HG:
IC:
GF:
AB:
CF:
IG:
CD:
HI:
AH
BC
DE
FE
A B C D E F GH I
A B CI D E F GH
A B CI D E FGH
AB CI D E FGH
AB CFGHI D E
niks
AB CDFGHI E
niks
Voorbeeld Kruskal
HG:
IC:
GF:
AB:
CF:
IG:
CD:
HI:
AH:
BC
DE
FE
A B C D E F GH I
A B CI D E F GH
A B CI D E FGH
AB CI D E FGH
AB CFGHI D E
niks
AB CDFGHI E
niks
ABCDFGHI E
Voorbeeld Kruskal
HG:
IC:
GF:
AB:
CF:
IG:
CD:
HI:
AH:
BC:
DE
FE
A B C D E F GH I
A B CI D E F GH
A B CI D E FGH
AB CI D E FGH
AB CFGHI D E
niks
AB CDFGHI E
niks
ABCDFGHI E
niks
Voorbeeld Kruskal
HG:
IC:
GF:
AB:
CF:
IG:
CD:
HI:
AH:
BC:
DE:
FE
A B C D E F GH I
A B CI D E F GH
A B CI D E FGH
AB CI D E FGH
AB CFGHI D E
niks
AB CDFGHI E
niks
ABCDFGHI E
niks
ABCDEFGHI
Voorbeeld Kruskal
HG:
IC:
GF:
AB:
CF:
IG:
CD:
HI:
AH:
BC:
DE:
FE:
A B C D E F GH I
A B CI D E F GH
A B CI D E FGH
AB CI D E FGH
AB CFGHI D E
niks
AB CDFGHI E
niks
ABCDFGHI E
niks
ABCDEFGHI
niks
Correctheid van Kruskal
• Lemma: gegeven MST 𝑇 van graaf (𝑉, 𝐸). Stel dat 𝐴 ⊆ 𝑇.
Zij 𝑒 ∈ 𝐸 een lichtste kant zodat 𝐴 ∪ {𝑒} cykelvrij is (en 𝑒 ∉
𝐴). Dan bestaat er MST 𝑇′ zodat 𝐴 ⊆ 𝑇′ en 𝑒 ∈ 𝑇′. Bovendien
geldt dat T ′ ⊆ 𝑇 ∪ 𝑒 .
• Bewijs:
– Als 𝑒 ∈ 𝑇 neem 𝑇 ′ = 𝑇
– Als 𝑒 ∉ 𝑇 bevat 𝑇 ∪ {𝑒} een cykel
– 𝐴 ∪ {𝑒} is cykelvrij dus de cykel bevat kant 𝑓 ∉ 𝐴, 𝑓 ≠ 𝑒
– 𝐴 ∪ {𝑓} is cykelvrij: 𝐴 ∪ 𝑓 ⊆ 𝑇 en 𝑇 is een boom
– 𝑒 is een lichtste kant met die eigenschap dus 𝑤 𝑒 ≤ 𝑤(𝑓)
– Dus T ′ = 𝑒 ∪ 𝑇\ 𝑓 ⊆ 𝑇 ∪ 𝑒 is een minimale(re) MST
want 𝑤 𝑇 ′ = 𝑤 𝑇 + 𝑤 𝑒 − 𝑤 𝑓 ≤ 𝑤(𝑇).
Correctheid van Kruskal
• Het lemma is niet genoeg. Bewijs met invariant (soort inductie)
initialisatie: 𝐸 = {𝑒1, 𝑒2, … , 𝑒𝑛}, 𝐴0 = ∅
for(i = 1 to n)
invariant: 𝐴𝑖 is uit te breiden met 𝑒𝑖 t/m 𝑒𝑛 tot MST
if(𝑒𝑖 voegt geen cykel toe)
𝐴𝑖+1 = 𝐴𝑖 ∪ 𝑒
else
𝐴𝑖+1 = 𝐴𝑖
Wil: invariant is nu waar voor 𝑖 + 1
• In het begin is de invariant waar (𝐸 is een verbonden graaf)
Correctheid van Kruskal
for(i = 1 to n)
invariant: 𝐴𝑖 is uit te breiden met 𝑒𝑖 t/m 𝑒𝑛 tot MST
if(𝑒𝑖 voegt geen cykel toe)
𝐴𝑖+1 = 𝐴𝑖 ∪ 𝑒
else
𝐴𝑖+1 = 𝐴𝑖
Formeel “er is MST 𝑇 zodat 𝐴𝑖 ⊆ 𝑇 ⊆ 𝐴𝑖 ∪ {𝑒𝑖 , … 𝑒𝑛 }”
• Stel de invariant is waar voor zekere 𝑖
• Dan is er een MST 𝑇 zodat 𝐴𝑖 ⊆ 𝑇 ⊆ 𝐴𝑖 ∪ {𝑒𝑖 , … 𝑒𝑛 }
Correctheid van Kruskal
for(i = 1 to n)
invariant: 𝐴𝑖 is uit te breiden met 𝑒𝑖 t/m 𝑒𝑛 tot MST
if(𝑒𝑖 voegt geen cykel toe)
𝐴𝑖+1 = 𝐴𝑖 ∪ 𝑒
else
𝐴𝑖+1 = 𝐴𝑖
Formeel “er is MST 𝑇 zodat 𝐴𝑖 ⊆ 𝑇 ⊆ 𝐴𝑖 ∪ {𝑒𝑖 , … 𝑒𝑛 }”
• Stel de invariant is waar voor zekere 𝑖
• Dan is er een MST 𝑇 zodat 𝐴𝑖 ⊆ 𝑇 ⊆ 𝐴𝑖 ∪ {𝑒𝑖 , … 𝑒𝑛 }
– Als het if-statement false is (𝐴𝑖 ∪ 𝑒𝑖 bevat een cykel):
• 𝐴𝑖+1 ⊆ 𝑇 is zeker waar want 𝐴𝑖 = 𝐴𝑖+1
• 𝑇 ⊆ 𝐴𝑖+1 ∪ {𝑒𝑖+1 , … 𝑒𝑛 } geldt ook want 𝑒𝑖 kan geen element
van 𝑇 zijn, 𝑇 is cykelvrij en bevat 𝐴𝑖 en 𝐴𝑖 ∪ 𝑒𝑖 is niet
cykelvrij
Correctheid van Kruskal
for(i = 1 to n)
invariant: 𝐴𝑖 is uit te breiden met 𝑒𝑖 t/m 𝑒𝑛 tot MST
if(𝑒𝑖 voegt geen cykel toe)
𝐴𝑖+1 = 𝐴𝑖 ∪ 𝑒
else
𝐴𝑖+1 = 𝐴𝑖
Formeel “er is MST 𝑇 zodat 𝐴𝑖 ⊆ 𝑇 ⊆ 𝐴𝑖 ∪ {𝑒𝑖 , … 𝑒𝑛 }”
• Stel de invariant is waar voor zekere 𝑖
• Dan is er een MST 𝑇 zodat 𝐴𝑖 ⊆ 𝑇 ⊆ 𝐴𝑖 ∪ {𝑒𝑖 , … 𝑒𝑛 }
– Als het if-statement true is (𝐴𝑖 ∪ 𝑒𝑖 is cykelvrij) roepen we
het lemma in. Er is een MST 𝑇′ met 𝐴𝑖 ∪ 𝑒𝑖 ⊆ 𝑇 ′ ⊆ 𝑇 ∪ 𝑒𝑖 .
Lemma: gegeven MST 𝑇 van graaf
(𝑉, 𝐸). Stel dat 𝐴 ⊆ 𝑇. Zij 𝑒 ∈ 𝐸
een lichtste kant zodat 𝐴 ∪ {𝑒}
cykelvrij is (en 𝑒 ∉ 𝐴). Dan bestaat
er MST 𝑇′ zodat 𝐴 ⊆ 𝑇′ en 𝑒 ∈ 𝑇′.
Bovendien geldt dat T ′ ⊆ 𝑇 ∪ 𝑒 .
Correctheid van Kruskal
for(i = 1 to n)
invariant: 𝐴𝑖 is uit te breiden met 𝑒𝑖 t/m 𝑒𝑛 tot MST
if(𝑒𝑖 voegt geen cykel toe)
𝐴𝑖+1 = 𝐴𝑖 ∪ 𝑒
else
𝐴𝑖+1 = 𝐴𝑖
Formeel “er is MST 𝑇 zodat 𝐴𝑖 ⊆ 𝑇 ⊆ 𝐴𝑖 ∪ {𝑒𝑖 , … 𝑒𝑛 }”
• Stel de invariant is waar voor zekere 𝑖
• Dan is er een MST 𝑇 zodat 𝐴𝑖 ⊆ 𝑇 ⊆ 𝐴𝑖 ∪ {𝑒𝑖 , … 𝑒𝑛 }
– Als het if-statement true is (𝐴𝑖 ∪ 𝑒𝑖 is cykelvrij) roepen we
het lemma in. Er is een MST 𝑇′ met 𝐴𝑖 ∪ 𝑒𝑖 ⊆ 𝑇 ′ ⊆ 𝑇 ∪ 𝑒𝑖 .
– 𝐴𝑖+1 = 𝐴𝑖 ∪ 𝑒𝑖 ⊆ 𝑇 ′ dus we hoeven enkel te checken dat 𝑇 ′ ⊆
𝐴𝑖+1 ∪ {𝑒𝑖+1 , … 𝑒𝑛 }
– Dat kan: 𝑇 ′ ⊆ 𝑇 ∪ 𝑒𝑖 ⊆ 𝐴𝑖 ∪ 𝑒𝑖 , … 𝑒𝑛 = 𝐴𝑖 ∪ 𝑒𝑖 ∪ 𝑒𝑖+1 , … 𝑒𝑛 =
𝐴𝑖+1 ∪ {𝑒𝑖+1 , … 𝑒𝑛 } 
Correctheid van Kruskal
initialisatie: 𝐸 = {𝑒1, 𝑒2, … , 𝑒𝑛}, 𝐴0 = ∅
for(i = 1 to n)
invariant: 𝐴𝑖 is uit te breiden met 𝑒𝑖 t/m 𝑒𝑛 tot MST
if(𝑒𝑖 voegt geen cykel toe)
𝐴𝑖+1 = 𝐴𝑖 ∪ 𝑒
else
𝐴𝑖+1 = 𝐴𝑖
bewezen: invariant is nog steeds waar (na ophogen i)
Zodra de for-loop klaar is dan “is 𝐴𝑛+1 met en+1 t/m en uit te
breiden tot MST” dus is 𝐴𝑛+1 een MST.
Is de MST uniek?
• Nee, maar wel als de kantgewichten uniek zijn!
Stel 𝐺 = (𝑉, 𝐸, 𝑤) is een ongerichte gewogen graaf en 𝑤 is
injectief (verschillende kanten naar verschillende waarden).
Stel we hebben 𝑇, 𝑈 ⊆ 𝐸 MST’s van 𝐺 en ze zijn niet hetzelfde.
Dan zijn er kanten die in precies 1 van 𝑇, 𝑈 zitten.
Bekijk de laagste kant 𝑒 die niet in beide zit.
Stel z.v.a. dat 𝑒 ∈ 𝑇. Dan bevat 𝑈 ∪ {𝑒} een cykel.
𝑒 ∈ 𝑇 en 𝑇 bevat géén cykel dus ≥ 1 cykelkant 𝑓 zit alleen in 𝑈.
Is de MST uniek?
• Nee, maar wel als de kantgewichten uniek zijn!
Stel 𝐺 = (𝑉, 𝐸, 𝑤) is een ongerichte gewogen graaf en 𝑤 is
injectief (verschillende kanten naar verschillende waarden).
Stel we hebben 𝑇, 𝑈 ⊆ 𝐸 MST’s van 𝐺 en ze zijn niet hetzelfde.
Dan zijn er kanten die in precies 1 van 𝑇, 𝑈 zitten.
Bekijk de laagste kant 𝑒 die niet in beide zit.
Stel z.v.a. dat 𝑒 ∈ 𝑇. Dan bevat 𝑈 ∪ {𝑒} een cykel.
𝑒 ∈ 𝑇 en 𝑇 bevat géén cykel dus ≥ 1 cykelkant 𝑓 zit alleen in 𝑈.
Per constructie 𝑤 𝑓 > 𝑤(𝑒) dus 𝑒 ∪ 𝑈\ 𝑓 is een MST met
lager gewicht dan 𝑈. Tegenspraak! 𝑇 en 𝑈 zijn hetzelfde.
Kroegentocht of TSP
• Travelling Salesman
• Bepaal een volgorde (rondtocht) om zo snel mogelijk een
aantal knopen te bezoeken in een graaf.
• Handelsreiziger: wil zijn product in een aantal steden
verkopen, wat is de kortste route.
• Is een “moeilijk” probleem: NP-compleet
• Waarschijnlijk kost het exponentiële tijd om op te lossen
TSP-Approximatie
• Met behulp van MST kunnen we TSP benaderen
TSP-Approximatie
• Met behulp van MST kunnen we TSP benaderen
• TSP is hoogstens 2 × zo lang als MST
TSP-Approximatie
• Met behulp van MST kunnen we TSP benaderen
• TSP is hoogstens 2 × zo lang als MST
•
•
•
•
Maar ook: MST is hoogstens zo groot als TSP
Laat kanten weg uit TSP tot je een MST hebt
Ergo: MST ≤ TSP ≤ 2 MST
MST 2 −approximeert TSP
• Werkt alleen als symmetrisch 
• Approximatie (begrensd) vs. heuristiek
Prim VS Kruskal
• Prim: breidt 1 boom steeds verder uit (als Dijkstra)
• Kruskal: laat boom groeien uit meerdere stukjes
Prim
Kruskal
Datastructuur
Priority Queue
Union-Find
Looptijd
𝑂(𝑚 log 𝑛) of 𝑂(𝑚 + 𝑛 log 𝑛) 𝑂(𝑚 log 𝑛) (sorteren)
Extra ruimte
𝑂(𝑛)
𝑂(𝑚)
• Ik vind Kruskal beter: makkelijk te implementeren en vaak
betere constante in de grote 𝑂
• Het is een kwestie van smaak
Conclusie
• Minimum Spanning Tree: lichtste, verbonden deelgraaf
• Algoritme van Prim of Kruskal
• Je kan van alles bewijzen als je een kant toevoegt en de
cykel weer doorbreekt
• Lokale eigenschappen → greedy algoritme
• Toepassingen van MST:
– Lege collegezaal (LAN-party!)
– Netwerk-broadcast
– Handschriftherkenning
– TSP-approximatie (kroegentocht)
Download