You are on page 1of 5

Прізвище: Храновський

Ім'я: Микола
Група: КН-304

Кафедра: САПР
Дисципліна: Методи та системи штучного інтелекту
Перевірив: Головацький Р. І.

ЗВІТ
до лабораторної роботи №2
“Неінформовані методи пошуку рішення задач в просторі й стані. Пошук в ширину ”
Мета роботи – розглянути метод пошуку ширину, набути практичні навички у
його використанні та програмуванні.

Завдання – дослідити рішення задачі «Гра у 8» за допомогою методу пошуку в


ширину.
Варіант 30

8 7 3

2 6 5

4 1

Теоретичні відомості
Неінформований пошук – стратегія пошуку рішення в просторі станів, в якій не
використовується додаткова інформація про стани, крім тієї, яка представлена в
конкретній задачі. Все, на що здатен метод не інформованого пошуку, – створювати синів
та відрізняти цільовий стан від нецільового.
Пошук в ширину (BFS) – це стратегія пошуку рішень в просторі станів, в якій
спочатку розгортається кореневий вузол, а потім – всі сини кореневого вузла, після цього
розгортаються сини цих синів і т.д. Перед тим, як виконується розгортання яких-небудь
вузлів на наступному рівні, розгортаються всі вузли на даній глибині в дереві пошуку.
Алгоритм є повним. Якщо всі дії мають однакову вартість, пошук в ширину
являється оптимальним.
Блок-схема алгоритму
Код програми
package pack;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Scanner;
public class EightGame {
static ArrayDeque<FirstLab> queue = new ArrayDeque<>();
static ArrayList<FirstLab> statesBase = new ArrayList<>();
static int generated;
static int duplicated;
public static void main(String[] args) throws CloneNotSupportedException{
FirstLab root=startGame();
System.out.println("Вихідна вершина:");
showNode(root);
boolean s =stepByStep();
boolean stop;
queue.addLast(root);
statesBase.add(root);
while(true){
FirstLab cur=queue.pollFirst();
if(cur==null) break;
if(cur.spaceCoordinates[0]>0){
stop=step(cur,-1,0,s);
if(stop) break;
if(s) s=stepByStep();
}
if(cur.spaceCoordinates[1]>0){
stop=step(cur,0,-1,s);
if(stop) break;
if(s) s=stepByStep();
}
if(cur.spaceCoordinates[0]<2){
stop=step(cur,1,0,s);
if(stop) break;
if(s) s=stepByStep();
}
if(cur.spaceCoordinates[1]<2){
stop=step(cur,0,1,s);
if(stop) break;
if(s) s=stepByStep();
}
}
}
public static FirstLab startGame(){
System.out.println("Введіть початкове розміщення чисел порядково, розділюючи їх пробілом, замість
пустої клітинки введіть нуль: ");
int firstNode[][]=new int[3][3];
for(int i=0;i<firstNode.length;i++){
Scanner scan = new Scanner(System.in);
String line = scan.nextLine();
String lineNumbers[] = line.split(" ",3);
for(int j=0;j<firstNode.length;j++)
firstNode[i][j]=Integer.valueOf(lineNumbers[j]);
}
FirstLab root = new FirstLab(firstNode);
return root;
}
public static void showNode(FirstLab n){
System.out.println("---------------------");
for(int i=0;i<n.nums.length;i++){
for(int j=0;j<n.nums.length;j++){
if(n.nums[i][j]!=0)
System.out.print(n.nums[i][j]+" ");
else
System.out.print(" ");
}
System.out.println();
}
}
public static boolean stepByStep(){
System.out.println("-------------------\nДля покрокового виконання введіть 0, для повного - 1:");
Scanner scan = new Scanner(System.in);
int choice = scan.nextInt();
if(choice==0)
return true;
else
return false;
}
public static boolean searchInBase(FirstLab n){
for(int i=0;i<statesBase.size();i++)
if(FirstLab.compareNodes(n,statesBase.get(i))) return true;
return false;
}
public static boolean checkWin(FirstLab winner){
int iterator =1;
for(int i=0;i<winner.nums.length;i++)
for(int j=0;j<winner.nums.length;j++){
if(winner.nums[i][j]!=0&&winner.nums[i][j]!=iterator) return false;
iterator++;
}
return true;
}

public static boolean step(FirstLab cur, int swapX, int swapY,boolean show){
boolean result=false;
FirstLab child = FirstLab.getChild(cur,swapX,swapY);
if(show)showNode(child);
generated++;
if(checkWin(child)){
showNode(child);
System.out.println("Вершина досягнута!\nКількість згенерованих станів: "+generated+"\nКількість
станів у базі: "+statesBase.size()+"\nКількість відкинутих станів: "+duplicated+"\nГлибина дерева пошуку:
"+child.depth);
result = true;
}
boolean isDuplicate=searchInBase(child);
if(!isDuplicate){
statesBase.add(child);
queue.addLast(child);
}
else{
if(show)System.out.println("Відкидаємо");
duplicated++;
}
return result;
}
}

package pack;

public class FirstLab {


int nums[][] = new int[3][3];
int depth=0;
int spaceCoordinates[] = new int[2];
public FirstLab(){}
public FirstLab(int n[][]){
for(int i=0;i<nums.length;i++)
for(int j=0;j<nums[0].length;j++){
nums[i][j]=n[i][j];
if(nums[i][j]==0){
spaceCoordinates[0]=i;
spaceCoordinates[1]=j;
}
}
}
protected static FirstLab clone(FirstLab original){
FirstLab clone = new FirstLab();
for(int i=0;i<clone.nums.length;i++)
for(int j=0;j<clone.nums[0].length;j++)
clone.nums[i][j]=original.nums[i][j];
clone.depth = original.depth;
clone.spaceCoordinates[0] = original.spaceCoordinates[0];
clone.spaceCoordinates[1] = original.spaceCoordinates[1];
return clone;
}
public static FirstLab getChild(FirstLab parent,int swapX, int swapY){
FirstLab child = FirstLab.clone(parent);
int temp = child.nums[child.spaceCoordinates[0]+swapX][child.spaceCoordinates[1]+swapY];
child.nums[child.spaceCoordinates[0]+swapX][child.spaceCoordinates[1]+swapY]=0;
child.nums[child.spaceCoordinates[0]][child.spaceCoordinates[1]]=temp;
child.depth++;

child.spaceCoordinates[0]+=swapX;
child.spaceCoordinates[1]+=swapY;
return child;
}
public static boolean compareNodes(FirstLab x, FirstLab y){
for(int i=0;i<x.nums.length;i++)
for(int j=0;j<x.nums[0].length;j++)
if(x.nums[i][j]!=y.nums[i][j]) return false;
return true;
}
}
Результат виконання програмного коду

Висновки: На даній лабораторній роботі було ознайомлено з методом пошуку в


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

You might also like