You are on page 1of 6

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

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

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

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

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


глибину.
Варіант 30

8 7 3

2 6 5

4 1

Теоретичні відомості
Неінформований пошук – стратегія пошуку рішення в просторі станів, в якій не
використовується додаткова інформація про стани, крім тієї, яка представлена в
конкретній задачі. Все, на що здатен метод не інформованого пошуку, – створювати синів
та відрізняти цільовий стан від нецільового.
Пошук в глибину (DFS) – це стратегія пошуку рішень в просторі станів, яка
полягає в тому, щоб йти «вглиб» дерева наскільки це можливо. Алгоритм пошуку
описується рекурсивно: перебираємо всі вихідні із поточного вузла сини. Якщо син не був
розглянутий раніше, то запускаємо алгоритм від даного сина (вузла), а потім повертаємося
і продовжуємо перебирати синів. Повернення відбувається в тому випадку, якщо у вузлі,
що розглядається, не залишилось нерозглянутих синів.
Алгоритм є повним. Якщо всі дії мають однакову вартість, пошук в ширину
являється оптимальним.
Блок-схема алгоритму
Код програми
import java.util.ArrayList;
import java.util.Scanner;
public class SecondLab {
int num[][] = new int[3][3];
int depth=0;
int spacecrd[] = new int[2];
public SecondLab(){}
public SecondLab(int n[][]){
for(int i = 0; i< num.length; i++)
for(int j = 0; j< num[0].length; j++){
num[i][j]=n[i][j];
if(num[i][j]==0){
spacecrd[0]=i;
spacecrd[1]=j; } } }
protected static SecondLab clone(SecondLab original){
SecondLab clone = new SecondLab();
for(int i = 0; i<clone.num.length; i++)
for(int j = 0; j<clone.num[0].length; j++)
clone.num[i][j]=original.num[i][j];
clone.depth = original.depth;
clone.spacecrd[0] = original.spacecrd[0];
clone.spacecrd[1] = original.spacecrd[1];
return clone; }
public static SecondLab getChild(SecondLab parent,int swapX, int swapY){ SecondLab child =
SecondLab.clone(parent);
int temp = child.num[child.spacecrd[0]+swapX][child.spacecrd[1]+swapY];
child.num[child.spacecrd[0]+swapX][child.spacecrd[1]+swapY]=0;
child.num[child.spacecrd[0]][child.spacecrd[1]]=temp;
child.depth++;
child.spacecrd[0]+=swapX;
child.spacecrd[1]+=swapY;
return child; } public static boolean compareNodes(SecondLab x, SecondLab y){ for(int i =
0;
i<x.num.length; i++)
for(int j = 0; j<x.num[0].length; j++)
if(x.num[i][j]!=y.num[i][j]) return false;
return true; }
static ArrayList<SecondLab> statesBase = new ArrayList<>();
static int generated;
static int duplicated;
static int inBase;
static int maxdepth;
public static void main(String[] args) { SecondLab root=startGame();
SecondLab cur[] = new SecondLab[4];
boolean s =stepByStep();
boolean stop=false;
int choice =1;
while(choice==1){
inBase=0;
if(root.spacecrd[0]>0){
statesBase = new ArrayList<>();
statesBase.add(root);
cur[0]=step(root,-1,0,s); if(s) s=stepByStep();
if(cur[0]!=null){
statesBase.add(cur[0]);
gameplay(cur[0],0,0,s,stop); } inBase=+statesBase.size(); }
if(root.spacecrd[1]>0){
statesBase = new ArrayList<>();
statesBase.add(root);
cur[1]=step(root,0,-1,s); if(s) s=stepByStep();
if(cur[1]!=null){
statesBase.add(cur[1]);
gameplay(cur[1],0,0,s,stop); }
inBase=+statesBase.size(); }
if(root.spacecrd[0]<2){
statesBase = new ArrayList<>();
statesBase.add(root);
cur[2]=step(root,1,0,s);
if(s) s=stepByStep();
if(cur[2]!=null){
statesBase.add(cur[2]);
gameplay(cur[2],0,0,s,stop); }
inBase=+statesBase.size(); }
if(root.spacecrd[1]<2){
statesBase = new ArrayList<>();
statesBase.add(root);
cur[3]=step(root,0,1,s);
if(s) s=stepByStep();
if(cur[3]!=null){
statesBase.add(cur[3]);
gameplay(cur[3],0,0,s,stop); }
inBase=+statesBase.size(); }
System.out.println("На жаль, на даній глибині не вдалося знайти результат, бажаєте
збільшити глибину пошуку на 1? (1/0)");
Scanner scan = new Scanner(System.in);
choice = scan.nextInt();
if(choice==1) maxdepth++; } }
public static void gameplay(SecondLab cur, int moveX, int moveY,boolean s,boolean stop){
int sum = moveX+moveY;
if(sum!=0){
cur = step(cur,moveX,moveY,s);
if(s) s=stepByStep();
if(cur==null)return;
if(cur.depth>=maxdepth) return; }
if(cur.spacecrd[0]>0) gameplay(cur,-1,0,s,stop);
if(cur.spacecrd[1]>0) gameplay(cur,0,-1,s,stop);
if(cur.spacecrd[0]<2) gameplay(cur,1,0,s,stop);
if(cur.spacecrd[1]<2) gameplay(cur,0,1,s,stop); }
public static SecondLab 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]); }
SecondLab root = new SecondLab(firstNode);
System.out.println("Введіть максимальну глибину дерева пошуку: ");
Scanner scan = new Scanner(System.in);
maxdepth = scan.nextInt();
return root; }
public static void showNode(SecondLab n){
System.out.println("\n");
for(int i = 0; i<n.num.length; i++){
for(int j = 0; j<n.num.length; j++){
if(n.num[i][j]!=0) System.out.print(n.num[i][j]+" ");
else
System.out.print(" "); }
System.out.println(); } }
public static boolean stepByStep(){
System.out.println("Наступний крок - 0, Відповідь - 1:");
Scanner scan = new Scanner(System.in);
int choice = scan.nextInt();
System.out.println("\n");
if(choice==0)
return true;
else
return false; }
public static boolean searchInBase(SecondLab n){
for(int i=0;i<statesBase.size();i++)
if(SecondLab.compareNodes(n,statesBase.get(i))) return true;
return false; }
public static boolean checkWin(SecondLab winner){
int iterator =1;
for(int i = 0; i<winner.num.length; i++)
for(int j = 0; j<winner.num.length; j++){
if(winner.num[i][j]!=0&&winner.num[i][j]!=iterator) return false;
iterator++; }
return true; }
public static SecondLab step(SecondLab cur, int swapX, int swapY,boolean show){
SecondLab child = SecondLab.getChild(cur,swapX,swapY);
if(show)showNode(child);
generated++;
if(checkWin(child)){
inBase+=statesBase.size();
showNode(child);
System.out.println("Вершина досягнута!\nКількість згенерованих станів:" + generated +
"\nКількість станів у базі: "+duplicated+"\nГлибина: "+child.depth);
System.exit(0); }
boolean isDuplicate=searchInBase(child);
if(!isDuplicate){
statesBase.add(child);
return child; }
else{
if(show)System.out.println("Відкинуте");
duplicated++; return null; } } }
Результат виконання програмного коду
Висновки: На даній лабораторній роботі було ознайомлено з методом пошуку в
глибину, проаналізовано отримані результати та набуто практичнi навички використання
методу пошуку в ширину та його програмній реалізації.

You might also like