Скачиваний:
33
Добавлен:
30.05.2020
Размер:
763.47 Кб
Скачать

 

Д-6-4\

2<

 

 

 

 

h~3i

8

12

7

Мал. 15

5V-

 

 

5

* 6

 

 

 

 

 

Мал. 16

 

 

 

 

Для неорієнтованого ребра графа порядок, в якому вказую­ ться вершини, які воно з'єднує, неважливий. Для орієнтова­ ного ребра першою вказується вершина, з якої воно виходить. В орграфі також існує поняття орієнтованого шляху: це послі­ довність ребер між двома вершинами з урахуванням їхньої орієнтації. Шлях в орграфі, який є циклом, називається орієн­ тованим циклом. До речі, порівняно з неорієнтованим графом, зображеним на малюнку 12, в орієнтованому графі (мал. 15) для вершини 1 існує вже тільки два орієнтованих цикли: (1-2, 2-5, 5-3, 3-1) та (1-4, 4-7, 7-3, 3-1). Вони ж одночасно є прос­ тими. Зв'язність орієнтованого графа визначається без ураху­ вання орієнтації його ребер.

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

Якщо ж у графі вказана ще й «вага» кожного ребра, то та­ кий граф називається зваженим. Тобто існують неорієнтовані зважені графи та орієнтовані зважені графи (мал. 16). Прикла­ дом може бути задача, коли задається напрям руху дорогами між населеними пунктами та вартість перевезення ними деяко­ го вантажу.

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

ейлерів та гамільтонів графи.

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

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

52

Способи представлення графів

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

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

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

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

 

1

2

3

4

 

 

1

0

J

0

1

0

1^2=>4

2

1

0

1

1

1

2^1=>5=>3=>4

3

0

1

0

1

1

3=>2=>4=^5

4

1

1

1

0

0

4г^1^3^>2

5

0

1

1

0

0

5=>3=>2

є)

Якщо матриця суміжності представляє неорієнтований незважений граф (мал. 17, а), то за наявності суміжності вер­ шин і та J відповідні елементи матриці дорівнюють 1, тобто а[і, j] = a\j, і] = 1, а у разі відсутності ребра між вершинами і та І - 0, тобто а[і, Л = a\J, і] = 0 (мал. 17, б).

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

Якою ж буде матриця суміжності для інших графів? Якщо матриця суміжності описує зважений орграф, то можлива відсутність симетричності (мал. 19 а, б). У разі, коли в орграфі всі суміжні вершини мають двоорієнтовані ребра (мал. 18, а), то матриця суміжності такого графа (мал. 18, б) збігається з матрицею суміжності для графа, зображеного на малюнку 17, а.

53

№вер- -

2

З

4

 

 

 

тттини -*••

0

 

1=>2=>4

0

1

0

1

 

 

1

0

1

1

1

 

2=>1=>5=>3=>4

 

0

1

0

1

1

 

3=>2=>4=>5

 

1

1

1

0

0

 

4=>1=>3=>2

 

0

1

1

0

0

 

5=>3=>2

в)

а)

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

ШИНИ 1 2

 

4

5

 

1

0

1

0

1

0

1=>2=>4

2

0

0

1

1

0

2=>3=>4

3

0

0

0

0

1

3=>5

4

0

0

1

0

0

4=>3

а

0

1

0

0

1

5=>2=>5

б)

 

 

 

 

 

в)

Мал. 19

Розглянемо тепер випадок зваженого графа. Елементи матриці суміжності а[і, у], що відповідає такому графу, збігатимуться зі значеннями «ваги» ребер між вершинами і та/ (мал. 20, а, б).

1

 

і >

 

 

№ вер-

X

£,:

О

І:

 

 

 

9

і/

* Ч

^

4

\

І

0

9

0

5

0

1^2 9 ^4 5

 

 

 

 

 

 

 

 

0

0

1

3

0

2=>3t=>4,

 

5

3

 

 

 

^~~"\ 5

*

0

0

0

0

10

3=>510

 

 

У

 

 

 

 

 

0

0

3

0

0

4 ^ 3 3

 

її

• і

 

 

 

 

0

4

0

0

2

5=>24=>52

 

і

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

4

 

і

 

 

 

б)

 

 

 

 

 

в)

а)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Мал. 20

Другим способом представлення графа є списки суміжних вершин. У цьому разі для кожної вершини записується список суміжних вершин, який у довільному порядку містить усі суміжні з нею вершини. Графам, зображеним на малюн­ ках 17, а; 18, а; 19, а; 20, а, відповідають списки суміжних вершин, зображені на малюнках 17, в; 18, в; 19, в; 20, в.

54

