标准8拼图深度优先搜索

时间:2013-12-05 03:13:29

标签: java algorithm search graph

我正在使用标准的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。有什么建议?

1 个答案:

答案 0 :(得分:0)

这里的主要问题是你正在使用相同的puzzleState数组来制作子节点,这是错误的方法,因为每次创建子节点时都会修改相同的引用,并且所有子节点最后都会有相同的puzzleState。

注意: - 要解决此问题,您必须使用新的puzzleState数组来创建子项。