Алгоритм Дініца: відмінності між версіями

Матеріал з Вікіпедії — вільної енциклопедії.
Перейти до навігації Перейти до пошуку
[неперевірена версія][неперевірена версія]
Вилучено вміст Додано вміст
Немає опису редагування
Рядок 1: Рядок 1:
'' 'Алгоритм Дініца' '' - поліноміальний алгоритм для знаходження [[Максимальний потік | максимального потоку]] в [[Транспортна мережа | транспортної мережі]], запропонований в 1970 році ізраїльським (колишнім радянським) вченим Юхимом Дініцем. [[Теорія складності обчислень # Тимчасова і просторова складності | Тимчасова складність]] алгоритму становить <math> O (V ^ 2 E) </ math>. Отримати таку оцінку дозволяє введення понять '' допоміжної мережі '' і '' блокуючого (псевдомаксімального) потоку ''. У мережах з одиничними пропускними здатностями існує більш сильна оцінка часової складності: <math> O (EV) </ math>.
Алгоритм Дініка '' або '' 'Алгоритм Дініца' '' - алгоритм [[сильно поліноміального]] для обчислення [[максимального потоку]] в [[flow network]], закладеному в 1970 році ізраїльською ( колишній радянський) комп'ютерний вчений Єфім (Хаїм) А. Диніц. <ref> {{цитувати журнал | автор = [[Ефім Дінітц]] | title = Алгоритм для вирішення задачі про максимальний потік в мережі з оцінкою потужності | журнал = Доктор наук Академії наук СРСР | обсяг = 11 | рік = 1970 | сторінки = 1277 & amp; 1280 | url = http: //www.cs.bgu.ac.il/ ~ dinitz / D70.pdf}} </ ref> Алгоритм працює в момент <math> O (V ^ 2 E) </ math> і аналогічний до [[Алгоритм Едмондса-Карпа]], який триває в часі <math> O (VE ^ 2) </ math>, в якому він використовує найкоротші шляхи доповнення. Впровадження концепцій "графа рівня" та "блокування потоку" дає алгоритм Dinic для досягнення своєї ефективності.


== Історія ==
== Опис ==
Ефім Диніц винайшов цей алгоритм у відповідь на заняття перед класом у класі алгоритмів [[Георгій Адельсон-Вельський, Адельсон-Вельський]]. У той час він не знав основних фактів, що стосуються [[алгоритму Форда-Фюльксона]]. <Ref> {{cite web | date = 2009-11-27 | author1 = Ilan Kadar | author2 = Sivan Albagli | title = алгоритм Дініца для знаходження максимального потоку в мережі | url = http: //www.powershow.com/view/c6619-OThkZ/Dinitss_algorithm_for_finding_a_maximum_flow_in_a_network_powerpoint_ppt_presentation}} </ ref>

Динітц згадує винахід його алгоритму в січні 1969 р., Який був опублікований у 1970 р. У журналі 'Доклегі Академії наук СРСР' '. У 1974 році Шимон Евен та його студент (аспірант) Алон Ітай в Тефіон-Ізраїльському технологічному інституті в Хайфі були дуже цікаві та заінтриговані алгоритмом Дініца, а також ідеєю Олександра Карзанова про блокування потоку . Проте їм було важко розшифрувати ці дві статті, кожен з яких обмежений до чотирьох сторінок, щоб задовольнити обмеження журналу "Доклегі Академії наук СССР". Навіть не здавався, і через три дні зусилля вдалося зрозуміти обидва паперу, крім питання про масштабоване обслуговування мережі. Протягом наступних кількох років навіть читав лекції з "Алгоритму Дініка", висловлюючи ігнорування імені автора під час його популяризації. Навіть та Ітя також сприяли цьому алгоритму шляхом об'єднання [[Breadth-first search | BFS]] та [[Depth-first search | DFS]], що є поточною версією алгоритму. <Ref> {{цитировать журнал | автор = Єфім Дініц | title = Алгоритм Дініца: оригінальна версія та Even's Version | url = http: //www.cs.bgu.ac.il/~dinitz/Papers/Dinitz_alg.pdf}} </ ref>

Протягом приблизно 10 років після винаходу алгоритму Форд-Фальксона було невідомо, чи можна було б завершити його в поліномиальному часі в загальному випадку ірраціональних потужностей краю. Це спричинило відсутність будь-якого алгоритму поліномиального часу для вирішення задачі максимальної течії в загальних випадках. Алгоритм Дініца та алгоритм [[Алгоритм Едмондса-Карпа]] (опублікований в 1972) одночасно показав, що в алгоритмі Форд-Фюккерсона, якщо кожен шлях збільшення є найкоротшим, то довжина шляхів збільшення не зменшує алгоритм завжди закінчується

== Визначення ==
Нехай <math> G = ((V, E), c, s, t) </ math> - [[транспортна мережа]], в якій <math> c (u, v) </ math> і <math> f (u, v) </ math> - відповідно пропускна здатність і потік через ребро <math> (u, v) </ math>.
Нехай <math> G = ((V, E), c, s, t) </ math> - [[транспортна мережа]], в якій <math> c (u, v) </ math> і <math> f (u, v) </ math> - відповідно пропускна здатність і потік через ребро <math> (u, v) </ math>.
: '' 'Залишкова пропускна здатність' '' - відображення <math> c_f \ colon V \ times V \ to R ^ + </ math> певний як:
: '' 'Залишкова пропускна здатність' '' - відображення <math> c_f \ colon V \ times V \ to R ^ + </ math> певний як:
:# Якщо <math>(u,v)\in E</math>,
: # Якщо <math> (u, v) \ in E </ math>,
:#: <math>c_f(u,v) = c(u,v) - f(u,v) </math>
: #: <Math> c_f (u, v) = c (u, v) - f (u, v) </ math>
:#: <math>c_f(v,u) = f(u,v)</math>
: #: <Math> c_f (v, u) = f (u, v) </ math>
:# <math>c_f(u,v) = 0</math> інакше.
: # <Math> c_f (u, v) = 0 </ math> інакше.


: '' 'Залишкова мережа' '' - граф <math> G_f = ((V, E_f), c_f | _ {E_f}, s, t) </ math>, де
: '' 'Залишкова сеть' '' - граф <math> G_f = ((V, E_f), c_f | _ {E_f}, s, t) </ math>, де
:: <math> E_f = \ {(u, v) \ in V \ times V \ mid c_f (u, v)> 0 \} </ math>.
:: <math> E_f = \ {(u, v) \ in V \ times V \ mid c_f (u, v)> 0 \} </ math>.


Рядок 25: Рядок 18:


: '' 'Блокуючий потік' '' - <math> st </ math> потік <math> f </ math> такий, що граф <math> G '= (V, E_L', s, t) </ math > з <math> E_L '= \ {(u, v) \ mid f (u, v) <c_f | _ {E_L} (u, v) \} </ math> не містить <math> st </ math > шляху.
: '' 'Блокуючий потік' '' - <math> st </ math> потік <math> f </ math> такий, що граф <math> G '= (V, E_L', s, t) </ math > з <math> E_L '= \ {(u, v) \ mid f (u, v) <c_f | _ {E_L} (u, v) \} </ math> не містить <math> st </ math > шляху.

== Алгоритм ==
'' 'Алгоритм Дініца' ''
: '' Вхід '': Мережа <math> G = ((V, E), c, s, t) </ math>.
: '' Вихід '': <math> s-t </ math> потік <math> f </ math> максимальної величини.
# Встановити <math> f (e) = 0 </ math> для кожного <math> e \ in E </ math>.
# Створити <math> G_L </ math> з <math> G_f </ math> графа <math> G </ math>. Якщо <math> \ operatorname {dist} (t) = \ infty </ math>, зупинитися і вивести <math> f </ math>.
# Знайти блокуючий потік <math> f \; '</ math> в <math> G_L </ math>.
# Доповнити потік <math> \ f </ math> потоком <math> f \; '</ math> і перейти до кроку 2.


== Аналіз ==
== Аналіз ==
Рядок 31: Рядок 33:
Використовуючи структури даних, звані [[динамічні дерева]], можна знаходити блокуючий потік на кожній фазі за час <math> O (E \ log V) </ math>, тоді час роботи алгоритму Дініца може бути покращено до <math> O ( VE \ log V) </ math>.
Використовуючи структури даних, звані [[динамічні дерева]], можна знаходити блокуючий потік на кожній фазі за час <math> O (E \ log V) </ math>, тоді час роботи алгоритму Дініца може бути покращено до <math> O ( VE \ log V) </ math>.


== Алгоритм ==
== Приклад ==
Нижче приведена симуляція алгоритму Дініца. У допоміжній мережі <math> G_L </ math> вершини з червоними мітками - значення <math> \ operatorname {dist} (v) </ math>. Блокуючий потік позначений синім.
'' 'Алгоритм Диніка' ''
: '' Input '': мережа <math> G = ((V, E), c, s, t) </ math>.
: '' Output '': тест <math> s-t </ math> <математика> f </ math> максимального значення.
# Встановіть <math> f (e) = 0 </ math> для кожного <math> e \ in E </ math>.
# Construct <math> G_L </ math> з <math> G_f </ math> з <math> G </ math>. Якщо <math> \ operatorname (dist) (t) = \ infty </ math>, зупиніть та виведіть <math> f </ math>.
# Знайдіть блокування потоку <math> f \; '</ math> в <math> G_L </ math>.
# Додати збільшене потік <math> \ f </ math> за допомогою <math> f \; '</ math> і повернутися до кроку 2.


{| class = "wikitable" style = "text-align: center; width: 915px;" border = "1"
== Аналіз ==
| -
Можна показати, що кількість шарів в кожному потоці блокування зростає щонайменше 1 разів і, таким чином, там
! width = "15px" |

! <Math> G </ math>
! <Math> G_f </ math>
! <Math> G_L </ math>
| -
! 1.
| [[Файл: Dinic algorithm G1.svg | 300px]]
| [[Файл: Dinic algorithm Gf1.svg | 300px]]
| [[Файл: Dinic algorithm GL1.svg | 300px]]
| -
|
| align = "left" colspan = "3" |
Блокуючий потік складається з шляхів:
# <Math> \ {s, 1, 3, t \} </ math> з 4 одиницями потоку,
# <Math> \ {s, 1, 4, t \} </ math> з 6 одиницями потоку, і
# <Math> \ {s, 2, 4, t \} </ math> з 4 одиницями потоку.
Отже, блокуючий потік містить 14 одиниць, а величина потоку <math> | f | </ math> дорівнює 14. Зауважимо, що доповнює шлях має '' 3 '' ребра.
| -
! 2.
| [[Файл: Dinic algorithm G2.svg | 300px]]
| [[Файл: Dinic algorithm Gf2.svg | 300px]]
| [[Файл: Dinic algorithm GL2.svg | 300px]]
| -
|
| align = "left" colspan = "3" |
Блокуючий потік складається з шляхів:
# <Math> \ {s, 2, 4, 3, t \} </ math> з 5 одиницями потоку.
Отже, блокуючий потік містить 5 одиниць, а величина потоку <math> | f | </ math> дорівнює 14 + 5 = 19. Зауважимо, що доповнює шлях має '' 4 '' ребра.
| -
! 3.
| [[Файл: Dinic algorithm G3.svg | 300px]]
| [[Файл: Dinic algorithm Gf3.svg | 300px]]
| [[Файл: Dinic algorithm GL3.svg | 300px]]
| -
|
| align = "left" colspan = "3" |
Сток <math> t </ math> не можна досягти в мережі <math> G_f </ math>. Тому алгоритм зупиняється і повертає максимальний потік величини 19. Зауважимо, що в кожному блокирующем потоці кількість ребер в доповнює шляху збільшується хоча б на одне.
| -
|}

== Історія ==
Алгоритм Дініца був опублікований в 1970 р колишнім радянським ученим Юхимом Дініцем, який зараз є членом факультету обчислювальної техніки університету Бен-Гуріон (Ізраїль), раніше, ніж [[алгоритм Едмондс - Карпа]], який був опублікований в 1972, але створений раніше . Вони незалежно показали, що в [[Алгоритм Форда - Фалкерсона | алгоритмі Форда - Фалкерсона]] в разі, якщо доповнює шлях є найкоротшим, довжина доповнює шляху не зменшується.

== Література ==
* {{Cite book | author = Yefim Dinitz | editor = [[Oded Goldreich]], Arnold L. Rosenberg, and Alan L. Selman | title = Theoretical Computer Science: Essays in Memory of [[Shimon Even]] | chapter = Dinitz 'Algorithm: The Original Version and Even's Version | year = 2006 | publisher = Springer | isbn = 978-3540328803 | pages = 218-240 | url = http://www.cs.bgu.ac.il/~dinitz/Papers/Dinitz_alg.pdf}}
* {{Cite book | author = B. H. Korte, Jens Vygen | title = Combinatorial Optimization: Theory and Algorithms (Algorithms and Combinatorics, 21) | chapter = 8.4 Blocking Flows and Fujishige's Algorithm | year = 2008 | publisher = Springer Berlin Heidelberg | isbn = 978-3-540-71844-4 | pages = 174-176}}

== Посилання ==
* [Http://e-maxx.ru/algo/dinic Алгоритм Дініца на сайті e-maxx.ru: Опис, докази, реалізація на C ++]

[[Категорія: Алгоритми на графах]]

Версія за 15:48, 24 листопада 2017

'Алгоритм Дініца' - поліноміальний алгоритм для знаходження максимального потоку в транспортної мережі, запропонований в 1970 році ізраїльським (колишнім радянським) вченим Юхимом Дініцем. Тимчасова складність алгоритму становить <math> O (V ^ 2 E) </ math>. Отримати таку оцінку дозволяє введення понять допоміжної мережі і блокуючого (псевдомаксімального) потоку . У мережах з одиничними пропускними здатностями існує більш сильна оцінка часової складності: <math> O (EV) </ math>.

Опис

Нехай <math> G = ((V, E), c, s, t) </ math> - транспортна мережа, в якій <math> c (u, v) </ math> і <math> f (u, v) </ math> - відповідно пропускна здатність і потік через ребро <math> (u, v) </ math>.

'Залишкова пропускна здатність' - відображення <math> c_f \ colon V \ times V \ to R ^ + </ math> певний як:
# Якщо <math> (u, v) \ in E </ math>,
#: <Math> c_f (u, v) = c (u, v) - f (u, v) </ math>
#: <Math> c_f (v, u) = f (u, v) </ math>
# <Math> c_f (u, v) = 0 </ math> інакше.
'Залишкова сеть' - граф <math> G_f = ((V, E_f), c_f | _ {E_f}, s, t) </ math>, де
<math> E_f = \ {(u, v) \ in V \ times V \ mid c_f (u, v)> 0 \} </ math>.
'Доповнює шлях' - <math> s-t </ math> шлях в залишковому графі <math> G_f </ math>.
Нехай <math> \ operatorname {dist} (v) </ math> - довжина найкоротшого шляху з <math> s </ math> в <math> v </ math> в графі <math> G_f </ math>. Тоді 'допоміжна сеть' графа <math> G_f </ math> - граф <math> G_L = (V, E_L, c_f | _ {E_L}, s, t) </ math>, де
<math> E_L = \ {(u, v) \ in E_f \ mid \ operatorname {dist} (v) = \ operatorname {dist} (u) + 1 \} </ math>.
'Блокуючий потік' - <math> st </ math> потік <math> f </ math> такий, що граф <math> G '= (V, E_L', s, t) </ math > з <math> E_L '= \ {(u, v) \ mid f (u, v) <c_f | _ {E_L} (u, v) \} </ math> не містить <math> st </ math > шляху.

Алгоритм

'Алгоритм Дініца'

Вхід : Мережа <math> G = ((V, E), c, s, t) </ math>.
Вихід : <math> s-t </ math> потік <math> f </ math> максимальної величини.
  1. Встановити <math> f (e) = 0 </ math> для кожного <math> e \ in E </ math>.
  2. Створити <math> G_L </ math> з <math> G_f </ math> графа <math> G </ math>. Якщо <math> \ operatorname {dist} (t) = \ infty </ math>, зупинитися і вивести <math> f </ math>.
  3. Знайти блокуючий потік <math> f \; '</ math> в <math> G_L </ math>.
  4. Доповнити потік <math> \ f </ math> потоком <math> f \; '</ math> і перейти до кроку 2.

Аналіз

Можна показати, що кожен раз кількість ребер в блокирующем потоці збільшується хоча б на одне, тому в алгоритмі не більше <math> n-1 </ math> блокуючих потоків, де <math> n </ math> - кількість вершин в мережі. Допоміжна мережа <math> G_L </ math> може бути побудована обходом в ширину за час <math> O (E) </ math>, а блокуючий потік на кожному рівні графа може бути знайдений за час <math> O (VE) </ math>. Тому час роботи алгоритму Дініца є <math> O (V) * (O (E) + O (VE)) = O (V ^ 2 E) </ math>.

Використовуючи структури даних, звані динамічні дерева, можна знаходити блокуючий потік на кожній фазі за час <math> O (E \ log V) </ math>, тоді час роботи алгоритму Дініца може бути покращено до <math> O ( VE \ log V) </ math>.

Приклад

Нижче приведена симуляція алгоритму Дініца. У допоміжній мережі <math> G_L </ math> вершини з червоними мітками - значення <math> \ operatorname {dist} (v) </ math>. Блокуючий потік позначений синім.

- <Math> G </ math> <Math> G_f </ math> <Math> G_L </ math> - 1. -

Блокуючий потік складається з шляхів:

  1. <Math> \ {s, 1, 3, t \} </ math> з 4 одиницями потоку,
  2. <Math> \ {s, 1, 4, t \} </ math> з 6 одиницями потоку, і
  3. <Math> \ {s, 2, 4, t \} </ math> з 4 одиницями потоку.

Отже, блокуючий потік містить 14 одиниць, а величина потоку <math> | f | </ math> дорівнює 14. Зауважимо, що доповнює шлях має 3 ребра.

- 2. -

Блокуючий потік складається з шляхів:

  1. <Math> \ {s, 2, 4, 3, t \} </ math> з 5 одиницями потоку.

Отже, блокуючий потік містить 5 одиниць, а величина потоку <math> | f | </ math> дорівнює 14 + 5 = 19. Зауважимо, що доповнює шлях має 4 ребра.

- 3. -

Сток <math> t </ math> не можна досягти в мережі <math> G_f </ math>. Тому алгоритм зупиняється і повертає максимальний потік величини 19. Зауважимо, що в кожному блокирующем потоці кількість ребер в доповнює шляху збільшується хоча б на одне.

-

Історія

Алгоритм Дініца був опублікований в 1970 р колишнім радянським ученим Юхимом Дініцем, який зараз є членом факультету обчислювальної техніки університету Бен-Гуріон (Ізраїль), раніше, ніж алгоритм Едмондс - Карпа, який був опублікований в 1972, але створений раніше . Вони незалежно показали, що в алгоритмі Форда - Фалкерсона в разі, якщо доповнює шлях є найкоротшим, довжина доповнює шляху не зменшується.

Література

  • Yefim Dinitz (2006). Dinitz 'Algorithm: The Original Version and Even's Version. У Oded Goldreich, Arnold L. Rosenberg, and Alan L. Selman (ред.). Theoretical Computer Science: Essays in Memory of [[Shimon Even]] (PDF). Springer. с. 218—240. ISBN 978-3540328803. {{cite book}}: Назва URL містить вбудоване вікіпосилання (довідка)
  • B. H. Korte, Jens Vygen (2008). 8.4 Blocking Flows and Fujishige's Algorithm. Combinatorial Optimization: Theory and Algorithms (Algorithms and Combinatorics, 21). Springer Berlin Heidelberg. с. 174—176. ISBN 978-3-540-71844-4.

Посилання