Скачиваний:
37
Добавлен:
30.05.2020
Размер:
3.32 Mб
Скачать

ному кроці. Такою є вершина 3. Виконаємо такі самі дії, що й на попередньому кроці: а[2,3] = а[3,2] = 0. Вершину 3 запише­ мо у першу послідовність (мал. 36, в).

З вершини 3 ми бачимо вершину 1. Перейдемо до неї, запи­ савши її наступною в послідовність і «спаливши» ребро (3,1): а[3,1] = а[1,3] = 0 (мал. 36, г).

Поки що тупикових ситуацій немає. Продовжуємо далі. З вершини 1 ми можемо перейти до вершини 4, що слідує з пер­ шого рядка таблиці суміжності. «Спалюємо» ребро (1,4) і запи­ суємо в першу послідовність номер вершини 4 (мал. 36, д).

Тепер наша увага переходить до вершини 4, тобто до четвер­ того рядка таблиці суміжності. Як бачимо, ще не всі ребра для цієї вершини «спалені» і ми можемо перейти до вершини 2. Зробимо це (мал. 36, є).

І саме тепер виникає колізія: переходячи до другого рядка таблиці суміжності, ми не маємо можливості далі кудись руха­ тися, усі ребра «спалені»! Таким чином ми визначили першу вершину з номером 2, для якої існує ейлерів шлях у заданому графі, що починається з вершини 1, але він не містить усіх ре­ бер графа. Це означає, що пошук можна продовжувати далі. Переносимо номер вершини 2 у другу послідовність, а в першій послідовності повертаємося до попередньої вершини 4 (мал. 37, а). Але й у вершини 4 немає жодного не «спаленого» ребра. Тому запишемо і цю вершину в другу послідовність і зробимо ще один крок назад у першій послідовності (мал. 37, б).

Вихід знайдено: вершина 1 має ще не «спалені» ребра і пер­ ша така вершина, у яку ми можемо перебратися, - це вершина 5! Запишемо номер цієї вершини в нашу першу послідовність після вершини 1 і спалимо ребро (1,5) (мал. 37, в).

Перейдемо до вершини 5. З таблиці суміжності видно, що на­ ступним ребром, яким можна рухатись, є ребро (5,6). Виконаємо всі дії стосовно переходу у вершину 6 ребром (5,6) (мал. 37, г).

3

1

2

3

4

5

6

 

 

3

1

2

3

4

5

6

 

 

1

 

 

0

0

0

і

]

 

 

 

1

 

 

0

0

й

1

1

 

 

 

 

 

 

 

 

 

2

 

0

0

0

І

0

0

 

 

2

 

0

 

0

0

0

0

 

 

 

 

 

 

 

 

 

 

 

3

 

0

0

0

0

0

0

 

і

3

 

0

0

0

0

0

0

 

 

•і

 

 

 

 

 

 

 

 

 

 

 

 

4

0

0

0

0

0

0

 

4

 

0

0

0

0

0

0

 

2

 

 

 

 

 

 

 

 

2

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

5

 

1

0

0

0

 

 

 

5

 

1

0

0

0

0

1

0

1

 

 

 

 

 

 

 

 

 

 

 

 

 

6

 

1

0

0

0

1

0

 

 

6

1

0

0

0

1

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1 2 3 1 4

2

 

 

 

 

 

 

 

 

|.1|2ІЗІШ|2| | . 1 | М

ш

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

[2 41 1 1 1 1 1 1 L П П

 

 

а)

 

 

 

 

 

 

 

 

 

б)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Мал. 37

 

 

 

 

 

 

 

 

 

72

5

 

1

 

3

1

2

3

4

5

б

5

 

1

3

1

2

3

4

5

6

 

і

 

• - - ~~~f

1

0

0

 

0

0

0

і

 

 

 

 

--•

1

 

0

0

0

0

1

 

 

 

 

 

 

2

0

 

0

0

І

0

0

 

 

 

 

 

2

0

0

0

0

0

0

 

 

 

 

 

3

0

 

0

0

0

0

0

 

 

 

 

