Jarník-Primův algoritmus (Jarníkův algoritmus, Primův algorimus, Prim-Jarníkův algorimus, DJP algorithm) slouží k určení minimální kostry grafu (kostra taková, že součet vah jejíchž hran je minimální). Tento algoritmus byl vynalezen v roce 1930 českým matematikem Vojtěchem Jarníkem a v roce 1957 znovu nezávisle objeven americkým matematikem Robertem Primem. Algorimus byl opět objeven v roce 1959 Edsgerem Dijkstrou.
Princip
Algoritmus vychází z libovolného uzlu a udržuje si seznam již objevených uzlů a jejich vzdáleností od propojené části grafu. V každém svém kroku připojí ten z uzlů, mezi nímž a projenou částí grafu je hrana nejnižší délky a označí sousedy nově připojeného uzlu za objevené, případně zkrátí vzdálenosti od již známých uzlů, pokud byla nalezena výhodnější hrana. V okamžiku, kdy jsou propojeny všechny uzly, algoritmus terminuje.
Složitost
Složitost Jarník-Primova algoritmu závisí na konkrétní implementaci seznamu. Seznam samotný může být modifikován při každém objevení nové hrany (tj. krát), jelikož vždy může dojít buď k objevení dosud neznámého uzlu nebo ke změně vzdálenosti některého již objeveného uzlu. Pokud budeme seznam implementovat pomocí binární haldy, jež se chová jako prioritní fronta, tak každá z operací modifikace seznamu bude mít asymptotickou složitost
. Celková asymptotická složitost Jarník-Primova algoritmu je proto
.
Kód
01.
/**
02.
* Jarnik-Primuv algoritmus
03.
* Nalezne minimalni kostru grafu
04.
* @graph graf
05.
* @weight vahy hran
06.
* @return pole predchudcu
07.
*/
08.
node[] jarnikAlgorithm(graph, weight)
09.
Queue q
//fronta
10.
q.addAllVetices(graph.vertices)
//pridej vsechny uzly do fronty
11.
12.
distances =
new
int
[q.size()]
//pole vzdalenosti
13.
distances[
0
] =
0
//koren
14.
for
i in
1
-> distances.length -
1
do
15.
distances[i] = +inf
//ostatni uzly jsou nekonecne daleko
16.
17.
predecessors =
new
node[q.size()]
//pole predchudcu
18.
predecessors[
0
] =
null
//koren nema predchudce
19.
20.
while
!queue.empty()
do
//dokud neni fronta prazdna
21.
u = queue.extractMin()
//vrat prvek v minimalni vzdalenosti
22.
for
node in descendants(u)
do
//pro vsechny potomky u
23.
if
queue.contains(node) AND weight(u, node) < d[node]
//pokud se nektery z potomku priblizil k dosud postavene kostre
24.
then predecessors[node] = u
//u je tedy jeho predek
25.
d[node] = weight(u, node)
//nastav nvou vzdalenost
26.
27.
return
predecessors
//vrat pole predchudcu
Literatura
- KOLÁŘ, Josef. Teoretická informatika. 2. vyd. Praha : Česká informatická společnost, 2004. 205 s. ISBN 80-900853-8-5.