Ім'я файлу: ШІ.docx
Розширення: docx
Розмір: 13кб.
Дата: 16.05.2021
скачати


ЛАБОРАТОРНА РОБОТА №1

з дисципліни:

“Комп'ютерні системи штучного інтелекту”
Тема : А-алгоритм, як евристичний метод пошукуВаріант №16






Мета роботи: Вивчити А-алгоритм та приклад його реалізації для гри у вісімки.

Відповіді на контрольні запитання:

Методологія пошуку в ширину - пошук в ширину обирає того кандидата, глибина якого найменша.

Принцип роботи А-алгоритму - Методологія пошуку полягає у послідовному спусканні по дереву від початкового стану до тих пір, поки не буде досягнутий деякий кінцевий стан. Якщо провести порівняння з пошуком в ширину, то можна помітити, що пошук вглибину обирає того кандидата, глибина якого найменша, а пошук за допомогою А-алгоритму для кожного кандидата визначає оцінку, і обирається кандидат з найкращою оцінкою. Граф, що відповідає заданому етапу пошуку, називається графом пошуку. Коли не вдається досягнути кінцевого стану у графі пошуку, виникає задача вибору деякого стану, до якого буде застосовуватись оператор з метою породження нових станів (“розкриття” станів).

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

Принцип роботи А*-алгоритмуАлгоритм пошуку назвемо допустимим, якщо він завжди знаходить оптимальний розв’язок. Якщо граф пошуку скінчений, а евристичний член h(n) є нижньою оцінкою мінімальної вартості шляху між станом n і якимсь із кінцевих станів (h*(n)), то має місце застосування алгоритму пошуку типу А* і тоді забезпечується виконання наступних умов:

1. Виконується зупинка програми, що реалізує цей алгоритм;

2. Така зупинка дозволяє або знайти деякий шлях до кінцевого стану (якщо

такий шлях існує), або підтвердити факти відсутності шляху;

3. Коли шлях до кінцевого стану знайдений, то він має мінімальну вартість. У загальному випадку якщо не забезпечується наявність такої нижньої оцінки h(n), алгоритм має тип А ( а не А*) і виконуються тільки умови 1 та 2.

Інші приклади використання А*-алгоритму - Алгоритм пошуку А* знаходить оптимальний шлях між двома вершинами в графі. В залежності від функції вартості, яка задає кожному ребру його «вагу», оптимальність може означати найкоротший, найшвидший або навіть найпростіший шлях. Теоретично, алгоритм може розв'язувати всі задачі, які можна представити у вигляді задачі пошуку оптимального шляху на графі. Алгоритм A* використовується як для планування шляхів, так і в комп'ютерних іграх. Для планування шляхів, як евристична функція використовується лінійна відстань до цілі, оскільки згідно з нерівністю трикутника вона дає оптимальні оцінки. Також алгоритм А* використовується в іграх, в яких необхідно досягти наперед заданий стан, наприклад, в задачі про вісім ферзів, або в п'ятнашках. Евристикою може слугувати, наприклад, кількість невірно пересунутих камінців.

Текст програми:

Board.ts

import { cloneDeep } from 'lodash';
type historyItem = { heuristic: number, move: string };
export class Board {

public static readonly EMPTY_VALUE = -1;
private previousMoves: string[] = [];
private history: historyItem[] = [];
constructor(private state: Array>) {

}
get depth(): number {

return this.history.length;

}
evaluate(): number {

let sum = 0;

let sort = 0;
for (let x = 0; x < this.state.length; x++) {

for (let y = 0; y < this.state[x].length; y++) {

const element = this.state[x][y];
sum += this.calculateDistance(x, y, element);

// sort += this.calculateSort(x, y, element);

}

}
if (isNaN(sum) || isNaN(sort))

throw new Error('kek');
return sum + 3 * sort;

}
equals(otherBoard: Board): boolean {

for (let x = 0; x < this.state.length; x++) {

for (let y = 0; y < this.state[x].length; y++) {

if (this.state[x][y] !== otherBoard.state[x][y]) {

return false;

}

}

}
return true;

}
printHistory(): void {

console.log(this.history.map(i => i.move).join(‘, ‘));

}
printMe(): void {

console.log(this.state);

}
getNextBoards(): Board[] {

const nextBoards: Board[] = [];
const [x, y] = this.getEmptyCoordinates();

if (y !== 0) {

const newBoard = new Board(cloneDeep(this.state));

newBoard.move('u');

nextBoards.push(newBoard);

}

if (y !== 2) {

const newBoard = new Board(cloneDeep(this.state));

newBoard.move('d');

nextBoards.push(newBoard);

}

if (x !== 0) {

const newBoard = new Board(cloneDeep(this.state));

newBoard.move('l');

nextBoards.push(newBoard);

}

if (x !== 2) {

const newBoard = new Board(cloneDeep(this.state));

newBoard.move('r');

nextBoards.push(newBoard);

}
return nextBoards;

}
move(direction: ('u' | 'r' | 'd' | 'l')): void {

this.history.push({

heuristic: this.evaluate(),

move: direction

});
const [x, y] = this.getEmptyCoordinates();
let newX: number;

let newY: number;

switch(direction) {

case 'u':

newX = x;

newY = y - 1;

break;

case 'r':

newX = x + 1;

newY = y;

break;

case 'd':

newX = x;

newY = y + 1;

break;

case 'l':

newX = x - 1;

newY = y;

break;

}
this.state[x][y] = this.state[newX][newY];

this.state[newX][newY] = Board.EMPTY_VALUE;

}
private getEmptyCoordinates(): number[] {

for (let x = 0; x < this.state.length; x++) {

for (let y = 0; y < this.state[x].length; y++) {

if (this.state[x][y] === Board.EMPTY_VALUE) {

return [x, y];

}

}

}

}
private calculateDistance(x: number, y: number, val: number) {

const goalX = val == Board.EMPTY_VALUE ? 2 : val % 3;

const goalY = val == Board.EMPTY_VALUE ? 2 : Math.ceil(val / 3);
return Math.abs(x - goalX) + Math.abs(y - goalY);

}
private calculateSort(x: number, y: number, value: number) {

if (value !== Board.EMPTY_VALUE) {

if (x === 1 && y === 1) {

return 1;

} else {

let xMove = 0;

if (y === 0 && x < 2) xMove = 1;

else if (y === 2 && x > 0) xMove = -1;
let yMove = 0;

if (x === 2 && y < 2) yMove = 1;

if (x === 0 && y > 0) yMove = -1;
const newX = x + xMove;

const newY = y + yMove;
const nextValue = this.state[newX][newY];

if (nextValue === value + 1 || (nextValue === Board.EMPTY_VALUE && value === 7)) {

return 0;

} else {

return 2;

}

}

} else {

return 0;

}

}

}