Яким способом представлення заданого графа краще за все користуватися? На це запитання можна відповісти тільки сто­ совно кожного конкретного алгоритму. Звичайно, що обробля­ ти елементи матриці суміжності нам зрозуміліше і простіше. В ній ми одразу можемо дізнатися, чи є дві задані вершини суміжними, яку «вагу» має ребро, що з'єднує дві задані верши­ ни, тощо.

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

Завдання

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

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

3.Виконати завдання 1 для орієнтованого незваженого графа, що не має петель та з кількістю вершин N = 5, вивівши ре­ зультат виконання програми у файл.

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

5.Виконати завдання 1 для орієнтованого зваженого графа, що має петлі та з кількістю вершин 2V = 5, вивівши результат виконання програми у файл.

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

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

8.Виконати завдання 2-6 для завдання 7.

55

Пошук у ширину

Раніше ми вже розглядали різноманітні пошукові алгорит­ ми: пошук заданої інформації в одновимірному масиві, в ме­ режі, у рядку. Під час дослідження задач, що пов'язані з оброб­ кою інформації, яку можна представити у вигляді графів, та­ кож постає питання пошуку. У першу чергу - це пошук шляху від однієї заданої вершини до іншої.

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

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

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

№ вер­

1

2

3

4

5

6

7

шини

1

0

1

1

1

0

0

0

2

1

0

1

0

1

1

0

3

1

1

0

1

1

0

0

4

1

0

1

0

0

0

0

5

0

1

1

0

0

0

1

6

0

1

0

0

0

0

1

7

0

0

0

0

1

1

0

б)

Мал. 21

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

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

56

того, щоб виключити їх надалі з перегляду. Яким чином мож­ на реалізувати такий захист? Можна запропонувати два спосо­ би: перший - проглядати послідовність переглянутих вершин (мал. 22, б), другий - використати множину для їх фіксації (мал. 22, в). Який з них ефективніший? Якщо кількість вер­ шин невелика, то раціональніше скористатися множиною, як­ що ж вона більша за 256 - то переглядом послідовності. Але у цьому разі інформацію про заданий граф необхідно представля­ ти у вигляді списку суміжних вершин.

4

®

U

а)

б)

в)

Мал. 22

Продовжимо пошук вершини 7. З малюнка 21, а видно, що з вершини 1 ми бачимо вершини 2, 3 і 4. Ту саму інформацію ми можемо отримати і з таблиці суміжності (мал. 21, б), пере­ глянувши рядок, що відповідає номеру вершини, з якої ми дивимося, тобто перший рядок таблиці. Давайте зафіксуємо цю інформацію у дереві пошуку (мал. 23, а), у послідовності номерів вершин, які ми переглянули (1) і які ми бачимо (2, 3, 4) (мал. 23, в). Серед них поки що шуканої вершини 7 немає.

4

 

 

 

1

2

3

4

 

 

 

U

 

 

б)

в)

Мал. 23

Для подальшого пошуку перейдемо до однієї з нових вершин, які ми побачили. Це вершини 2, 3 і 4. У нашій послідовності (мал. 23, б) першою записана вершина 2, тому й перейдемо до неї. Які вершини ми бачимо з вершини 2 (мал. 21, а)? Це верши­ ни 1, 3, 5 і 6. Цю саму інформацію можна отримати з другого рядка таблиці суміжності (мал. 21,6). Однак лише вершини 5 і 6 є новими, а вершини 1 і 3 ми вже бачили на попередніх кроках нашого алгоритму. Доповнимо дерево пошуку (мал. 24, а), по­ слідовність переглянутих і «видимих» вершин (мал. 24, б) та множину (мал. 24, в) новою інформацією.

57

я-

125

Гї і 2 I 3 1 4 І 5Тб~

„436^

U

 

б)

в)

Мал. 24

Чи завершили ми наш пошук? Зрозуміло, що ні, оскільки ні

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

Зми бачимо вершини 1, 2, 4 і 5. Але вони не є новими, тому ми їх не фіксуємо ні у дереві пошуку, ні у послідовності вершин, ні

умножині (мал. 25, а, б, в).

0-

Г1 І 2 1 3 | 4 ГбТб

-о-

б)

в)

 

Мал. 25

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

4

125'

2 | » | 4 | б 1 б Г~

„43CL

й

 

б)

в)

Мал. 26

 

58

Продовжуючи логіку нашого алгоритму, переходимо до вер­ шини 5 - наступної у нашій послідовності (мал. 27, б). З верши­ ни 5 ми бачимо вершини 2, 3, 7. Перші дві з цих вершин уже бу­ ли переглянуті, а от вершина 7 не тільки нова, але й ще шука­ на. Тому алгоритм можна вважати завершеним, а відповідь на поставлене на початку запитання буде такою: «У заданому графі вершина 7 є досяжною з вершини 1».

 

 

 

 

4

 

 

1

2

3

4

5

6

7

й

б)

в)

 

Мал. 27

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

