Тема. Пошук у ширину та глибину
Мета. Формування умінь розв’язувати задачі на пошук у ширину та глибину з використанням черги та стеку
Завдання 1
У прямокутній матриці розмірністю 10*10 задано карту місцевості, де пробіл позначає воду, а зірочка – суходіл. Відомо, що на карті зображено острів довільної форми з усіх боків оточений водою. Острів може містити водоймища, площа яких не входить до складу острова. Якщо на озері, що міститься на острові є також острів, то його площу не враховувати в загальну площу острова. Написати програму, яка з текстового поля зчитуватиме карту до масиву та визначатиме площу острова.
Приклад вхідних даних | Результат |
**** * * **** * *
| 12 |
****** * * * * * * * ***** *** * ***
| 24 |
Розв’язання
Задача розв’язується з використанням черги.
Алгоритм
1. Зчитуємо дані з текстового поля до двовимірного масиву
2. Послідовним переглядом виявляємо перший елемент з символом «*».
3. Поміщаємо координати цього елемента в чергу
4. Замінюємо значення елементу на символ « »(пробіл)
5. Додаємо до значення лічильника одиницю
6. Запускаємо цикл, який виконується доки черга не стане порожньою. У циклі виконуємо наступні дії:
а) зчитуємо координати тіла з черги і зчитуємо символ з цієї комірки;
б) якщо цей символ «*», то поміщаємо до черги координати чотирьох сусідів цієї комірки, замінюємо символ на « » і додаємо одиницю до лічильників)
7. Записуємо до текстового поля або надпису значення з лічильника.
Public Class Form1
Structure S_Queue
Public x, y As Double
End Structure
Dim Queue(100) As S_Queue 'Масив для збереження черги
Dim First As Integer = 0 'Початок черги
Dim Last As Integer = -1 'Кінець черги
Sub PutQueue(ByVal x As Double, ByVal y As Double)
'Процедура запису даних до черги
Last += 1
Queue(Last).x = x
Queue(Last).y = y
End Sub
Function IsEmpty() As Boolean
'Процедура перевірки черги на порожність
IsEmpty = First > Last
End Function
Function GetQueue(ByRef x As Double, ByRef y As Double) As Boolean
'Процедура читання даних з черги
If Not IsEmpty() Then
x = Queue(First).x
y = Queue(First).y
First += 1
GetQueue = True
Else
GetQueue = False
End If
End Function
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim mass(10, 10) As Char
Dim Count As Integer = 0
Dim x, y As Integer
Dim s() As String = TextBox1.Text.Split(Chr(10))
For i = 0 To 9
For j = 0 To 9
mass(i, j) = s(i)(j)
Next
Next
For i = 0 To 9
For j = 0 To 9
If mass(i, j) = "*" Then
PutQueue(i, j)
mass(i, j) = " "
Count += 1
End If
Next
Next
While Not IsEmpty()
GetQueue(x, y)
If mass(x, y) = "*" Then
If x + 1 < 10 Then PutQueue(x + 1, y)
If x - 1 > -1 Then PutQueue(x - 1, y)
If y - 1 > -1 Then PutQueue(x, y - 1)
If y + 1 < 10 Then PutQueue(x, y + 1)
mass(x, y) = " "
Count += 1
End If
End While
Label2.Text = Count
End Sub
End Class
Завдання 2
Граф задано даними з текстового поля. У першому рядку міститься кількість вершин, у наступних рядках попарно вершини, з'єднані між собою ребрами.
Необхідно вивести повідомлення про можливість чи неможливість переходу з вершини A до вершини B.
Наприклад вхідних та вихідних даних:
Вхідні дані | Результат | ||
TextBox1 | TextBox2 | TextBox3 | TextBox4 |
7 1 2 1 3 1 4 2 3 2 5 2 6 3 5 3 4 5 7 6 7 | 1 | 7 | Шлях є |
Алгоритм розв’язання.
Задачу роз в’яжемо використовуючи пошук у глибину.
1. Створити таблицю суміжності, прочитавши дані про граф з текстового поля.
2. Читаємо з другого текстового поля номер вершини, з якої треба прокласти шлях p.
3. Читаємо з другого текстового поля номер вершини, до якої треба прокласти шлях k.
4. Записуємо в стек номер початкової вершини k.
5. Виконуємо цикл (пункти 6-8), доки стек не порожній.
6. Зчитуємо зі стеку вершину.
7. Якщо ця вершина результуюча, то достроково виходимо з циклу (пункт 9) та виводимо повідомлення про успішний пошук.
8. Поміщаємо до стеку всі вершини, пов’язані з даною, а дану вершину, помічаємо як не пов’язану з іншими.
9. Виводимо повідомлення про результат пошуку.
Код мовою VB.NET
Public Class Form1
Dim stack(100) As Double 'Масив для збереження стеку
Dim Count As Integer = -1 'Лічильник кількості елементів у стеку
Sub Push(ByVal x As Double)
'Процедура запису даних до стеку
Count += 1
stack(Count) = x
End Sub
Function IsEmpty() As Boolean
'Процедура перевірки стеку на порожність
IsEmpty = Count < 0
End Function
Function Pop(ByRef x As Double) As Boolean
'Процедура читання даних зі стеку
If Not IsEmpty() Then
x = stack(Count)
Count -= 1
Pop = True
Else
Pop = False
End If
End Function
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
'Очистимо стек
Count = -1
'Оголосимо локальні змінні
Dim n, p, k As Integer
Dim matr(100, 100) As Integer
Dim a, b, r, x As Integer
'Читаємо кількість вузлів графу
n = Val(TextBox1.Lines(0))
'Заповнюємо матрицю суміжності
Dim s As String
For i = 1 To TextBox1.Lines.Count - 1
s = TextBox1.Lines(i)
s = s.Trim()
If s <> "" Then
r = s.IndexOf(" ")
a = Val(s.Substring(0, r))
b = Val(s.Substring(r + 1, s.Length - r - 1))
matr(a, b) = 1
matr(b, a) = 1
End If
Next
'Читаємо номер початкової вершини
p = Val(TextBox2.Text)
'Читаємо номер кінцевої вершини
k = Val(TextBox3.Text)
'Починаємо пошук шляху
'Поміщаємо до стеку номер початкової вершини
Push(p)
'Локальна змінна-прапорець для відмічання завершення пошуку
Dim flag As Boolean = False
'Виконуємо цикл доки стек не порожній
While Not IsEmpty()
'Отримуємо зі стеку номер вершини
Pop(x)
'Перевіряємо умову досягання результуючої вершини
If x = k Then
flag = True 'Шлях знайдено
Exit While 'Видодимо з циклу
End If
'Шукаємо у матриці суміжності пов'язані з x вершини
For i = 1 To n
If matr(i, x) = 1 Then
Push(i) 'Додаємо пов'язану з x вершину до стеку
matr(i, x) = 0 'Помічаємо вершину x як пройдену
matr(x, i) = 0 'Помічаємо вершину x як пройдену
End If
Next
End While
'Виводимо повідомлення про результат пошуку
If flag Then
TextBox4.Text = "Шлях є"
Else
TextBox4.Text = "Шляху немає"
End If
End Sub
End Class
Завдання для самостійного виконання
Література
Караванова, Т.П. Інформатика: методи побудови алгоритмів та їх аналіз: обчисл. алгоритми: навч. посіб. для 9-10 кл. з поглибл. вивч. інформатики. Т.П.Караванова.– К.: Генеза, 2009. – 336 с.: іл. – Бібліогр.: с. 331. (Сторінки 56-68)