Main.ts

import { Board } from "./board";
const startState =

[

[2, 4, 3],

[7, Board.EMPTY_VALUE, 1],

[5, 8, 6]

];
const board = new Board(startState);
const queue = [board];

const passedBoards: Board[] = [board];

while (queue.length > 0) {

const currentBoard = queue.reverse().pop();
console.log('---------------------------------------');

console.log(current state ', currentBoard.toString());

console.log('score: ', currentBoard.evaluate());
if (currentBoard.evaluate() === 0) {

currentBoard.printHistory();

console.log('exit');

process.exit(1);

} else {

currentBoard.getNextBoards().forEach(board => {

if (!passedBoards.some(passedBoard => passedBoard.equals(board))) {

passedBoards.push(board);

board.printMe();

queue.push(board);

}

});

queue.sort((a, b) => a.evaluate() - b.evaluate());

queue[0].printHistory();

console.log(queue.length);

console.log(passedBoards.length);

}

}

Демонстрація роботи:

heuristic:5

depth:21

total:26

---

---

current state

1 8 3

2 6 0

7 5 4

current scores

heuristic:6

depth:20

total:26

---

---

current state

1 8 3

2 4 5

7 0 6

current scores

heuristic:6

depth:20

total:26

---

---

current state

0 5 2

1 6 4

7 8 3

current scores

heuristic:7

depth:19

total:26

---

---

current state

0 5 2

1 6 4

7 8 3

current scores

heuristic:7

depth:19

total:26

---

---

current state

6 7 3

4 5 8

1 0 2

current scores

heuristic:6

depth:20

total:26

---

---

current state

1 2 8

6 3 0

7 4 5

current scores

heuristic:6

depth:20

total:26

---

---

current state

6 2 4

7 5 3

0 1 8

current scores

heuristic:7

depth:19

total:26

---

---

current state

8 5 3

4 1 2

7 0 6

current scores

heuristic:6

depth:20

total:26

---

---



------------------

current state

2 7 1

4 5 6

0 8 3

current scores

heuristic:5

depth:21

total:26

---

---

current state

2 7 1

4 5 6

8 3 0

current scores

heuristic:5

depth:21

total:26

---

---

current state

1 2 3

4 5 0

8 6 7

current scores

heuristic:4

depth:22

total:26

---

---

current state

4 2 1

8 5 3

7 6 0

current scores

heuristic:5

depth:21

total:26

---

---

current state

1 2 3

4 5 0

7 8 6

current scores

heuristic:2

depth:24

total:26

---

---

current state

1 2 3

4 5 6

7 8 0

current scores

heuristic:0

depth:25

total:25

[[1, 2, 3], [4, 5, 6], [7, 8, 0]]

['l', 'u', 'r', 'r', 'd', 'l', 'l', 'u', 'r', 'r', 'u', 'l', 'd', 'r', 'd', 'l', 'l', 'u', 'r', 'r', 'u', 'l', 'd', 'r', 'd']

25


Висновок. На даній лабораторній роботі я вивчив А-алгоритм та реалізував його для гри у вісімки.


скачати

© Усі права захищені
написати до нас