Алгоритм Прима — различия между версиями

Материал из Викиконспекты
Перейти к: навигация, поиск
(добавленн пример)
Строка 22: Строка 22:
  
 
==Пример==
 
==Пример==
{| border = 1 cellspacing = 2 cellpadding = 5 class = "wikitable"
+
Задан неориентированный связный граф, требуется построить в нём минимальное остовное дерево.<br/>
 +
Создадим новый граф, содержащий все вершины из заданного графа, но не содержащий рёбер.<br/>
 +
Этот новый граф будет ответом, его множество рёбер будет изменено по ходу выполнения алгоритма.<br/>
 +
Создадим новое множество вершин с внешними значениями - приоритетами, из которого будем извлекать минимум.<br/>
 +
Заполним все приоритеты этого множества бесконечностью.<br/>
 +
Выберем любую вершину, от которой будет начато построение минимального остовного дерева (в примере это вершина '''a''').<br/>
 +
Установим приоритет этой вершины равный нулю.
 +
{| class = "wikitable"
 
! Изображение !! Множество вершин !! Описание
 
! Изображение !! Множество вершин !! Описание
 
|-
 
|-
 
|[[Файл:Mst_prima_1.png|200px]]
 
|[[Файл:Mst_prima_1.png|200px]]
 
|
 
|
{|
+
{| width="100%"
 
| '''a''' || '''b''' || '''c''' || '''d''' || '''e'''
 
| '''a''' || '''b''' || '''c''' || '''d''' || '''e'''
 
|-
 
|-
 
| <tex> 0 </tex> || <tex> \inf </tex> || <tex> \inf </tex> || <tex> \inf </tex> || <tex> \inf </tex>
 
| <tex> 0 </tex> || <tex> \inf </tex> || <tex> \inf </tex> || <tex> \inf </tex> || <tex> \inf </tex>
 
|}
 
|}
| Извлечём из множества вершину '''a''', так как её приоритет минимален, и рассмотрим её соседей '''b''', '''c''', и '''e'''. <br/>Обновим их приоритеты и добавим в ответ рёбра '''ab''', '''ac''', и '''ae'''.
+
| Извлечём из множества вершину '''a''', так как её приоритет минимален.<br/>Рассмотрим смежные с ней вершины '''b''', '''c''', и '''e'''. <br/>Обновим их приоритеты, как веса соответствующих рёбер '''ab''', '''ac''' и '''ae''', которые будут добавленны в ответ.
 
|-
 
|-
 
|[[Файл:Mst_prima_2.png|200px]]
 
|[[Файл:Mst_prima_2.png|200px]]
 
|
 
|
{|
+
{| width="100%"
 
| <s>a</s> || '''b''' || '''c''' || '''d''' || '''e'''
 
| <s>a</s> || '''b''' || '''c''' || '''d''' || '''e'''
 
|-
 
|-
 
| <tex> 0 </tex> || <tex> 3 </tex> || <tex> 4 </tex> || <tex> \inf </tex> || <tex> 1 </tex>
 
| <tex> 0 </tex> || <tex> 3 </tex> || <tex> 4 </tex> || <tex> \inf </tex> || <tex> 1 </tex>
 
|}
 
|}
| Теперь минимальный приоритет у вершины '''е'''. Извлечём её и рассмотрим её соседей.<br/>Изменим приоритет только у вершины '''d''',так как приоритеты вершин '''a''' и '''с''' меньше,<br/>чем веса у соответствующих рёбер '''ea''' и '''ec''', и добавим в ответ ребро '''ed'''.  
+
| Теперь минимальный приоритет у вершины '''е'''.<br/> Извлечём её и рассмотрим смежные с ней вершины '''a''', '''c''', и '''d'''.<br/>Изменим приоритет только у вершины '''d''', так как приоритеты вершин '''a''' и '''с''' меньше,<br/>чем веса у соответствующих рёбер '''ea''' и '''ec''', и установим приоритет вершины '''d''' равный весу ребра '''ed''', которое будет добавленно в ответ.
 
|-
 
|-
 
|[[Файл:Mst_prima_3.png|200px]]
 
|[[Файл:Mst_prima_3.png|200px]]
 
|
 
|
{|
+
{| width="100%"
 
| <s>a</s> || '''b''' || '''c''' || '''d''' || <s>e</s>
 
| <s>a</s> || '''b''' || '''c''' || '''d''' || <s>e</s>
 
|-
 
|-
 
| <tex> 0 </tex> || <tex> 3 </tex> || <tex> 4 </tex> || <tex> 7 </tex> || <tex> 1 </tex>
 
| <tex> 0 </tex> || <tex> 3 </tex> || <tex> 4 </tex> || <tex> 7 </tex> || <tex> 1 </tex>
 
|}
 
|}
| После извлечения вершины '''b''' ничего не изменится, так как приоритеты вершин '''a''' и '''с''' меньше,<br/>чем веса у соответствующих рёбер '''ba''' и '''bc'''. Однако, после извлечения следующий вершины - '''c''',<br/>будет обновлён потенциал у вершины '''d''' на более низкий (равный весу ребра '''cd''') и в ответе ребро '''ed''' будет заменено на '''cd'''.
+
| После извлечения вершины '''b''' ничего не изменится, так как приоритеты вершин '''a''' и '''с''' меньше,<br/>чем веса у соответствующих рёбер '''ba''' и '''bc'''. Однако, после извлечения следующей вершины - '''c''',<br/>будет обновлён приоритет у вершины '''d''' на более низкий (равный весу ребра '''cd''') и в ответе ребро '''ed''' будет заменено на '''cd'''.
 
|-
 
|-
 
|[[Файл:Mst_prima_4.png|200px]]
 
|[[Файл:Mst_prima_4.png|200px]]
 
|
 
|
{|
+
{| width="100%"
 
| <s>a</s> || <s>b</s> || <s>c</s> || '''d''' || <s>e</s>
 
| <s>a</s> || <s>b</s> || <s>c</s> || '''d''' || <s>e</s>
 
|-
 
|-
 
| <tex> 0 </tex> || <tex> 3 </tex> || <tex> 4 </tex> || <tex> 2 </tex> || <tex> 1 </tex>
 
| <tex> 0 </tex> || <tex> 3 </tex> || <tex> 4 </tex> || <tex> 2 </tex> || <tex> 1 </tex>
 
|}
 
|}
| Далее будет рассмотрена следующая вершина - '''d''', но ничего не изменится,<br/>так как приоритеты вершин '''e''' и '''с''' меньше, чем веса у соответствующих рёбер '''de''' и '''dc'''.<br/>После этого в заданном множестве не останется вершин, которые не были бы рассмотрены,<br/>алгоритм завершит работу, так как минимальное остовное дерево будет построено.
+
| Далее будет рассмотрена следующая вершина - '''d''', но ничего не изменится,<br/>так как приоритеты вершин '''e''' и '''с''' меньше, чем веса у соответствующих рёбер '''de''' и '''dc'''.<br/>После этого алгоритм завершит работу, так как в заданном множестве не останется вершин,<br/>которые не были бы рассмотрены
 
|}
 
|}
  
