Проблему можна форально визначити, описавши 5 компонентів:
Описані вище елементи визначають структуру даних, яка є вхідним об’єктом алгоритму пошуку рішення. Розв’язком є шлях (послідовність дій) з початкової вершини до вершини, на якій досягається мета. Якість вимірюється вартістю вздовж шляху. Оптимальний розв’язок це той, що має найнижчу вартість.
В цій лекції ми розглянемо алгоритми неінформованого пошуку у дереві варіантів. Велика кількість задач ШІ може бути сформульована як задача пошуку на орієнтованих графах.
Розв’язання - це шлях (послідовність дій) з початкової вершини. Можливі шляхи, що починаються з початкового стану формують дерево пошуку. Всі алгоритми починаються однаково - ми виконуємо всі можливі дії для початкового стану та отримуємо множину вершин. Далі виконується вибір однієї з вершин (тут алгоритми починають відрізнятись). Якщо наша ціль виконана для вибраної вершини то алгоритм закінчує роботу. Якщо ж ні, то перевірена вершина помічається як пройдена. В кожен момент роботи алгоритму є три множини вершин графу: перевірені, границя і неперевірені. На кожному кроці алгоритм пошуку вибирає вершини з границі, перевіряє їх та додає до перевірених і потім відбирає нові неперевірені вершини до границі.
DFS алгоритм це рекурсивний алгоритм, що використовує ідею повернення. Він пропонує обшукувати всі вузли “в глибину”, якщо це можливо, в іншому разі повертатися до першої “розвилки”. Повернення тут означає, що при русі вперед ми отримуємо декілька вузлів, при цьому один вибирається для подальшого дослідження а інші зберігаються в стек. Важливо при цьому помічати вузли, які ми вже дослідили, щоб уникнути подвійних обходів. Границя в DFS працює за принципом LIFO (last-in, first-out). Розглянемо реалізацію в NetLogo
breed [dwarfs dwarf]
dwarfs-own [
current-patch
n-stack
]
patches-own[
visited
neighbors-black
]
to setup
clear-all
reset-ticks
draw-lines
ask patches [
set visited 0]
black-patches-around
create-dwarfs num [
set n-stack []
let p one-of patches with [pcolor = black]
set xcor [pxcor] of p
set ycor [pycor] of p
ask p [set visited 1]
]
end
to go
tick
draw-maze
black-patches-around
end
to draw-lines
ask patches [
if (remainder pxcor 2 != 0) or (remainder pycor 2 != 0) [
set pcolor grey]
]
let number-outs outs
ask patches with [(abs pxcor = max-pxcor or abs pycor = max-pycor)][
if (remainder pxcor 2 = 0) or (remainder pycor 2 = 0) [
if (number-outs > 0 ) [
set pcolor white
set number-outs number-outs - 1
]
]]
end
to black-patches-around
ask patches [
let p-set other patches with [
(distance myself < 2.1)
and (pcolor = black)
and (visited = 0)]
set neighbors-black p-set
]
end
to draw-maze
ask turtles [
let target-patch 0
ask patch-here [
set pcolor white
set target-patch one-of neighbors-black
]
ifelse (target-patch = nobody)[
if (empty? n-stack) [die]
let p pop-n
ifelse (p = nobody) [stop]
[
set xcor [pxcor] of p
set ycor [pycor] of p]
][
push-n patch-here
ask target-patch [set visited 1]
set heading towards target-patch
run "fd 1"
ask patch-here [
set visited 1
set pcolor white]
run "fd 1"
]
]
end
; stack implementation
;; Save the patches state
to push-n [p];; patch procedure
set n-stack fput p n-stack
end
;; restore the patches state
to-report pop-n ;; patch procedure
; need to go through update-n to keep total statistic correct
let r first n-stack
set n-stack but-first n-stack
report r
end
В алгоритмі BFS границя створюється за принципом FIFO (first-in, first-out) черги. Таким чином, вибирається останній доданий елемент у границю.
BFS корисний в ситуаціях, коли
breed [dwarfs dwarf]
dwarfs-own [
current-patch
n-stack
]
patches-own[
visited
neighbors-black
]
to setup
clear-all
reset-ticks
draw-lines
ask patches [
set visited 0]
black-patches-around
create-dwarfs num [
set n-stack []
let p one-of patches with [pcolor = black]
set xcor [pxcor] of p
set ycor [pycor] of p
ask p [set visited 1]
]
end
to go
tick
draw-maze
black-patches-around
end
to draw-lines
ask patches [
if (remainder pxcor 2 != 0) or (remainder pycor 2 != 0) [
set pcolor grey]
]
let number-outs outs
ask patches with [(abs pxcor = max-pxcor or abs pycor = max-pycor)][
if (remainder pxcor 2 = 0) or (remainder pycor 2 = 0) [
if (number-outs > 0 ) [
set pcolor white
set number-outs number-outs - 1
]
]]
end
to black-patches-around
ask patches [
let p-set other patches with [
(distance myself < 2.1)
and (pcolor = black)
and (visited = 0)]
set neighbors-black p-set
]
end
to draw-maze
ask turtles [
let target-patch 0
ask patch-here [
set pcolor white
set target-patch one-of neighbors-black
]
ifelse (target-patch = nobody)[
if (empty? n-stack) [die]
let p pop-n
ifelse (p = nobody) [stop]
[
set xcor [pxcor] of p
set ycor [pycor] of p]
][
push-n patch-here
ask target-patch [set visited 1]
set heading towards target-patch
run "fd 1"
ask patch-here [
set visited 1
set pcolor white]
run "fd 1"
]
]
end
; queue implementation
;; Save the patches state
to push-n [p];; patch procedure
set n-stack fput p n-stack
end
;; restore the patches state
to-report pop-n ;; patch procedure
; need to go through update-n to keep total statistic correct
let r last n-stack
set n-stack but-last n-stack
report r
end
Ідея: сортувати чергу за кількістю “сусідів” - можливих шляхів руху.
to sort-stack
set n-stack sort-by [[a1 a2] -> [neighbors-black-number] of a1 < [neighbors-black-number] of a2] n-stack
end