—І

3

0

0

0

о

0

0

 

 

 

 

 

4

0

 

0

 

0

0

0

0

 

 

 

 

4

0

0

0

0

0

0

 

6

 

4

 

2

 

 

 

 

 

 

 

 

 

 

6

 

4

2

 

 

 

 

 

 

 

 

 

 

5

0

 

0

 

0

0

0

1

 

5

0

и

0

0

0

0

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

6

1

0

 

0

0

1

0

 

 

 

 

 

6

1

0

0

0

0

0

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1 2 3 1 5 2

 

 

 

 

 

 

 

 

 

 

| 1 | 2 3 | 1 | 5 | 6 |

 

і

 

 

 

' . І

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2 4

 

 

 

 

 

 

 

 

 

 

 

 

 

| 2 | 4 |

|

| |

|

|

!

|

| -1

|

 

 

 

 

 

 

 

в)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

>)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

5

 

1

 

 

 

 

 

 

 

 

5

 

1

3

 

 

 

 

 

 

 

 

 

3

1

2

3

4

5

6

 

І

2

 

3

4

5

6

 

 

--•--

 

 

 

 

 

 

 

 

 

 

f""

•-•%•--•

--•

 

 

 

 

 

 

 

 

 

 

 

І

 

 

0

 

 

0

0

0

0

/

0

0

 

0

0

 

 

 

! /

 

 

 

2

0

 

 

 

 

()

0

0

0

 

 

 

 

 

2

0

 

 

0

1

 

 

 

• /

 

 

--'і

3

0

 

0

 

 

0

0

0

0

 

А— —4

3

0

1

0

0

0

0

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

4

 

4

0

0

0

0

0

0

 

4

0

0

0

0

0

0

 

6

 

 

2

 

 

 

 

 

 

 

 

6

 

4

2

 

 

 

 

 

 

 

 

 

 

5

0

0

 

 

0

0

0

0

 

5

0

0

 

0

0

0

0

 

 

 

 

 

 

6

0

0

 

 

0

0

0

0

 

 

 

 

 

6

0

0

 

0

0

0

0

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2 3 1 5 6 їГг

 

'

 

 

і

і

 

1 2 3 1 5 6 1

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

4

 

 

 

 

 

і

 

 

 

 

 

 

 

2

4

11

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

д)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

є)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Мал. 37 (продовження)

 

 

 

 

 

 

 

 

 

 

З малюнка 37, г видно, що в нас залишилося тільки одне «неспалене» ребро, яким ми зараз і пройдемося (мал. 37, д). Що ж тепер робити? Слід виконувати описаний алгоритм: якщо на по­ точному кроці відсутні «неспалені» ребра, то необхідно номер поточної вершини запам'ятовувати як фрагмент ейлерового шляху і повертатися до попередньої переглянутої (мал. 37, є). У нашому випадку запам'ятовуємо вершину 1 і переходимо до вершини 6.

Наступні кроки виконання алгоритму очевидні: оскільки в таблиці суміжності не залишилося жодного елемента зі значен­ ням 1, тобто в заданому графі всі ребра «спалені», то автома­ тично всі елементи першої послідовності у зворотному порядку перенесуться до другої, де і буде визначено ейлерів шлях у за­ даному графі (мал. 38, а, б).

Після такого детального покрокового розбору виконання алгоритму визначення ейлерового шляху в заданому графі не повинно виникати жодних проблем з його реалізацією.

Спочатку визначимося, які структури даних слід застосува­ ти для реалізації алгоритму. По-перше, це двовимірний масив для фіксації наявності ребер між заданими вершинами графа,

73

{Ініціалізація початку визначення ейлерового шляху.} {Пошук ведеться, допоки існують «неспалені» ребра.}

 

 

 

3

 

Т

2

3

4

5

6

 

5

 

 

 

 

 

о

 

 

 

 

 

 

1

 

0

0 0 0 0

Ш

•-

 

 

 

 

 

о

 

 

 

 

 

2

 

 

ог6

0

 

 

 

 

 

 

 

о

 

 

•-

 

3

 

