You are on page 1of 14

AI Basics: КР №1

Варіант №2

Завдання №1
Опис:

Ваша карта заповнена перешкодами. Необхідно розрахувати найкоротший шлях від гравця
до ворога. Опишіть, як би ви реалізували поставлену задачу та який алгоритм би
використали.

Гра:

В такій ситуації оптимальніше всього буде використовувати алгоритм А*.Оскільки він видає
в результаті найоптимальніший та найкоротший маршрут. Оскільки його головна
відмінність від алгоритму Дейкстри - це те що він використовує додатково Евристичний
метод. Це робиться для того щоби ми бачили,перехід на яку вершину буде більш вигідним.

Наприклад:

1
Опис даного зображення: В нас є поле на якому є стартова точка(Жовта), кінцева
точка(Червоний крестик на ній), пусті точки(на які ми можемо переходити та розглядати) так
заблоковані точки(стіни).

Першим кроком нам потрібно розглянути всі вершини,які зв’язані ребром(якщо б ми


розглядали це поле,як граф) з нашою початковою точкою.

Також потрібно помітити стартову вершину,як уже розглянуту(це означає,що її ми


розглядати вже не будемо).

На наступному кроці нам потрібно обрати наступну вершину з списку можливих для
переходу в неї, але перед цим нам потрібно знайти ще 2 числових значення для кожної
точки, а саме:

● Довжина шляху з стартової точки в наступну розглядаєму вершину(в нашому


випадку рух на одну клітину вверх,вниз,вліво,вправо в ортогональному напрямі
буде коштувати по 10 одиниць,а рух по діагоналі 14 одиниць по теоремі Піфагора).Ці
значення відмічені зеленими цифрами внизу клітинок.
● Евристичне наближення - це довжина шляху з поточної вершини в кінцеву. Є дуже
багато методів, які можуть допомогти вирахувати це наближення.Наприклад:
1. Манхеттена
2. Евклідова
3. Чебишева

Та інші

2
В даному прикладі буде розглянутий метод Манхеттена (По ньому в даній задачі ми
шукаємо загальну кількість точок,потрібну для досягнення кінцевої точки.При цьому ми
ігноруємо діагональне переміщення та будь-які перешкоди на нашому шляху.
Підрахувавши кількість клітинок ми множимо їх на 10). Ці значення відмічені синіми
цифрами внизу кожної клітинки

Для прикладу візьмемо точку справа від поточної. Від неї до кінцевої рівно 3 клітинки. 3*10
= 30 одиниць.

3
Далі потрібно просумувати ці два значення для кожної клітинки, щоб отримати її вагу (Ці
значення відмічені червоними цифрами зверху кожної клітинки).

Далі потрібно обрати наступну клітинку для переходу. Вона потрібна мати найменшу вагу.
На даний це клітинка В(З) з вагою 40.

На наступному кроці нам потрібно розглянути клітинки, які оточують клітинку В(З) (Стіни ми
не розглядаємо,так як їх ми не можемо пройти)

4
Добавляємо клітинку Г(4) та рахуємо 2 значення та вагу клітинки. 24 (довжина шляху) ми
отримали шляхом суми 10(В(3)) та 14(Г(4)).

Но якщо розглянути таким способом клітинку Г(3) то отримаємо, що довжина шляху з


клітинки В(3) буде дорівнювати 20, але ми не перезаписуємо поточне значення, так як
14<20.

Далі переходимо в точку В(3) та помічаємо її, як закриту.

Наступні клітинки з мінімальними вагами Г(3) та Г(4), їх вага 54.

5
В такому випадку наступна клітинка буде обрано випадковим чином (В нашому випадку
Г(3)).

Повторюємо ті ж самі кроки, що і з колишньою точкою:

1. Розглядаємо оточуючі точки


2. Рахуємо для них вагу
3. Переходимо в точку з найменшою вагою

Повторюємо ці кроки,поки не дійдемо до кінцевої точки.

Коли ми дійшли до кінцевої точки, то по напрямку стрілок на кожній клітинці(Вони вказують


на ту точку з якої ми прийшли) потрібно відновити шлях(Він поміченний червоними лініями).

6
Ми можемо бачити, що довжина шляху з стартової точки до кінцевої дорівнює 48 одиниць.

На цьому алгоритм завершено!

Псевдокод алгоритму:

program a-star

// Ініціалізація списку відомих вершин, список досліджених порожній

// (f-значення початкової вершини відсутнє)

openlist.enqueue(startknote, 0)

// цей шлях буде пройдений доки:

// - буде знайдено оптимальний розв'язок або

// - встановлено, що розв'язків не існує

repeat

// Вилучити вершину з найменшим f-значенням

currentNode := openlist.removeMin()

// Досягнута кінцева вершина?

if currentNode == endknote then

return PathFound

// Якщо кінцева вершина не досягнута: додати суміжні

// до поточної вершини в список відомих

expandNode(currentNode)

// поточна вершина вже повністю досліджена

closedlist.add(currentNode)

until openlist.isEmpty()

// список відомих порожній, розв'язків не існує

return NoPathFound

7
end

// перевіряє суміжні вершини та додає до списку відомих якщо:

// - суміжні вершини зустрічаються вперше або

// - знайдений кращий шлях до цієї вершини

function expandNode(currentNode)

foreach successor of currentNode

// пропустити, якщо вершина знаходиться в списку досліджених

if closedlist.contains(successor) then

continue

// обчислити значення g нового шляху:

// значення g попередньої вершини + вартість щойно пройденого ребра

tentative_g = g(currentNode) + c(currentNode, successor)

// якщо суміжна вершина вже в списку відомих,

// але знайдений шлях не кращий за вже відомий - пропустити

if openlist.contains(successor) and tentative_g >= g[successor] then

continue

// встановити вказівник на попердню вершину та зберегти g

successor.predecessor := currentNode

g[successor] = tentative_g

// оновити значення f вершини у списку відомих

// або додати вершину до списку відомих

f := tentative_g + h(successor)

if openlist.contains(successor) then

8
openlist.decreaseKey(successor, f)

else

openlist.enqueue(successor, f)

end

end

Завдання №2
Опис:

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

Гра:

Pac-Man

Задача зводиться до алгоритму MiniMax (можливо в деяких випадках буде доцільніше


використовувати expectimax, про ці випадки ми поговоримо далі). Задача алгоритму
minimax визначити найоптимальнішу стратегію, виконавши побудову дерева ходів гравця
max (в нашому випадку це пакман), та min в нашому випадку це вороги. Хід макса це наш
хід, на якому ми серед кожного з можливих ходів будемо вибирати найбільш оптимальний,
після цього викличемо алгоритм min. На ході min ми зробимо копію ворогів походимо
кожним з них відповідно до оновлених координат Max, якщо привид пертнувся з пакманом

повернемо -∞, як позначка того, що даний вибір веде до нашої поразки. В іншому випадку
викликаємо алгоритм Max і так допоки не дістанемося термінального стану.

9
Алгоритм MinMax є універсальним але в деяких випадках потребує покращень для швидкої
роботи. Обчислення повного графу може зайняти тривалий час, а при грі з комп’ютером ми
очікуємо швидкого відклику для цього доречно застосувати неоптимальну стратегію. Ми
будемо керувати глибиною рекурсійного виклику. Тобто нам не обов’язково доходити до
термінального стану, але потрібно в кінці вивести оцінку нашого шансу на перемогу. В
нашому випадку цією оцінкою буде кількість монет які підібрав головний герой на свому
шляху. За кожну монету ми будемо додавати +10 до score і за кожну пройдену клітинку +1.
За кожну пройдену клітинку потрібно додавати, оскільки це буде стимулювати пакмена
рухатися далі, а не стояти на місці.

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

Зрозуміло, що MiniMax дає нам 100% шанси отримати перемогу (при коректуванні глибини
рекурсії шанси нижчі), але інколи ми граємо з ворогом, який не завжди оптимально грає,
тому хорошою ідеєю є застосування expectimax алгоритму. Як зрозуміло з назви замість
нод min ми використовуємо expecti.

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

11
При роботі з expectimax відрізати гілки (alfa, beta pruning) не можна, оскільки ми не
зможимо спрогнозувати подальший хід.

12
Виникає питання чи можна виконати обмеження по глибині рекурсії.

13
Якщо подивитися по рисунку, то можна побачити, що дана ідея з керуванням рекурсії має
право на життя.

Головне питання як підібрати коефіцієнти. Один з способів підібрати коефіцієнт за


допомогою досліджень.

14

You might also like