Строка 82: Строка 89:
 
|}
 
|}
  
== См. также ==
+
==См. также==
* [[Алгоритм Краскала]]
+
* [[Алгоритм Прима]]
* [http://www.mincel.com/java/prim.html Визуализатор алгоритма]
+
* [[Алгоритм Борувки]]
  
 
== Литература ==
 
== Литература ==
 
* ''Кормен, Томас Х., Лейзерсон, Чарльз И., Ривест, Рональд Л., Штайн Клиффорд'' '''Алгоритмы: построение и анализ''', 2-е издание. Пер. с англ. — М.:Издательский дом "Вильямс", 2010. — с.653 — 656.— ISBN 978-5-8459-0857-5 (рус.)
 
* ''Кормен, Томас Х., Лейзерсон, Чарльз И., Ривест, Рональд Л., Штайн Клиффорд'' '''Алгоритмы: построение и анализ''', 2-е издание. Пер. с англ. — М.:Издательский дом "Вильямс", 2010. — с.653 — 656.— ISBN 978-5-8459-0857-5 (рус.)
 +
 +
==Ссылки==
 +
* [http://rain.ifmo.ru/cat/view.php/vis/graph-spanning-trees/prim-2003 Визуализатор алгоритма №1]
 +
* [http://rain.ifmo.ru/cat/view.php/vis/graph-spanning-trees/mst-2005 Визуализатор алгоритма №2]
 +
* [http://rain.ifmo.ru/cat/view.php/vis/graph-spanning-trees/mst-2006 Визуализатор алгоритма №3]
  
 
[[Категория: Алгоритмы и структуры данных]]
 
[[Категория: Алгоритмы и структуры данных]]
 
[[Категория: Остовные деревья ]]
 
[[Категория: Остовные деревья ]]

Версия 17:25, 17 января 2013

Алгоритм Прима — алгоритм поиска минимального остовного дерева (minimum spanning tree, MST) во взвешенном неориентированном связном графе.

Идея

Данный алгоритм очень похож на алгоритм Дейкстры. Будем последовательно строить поддерево [math]F[/math] ответа в графе [math]G[/math], поддерживая приоритетную очередь [math]Q[/math] из вершин [math]G \setminus F[/math], имеющую ключом для вершины [math]v[/math] величину [math]\min\limits_{u \in VF, uv \in EG}w(uv)[/math] (вес минимального ребра из вершин [math]F[/math] в вершину [math]v[/math]). Также для каждой вершины очереди будем хранить [math]p(v)[/math] — вершину [math]u[/math], на которой достигается минимум в определении ключа. Дерево [math]F[/math] поддерживается неявно, и его ребра — это пары [math]\left(v,p(v)\right)[/math], где [math]v \in G \setminus \{r\} \setminus Q[/math], а [math]r[/math] — корень [math]F[/math]. Изначально [math]F[/math] пусто, в очереди все вершины с ключами [math]+\infty[/math]. Выберём произвольную вершину [math]r[/math] и присвоим её ключу [math]0[/math]. На каждом шаге будем извлекать минимальную вершину [math]v[/math] из приоритетной очереди и релаксировать все ребра [math]vu[/math], такие что [math]u \in Q[/math], выполняя при этом операцию [math]\text{decrease-key}[/math] над очередью и обновление [math]p(v)[/math]. Ребро [math]\left(v,p(v)\right)[/math] при этом добавляется к ответу.

Реализация

[math]\text{Prim}(G, w)[/math]
   [math]for[/math] [math]v \in V[G][/math]
       [math] key[v] \leftarrow \infty [/math]
       [math]p[v] \leftarrow \text{NIL}[/math]
   [math]r \leftarrow [/math] произвольная вершина в [math]V[G][/math]
   [math]key[r] \leftarrow 0 [/math]
   [math]Q \leftarrow V[G] [/math]
   [math]while[/math] [math] Q \neq \emptyset [/math]
       [math]v \leftarrow \text{extract-min}(Q) [/math]
       [math]for[/math] [math] u \in Adj[v] [/math]
           [math]if[/math] [math]u \in Q[/math] и [math]key[u] \gt  w(v, u) [/math]
               [math] p[u] \leftarrow v [/math]
               [math]key[u] \leftarrow w(v, u)[/math]
               [math]\text{decrease-key}(Q, u, key[u]) [/math]

Ребра дерева восстанавливаются из его неявного вида после выполнения алгоритма.

Пример

Задан неориентированный связный граф, требуется построить в нём минимальное остовное дерево.
Создадим новый граф, содержащий все вершины из заданного графа, но не содержащий рёбер.
Этот новый граф будет ответом, его множество рёбер будет изменено по ходу выполнения алгоритма.
Создадим новое множество вершин с внешними значениями - приоритетами, из которого будем извлекать минимум.
Заполним все приоритеты этого множества бесконечностью.
Выберем любую вершину, от которой будет начато построение минимального остовного дерева (в примере это вершина a).
Установим приоритет этой вершины равный нулю.

Изображение Множество вершин Описание
Mst prima 1.png
a b c d e
[math] 0 [/math] [math] \inf [/math] [math] \inf [/math] [math] \inf [/math] [math] \inf [/math]
Извлечём из множества вершину a, так как её приоритет минимален.
Рассмотрим смежные с ней вершины b, c, и e.
Обновим их приоритеты, как веса соответствующих рёбер ab, ac и ae, которые будут добавленны в ответ.
Mst prima 2.png
a b c d e
[math] 0 [/math] [math] 3 [/math] [math] 4 [/math] [math] \inf [/math] [math] 1 [/math]
Теперь минимальный приоритет у вершины е.
Извлечём её и рассмотрим смежные с ней вершины a, c, и d.
Изменим приоритет только у вершины d, так как приоритеты вершин a и с меньше,
чем веса у соответствующих рёбер ea и ec, и установим приоритет вершины d равный весу ребра ed, которое будет добавленно в ответ.
Mst prima 3.png
a b c d e
[math] 0 [/math] [math] 3 [/math] [math] 4 [/math] [math] 7 [/math] [math] 1 [/math]
После извлечения вершины b ничего не изменится, так как приоритеты вершин a и с меньше,
чем веса у соответствующих рёбер ba и bc. Однако, после извлечения следующей вершины - c,
будет обновлён приоритет у вершины d на более низкий (равный весу ребра cd) и в ответе ребро ed будет заменено на cd.
Mst prima 4.png
a b c d e
[math] 0 [/math] [math] 3 [/math] [math] 4 [/math] [math] 2 [/math] [math] 1 [/math]
Далее будет рассмотрена следующая вершина - d, но ничего не изменится,
так как приоритеты вершин e и с меньше, чем веса у соответствующих рёбер de и dc.
После этого алгоритм завершит работу, так как в заданном множестве не останется вершин,
которые не были бы рассмотрены

Корректность

По поддерживаемым инвариантам после извлечения вершины [math]v[/math] ([math]v \neq r[/math]) из [math]Q[/math] ребро [math]\left(v,p(v)\right)[/math] является ребром минимального веса, пересекающим разрез [math]\left(F,Q\right)[/math]. Значит, по лемме о безопасном ребре, оно безопасно. Алгоритм построения MST, добавляющий безопасные ребра, причём делающий это ровно [math]|V|-1[/math] раз, корректен.

Оценка производительности

Производительность алгоритма Прима зависит от выбранной реализации приоритетной очереди, как и в алгоритме Дейкстры. Извлечение минимума выполняется [math]V[/math] раз, релаксация — [math]O(E)[/math] раз.

Структура данных для приоритетной очереди Асимптотика времени работы
Наивная реализация [math]O(V^2+E)[/math]
Двоичная куча [math]O(E\log{V})[/math]
Фибоначчиева куча [math]O(V\log{V}+E)[/math]

См. также

Литература

  • Кормен, Томас Х., Лейзерсон, Чарльз И., Ривест, Рональд Л., Штайн Клиффорд Алгоритмы: построение и анализ, 2-е издание. Пер. с англ. — М.:Издательский дом "Вильямс", 2010. — с.653 — 656.— ISBN 978-5-8459-0857-5 (рус.)

Ссылки