о і о 1 л Гої 0

0

 

 

 

 

 

 

 

о

6

 

 

4

 

0

0

0

0

0

 

 

6

 

 

 

 

О о

 

4

2

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

5

 

0

0

0

0

0

0

 

 

 

 

 

 

О

 

о

 

 

 

 

 

6

 

0

 

0

0

0

 

 

 

 

 

 

О

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1 2

 

3

1 5

6

1

 

 

 

 

 

 

1

2

3

1\5\6\1

 

 

2

4

 

1 6

 

 

 

 

 

 

 

 

 

 

2

4

1 6

5

1 3

2

1

 

 

 

 

 

 

а)

 

 

 

 

 

 

 

 

 

 

 

б)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Мал. 38

 

 

 

 

 

 

 

елементами якого є значення 0 та 1. По-друге, одновимірний масив, у якому обробляються елементи з найбільшим поточ­ ним індексом. Протягом виконання алгоритму цей індекс може як збільшуватися, так і зменшуватися. Ми знаємо таку струк­ туру даних, що реалізує роботу з одновимірним масивом саме таким чином, - це стек. І ще один одновимірний масив, в який дописуватимуться елементи - номери вершин заданого графа, що формують ейлерів шлях у ньому.

Отже, можна запропонувати такий варіант реалізації алго­ ритму пошуку ейлерового шляху в заданому графі мовою Pascal:

top := 1; rez_top := 0; while top <> Odo

begin

while (a[i, j] <> 1) a n d (j <= n) do inc(j); {Пошук існуючого ребра з і-ї вершини.}

if (j <= П)

 

 

{Якщо таке ребро існує,}

then

 

 

{то}

begin

 

 

 

inc(top); stackftop] := j;

{дописуємо номер поточної вершини у стек}

а[і, j] := 0; a[j, і] := 0;

{і «спалюємо» знайдене ребро,}

end

 

 

 

else

 

 

 

b e g i n

 

