深度首先搜索无限循环代码

时间:2015-03-26 13:15:33

标签: java infinite-loop depth-first-search

我正在尝试解决传教士和食人族问题,我正在尝试实施DFS算法以找到最佳解决方案。不幸的是,这段代码带我进入无限循环,我不明白为什么。有人可以帮忙吗?谢谢!

import java.util.*;

public class DFS3 { 

    public State2 exec(State2 root) {       
        if (root==null)
            return null;

        Stack<State2> stack = new Stack<State2>();
        Set<State2> visitedNodes = new HashSet<State2>();
        //Add the root to the stack
        stack.push(root);

        while(!stack.isEmpty()) 
        {
            State2 n = stack.pop();
            //Check to see if node n is the requested node
            if(n.isGoal())          
                return n;
            else
            {
                //Create an array of the leaf nodes to node n
                List<State2> children = n.generateSuccessors();
                for(int i =0; i<children.size(); i++)
                {
                    //Add the leaf nodes to the stack
                    if ( !visitedNodes.contains(children.get(i)) ) {
                        stack.push(children.get(i));
                        visitedNodes.add(children.get(i));
                    }                
                    System.out.println(stack.peek());
                }
            }
        }
        //Not found so return null
        return null;
   }
}

这就是我如何产生新的成功者。

public List<State2> generateSuccessors() {
        List<State2> successors = new ArrayList<State2>();
        if (boat == Position.LEFT) {//la dreapta
            testAndAdd(successors, new State2(cL, mL - 2, Position.RIGHT,
                    cR, mR + 2)); // 2 misionari stanga-dreapta
            testAndAdd(successors, new State2(cL - 2, mL, Position.RIGHT,
                    cR + 2, mR)); // doi canibali stanga-dreapta
            testAndAdd(successors, new State2(cL - 1, mL - 1, Position.RIGHT,
                    cR + 1, mR + 1)); // un misionar si un canibal stanga-dreapta
            testAndAdd(successors, new State2(cL, mL - 1, Position.RIGHT,
                    cR, mR + 1)); // un misionar stanga-dreapta
            testAndAdd(successors, new State2(cL - 1, mL, Position.RIGHT,
                    cR + 1, mR)); //un canibal
        } else { //la stanga
            testAndAdd(successors, new State2(cL, mL + 2, Position.LEFT,
                    cR, mR - 2)); 
            testAndAdd(successors, new State2(cL + 2, mL, Position.LEFT,
                    cR - 2, mR)); 
            testAndAdd(successors, new State2(cL + 1, mL + 1, Position.LEFT,
                    cR - 1, mR - 1)); 
            testAndAdd(successors, new State2(cL, mL + 1, Position.LEFT,
                    cR, mR - 1)); 
            testAndAdd(successors, new State2(cL + 1, mL, Position.LEFT,
                    cR - 1, mR)); 
        }
        return successors;
    }

    private void testAndAdd(List<State2> successors, State2 newState) {
        if (newState.isValid()) {
            newState.setParentState(this);
            successors.add(newState);
        }
    }

1 个答案:

答案 0 :(得分:0)

看起来这个算法对我有用。

import java.util.*;    

public class DFS2 {
    public static State2 exec(State2 root) {

        boolean found = false; 
        List<State2> visited = new ArrayList<State2>(); 
        Stack<State2> toVisit = new Stack<State2>(); 
        toVisit.push(root);
        while (!toVisit.isEmpty() && !found) {
            State2 nod = toVisit.pop();
            visited.add(nod);

            if (nod.isGoal()) { 
                found = true;               
                return nod;
            }
            else { 
                List<State2> copii=new ArrayList<State2>();
                List<State2> children = new ArrayList<State2>();
                children = nod.generateSuccessors();
                for(int i =0; i<children.size(); i++)
                {
                    //Add the leaf nodes to the stack
                    if ( !visited.contains(children.get(i)) )               
                            copii.add(children.get(i));
                }
                toVisit.addAll(0, copii);
            }
        }
       return null;
}
}