messi256 Ответов: 1

Решите 8-головоломку на java


Использование информированных и неинформированных алгоритмов поиска для решения 8-puzzl

это моя проблема


Проблема, с которой я сталкиваюсь сейчас с приведенным выше кодом, заключается в том, что всякий раз, когда программа выскакивает из стека, она не соответствует значению, которое было выдвинуто ранее в методе функции swap (класс Puzzle).e в java

Что я уже пробовал:

public class Main {

	public static void main(String[] args) {

        int startState[][] = {{6,2,5}, {1,8,0}, {7,4,3}}, goalState[][] = {{7,6,5}, {8,0,4}, {1,2,3}};

        System.out.println("Solving puzzle using DFS...");
        DFS dfs = new DFS(startState, goalState);
        dfs.search();
    }
	}
<pre>public class Node {
	 int state[][] = new int[3][3];
	    
	    public Node() {
	    }
	    
	    public Node(int state[][]) {
	        this.state = state;
	    }
	    
	    public int getNum(int posX, int posY) {
	        return state[posX][posY];
	    }
	    
	    public void setNum(int num, int x, int y) {
	        state[x][y] = num;
	    }
	    
	    public int getX(int num) {
	        int positionX = 0;

	        for (int x = 0; x < 3; x++) {
	            for (int y = 0; y < 3; y++) {
	                if (state[x][y] == num) {
	                    positionX = x;
	                    break;
	                }
	            }
	        }

	        return positionX;
	    }
	    
	    public int getY(int num) {
	        int positionY = 0;

	        for (int x = 0; x < 3; x++) {
	            for (int y = 0; y < 3; y++) {
	                if (state[x][y] == num) {
	                    positionY = y;
	                    break;
	                }
	            }
	        }

	        return positionY;
	    }
	    
	    public void getCoordinate(int coordinate[], int num) {
	        for (int x = 0; x < 3; x++) {
	            for (int y = 0; y < 3; y++) {
	                if (state[x][y] == num) {
	                    coordinate[0] = x;
	                    coordinate[1] = y;
	                    break;
	                }
	            }
	        }
	    }
	    
	    public void getState(int state[][]) {
	        state = this.state;
	    }
	    
	    public String toString() {
	        String output = "";

	        for (int x = 0; x < 3; x++) {
	            for (int y = 0; y < 3; y++) {
	                output += state[x][y];
	            }
	            output += "\n";
	        }

	        return output;
	    }
}
<pre>import java.util.Stack;
import java.util.ArrayList;

public class DFS {
    private int moveCounter = 0;
    private Stack<Node> fringe = new Stack<Node>();
    private Node startState, goalState, currentState = new Node();
    private ArrayList<Node> closed = new ArrayList<Node>();

    public DFS(int start[][], int goal[][]) {
        startState = new Node(start);
        goalState = new Node(goal);
        fringe.push(startState);
    }

    private void succesor(Node currentState) {
        Node newState = new Node();
        puzzle p = new puzzle();

        newState = p.moveUp(currentState);

        if (newState != null) {
            fringe.push(newState);
        }

        newState = p.moveRight(currentState);

        if (newState != null) {
            fringe.push(newState);
        }

        newState = p.moveDown(currentState);

        if (newState != null) {
            fringe.push(newState);
        }

        newState = p.moveLeft(currentState);

        if (newState != null) {
            fringe.push(newState);
        }
    }