{у протилежному випадку запам'ятовуємо}

inc(rez_top); rez[rez_top] := stack[top];

{номер поточної вершини}

d e c ( t o p )

{і переходимо до перегляду попередньої вершини у стеку.}

end;

І := Stack[top]; j := 1; {Продовжуємо пошук «неспалених» ребер із поточної вершини.} end;

Для визначення існування ейлерового шляху в заданому графі можна провести підрахунок степенів вершин цього графа під час введення початкових даних:

74

c o u nt := 0; {Ініціалізація підрахунку кількості вершин графа непарного степеня.}

for і := 1 to n do begin

St := 0;

{Ініціалізація визначення степеня вершини.}

for j := 1 to n do

 

begin

 

read(f _ in, a[i, j]);

{Введення елементів таблиці суміжності.}

if а[І, j] = 1 then inc(st)

{Підрахунок степеня поточної вершини.}

end;

 

if odd(st) then {Якщо степінь поточної вершини непарний, то враховуємо}

begin inc(count); b := і end; {цю вершину і запам'ятовуємо її номер.}

end;

if count = 0 then Stack[top]

:= 1;

{Якщо всі вершини графа парні, то почи­

 

 

наємо} {пошук із 1-ї вершини.}

if count = 2 then Stack[top]

:.= b;

{Якщо існує 2 непарні вершини, то почи­

 

 

наємо} {пошук з однієї з них.}

Наведений аналіз степенів вершин заданого графа може бути використаний для визначення у ньому ейлерового шляху: якщо кількість непарних вершин не відповідає умовам існування ей­ лерового шляху, то і виконувати алгоритм немає потреби.

Очевидно уважний читач помітив, що в наведеному прикладі графа отриманий ейлерів шлях не є єдиним. Наприклад, шлях 1 2 3 1 6 5 1 4 2 також є ейлеровим. Але ми й не ставили задачу знайти всі ейлерові шляхи, а визначалися зі стратегічним пи­ танням: чи існує такий шлях. І цю задачу ми розв'язали.

Оцінимо ефективність роботи алгоритму побудови як ейле­ рового циклу або шляху в графі з п вершинами і т ребрами. Оскільки протягом виконання цього алгоритму по кожному ребру проходять лише один раз, а вершини фактично не роз­ глядаються, то оцінка цього алгоритму логічно буде О(т).

Тепер перейдемо до визначення гамільтонових шляхів у за­ даних графах. Нагадаємо, що гамільтоновим називається та­ кий шлях у графі, який проходить по кожній вершині лише один раз. На жаль, до сьогодні не існує необхідних і достатніх умов існування гамільтонового шляху у графі. Це питання ви­ вчається вже понад сто років, і відповідь досі не знайдена. Але це говорить лише про те, що не існує оптимальних методів по­ шуку гамільтонового шляху у графі, однак метод повного пере­ бору завжди дасть правильну відповідь.

Для визначення існування чи відсутності гамільтонового шляху в заданому графі необхідно переглянути всі варіанти перестановок вершин цього графа. Одночасно з отриманням чергової перестановки цих вершин необхідно перевірити на­ явність ребер між сусідніми вершинами у ній. У разі розв'я­ зання задачі про наявність хоча б одного з таких шляхів на цьому можна завершити виконання алгоритму. Якщо треба

75

визначити всі гамільтонові шляхи, необхідно виконувати ал­ горитм до кінця перегляду всіх можливих перестановок вер­ шин графа.

Ця задача відноситься до NP-повних, і зрозуміло, що для ве­ ликої кількості вершин графа вона дуже вимоглива щодо часу виконання. Хоча можна ввести деякі евристичні оптимізації в алгоритм, однак вони не набагато покращують час його вико­ нання. До таких покращень можна віднести, наприклад, при­ пинення визначення існуючих ребер між вершинами поточної перестановки у разі, коли натрапимо на перше відсутнє ребро.

Отже, алгоритм пошуку гамільтонового шляху в заданому графі можна сформулювати так.

1.Згенерувати поточну перестановку вершин заданого графа.

2.Розглянути першу пару послідовних вершин у переста­ новці.

3.Якщо ребро між поточною парою вершин перестановок відсутнє, то перейти до п. 6.

4.Якщо існує наступна пара послідовних вершин у графі, то перейти до п. 3.

5.Якщо для всіх пар послідовних вершин існують ребра у графі, то перейти до п. 7.

6.Якщо існує наступна перестановка вершин заданого гра­ фа, то перейти до п. 1. У протилежному випадку перейти до п. 8.

7.Вивести вміст перестановки вершин заданого графа, для якого існують усі ребра.

8.Завершити алгоритм.

Описаний алгоритм досить очевидний, тому можна зразу пе­ рейти до його реалізації у вигляді фрагмента Pascal-програми:

flag := false;

{Ініціалізація початку роботи алгоритму.}

і:=1;

 

 

repeat

 

 

j := 1;

 

{Визначення існування всіх ребер}

while (d[a[j], a[j + 1 ]] = 1) and (j < n) do inc(j); {поточної перестановки вершин.}

if j = n then

{Якщо така перестановка існує, то}

 

begin

 

 

for j := 1 to n do

 

 

write(f_Out, a[j], ' ');

{виводимо послідовність вершин.}

 

 

{Встановлюємо ознаку існування}

 

writeln(f_out); flag :=true;

{гамільтонового шляху.}

 

end;

 

Іпс(і);

 

{Перехід до наступної перестановки.}

perm;

{Визначення наступної перестановки вершин графа.}

until (І >= f) ОГ flag; {Завершення пошуку в разі, коли відповідь знайдена або відсутня.}

Зауважимо, що змінна / містить значення кількості всіх можливих перестановок вершин графа я!, і саме за допомогою

76

лічильника і, який змінюється у межах від 1 до /, ми можемо визначити, чи існує в ньому хоча б один гамільтонів шлях. Окрім цього, у наведеному фрагменті використано звернення до процедури генерування перестановок.

Виконавши описаний вище алгоритм для графа, зображено­ го на малюнку 36, а, отримаємо результат:

3 2 4 1 5 6 Якщо дещо модифікувати наведений фрагмент програми і

визначити всі можливі гамільтонові шляхи у розглянутому прикладі графа, то отримаємо таку відповідь:

3241 56

324165

423156

423165

561 324

561423

651324

651423

Отже, наведений приклад графа є не тільки ейлеровим, а ще й гамільтоновим.

Алгоритм побудови гамільтонового шляху або циклу, як бу­ ло зазначено, відноситься до NP-повних задач, що й визначає оцінку ефективності його роботи як О(пі).

Для тестування наведених алгоритмів необхідно поряд із зв'язними графами розглянути і незв'язні. Це дасть змогу пе­ ревірити коректність розроблених алгоритмів щодо аналізу визначення ейлерових та гамільтонових шляхів. Серед зв'яз­ них графів необхідно розглянути як повні графи, так і неповні.

Завдання

1.Розробити та реалізувати у вигляді програми алгоритм ви­ значення заданого графа як ейлерового.

2.Розробити та реалізувати у вигляді програми алгоритм ви­ значення ейлерового циклу у графі.

3.Виконати завдання 1-2 для графа з кількістю вершин N < 10,

вякому всі вершини мають парні степені. Результат вико­ нання програми вивести у файл.

4.Виконати завдання 1-2 для графа з кількістю вершин N < 10,

вякому є дві вершини з непарними степенями. Результат виконання програми вивести у файл.

5.Виконати завдання 1-2 для графа з кількістю вершин N = 100,

вякому всі вершини мають парні степені. Результат вико­ нання програми вивести у файл.

77

6. Виконати завдання 1-2 для графа з кількістю вершин N= 100, в якому є дві вершини з непарними степенями. Ре­ зультат виконання програми вивести у файл.

7.Розробити та реалізувати у вигляді програми алгоритм ви­ значення гамільтонового циклу у графі.

8.Виконати завдання 7 для графа з кількістю вершин N = 5. Результат виконання програми вивести у файл.

9.Виконати завдання 7 для графа з кількістю вершин N > 5. Результат виконання програми вивести у файл.

УЗапитання для самоконтролю

1.Які питання вивчає теорія графів? Розділом якої науки вона є?

2.Чим відрізняються задачі, для розв'язання яких можна застосу­ вати оптимізаційні методи від задач, розв'язок яких - повний перебір усіх можливих варіантів?

3.Які задачі, що розглядалися нами раніше, можна віднести до теорії графів?

4.Що називається графом? З яких елементів він складається?

5.Поясніть такі поняття: інцидентність, суміжність, петля, нуль-граф.

6.Які графи називаються повними, плоскими, просторовими?

7.Як визначається степінь вершини?

8.Коли можна стверджувати, що існує шлях між двома заданими вершинами? Як визначається довжина шляху?

9.Які вершини називаються зв'язними? Який граф називається зв'язним?

10.Який шлях називається циклом? Який цикл називається прос­ тим? Наведіть приклади.

11.Який граф називається деревом, а який лісом?

12.Які графи називаються орієнтованими, зваженими? Наведіть приклади.

13.Які графи називаються ейлеровими, гамільтоновими? Наведіть приклади.

14.Які є способи представлення графів? Наведіть приклади різних графів та їх представлення. Порівняйте ці способи.

15.Який пошуковий метод називається пошуком у ширину в графі? По­ ясніть покроково роботу цього методу на конкретному прикладі.

16.Які структури даних необхідно використати під час реалізації у вигляді програми алгоритму пошуку в ширину?

17.Якими є ознаки визначення наявності і відсутності шляху між двома вершинами в заданому графі під час пошуку в ширину?

18.Яким чином можна визначити шлях від однієї вершини до іншої у заданому графі під час пошуку в ширину?

19.Опишіть алгоритм пошуку в ширину у словесній формі.

20.Запропонуйте варіант реалізації алгоритму пошуку в ширину у вигляді Pascal-програми.

21. Яким чином може бути відредагований фрагмент програми, що реалізує алгоритм пошуку в ширину, для випадку визначення шляху між двома вершинами заданого графа?

22.Чим відрізняється стратегія організації пошуку в глибину від по­ шуку в ширину?

78

23.Прокоментуйте роботу алгоритму пошуку в глибину в покроковому режимі виконання на конкретному прикладі.

24.Якими є ознаки існування і відсутності шляху між двома верши­ нами заданого графа в алгоритмі пошуку в глибину?

25.Сформулюйте словесний алгоритм пошуку в глибину.

26.Запропонуйте свій варіант реалізації алгоритму пошуку в глиби­ ну у вигляді фрагмента Pascal-програми.

27.Яким чином можна вивести одержаний шлях між двома верши­ нами заданого графа, що міститиметься у стеку?

28.Порівняйте два пошукових методи на графах, відзначивши пози­ тивні і негативні сторони кожного з них.

29.Які існують критерії наявності ейлерового шляху в заданому графі? Наведіть приклади ейлерових графів.

30.Сформулюйте алгоритм пошуку ейлерового шляху в заданому графі і обґрунтуйте його основні моменти.

31. Покроково виконайте алгоритм пошуку ейлерового шляху або циклу в графі на власному прикладі.

32.Які структури даних необхідно використати для реалізації алго­ ритму пошуку ейлерового шляху в заданому графі у вигляді Pascal-програми?

33.Запишіть фрагмент Pascal-програми, що реалізує алгоритм по­ шуку ейлерового шляху в заданому графі.

34.Як визначити наявність ейлерового шляху в заданому графі? За­ пишіть фрагмент Pascal-програми.

35.Яким є алгоритм пошуку гамільтонового шляху в заданому графі?

36.До якого класу задач можна віднести задачу пошуку гамільтоно­ вого шляху в заданому графі? Обґрунтуйте свою відповідь.

37.Запишіть реалізацію алгоритму пошуку гамільтонового шляху в заданому графі у вигляді фрагмента Pascal-програми.

Топологічне сортування

Ця задача не має ніякого відношення до відомих нам методів сортування і розуміє зовсім інше сортування, ніж сортування елементів у масиві. Але разом з тим вона, як і всі попередні роз­ глянуті алгоритми, базується на використанні пошуку у графі.

Під топологічним сортуванням будь-якого орієнтованого

графа розуміють таку послідовність його вершин fc,, t2,..., tn, у якій кожна вершина з номером t- є нащадком будь-якої верши­ ни з номером tt, де і < j. Або ще кажуть, що для послідовності вершин заданого графа, яка є результатом їхнього топологічно­ го сортування, існують лише ребра (tt, t), де і < j.

Наприклад, розглянемо граф, зображений на малюнку 39, а. У ньому вершини 1, 2 і 6 є нащадками вершини 3, а вершина 5, у свою чергу, є нащадком вершини 6. Тому в топологічній по­ слідовності вершин цього графа спочатку має йти вершина З, потім вершини 1, 2, 6, а за ними вершина 5. Чи можна вибуду­ вати таку послідовність для графа, зображеного на малюн­ ку 39, б? Мабуть, ні, оскільки, з одного боку, вершина 6 є на­ щадком вершини 3, а з іншого боку, вершина 3 є нащадком

79

 

 

A>

а)

б)

