我目前正在编写A *算法的实现,以便解决8puzzle问题。我已经取得了很大的进步,但我的算法似乎陷入了一个无限的过程中,我真的不知道我在哪里犯了错误。
这是我的代码:
Board.java:
public class Board {
private int currentState[][] = new int[3][3];
private int nbMoves; // variable for the cost of the current board
private int manhattanDistance;
private int f = manhattanDistance + nbMoves;
public Board() {}
public Board(int b1[][]) {
this.currentState = b1;
}
public int getValue(int x, int y) {
return currentState[x][y];
}
public void setValue(int n, int x, int y) {
currentState[x][y] = n;
}
public int getNbMoves() {
return nbMoves;
}
public void setNbMoves(int n) {
nbMoves = n;
}
// Function to get the x coordinate of the specified value n
public int getX(int n) {
int posX = 0;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (currentState[i][j] == n) {
posX = i;
break;
}
}
}
return posX;
}
// Function to get the y coordinate of the specified value n
public int getY(int n) {
int posY = 0;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (currentState[i][j] == n) {
posY = j;
break;
}
}
}
return posY;
}
// Function to get and stock the Coordinate of the desired value in a 1D array coord
// We will use it to get the coordinates of the 0 tile.
public void getCoordinate(int coord[], int n) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (currentState[i][j] == n) {
coord[0] = i;
coord[1] = j;
break;
}
}
}
}
// Function to get the current state of the board
public void getCurrentState(int state[][]) {
state = this.currentState;
}
// Function to test if 2 boards are the same
public boolean equals(int b[][]) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (this.currentState[i][j] != b[i][j]) {
return false;
}
}
}
return true;
}
public void setManhattanDistance() {
int md = 0;
for (int x = 0; x < 3; x++) {
for (int y = 0; y < 3; y++) {
int value = currentState[x][y]; // Contain the value of the tile
// Then we calculate the Manhattan Distance for each tile,
// except for the 0 tile.
if (value != 0) {
int expected_X = (value - 1) / 3; // expected vertical coordinate
int expected_Y = (value - 1) % 3; // expected horizontal coordinate
int true_x = x - expected_X;
int true_y = y - expected_Y;
md += Math.abs(true_x) + Math.abs(true_y);
}
}
}
manhattanDistance = md;
}
// Function to set the f() value
public int getF() {
return f;
}
// Function for printing the current state of board
public void print() {
for (int i = 0; i<3; i++) {
for (int j = 0; j<3; j++) {
System.out.print(currentState[i][j] + " ");
}
System.out.println("");
}
}
}
BFSearch.java:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class BFSearch {
private ArrayList<Board> closedlist = new ArrayList<Board>();
private ArrayList<Board> openlist = new ArrayList<Board>();
private ArrayList<Board> getChildren = new ArrayList<Board>();
private Board currentState,goalState = new Board();
public BFSearch(int start[][], int goal[][]) {
currentState = new Board(start);
goalState = new Board(goal);
}
// Function to get every children possible for the current state of the board
// A board can have a maximum of 4 children (1 for every direction)
public ArrayList<Board> children(Board currentState) {
Board newState = new Board();
ArrayList<Board> children = new ArrayList<Board>();
Pos p = new Pos();
newState = p.Up(currentState);
// If the move is possible, then we increment by 1 the number of moves (to calculate f() value)
// we calculate it's manhattan distance,
// and we add it to the list of children
if (newState != null) {
newState.setNbMoves(currentState.getNbMoves() + 1);
newState.setManhattanDistance();
children.add(newState);
}
newState = p.Down(currentState);
// If the move is possible, then we increment by 1 the number of moves (to calculate f() value)
// we calculate it's manhattan distance,
// and we add it to the list of children
if (newState != null) {
newState.setNbMoves(currentState.getNbMoves() + 1);
newState.setManhattanDistance();
children.add(newState);
}
newState = p.Left(currentState);
// If the move is possible, then we increment by 1 the number of moves (to calculate f() value)
// we calculate it's manhattan distance,
// and we add it to the list of children
if (newState != null) {
newState.setNbMoves(currentState.getNbMoves() + 1);
newState.setManhattanDistance();
children.add(newState);
}
newState = p.Right(currentState);
// If the move is possible, then we increment by 1 the number of moves (to calculate f() value)
// we calculate it's manhattan distance,
// and we add it to the list of children
if (newState != null) {
newState.setNbMoves(currentState.getNbMoves() + 1);
newState.setManhattanDistance();
children.add(newState);
}
return children;
}
public void solve() {
boolean solved = false;
int movecount = 0;
currentState.setNbMoves(0);
// We add the currentState of the board to the open list
openlist.add(currentState);
// While we don't have a solution
while (!solved) {
currentState = openlist.get(0);
// If we arrived at the goal state then we print it and stop the program
if (currentState.equals(goalState)) {
currentState.print();
solved = true;
}
// We get the list of possible children
getChildren = children(currentState);
// We move the First board of the open list to the closed list
closedlist.add(currentState);
openlist.remove(0);
// Need to sort the children depending on their f() value
// I declared an anonymous comparator for that.
Collections.sort(getChildren, new Comparator<Board>() {
@Override
public int compare(Board b1, Board b2) {
Integer f1 = b1.getF();
Integer f2 = b2.getF();
return f1.compareTo(f2);
}
});
// Then, we add the children to the open list
for (Board b : getChildren) {
openlist.add(b);
}
movecount++;
}
// We print every step of the solution
for (Board bd : closedlist) {
bd.print();
}
// We print the number of move required
System.out.println("Number of move required : " + movecount);
}
}
然后,我的主要执行程序,EightPuzzle.java:
public class EightPuzzle {
public static void main(String[] args) {
int startState[][] = {{1,2,3}, {4,5,6}, {7,8,0}};
int goalState[][] = {{1,2,3}, {4,5,6}, {7,8,0}};
BFSearch bfs = new BFSearch(startState, goalState);
System.out.println("Researching the solution...");
bfs.solve();
}
}
我有另外一个类(Pos.java),主要是为瓷砖做动作(比如上升,交换等等)但我不认为问题来自那个。
当我执行我的程序时,只有&#34;研究解决方案......&#34;即使我等了很多时间,也没有打印。即使开始状态和目标状态相同......(正如您在主程序中看到的那样)
如果你有任何想法,非常感谢你!