Тепер ми можемо проаналізувати умови завершення роботи алгоритму пошуку в ширину. Таких випадків є два: шукана вершина знайдена і відомий шлях до неї, або шукана вершина є недосяжною і шлях до неї відсутній.

Ми розглянули саме перший випадок пошуку вершини в графі, коли шукана вершина 7 є досяжною із заданої верши­ ни 1. Шлях від вершини 1 до вершини 7 присутній у черзі, але без додаткової інформації він дещо прихований. Для отриман­ ня цього шляху необхідно запам'ятовувати також і номери вер­ шин, з яких ми побачили кожну наступну вершину. На малюн­ ку 28 ця інформація позначена індексами для кожної поточної вершини, записаної у чергу.

1„ 2і Зі 4і 52 62 75

Мал. 28

59

Другий випадок може бути розтлумачений так: «голова» черги досягнула її «хвоста», а серед нових «побачених» вершин так і не з'явилася шукана. Це означає, що ми переглянули всі досяжні вершини графа, але не змогли дістатися до шуканої.

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

1.Вказати номер вершини k, з якої починається пошук за­ даної шуканої вершини І.

2.Почати перегляд вершин заданого графа з вершини k, за­ писавши її в чергу: і := k. Одночасно ця вершина є і останньою «побаченою» вершиною: j := k.

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

ги ; на 1 (j := j + 1).

4.Якщо серед нових «побачених» вершин, записаних у чер­ гу, є шукана вершина, то перейти до п. 8.

5.Для переходу до перегляду наступної «побаченої» верши­ ни збільшити значення індексу «голови» черги і(і:=і + 1).

6.Якщо значення індексу «голови» черги і збіжиться зі зна­ ченням індексу його «хвоста» ;', то перейти до п.10.

7.Перейти до перегляду наступної «побаченої» вершини і (п. 3).

8.Вивести інформацію про те, що шукану вершину І досяг­ нуто і шлях до неї від вершини k існує.

9.Перейти до п. 11.

10.Вивести інформацію про те, що шукана вершина І недо­ сяжна від вершини k і шлях до неї відсутній.

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

Перейдемо до реалізації описаного алгоритму у вигляді фрагмента Pascal-програми:

head := 1; tail := 2; а[1] := k;

 

 

{Ініціалізація початкових значень.}

flag := false; s := [k];

 

 

 

while (head < tail) and not flag do

{«Голова» менша за «хвіст» та}

begin

 

 

{не досягнуто шуканої вершини.}

і := 1;

{Перегляд к-го рядка таблиці суміжності спочатку.}

while (і <= n) and not flag do

{Вести пошук, доки не досягнуто кінця рядка}

begin

 

 

{або не знайдено шуканої вершини.}

if (d[a[head], І]= 1) and not in S) {Якщо поточна вершина є «видимою»}

then

 

 

{і ще не переглядалася, тоді}

begin

 

 

 

a[tail] := і; s := s + [ і ] ;

 

{записуємо її у «хвіст» черги та додаємо}

inc(tail);

{до множини, збільшуємо індекс «хвоста» черги.}

if І = І then flag := true;

{Фіксуємо умову досягнення шуканої вершини.}

end;

 

 

 

ІПС(І) {Перехід до наступного елемента к-го рядка таблиці суміжності.}

end;

60

if n o t f a l s e

{Якщо не досягнуто шуканої вершини,}

t h e n inc(head)

{то збільшуємо індекс «голови» черги.}

end;

 

if flag t h e n write(f_OUt, 'YES') {Інформація про те, що знайдено шукану вершину.} {Інформація про те, що} e l s e Wlite(f_OUt, 'NO'); {не знайдено шукану вершину.}

Для реалізації алгоритму, що визначає шлях від заданої до шуканої вершини, необхідно зробити корективи.

Опис одновимірного масиву, який реалізує структуру даних «черги», можна запропонувати такий:

a: array[1..100] of record

top, prev: byte; end;

Початкові значення параметрів «черги» будуть такими: head := 1; tail := 2; a[l].top := k; a[i].prev := 0;

а фрагмент програми, що поповнює «чергу» новими «видими­ ми» вершинами, такий:

if (d[a[head].top, і] = 1) and not (і in s) then

begin

a[tail].top := i; a[tail].prev := head; inc(tail); s := s + [i];

if і = I then flag := true; end;

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

if flag

 

then

 

begin

 

writeln(f_put, 'YES');

 

r e p e a t

{Виведення номера поточної вершини}

write(f_out, a[tail].top, ' ');

{визначеного шляху.}

 

{Перехід до вершини, з якої було видно}

tail := a[tail].prev;

{поточну вершину шляху.}

u n t i l a[tail].prev = 0;

{Завершення визначення шляху.}

write(f_OUt, a[tail].top); {Виведення номера вершини, що є початком шляху.} end

else write(f_out, 'NO');

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

61