в)

 

Мал. 39

 

вершини 6. Така ситуація є ознакою наявності циклу в орієнто­ ваному графі, і, відповідно, у такому графі неможливо встанови­ ти топологічну послідовність вершин.

Орієнтовані графи, які не мають циклів, називаються ацик­ лічними. Тому можна зробити висновок: топологічне сортування можна організувати лише для орієнтованих ациклічних графів.

У яких задачах необхідно використовувати топологічне сор­ тування? Можна навести такі приклади: виконання плану на­ вчального закладу вимагає певної послідовності у викладанні навчальних курсів; великі проекти часто розбивають на су­ купність менших задач, які виконуються у певному порядку, і тільки таким чином забезпечують повне виконання завершен­ ня всього проекту; збираючись уранці на заняття, необхідно враховувати послідовність одягання окремих елементів одягу.

На чому базується алгоритм топологічного сортування? Ви­ являється, що на алгоритмі пошуку в глибину. Нагадаємо його основні моменти, узагальнивши попередньо розглянутий варіант. Тобто не будемо шукати задану вершину, а поставимо за мету переглянути всі вершини графа. Використовуючи для цього стек, ми фактично врешті-решт повернемося в його поча­ ток. Протягом виконання алгоритму ми періодично будемо по­ трапляти в тупик: це означатиме, що з деякої вершини k нашого графа ми вже не можемо «побачити» нових вершин і записати їх у стек. Результатом розв'язання цієї проблеми є повернення

