我正在使用标准的8个拼图解算器,并且已经成功地使用它与BFS一起工作。另一方面,深度首先是无限循环。这是我的DFS算法代码:
public static void depthFirstSolver(PuzzleNode initialNode)
{
Stack<PuzzleNode> puzzleStack = new Stack<PuzzleNode>();
puzzleStack.push(initialNode);
HashSet<PuzzleNode> visitedPuzzles = new HashSet<PuzzleNode>();
int[][] goalState = initialNode.getGoalState();
for(PuzzleNode pn : initialNode.childrenPuzzles)
{
pn.generateChildren();
puzzleStack.push(pn);
}
while(!puzzleStack.isEmpty())
{
PuzzleNode temp = puzzleStack.pop();
temp.generateChildren();
LinkedList<PuzzleNode> childrenPuzzles = temp.childrenPuzzles;
if(Arrays.deepEquals(temp.getPuzzleState(), goalState))
{
System.out.println("CURRENT STATE: ");
temp.printPuzzleState();
temp.findCompletePathFromRoot();
break;
}
else
{
if(!visitedPuzzles.contains(temp))
{
for(PuzzleNode pn : childrenPuzzles)
{
pn.generateChildren();
puzzleStack.push(pn);
}
temp.setPuzzleNodeVisited();
temp.printPuzzleState();
}
}
}
}
这是generateChildren方法:
public void generateChildren()
{
for(int i = 0; i < 4; i++)
{
PuzzleNode temp = new PuzzleNode(puzzleState, this);
if(temp.moveBlank(i) == true)
{
System.out.println("I:" + i); //diag
childrenPuzzles.add(temp);
temp.printPuzzleState(); //diag
}
}
}
另外,这里是moveBlank:
public boolean moveBlank(int whichDirectionToMove)
{
//0 = left, 1 = right, 2 = up, 3 = down
boolean[] placesToMove = getMovableBlankPositions();
if(placesToMove[whichDirectionToMove] == false)
return false;
//DIAG
System.out.println("************************************");
//DIAG
switch(whichDirectionToMove)
{
case 0: //left
{
int temp = puzzleState[blankRow][blankCol - 1];
puzzleState[blankRow][blankCol - 1] = 0;
puzzleState[blankRow][blankCol] = temp;
blankCol--;
movementType = "move blank left";
// DIAG
System.out.println("moved blank left");
// DIAG
break;
}
case 1: //right
{
int temp = puzzleState[blankRow][blankCol + 1];
puzzleState[blankRow][blankCol + 1] = 0;
puzzleState[blankRow][blankCol] = temp;
blankCol++;
movementType = "move blank right";
// DIAG
System.out.println("moved blank right");
// DIAG
break;
}
case 2: //up
{
int temp = puzzleState[blankRow - 1][blankCol];
puzzleState[blankRow - 1][blankCol] = 0;
puzzleState[blankRow][blankCol] = temp;
blankRow--;
movementType = "move blank up";
// DIAG
System.out.println("moved blank up");
// DIAG
break;
}
case 3: //down
{
int temp = puzzleState[blankRow + 1][blankCol];
puzzleState[blankRow + 1][blankCol] = 0;
puzzleState[blankRow][blankCol] = temp;
blankRow++;
movementType = "move blank down";
// DIAG
System.out.println("moved blank down");
// DIAG
break;
}
}
return true;
}
实质上,移动空白的值为0-3,其中:0 =左,1 =右,2 =上,3 =下。 PuzzleNode类包含潜在移动的链接列表。此列表称为childrenPuzzles,并在调用generateChildren()方法时更新。 getMovableBlankPositions()返回一个4索引bool数组,其指示(和t / f值)确定是否可以使用这些方向上的空格。 BFS工作得很好,它是无限循环的DFS。有什么建议?
答案 0 :(得分:0)
这里的主要问题是你正在使用相同的puzzleState数组来制作子节点,这是错误的方法,因为每次创建子节点时都会修改相同的引用,并且所有子节点最后都会有相同的puzzleState。
注意: - 要解决此问题,您必须使用新的puzzleState数组来创建子项。