Пошук у глибину
При пошуку в ширину ми розглядали усі нові
вершини, що нам було видно з поточної
вершини, у яку переміщувалися на
кожному наступному кроці.
Під час пошуку в
глибину ми на кожному кроці алгоритму, знаходячись у наступній поточній вершині, будемо бачити лише одну нову, досі
не видиму, вершину і
переходити до неї.
Розглянемо той самий граф, що і при пошуку
в ширину, і його таблицю суміжності. Знову шукатимемо шляхит від вершини 1 до вершини 7. Так само
буватимемо дерево пошуку, послідовність переглянутих
і нових «видимих» вершин та
множину «відвіданих» вершин. На малюнку 1 зображено перший крок нашого
алгоритму, який повністю збігається з першим
кроком алгоритму пошуку в ширину.
Згідно з таблицею суміжності першою новою вершиною, яку ми бачимо з
вершини 1, є вершина 2. Перейдемо до неї, додавши її у дерево пошуку, в послідовність «відвіданих» вершин і у множину
(Малюнок 2).
Перейшовши тепер у вершину 2, згідно з
таблицею суміжності першою новою «видимою»
вершиною є вершина З, оскільки вершину 1 ми вже відвідали. Додамо цю
нову вершину до нашого дерева пошуку, в
послідовність та множину (Малюнок 3)
і перейдемо у послідовності до неї.
Якщо на наступному
кроці алгоритму ми подивимося з вершини 3, то побачимо вершини у такій послідовності (третій рядок
таблиці суміжності): 1, 2, 4, 5. Серед них першою новою вершиною є вершина 4.
Додамо її до переглянутих і перейдемо до неї (Малюнок 4).
З вершини 4 ми побачимо вершини 1 і 3, але жодна з
них не є новою. Далі шляху немає, тому
повертаємось назад. Оскільки попередньою вершиною була вершина 3, тому повернемось до неї (Малюнок 5).
Подивимося чи є з вершини 3 інший шлях, відмінний від
вершини 4? Це шлях через вершину 5. Вона є
наступною новою вершиною, яку ми бачимо з вершини 3. Перейдемо до неї,
записавши її у дерево пошуку, замінивши нею вершину 4 у послідовності та
дописавши її у множину (Малюнок 6).
З вершини 5 бачимо вершини 2, 3, 7. Новою є вершина 7, одночасно вона є шуканою. Тому
дописуємо її в дерево пошуку, послідовність та множину (Малюнок 7).
Отже, у заданому графі вершина 7 є досяжною з
вершини 1 і шлях до неї міститься у послідовності (Малюнок 7).
Отриманий шлях не співпадає зі шляхом,
знайденим за допомогою алгоритму пошуку в
ширину.
З алгоритму пошуку в
глибину видно, що на кожному його кроці ми працюємо з таблицею суміжності, беручи
звідти інформацію про одну нову «видиму» вершину із поточної вершини графа. Ця нова
вершина записується у послідовність, яка обробляється за алгоритмом роботи зі
стеком: ми дописуємо нову інформацію в кінець цієї послідовності і, у разі
потрапляння у тупик, повертаємося до її передостаннього елемента, не розглядаючи надалі
останній записаний елемент послідовності. І на останок: для запобігання
повернення у тупикові вершини інформацію про всі відвідані вершини зберігатимемо
у множині.
Ми розглянули алгоритм пошуку в
глибину на прикладі графа, де шукана вершина є досяжною із заданої, і отримали
позитивну
відповідь стосовно існування шляху між цими двома вершинами. Є можливою ситуація, коли шлях відсутній.
Тоді при потраплянні у тупик, потрібно повернутися
до попередньої «переглянутої» вершини і намагалися знайти іншу нову, ще не «побачену», вершину. Якщо такої немає, то повернемося до попередньої відносно неї і будемо шукати вихід із цієї вершини і т.
д. У разі відсутності шляху між двома заданими вершинами ми завершимо перегляд усіх записаних у стек вершин,
повертаючись кожного разу до
попередньої, очистивши при цьому стек. Отже, ознакою відсутності
шляху в графі між двома заданими вершинами є те, що на деякому кроці алгоритму стек
стане порожнім.
Сформулюємо описаний алгоритм пошуку в глибину у словесній формі.
1. Вказати номер вершини k, з якої починається пошук заданої шуканої вершини z.
2.
Почати
перегляд вершин заданого графа з вершини k, записавши її у стек: і := k.
3.
Якщо існує нова вершина з найменшим порядковим номером, яку можна
побачити з вершини і, то зафіксувати її, записавши у стек і
збільшивши при цьому індекс вершини стеку і на 1: і := і + 1. У протилежному випадку
перейти до п. 5.
4.
Якщо нова «побачена» вершина, записана у стек, є шуканою, то перейти до п. 7.
5.
Якщо з поточної вершини графа, яка записана у вершині стеку, не видно
жодної нової вершини, то відкинути цю вершину, перейшовши до попередньої у стеку,
зменшивши для цього значення
індексу вершини стеку на 1: і := і - 1. Якщо після цього стек
став порожнім, тобто і = 0, то перейти до п. 9.
6.
Перейти до перегляду наступної «побаченої» вершини і (п.
3).
7.
Вивести інформацію про те, що шукану вершину z досягнуто
і шлях до неї від вершини k існує.
8. Перейти до п. 10.
9.
Вивести інформацію про те, що шукана вершина z недосяжна
від вершини k і шлях до неї відсутній.
10. Завершити алгоритм.
Наведемо фрагменти алгоритму пошуку в глибину у вигляді Pascal-програми:
Описуємо масив для
послідовності вершин var a:array[1..100] of byte;
Вводимо матрицю
суміжності d розмірністю n*n.
top:=1; a[1]:=k; {Ініціалізація роботи алгоритму.}
flag := false; s:=[k];
while (top > 0) and not flag do {Поки стек не порожній і не знайдено шукану}
{вершину,}
{вершину,}
begin
i:=1; {починаємо пошук нової «видимої» вершини.}
While (і <= n) and not flag do {Пошук нової «видимої» вершини з к-ї вершини.}
begin
if (d[a[top], i] = 1) and not (і in S)
{Якщо існує нова «видима» вершина,}
then begin
inc(top); a[top] := i; {то записуємо її у стек і}
s:=s+[i]; {заносимо у множину.}
if i = z
then flag := true; {Якщо нова вершина є шуканою, то фіксуємо це.}
end
else inc(і) {Інакше переходимо до нової «побаченої» вершини.}
else inc(і) {Інакше переходимо до нової «побаченої» вершини.}
end;
if not false then dec(top) {Якщо відсутні нові «видимі» вершини,}
end; {то повертаємося до попередньої.}
Для виведення знайденого шляху між двома заданими вершинами графа можна
використати такий фрагмент:
if flag then begin {Якщо шлях знайдено, то}
writeln('YES'); {виводимо інформацію про це і}
while top <>0 do
begin {виводимо послідовність}
write(a[top],' '); dec(top) {елементів
стеку.}
end
end
else write('NO'); {Виведення інформації про відсутність шляху.}
Порівняємо пошукові
методи у ширину та в глибину для графів. Для заданого графа
ми отримали різні шляхи від вершини1 до вершини 7, причому кожен шлях є
правильним. Це відбулось тому, що ці методи використовують різні стратегії
пошуку:
під час пошуку в ширину ми послідовно переглядаємо усі видимі вершини і таким
чином якнайшвидше досягнемо шуканої вершини, а під час пошуку в глибину на кожному
кроці ми
переглядаємо лише одну нову вершину і тому можемо піти у хибному
напрямі. Отже, робимо висновок, що алгоритм пошуку в ширину завжди визначає
найкоротший шлях між двома заданими вершинами графа.
Відносно реалізації методів пошук у глибину простіший, оскільки одразу в
стеку отримуємо шуканий шлях, та й при організації роботи зі стеком виникає менше
помилок. Однак цей метод не завжди визначає найкоротший шлях між
заданими вершинами. І відповідь про відсутність шляху в разі використання пошуку
в ширину може бути отримана швидше, ніж під час пошуку в глибину. Однак реалізація
алгоритму пошуку в ширину вимагає організації такої структури даних, як черга, і
більш складної стратегії визначення
шляху між двома заданими вершинами.
Ці алгоритми пошуку служать для визначення шляху між двома заданими вершинами
графа, при їхній допомозі можна визначати
зв'язність графа, на цих алгоритмах базуються деякі інші алгоритми пошуку.
Оцінка ефективності роботи алгоритму пошуку в глибину така ж, як і для пошуку в ширину, і
становить О(п + т).
Тестування обох алгоритмів повинно передбачати дослідження як зв'язних, так
і незв'язних графів. Причому зв'язні графи слід розглянути такі, у яких кількість
вершин значно більша кількості ребер, і такі, у яких кількість ребер значно переважає кількість
вершин. Отримані результати для обох алгоритмів потрібно порівняти щодо довжини шляху
та кількості виконаних кроків.
Завдання
1. Розробити і
реалізувати у вигляді програми алгоритм пошуку в глибину.
2. Виконати завдання 1 для графа з кількістю
вершин N =5, в якому досліджувані
вершини є досяжними.
3. Виконати завдання 1 для графа з кількістю
вершин N =5, в якому досліджувані
вершини є недосяжними.
4.
Виконати
завдання 2-3 для N = 100.
Немає коментарів:
Дописати коментар