устеку на один крок назад, тобто до вершини, яка передує вер­ шині k. Фактично наявність тупика у вершині k говорить про те, що ми з неї вже побачили і відвідали всі вершини, які є її на­ щадками. Саме тому можна стверджувати, що вершина k може бути виведена на початок списку вершин, які слідували за нею

устеку, а також той факт, що між вершиною k та її вершинаминащадками існує топологічна відповідність.

Аяк бути тоді, коли заданий граф складається з кількох підграфів? У цьому разі можна також говорити про існування послідовності переліку вершин, кожна з яких має ребро лише

80

з наступними в цій послідовності вершинами. Наприклад, на малюнку 39, в такою може бути послідовність 3, 2, 1, 6, 4, 5 або 2, 4, 3, 1, 6, 5. Погодьтеся, що й ці варіанти топологічних послідовностей вершин графа, зображеного на малюнку 39, в, не є єдиними.

Згідно із запропонованою ідеєю побудови алгоритму топо­ логічного сортування, у разі, коли ми опрацюємо один під граф заданого графа, стек, що створювався для його реалізації, буде вичерпано. Але оскільки залишилися ще не опрацьовані вер­ шини, то логічно почати все з початку, розглядаючи ті верши­ ни, які ще залишилися не «побаченими». Процес буде заверше­ но лише тоді, коли стек стане порожнім і при цьому будуть відвідані всі вершини заданого графа.

