Professional Documents
Culture Documents
Raz3Te3Alg UA
Raz3Te3Alg UA
Лекція 3.1. Базові поняття оцінки алгоритмів і їх застосування для обходу вершин
графу
У цій лекції розглянемо необхідні для оцінки трудомісткості алгоритмів означення і
продемонструємо їх для важливого класу алгоритмів пошуку в глибину.
1. Аналіз і оцінка алгоритмів . Будемо думати, що наша універсальна машина здатна
виконувати зазначену множину операцій.
2. Алгоритм пошуку в глибину і його оцінка. Нехай G - неорієнтований зв'язний граф.
У процесі пошуку в глибину вершинам графа G привласнюються номери (ПГ-номери), а його
ребра позначаються. На початку ребра не позначені, вершини не мають ПГ-номерів.
Починаємо з довільної вершини V0 . Приписуємо їй ПГ-номер ПГ(V0) = 1 і обираємо довільне
ребро V0W. Ребро V0W позначається як «пряме», а вершина w одержує (з V0) ПГ-номер ПГ(w) =
2. Після цього переходимо у вершину w. Нехай у результаті виконання декількох кроків
цього процесу прийшли у вершину х, і нехай k — останній привласнений ПГ-номер. Далі
діємо в залежності від ситуації в такий спосіб:
1. Маємо непозначене ребро ху. Якщо у вершини у уже є ПГ-номер, то ребро ху
позначаємо як «зворотнє» і продовжуємо пошук непозначеного ребра, інцидентного вершині
х. Якщо ж вершина в ПГ-номера не має, то нехай ПГ(y)=k+1, ребро ху помічаємо як «пряме»
і переходимо у вершину в. Вершина у вважається тією, що має свій ПГ-номер з вершини х.
На наступному кроці будемо переглядати ребра, інцидентні вершині в.
2. Усі ребра, інцидентні вершині х, позначені. У цьому випадку повертаємося у
вершину, з якої х одержала свій ПГ-номер.
Процес закінчиться, коли всі ребра будуть позначені і відбудеться повернення у
вершину V0.
Описаний процес можна реалізувати так, щоб час роботи відповідного алгоритму
складав 0(|EG|+|G|).
Такий алгоритм (алгоритм A1) ми зараз розглянемо. Нехай граф G заданий списками
суміжності, тобто Nv — список вершин, інцидентних вершині v, і V0 — вихідна вершина, з
яким починається пошук. У процесі роботи алгоритму кожна вершина графу лише один раз
включається в список Q і виключається з нього. Вершина включається в цей список відразу
після одержання ПГ-номера, і виключається, як тільки відбудеться повернення з цієї
вершини. Включення і виключення вершин починається завжди з кінця списку, тобто Q —
стек. Результат роботи алгоритму — чотири списки ПГ, F, Т і В:
ПГ(v) - ПГ-номер вершини v; F(v) - ім'я вершини, з якої вершина v одержала свій ПГ-
номер; Т і В — відповідно списки орієнтованих «прямих» і «зворотніх» ребер графа G. Ці
ребра одержують орієнтацію в процесі роботи алгоритму A1. Саме, якщо ребро ху
позначається з вершини х як «пряме», то в Т заноситься дуга (x, y), а як «зворотнє», то ця
дуга заноситься у В.
Алгоритм A1 пошуку в глибину в неорієнтованому зв'язному графі.
1. ПГ(V0):=1, Q(1):=V0, F(V0):=0, Т:=Ø,У:=Ø, k:=1, р:=1 [k - останній приписаний ПГ-
номер, р — покажчик кінця стека Q, тобто Q(p) - ім'я останньої вершини стека Q].
2. v := Q(p) [v — досліджувана вершина].
3. Переглядаючи список Nv знайти таку вершину w, що ребро vw не позначене, і
перейти до п. 4. Якщо таких вершин немає, то перейти до п. 5.
4. Якщо вершина w має ПГ-номер, то позначити ребро vw як «зворотнє» і занести дугу
(v,w) у список В. Перейти до п. 3 і продовжити перегляд списку Nv. Інакше k:=k+1,
ПГ(w):=k, F(w):=v, ребро vw позначити як «пряме» і дугу (v, w) занести в список Т, р:=р+1,
Q(p) := w [вершина w одержала ПГ-помер і занесена в стек Q]. Перейти до п. 2.
5. р:=р—1 [вершина v викреслена з Q ] Якщо р = 0, то кінець. Інакше перейти до п. 2.
Коректність алгоритму безперечна. Оцінимо його трудомісткість. Кожне включення і
виключення вершини зі стека Q виконується за час 0(1). Тому для всієї роботи, зв'язаної зі
зміною стека Q, достатньо часу 0(/G/). Кожне виконання п. 4 вимагає 0(1) часу, і для кожної
вершини v Є VG цей пункт виконується deg v раз. Тому витрати на його виконання в цілому
складуть ПРО( ∑ deg v) == 0(|EG|). Сумарний час
Виконання п.3 також складе 0(|EG|), якщо подбати про те, щоб кожна вершина списку
Nv розглядалася тільки один раз при всіх виконаннях цього пункту. Цього легко домогтися,
якщо, наприклад, увести таку нову функцію (масив) t, що t(v)-номер першої непереглянутої
вершини в списку Nv. Тоді наступний перегляд п.3 варто починати з вершини z =Nv(t(v)).
Отже, трудомісткість алгоритму A1 складає 0(|EG|+|G|). Зрозуміло, що цей час є
найкращим з можливих з множини, тому що кожна вершина і кожне ребро графа G повинні
бути переглянуті хоча б один раз.
Легко бачити, що необхідний для реалізації алгоритму A1 обсяг пам'яті також складає
0(|EG| + |G|).
На мал. 7 ліворуч зображені граф G і списки суміжності, якими він заданий. Праворуч
представлені результати застосування до цього графа пошуку в глибину з вершини vo=1.
1 1
N1 = (3,2,5)
2 N2=(4,1,5)
2 2
3 N3=(1,5)
4 5 N4=(2,5) 5
N5=(2,1,3,4,7,6) 3
6 N6=(5,7)
7
N7=(5,6) 6
7
Мал. 73.1
«Прямі» ребра проведені суцільними лініями, а «зворотні» пунктирними. Кожній
вершині приписаний її ПГ-номер.
Зі способу побудови безлічей Т и В безпосередньо випливають наступні твердження.
Твердження 73.1. Дуги безлічі Т утворять орієнтоване остовное дерево з коренем у
вершині vo.
Це остовне дерево часто називають остовне глибинне дерево (ОГД). Позначати його
будемо також через Т.
Твердження 73.2. Якщо орієнтоване ребро (х, у) належить У, то ПГ(x)> ПГ(y),
тобто «зворотні» ребра завжди ведуть до раніше пройдених вершин.
Пошук у глибину використовують як складену частину в багатьох алгоритмах.
Відзначимо одну задачу, розв’язок якої можна одержати за допомогою алгоритму A1 відразу,
майже без додаткових обчислювальних витрат. Це — задача виділення зв'язних компонентів
графа. Щоб вирішити її за час 0(|EG| + |G|), достатньо один раз переглянути список вершин
графа, виконуючи наступні дії. Якщо вершина, що переглядається, vl має Пг-номер, то
перейти до наступного. Інакше — покласти vo=vl, ПГ(vo)= k+1, де k — останній привласнений
ПГ-номер, і застосувати пошук у глибину. Після його закінчення (тобто виділення
компонента, що містить vl) продовжити перегляд списку, перейти до вершини vl+1. Розрізняти
вершини різних компонентів можна, наприклад, по їхній Пг-номерам, якщо для кожного
компонента запам'ятати останній Пг-номер.
Лекція 3.2. Алгоритми визначення двохзв’язних компонент і їх оцінка
У цій лекції ми розглянемо застосування пошуку в глибину до виділення двох
зв’язних компонентів графа. Тут справа обстоїть не так просто, як у попередній задачі.
Звичайно, можна було б, видаляючи по черзі вершини графа і щораз виділяючи зв'язкові
компоненти, знайти його точки зчленування і блоки. Такий підхід, однак, приводить до
алгоритму складності принаймні O(|G||EG|). Використання більш глибоких властивостей ПГ
дозволяє одержати лінійний по складності алгоритм розв’язку цієї задачі.
1. Дослідження властивостей алгоритму пошуку в глибину. Надалі зручно
використовувати наступні терміни. Нехай D = (V, A) – орієнтоване дерево, x, y V. Назвемо
x батьком вершини y, а y – сином вершини x, якщо дуга (x, y) належить А. Будемо говорити,
що вершини x і y порівнянні, якщо при цьому y досяжна з x. Якщо при цьому y досяжна з x,
то x – предок вершини y, а y – нащадок вершини x. Підграф графа D, породжений безліччю,
що складається з вершини y і всіх її нащадків, будемо позначати через Dy і називати
піддеревом з коренем y.
Нехай у графі G пророблений пошук у глибину з вершини v0 і отримане остовне
глибинне дерево Т і безліч компонентів.
Теорема 74.1. Якщо дуга (x, y) належить У, то x є нащадком вершини y у Т.
Доказ. Треба довести, що вершина x належить піддереву Ту. Припустимо противне.
Відповідно до твердження 73.2 вершина x одержує свій Пг-номер пізніше, ніж y. Тому
присвоєння вершині x Пг-номера відбудеться не раніш, ніж будуть відвідані усі вершини
дерева Ту і відбудеться повернення у вершину s = F(y). Але повернення в s не може
відбутися перш, ніж усі вершини безлічі Ny одержать Пг-номера. Оскільки xNy і ПГ-
номера до цього моменту не має, то одержуємо протиріччя.
наступні два твердження показують, яким чином пошук у глибину «реагує» на точки
зчленування графа.
Теорема 74.2. Вершина v0 є точкою зчленування графа G тоді і только тоді, коли
вона має не менш двох синів.
Доведення. Нехай v0 – точка зчленування графа G. Безперечно, що кожен блок графу,
що включає вершину v0 містить принаймні одного з її синів.
Нехай тепер s1, s2, ...,sk – сини вершини v0. Розглянемо піддерева.
Tsi (i 1, k ).
Безперечно, що
k
VG v0 Vsi .
i 1
v0
B1
C1 C2B3
B
4
B2
Мал. 74.1
c3
B6
c4 y
B7
Приклад. На мал. 74.2 зображений граф G і приведені списки суміжності його вершин. Цей
граф має чотири блоки В1, У2, У3, У4 і дві крапки зчленування d і x. Пошук у глибину
починається з вершини a, тобто v0=a. На мал. 74.3 відбита ситуація, що склалася
безпосередньо перед виділенням блоку B4. До цього моменту шість ребер позначені як
«прямые» і одне как «зворотне». Прямі ребра проведені жирними лініями, а зворотне –
пунктирної. Тим і іншим додана відповідна орієнтація. Позначені ребра розташовані в стеці
S у тім порядку, у якому вони одержували позначки. Пари чисел (,), приписана вершині v,
має наступний сенс: =ПГ(v), а - значення l(v), обчислене до розглянутого моменту.
Після того, як ребро tx одержало позначку «зворотне», відбулося повернення у
вершину z. При цьому порівняння величин ПГ(z)=6 і l(t)=5 показало, что вершина z не є
точкою зчленування. Далі при поверненні з вершини z у x виявляється, что l(z) = 5 = ПГ(x).
Отже, усі ребра від tx до xz у стеці S складають блок графа G. Ці ребра –tx, tz, xz –
віддаляються з S, і тим самим виділений блок B4.
Після цей алгоритм працює так, ніби блоку B4 у графі G не було взагалі. Ключові
моменти подальшої роботи алгоритму ілюструються на мал. 74.4. Кожний із трьох графів
(разом з їхніми позначками і стеком S), зображених на цьому малюнку, відбиває ситуацію,
що створилася безпосередньо перед видаленням чергового блоку.
Виділення останнього блоку, т.е видалення его ребер зі стека S, відбудеться при
поверненні у вершину v0=a, для якої ПГ(a)=1=l(c). Таким чином, на вершину v0=a алгоритм
«реагує» точно так само, як на крапку зчленування.
Мал. 75.2
Приклад 2. Застосуємо алгоритм A4 до графу, зображеному на мал. 75.2 На першій
ітерації буде знайдена безліч E1={a1a2, a1a3,a4a7,a5a8,a6a9,a9a10} мінімальних по вазі ребер
для лісу, що має одновершинні компоненты. Кістякові ліси, отримані в результаті виконання
1-й, 2-ї, і 3-ї ітерацій, зображені на мал. 75.3. Останній з них є мінімальним кістяком.
K раз
Будемо вважати, что граф G заданий матрицею ваг або списками суміжності.
Алгоритм A4 Дийкстры пошуки найкоротшого шляху.
Мал. 75.2
1. Покласти l(s):=0 і вважати цю мітку постійною. Покласти l(v) := ( для всіх v ( VG,
v(s, і вважати ці мітки тимчасовими. Покласти p:=s.
2. Для всіх v ( Г(p) з тимчасовими мітками виконати: якщо l(v)>l(p)+w(p,v), те
l(p):=l(p)+w(p,v) і ((v):=p. Інакше l(v) і ((м) не змінювати.
3. Нехай V' – безліч вершин з тимчасовими мітками l. Знайти вершину v*, таку що
l(v*) = min l(v).
v(V(
Вважати мітку l(v*) постійною міткою вершини l(v*).
4. p := v*. Якщо p = t, то перейти до п. 5 [l(t) – вага найкоротшого шляху]. Інакше
прейти до п. 2.
5.
P * : ( s,..., 3 (t ), 2 (t ), (t ), t )
[P* – найкоротший шлях]. Кінець.
Перш ніж перейти до обґрунтування алгоритму, зробимо три корисних зауваження.
Зауваження 1. Як легко бачити, алгоритм А5 застосовуємо до змішаного і , в
частково, до неорієнтованих графам. Для цього досить кажне неориєнтоване ребро uv графу,
що має вагу w(u, v), розглядати як пари дуг (u, v) і (v, u) тієї ж ваги.
Зауваження 2. Якщо п. 4 модифікувати таким чином, щоб алгоритм закінчував роботу
тілько після одержання усіма вершинами постійних міток, то він буде будувати найкоротші
шляхи з s у кожну з інших вершин. Якщо до того ж разом з перетворенням метки вершини v*
у постійну (п. 3 алгоритму) заносити дугу ((v*), v*) у безлічі А*, то після закінчення роботи
алгоритму граф D = (VG, A*) буде кореневим орієнтованим кістяковим деревом. Це дерево
називається деревом найкоротших шляхів з s графа G. Для будь-якої вершини vVG єдиний
шлях (s, v)-шлях у дереві D є найкоротчшим (s, v)-шляхом у графі G.
Зауваження 3. Алгоритм А5, модифікований так, як зазначено в зауваженні 2, можна
розглядати як алгоритм побудови дерева D найкоротших шляхів з вершин s графа G. З цього
погляду алгоритм А5 анологічен алгоритму А3 побудови мінімального кістяка. дійсно,
побудова дерева D складається в послідовному збільшенні вже побудованого фрагменту
шляхом додавання деякої дуги, “вихідної” з цього фрагмента. При цьому влучні l і грають
таку ж роль, як і мітки і в алгоритмі А3.
Теорема 76.1. Алгоритм А5, будує в графе G найкоротший (s, t)-шлях за час
Доказ. Помітимо спочатку, що мітка вершини v (l(v) (() дорівнює вазі (s, v)-шляху, що
O(| G |2 ).
побудований алгоритмом до цього моменту. Він визначається мітками (, що маються на цей
момент. Тому для доказу оптимальності (s, t)-шляху, що відповідає постійній мітці l(t),
досить довести, що постійна мітка l(v) кожної вершини v дорівнює ваги найкоротшого (s, v)-
шляху. Це твердження будемо доводити по індукції. Нехай вершина v отримала свою
постійну мітку на k-й ітерації, тобто після k-го виконання п. 3. При k = 1 справедливість
твердження очевидна. Припустимо, що воно вірно для вершин, що одержали свої постійні
мітки на ітераціях 2, 3, ..., k – 1. Позначимо через P( (s, t)-шлях, побудований алгоритмом у
результаті k ітерацій, а через Р* – найкоротший (s, v)-шлях. За умовою w(P() = l(v).
Нехай V1 і V2 – безлічі вершин, що мають відповідно постійні і тимчасові мітки
перед початком k-ї ітерації. Розглянемо дві можливі ситуації:
а) Шлях Р* містить вершини з V2. Нехай (v – перша (вважаючи від s) така вершина,
що належить Р*, а вершина v( передує(v на шляху Р*, тобто (v(,(v)(AP*. Відповідно до
вибору(v маємо v((V1. Позначимо через Р1* частину шляху Р* від s до(v. По припущенню
індукції l((v) – вага найкоротшого (s, (v)-шляху. Тому
w(Р1* ) = l((v) + w(v((v) ( l((v).
Оскільки l((v) – тимчасова мітка, а остання мітка l(v) вершини v вибирається на k-й ітерації
як найменша з тимчасових, то l((v) ( l(v). Об'єднавши цю нерівність з (1), одержимо
w(P*) ( w(P1*) ( l(v) = w(P(),
т. ч. P( – найкоротший (s, t)-шлях.
б) Усі вершини шляху Р* входять у V1. Нехай v( і v(( – такі вершини, що (v(, v)(АР* і
(v((, v)(АР(. Позначимо через Р( частина шляху Р* від s до v(, відповідно до припущення
індукції маємо w(P() ( l(v(). Тому, якщо v( = v((, то відразу одержуємо нерівність
w(P*) = w(P() + w(v(, v) ( l(v() + w(v(, v) = w(P().
Допустимо тепер, що v(( ( v(. Оскільки v одержує постійну мітку l(v) з v((, а не з v(, те
V(P*) = l(v() + w(v(, v) ( l(v(() + w(v((, v) = w(P().
Таким чином, і у випадку б) вірна нерівність w(P() ( w(P*), тобто P( – найкоротший (s,
v)-пута.
Оцінимо тепер трудомісткість алгоритму. Обчислювальні витрати максимальні, коли
вершина t одержує постійну мітку останньої і граф G є повним. У цьому випадку число
ітерацій алгоритму дорівнює |G| – 1, тобто кожний із пп. 2 – 4 виконується |G| – 1 разів.
Очевидно, що п. 4 виконується за час ПРО(1), а для виконання кожної з пп. 2, 3 досить часу
ПРО(|G|).
Мал. 76.1
W s.
Саме в цьому складається ітерація алгоритму А7, що, починаючи з W = W,
W 0 ,W 1 , ,W n , что W m получается
изW m1
W m 1 .
будує таку послідовність матриць застосуванням t-операції до індексу m і матриці
Якщо в графі G немає від’ємних контурів, то елемент
Wijm матрици W m
при кожному m дорівнює вазі найкоротшого (i, j)-шляху, усі внутрішні вершини якого
належать безлічі {1, 2, ..., m}. Таким чином, остання з цих матриць,
містить ваги найкоротших шляхів між усіма парами вершин графу. Для того щоб після
W n,
закінчення роботи алгоритму мати можливість швидко знайти найкоротший шлях між будь-
якою парою вершин, будемо на k-й ітерації разом з матрицею
Wk
будувати матрицю
P k || Pijk || .
Спочатку думаємо
Pij0 i (i, j 1, n.
Далі, на k-й ітерації думаємо
Pijk Pijk 1 , если Wijk Wijk 1 , иPijk Pijk 1 , если Wijk Wikk 1 Wkjk 1 .
номер вершини, що передує вершині j у поточному (i, j)-шляху, тобто в найкоротшому (i, j)-
шляху, усі внутрішні вершини якого містяться в безлічі {1, 2, ..., k}. Матриця
P n | Pijn |
грає ту ж роль, що й мітки у попередніх алгоритмах А5 і А6. За допомогою цієї матриці
найкоротший (i, j)-шлях L(i, j) визначається в такий спосіб: L(i, j) = (i, ..., j3, j2, j1, j), де
j1 Pijn , j2 Pijn1 , j3 Pijn2 ,...
Алгоритм А7 відшукання найкоротших шляхів між усіма парами вершин.
1.
W 0 : W , k : 1, P 0 :|| Pij0 ||, гдеPij0 i, еслиWij , иPij0 0
у противному випадку.
2. Виконати для всіх
i, j 1, n : если Wijk 1 Wikk 1 Wkjk 1 , то Wijk : Wijk 1 , Pijk : Pijk 1 .
Иначе Wijk : Wikk 1 Wkjk 1 , Pijk : Pkjk 1 .
3. Якщо для деякого l,
1 l n,Wllk 0,
то кінець [у графе маємо від’ємний контур]. Інакше перейти до п. 4.
4. k:=k+1. Якщо k=n+1, то кінець
[W n || Wijn ||
матриця ваг найкоротших шляхів, обумовлених за допомогою матриці
P n || Pijn ||].
Зауваження 5. Алгоритм буде застосовний до змішаних графів, якщо кожне
неорієнтоване ребро замінити на двох дуг тієї ж ваги (див. зауваження 2). При цьому варто
врахувати, что неорієнтоване ребро від’ємної ваги приводить до від’ємного контуру.
Зауваження 6. Алгоритм «відмовляється» будувати найкоротші шляхи, коли в графі
G маються від’ємні контури. У цьому випадку задача відшукання найкоротшого шляху між
двома вершинами (чи між усіма парами вершин) залишається коректною, але стає дуже
важкою. Можна показати, что вона не менш важка, чим, наприклад, задача про комівояжера.
Перейдемо тепер до обґрунтування алгоритму А7 і оцінювання його трудомісткості.
Теорема 76.3. Нехай зважений орієнтований мультиграф L має ейлеровий ланцюг, що
з'єднує вершини a і b. Якщо в L немає від’ємних контурів, то в ньому є такий (a, b)-шлях Р,
що w(L) w(P).
Доказ. Будемо вважати, що мультиграф L не є шляхом (інакше твердження
тривіальне). Тому він містить деякий контур S. Видаливши з L усі дуги цього контуру,
одержимо мультиграф L’. Оскільки w(S) 0, то w(L) w(L).
Крім того, відповідно до теореми 65.2 напівступеня вершин мультиграфа L’ задовольняють
співвідношенням
d (a ) d (a ) 1, d (b) d (b) 1, d (v) d (v), v a, b.
Тому вершини a і b належать до однієї її слабкої компоненти L’’, і остання містить
ейлеров (a, b)-ланцюг. Продовжуючи подібним чином, одержимо необхідний (a, b)-шлях.
Теорема 76.4. Якщо в графі немає від’ємних контурів, то при всіх
k , i , j 1, n Wijk
вага найкоротшого (i, j)-шляху, усі внутрішні вершини якого містяться в безлічі {1, 2, ..., k}.
Доказ. Доводимо індукцією по k. При k=1 справедливість твердження очевидна.
Припустимо, что воно справедливо для 2, 3, ..., k – 1, і розглянемо
Wijk . Пусть P 0
найкоротший (i, j)-шлях, усі внутрішні вершини якого належать безлічі {1, 2, ..., k}. Якщо
P 0 не включает вершину k , то Wijk Wijk 1
і, відповідно до припущення індукції,
w( P 0 ) Wijk 1 Wijk 1 .
Допустимо тепер, что P містить вершину k. Позначимо через
P10 и P20 части пути P 0
від i до k і від k до j відповідно. Припустимо, что один з цих шляхів, наприклад
P10 ,
не є найкоротшим, і нехай P’ – найкоротший (i, k)-шлях, усі вершини якого містяться в
безлічі {1, 2, ..., k-1}. Розглянемо мультиграф L, що виходить із графа
P / P20 ,
заміною кожної дуги, що входить одночасно в
P / и P20 ,
двома екземплярами цієї дуги. Очевидно, що L не містить від’ємних контурів. Тому,
відповідно до твердження 76.3, L містить такий (i, j)-шлях Р, що
w( L) w( P) и, следовательно, w( P 0 ) w( P10 ) w( P20 ) w( P / ) w( P20 ) w( L) w( P).
Ця нерівність суперечить мінімальності P.
Таким чином, шляху
P10 и P20
Є найкоротшими серед, відповідно, (i, k)- і (k, j)-шляхів, усі внутрішні вершини яких
належать безлічі {1, 2, ..., k – 1}. Тому, скориставшись припущенням індукції, одержимо
Мал. 76.2
0 2 3 3 0 1 1 1
0 2 2 0 2 2
W1 , P1 ,
0 3 3 3 0 3
4 2 5 0 4 1 4 0
0 2 0 3 0 1 2 1
0 2 2 0 2 2
W2 , P2 ,
0 3 3 3 0 3
4 2 4 0 4 11 2 0
0 2 0 3 0 2 1
0 2 1 2 0 2 3
W3 , P3 ,
0 3 3 3 0 3
4 2 4 0 4 1 2 0
P2144 4, P244 3, P234 2.
P
Знайдемо, наприклад, за допомогою матриці P4 найкоротший (2, )-шлях: P421 = 4, P424 = 3, P423
= 2. Отже, (2, 3, 4 , 1) – найкоротший (2,1)-шлях.
0 2 0 3 0 1 2 1
3 0 2 1 4 0 2 3
W4 , P4 .
1 1 0 3 4 1 0 3
4 2 4 0 4 1 2 0
мал. 77.1.
G G
Мал. 77.2
G X {x : x X , d ( x ) 0}, Y { y : y Y , d ( y ) 0}
[в графе G X Y множество вершин, не насыщенных текущим
паросочитанием ]. Выполнить в графе G поиск в ширину ( алгоритм А6 )
из множества Х .
Y
Теорема 77.3. Алгоритм А8 будує найбільше паросполучення в двочастковому графі
G = (X, Y, EG) за час O (|EG| min {|X|, |Y|}).
Те, що алгоритм коректний і побудоване їм паросполучення є найбільшим, випливає з
теореми 77.1 і твердження 77.2. Очевидно також, що число ітерацій алгоритму (тобто
виконань п. 2 – 5) не перевершує величини min {|X|, |Y|}, оскільки на кожній ітерації, крім
останньої, величини
| X |и |Y |
зменьшується на одиницю.
Відповідно до твердження 76.2 п. 3 виконується за час O(|EG|). Легко показати, що ця
ж оцінка трудомісткості справедлива і для інших кроків алгоритму. Таким чином, час
виконання окремої ітерації складає O( |EG| ), а алгоритму в цілому – O (|EG| min {|X|, |Y|}).
Разом з найбільшим паросполученням алгоритм А8 фактично знаходить і найменше
верхове покриття в графе G. У результаті останнього виконання п. 3 алгоритму буде
встановлена відсутність шляху з
X иY
у графе G. Отже, тільки частина вершин цього графа буде мати мітки після закінчення
пошуку в ширину з
X .
Позначимо через X і Y, відповідно, безлічі непомічених вершин частки Х и позначених
вершин частки Y. Покладемо Z = X + Y.
Будемо вважати, що в графе G немає ізольованих вершин.
Теорема 77.4. Безліч Z є меншим верховим покриттям графа G.
Твердження достатнє довести для зв’язаних графів. Нехай (a, b) – довільна дуга
графа(G. Якщо a(Y, b(X, то ці вершини або обидві позначені, або ні. В обох випадках дуга (a,
b) инцідентна вершині безлічі Z. Нехай a(X, b(Y. Тоді, якщо вершина не позначена, то a(Z.
Якщо ж a позначена, то і вершина b позначена і, отже, b(Z.
Отже, будь-яка дуга графа (G инцидентна деякій вершині безлічі Z, тобто Z – покриття
графа G. Крім того, легко бачити, що | Z | = | T |, де Т – безліч усіх дуг графа (G, що ведуть з
безлічі Y. Безлічі Т в графі G відповідає найбільше паросполучення. Тому з теореми 32.2
випливає, що верхове покриття Z є найменшим.
Використаний тут метод ланцюгів, що чергуються, відіграє важливу роль і при
рішенні більш загальних задач. Одну з них ми зараз розглянемо.
2. Алгоритм побудови паросполучень для зважених графів. Нехай G = (X, Y, EG) –
повний двочастковий зважений граф, | X | = | Y | = n. Потрібно знайти в графе G
паросполучення, вага якого мінімальний. Легко бачити, что це – згадувана раніше задача
про призначення (див. гл. IV, параграфа 30).
Зроблене паросполучення мінімальної ваги назвемо для стислості оптимальним
розв’язком.
Задача про призначення володіє двома простими властивостями:
1. Оскільки для кожної вершини будь-яке зроблене паросполучення містить у
точності одне ребро, инцідентне цій вершині, то безліч оптимальних рішень не
зміниться, якщо ваги всіх ребер, инцідентних якій-небудь вершині, збільшити
(зменшити) на те саме число.
2. Якщо ваги всіх ребер графа невід’ємні і вага деякого зробленого паросполучення
дорівнює нулю, то воно є оптимальним розв’язком.
Нехай, як звичайно, w(x, y) – вага ребер xy. Будемо вважати, що
2 0* 0 0 0
0 * 7 9 8 6
0 1 3 2 2
0 8 7 6 4
0 7 6 8 3
мал. 77.3
3 0 0 0 0 *
0 * 6 8 7 5
0 0* 2 1 1
0 7 6 5 3
0 6 5 7 2
Мал. 77.4
5 0 0 0* 0
0 * 4 6 5 3
2 0* 2 1 1
0 5 4 3 1
0 4 3 5 0 *
Мал. 77.5
6 0 0 0* 0
0 * 3 5 4 2
3 0* 2 1 1
0 4 3 2 0
1 4 3 5 0 *
Мал. 77.6
Одержимо ??= W32 = 2. Результати наступного застосування до графа G операції ({x2, x4,
x5}, {y1}, 2) і модифікований граф(T, представлені на мал. 77.5. У цьому графі мається шлях
Р = (x5, y5, x1, y4) із з XM у YM. «Новий» граф(T, отриманий у результаті виконання п. 5,
також зображений на мал. 77.5. Пошук у ширину в цьому графі з безлічі XM = {x4} дає Х' =
{x2, x4}, У' = {y1}. Знаходимо ??= W32 = 1. Результати наступного виконання пп. 8, 9
представлені на мал. 77.6. Пошук у ширину з x4 дає Х' = {x2, x4, x5}, Y '= {y1, y5}.
Знаходимо ??= W32 = 2. Одержуємо нові матрицю і граф(T (мал. 77.7). У графі(T маємо (x4,
y3)-шлях Р = (x4, y4, x1, y3). Змінивши цей граф відповідно до п. 5, одержимо новий (мал.
77.7), у якому XM = YM = (.
П'ять его дуг, що ведуть «від X до Y», відповідають ребрам зробленого паросполучення
мінімальної ваги у вихідному графі G. Вага цього
8 0 0* 0 2
0 * 1 3 2 2
5 0* 2 1 3
0 2 1 0* 0
1 2 1 3 0 *
мал. 77.7