    public void search() {
        boolean found = false, exist = false, checkElement = true;
        Node tmpNode = new Node();

        currentState = fringe.pop();
        closed.add(currentState);
        succesor(currentState);

        for (int x = 1; x < 2 ; x++) {
            while (!found) {
                try {
                    currentState = fringe.pop();

                    for (int i = 0; i < closed.size(); i++) {
                        tmpNode = closed.get(i);

                        if (currentState.toString().equals(tmpNode.toString())) {
                            exist = true;
                            break;
                        }                        
                    }

                    if (!exist) {
                        moveCounter++;

                        if (currentState.getX(x) == goalState.getX(x) && currentState.getY(x) == goalState.getY(x)) {
                            found = true;
                            break;
                        }
                        else {
                            closed.add(currentState);
                            succesor(currentState);
                        }
                    }
                }
                catch (Exception e) {
                    System.out.println("No solutions found!");
                    break;
                }
            }
        }

        System.out.println("Number of step(s): " + moveCounter);
    }
}
<pre>public class puzzle {
	   public void Puzzle() {
	    }
	    
	    private void swap(Node newState, int newPosition[]) {
	        int emptyTile[] = new int[2], tmpNum;                

	        newState.getCoordinate(emptyTile, 0);
	        tmpNum = newState.getNum(newPosition[0], newPosition[1]);
	        
	        newState.setNum(0, newPosition[0], newPosition[1]);
	        newState.setNum(tmpNum, emptyTile[0], emptyTile[1]);
	    }
	        
	    public Node moveUp(Node currentState) {
	        Node newState = new Node();
	        newState = null;
	        int newPosition[] = new int[2];

	        if (currentState.getX(0) - 1 >= 0) {
	            newState = currentState;
	            newPosition[0] = newState.getX(0) - 1;
	            newPosition[1] = newState.getY(0);

	            swap(newState, newPosition);
	        }

	        return newState;
	    }        
	        
	    public Node moveRight(Node currentState) {
	        Node newState = new Node();
	        newState = null;
	        int newPosition[] = new int[2];

	        if (currentState.getY(0) + 1 <= 2) {
	            newState = currentState;
	            newPosition[0] = newState.getX(0);
	            newPosition[1] = newState.getY(0) + 1;

	            swap(newState, newPosition);
	        }

	        return newState;
	    }        
	        
	    public Node moveDown(Node currentState) {
	        Node newState = new Node();
	        newState = null;
	        int newPosition[] = new int[2];

	        if (currentState.getX(0) + 1 <= 2) {
	            newState = currentState;
	            newPosition[0] = newState.getX(0) + 1;
	            newPosition[1] = newState.getY(0);

	            swap(newState, newPosition);
	        }

	        return newState;
	    }        
	        
	    public Node moveLeft(Node currentState) {
	        Node newState = new Node();
	        newState = null;
	        int newPosition[] = new int[2];

	        if (currentState.getY(0) - 1 >= 0) {
	            newState = currentState;
	            newPosition[0] = newState.getX(0);
	            newPosition[1] = newState.getY(0) - 1;

	            swap(newState, newPosition);
	        }

	        return newState;
	    }      
}

Richard MacCutchan

И что же? Где именно происходит ошибка и каковы полные детали?

1 Ответов

Рейтинг:
1

OriginalGriff

Компиляция не означает, что ваш код верен! :смеяться:
Подумайте о процессе разработки как о написании электронного письма: успешная компиляция означает, что вы написали электронное письмо на правильном языке - например, на английском, а не на немецком, - а не то, что письмо содержало сообщение, которое вы хотели отправить.

Итак, теперь вы входите во вторую стадию разработки (на самом деле это четвертая или пятая, но вы перейдете к более ранним стадиям позже): тестирование и отладка.

Начните с рассмотрения того, что он делает, и как это отличается от того, что вы хотели. Это важно, потому что это дает вам информацию о том, почему он это делает. Например, если программа предназначена для того, чтобы позволить пользователю ввести число, а он удваивает его и печатает ответ, то если ввод / вывод был таким:

Input   Expected output    Actual output
  1            2                 1
  2            4                 4
  3            6                 9
  4            8                16
Тогда совершенно очевидно, что проблема заключается в бите, который удваивает его - он не прибавляет себя к себе или умножает его на 2, он умножает его на себя и возвращает квадрат входного сигнала.
Таким образом, вы можете посмотреть на код, и очевидно, что он находится где-то здесь:
int Double(int value)
   {
   return value * value;
   }

Как только у вас появится идея, что может пойти не так, начните использовать отладчик, чтобы выяснить, почему. Поместите точку останова в первую строку метода и запустите приложение. Когда он достигнет точки останова, отладчик остановится и передаст управление вам. Теперь вы можете запускать свой код построчно (так называемый "одноступенчатый") и просматривать (или даже изменять) содержимое переменных по мере необходимости (черт возьми, вы даже можете изменить код и повторить попытку, если вам это нужно).
Подумайте о том, что должна делать каждая строка кода перед ее выполнением, и сравните это с тем, что она действительно делала, когда вы использовали кнопку "Step over" для выполнения каждой строки по очереди. Он сделал то, что вы ожидали? Если да, то переходите к следующей строке.
Если нет, то почему? Чем это отличается?
Надеюсь, это поможет вам определить, в какой части этого кода есть проблема и в чем она заключается.
Это навык, и его стоит развивать, поскольку он помогает вам как в реальном мире, так и в развитии. И, как и все навыки, он только улучшается при использовании!