Подібна ситуація може виникнути і під час перегляду вер­ шин орієнтованого графа, що не містить окремих підграфів. Наприклад, починаючи перегляд вершин з вершини 1 у графі, зображеному на малюнку 39, а, ми перейдемо до вершин 6 і 5. Оскільки нових вершин з них не видно, то ми врешті-решт по­ вернемося до стартової вершини 1, що знаходиться на початку стеку. Однак залишилися непереглянуті вершини 2,3,4. Якщо ми далі продовжимо з вершини 2, то, перейшовши у вершину 4, знову попадемо у тупик, і стек далі не буде заповнюватися. Завершимо перегляд вершин цього графа вершиною 3. Таким чином, протягом виконання такого обходу вершин орієнтова­ ного графа (мал. 39, а) тричі буде спорожнюватися стек.

Ми повністю готові до формулювання алгоритму топо­ логічного сортування орієнтованого графа.

1.Визначити вершину і, з якої починається перегляд непереглянутих вершин графа, і записати її в послідовність.

2.Якщо послідовність вершин, що «переглянуті», не по­ рожня та існує ребро (і, j), де вершина/ ще не переглядалася, то перейти до неї, записавши її наступною в послідовність вер­ шин; перейти до п. 2.

3.Якщо не існує ребра (і, /), де вершина у ще не перегляда­ лася, визначити вершину і як наступну вершину в топологіч­ ній упорядкованій послідовності та перейти до попередньої вершини в послідовності вершин, що переглядаються.

4.Якщо послідовність вершин, що переглядаються, порож­ ня і не всі вершини заданого графа переглянуті, то перейти до п. 1.

5.Завершити алгоритм.

Розглянемо покрокове виконання алгоритму на прикладі графа, зображеного на малюнку 40, а, і відповідну йому матри­ цю суміжності (мал. 40, б).

Почнемо перегляд вершин графа з вершини номер 1 і запи­ шемо її в послідовність переглянутих вершин - перший рядок

81

Соседние файлы в папке Методи побудови алгоритмів та їх аналіз