Minimum Spenntrær - Kruskal & Prim Lars Vidar Magnusson 4.4.2014 Kapittel 23 Kruskal algoritmen Prim algoritmen
Kruskal Algoritmen Kruskal algoritmen kan beskrives med følgende punkter. Vi har en en sammenkoblet urettet graf G = (V, E) og en vektfunksjon w : E R. Vi starter med at alle noder er sitt eget komponent. Vi slår sammen to komponenter ved å velge en lett kant som kobler de sammen. Vi søker gjennom kantene i monotonisk stigende rekkefølge i forhold til vekten til kanten. Vi bruker disjoint-sett datastrukturen bedømme om en kant knytter sammen to ulike komponenter.
Pseudokode for Kruskal Algoritmen Pseudokoden for Kruskal algoritmen er listet under.
Eksempelgraf Figuren under viser en graf med minimum spenntree merket med grå kanter. Vi skal se på hvordan Kruskal finner et MST for denne grafen.
Hvordan Kruskal Algoritmen Fungerer I
Hvordan Kruskal Algoritmen Fungerer II
Analyse av Kruskal Algoritmen Kruskal algoritmen er en sammensatt algoritme. Vi har V kall til Make-Set i.e Θ(V ) Sortering av kantene i monotonisk stigende rekkefølge tar O(E log E) Den andre for-løkken inneholder O(E) kall til Find-Set og Union. Hvis vi ser bort i fra den minste av disse, og hvis vi går utifra at vi bruker både union by rank og path compression, så sitter vi igjen med. O((V + E)α(V )) + O(E log E)
Analyse av Kruskal Algoritmen Uttrykket på forrige slide kan vi forenkles ytterligere. Siden G er sammenkoblet er E V 1 så da kan vi forenkle til O(Eα(V )) + O(E log E). α(v ) O(log V ) O(log E) Da har vi kjøretid på O(E log E). E V 2 som gir oss log E = O(2 log V ) = O(log V ). Den endelige kjøretiden blir derfor typisk oppgitt som O(E log V ). Merk at kjøretiden er O(E α(v )) hvis kantene allerede er sorterte.
Prim Algoritmen I motsetning til Kruskal algoritmen, som under kjøringen bygger på en skog, vil Prim algoritmen alltid bare bygge på et tre. A er alltid et tre Starter fra en tilfeldig rot r. For hvert steg så finner vi en lett kant mellom kuttet (V A, V V A ), hvor V A er de nodene som er sammenkoblet av A. Så hvordan finner vi en slik lett kant effektivt?
Hvordan Finne en Lett Kant i Prim Algoritmen Prim algoritmen bruker en prioritetskø for å finne en passende lett kant effektivt. Køen inneholder noder som er med i V V A. Prioritetskøen er ordnet i forhold til den minste vekten til en kant (u, v) slik at u V A Sorteringsnøkkelen til en node v er hvis v ikke er en nabo til en av nodene i V A. Når vi kaller Extract-Min får vi en node v slik at det eksisterer en node u V A og (u, v) er en lett kant som krysser (V A, V V A )
Andre Merknader med Prim Algoritmen Kantene i A er et tre med rot i r r blir gitt som input, men kan være hvilken som helst av nodene. Hver node v er klar over sin forelder via v.π (r.π = nil). Under kjørint så er A = {(v, v.π) : v V {r} Q}. Når algoritmen er ferdig er V A = V som impliserer at Q =, og da har vi et MST i A = {(v, v.π) : v V {r}}
Pseudokode for Prim Algoritmen Pseudokoden for Prim algoritmen er listet under. Merk at pseudokoden skiller litt fra boka i at den eksplisett kaller Insert og Decrease-Key for å arbeide med køen.
Hvordan Prim Algoritmen Fungerer Figuren under viser hvordan Prim algoritmen kjører på eksempelgrafen.
Hvordan Prim Algoritmen Fungerer II Figuren under viser hvordan Prim algoritmen kjører på eksempelgrafen.
Analyse av Prim Algoritmen Prim algoritmen er også en sammensatt algoritme. Kjøretiden er avhengig av hvordan prioritetskøen er implementert. Hvis vi antar at prioritetskøen er en binær heap så får vi følgende. Vi har V kall til Insert som gir oss O(V log V ). Minke nøkkelen til rotnoden er O(log V ). Vi har V kall til Extract-Min som gir oss O(V log V ). Vi har E kall til Decrease-Key som gir oss O(E log V ). Siden V E så får vi en total kjøretid på O(E log V ). Dette kan forbedres hvis vi i stedet for en binær heap hadde brukt en Fibonacci heap (O(V log V + E)).