Java 使用DFS优化解决8个难题

Java 使用DFS优化解决8个难题,java,artificial-intelligence,stack-overflow,depth-first-search,Java,Artificial Intelligence,Stack Overflow,Depth First Search,我正在使用Java来解决使用DFS的8字难题 这就是我想到的: public static boolean found = false; public void solveDepthFirst(EightPuzzle currentState, int lastMove){ if(currentState.goal()){ System.out.println(currentState);

我正在使用Java来解决使用DFS的8字难题

这就是我想到的:

    public static boolean found = false;

        public void solveDepthFirst(EightPuzzle currentState, int lastMove){

            if(currentState.goal()){
                System.out.println(currentState);
                found = true;//to stop DFS when a solution is found (even if not optimal)
                return;
            }

            for(int i=0;i<numMoves;++i){
                if(found) return;

                EightPuzzle e = currentState.move(i);//0 = up, 1 = down, 2 = left, 3= right

                if(!e.equals(currentState) && i != lastMove
                        && !visitedNodes.contains(e.toString())){
                    solveDepthFirst(e, i);  
                }           
                     if(!visitedNodes.contains(currentState.toString())){
                visitedNodes.add(currentState.toString());
                     }
            }
        }
public static boolean found=false;
公共无效solveDepthFirst(EightPuzzle currentState,int lastMove){
if(currentState.goal()){
System.out.println(当前状态);
found=true;//在找到解决方案时停止DFS(即使不是最优的)
返回;
}

对于(int i=0;i我认为,在继续递归调用之前标记已访问的状态,可以大大加快搜索速度。除此之外,此谜题没有太多优化:您只需尝试所有可能的移动。

首先,您可以创建堆栈而不是递归调用。 将最后一步添加到EightPuzzle类

这就是你得到的:

// Queue<EightPuzzle> queue = new PriorityQueue<EightPuzzle>();
Stack<EightPuzzle> stack = new Stack<EightPuzzle>();

public void solveDepthFirst() {

    while (true) {
        EightPuzzle currentState = stack.pop(); // queue.poll();
        if (currentState.goal()) {
            System.out.println(currentState);
            found = true;// to stop DFS when a solution is found (even if
                            // not
                            // optimal)
            return;
        }

        for (int i = 0; i < 4; ++i) {
            if (found)
                return;

            EightPuzzle e = currentState.move(i);// 0 = up, 1 = down, 2 =
                                                    // left,
                                                    // 3= right

            if (!e.equals(currentState) && i != currentState.getLastMove()
                    && !visitedNodes.contains(e)) {
                stack.push(e); // queue.add(e);
            }
            if (!visitedNodes.contains(currentState.toString())) {
                visitedNodes.add(currentState);
            }
        }
    }
}
//Queue Queue=new PriorityQueue();
堆栈=新堆栈();
公共部门部门部门优先(){
while(true){
EightPuzzle currentState=stack.pop();//queue.poll();
if(currentState.goal()){
System.out.println(当前状态);
found=true;//在找到解决方案时停止DFS(即使
//不是
//(最佳)
返回;
}
对于(int i=0;i<4;++i){
如果(找到)
返回;
EightPuzzle=currentState.move(i);//0=向上,1=向下,2=
//左,,
//3=对
如果(!e.equals(currentState)&&i!=currentState.getLastMove()
&&!visitedNodes.contains(e)){
stack.push(e);//queue.add(e);
}
如果(!visitedNodes.contains(currentState.toString())){
visitedNodes.add(当前状态);
}
}
}
}
当使用递归调用而不是迭代设计时,性能会显著下降

之后,您可以使用PriorityQueue进一步优化(但它不是真正的DFS)。使用的启发式方法可以是曼哈顿距离。这样,要搜索的第一个解决方案最接近目标。它更有效,但不严格DFS