迭代深化搜索Java实现

时间:2017-04-25 16:54:37

标签: java algorithm search nodes iterative-deepening

我一直在尝试用Java实现Iterative Deepening Search。但是,由于某些原因,并非所有子节点都被访问,导致结果不正确。到目前为止,这是我的代码:

public int IDS(Node start, Node goal){
        int depth = 0; //set starting depth to 0
        Node current=start; //current node is equal to start
        int goalNode=0; //goalNode is originally set to 0
        //List<Node> tempList=new ArrayList<Node>();

        while(goalNode==0){ //while goalNode is equal to 0
            List<Node> visited=new ArrayList<Node>(); //create an array list of nodes
            goalNode=DLS(current, goal, depth, visited); 
            depth++; //increment the depth
        }
        System.out.println("RESULT");
        return goalNode;
    }

    public int DLS(Node current, Node goal, int depth, List<Node> visited){
        if(depth>=0){
            if ( current == goal ){ //stop program
                System.out.println("REACHED GOAL");
                return current.value;
            }else{
                visited.add(current); //add the current node to visited list (in the beginning =start)

                List<Node> temp = Adjacency_List.get(current.value); //get children of current node

                for(Node node: temp){ //for each child
                    System.out.println("Current Node: "+current.value);
                    System.out.println(current.value + " - " + node.value);
                    if(node != null && !visited.contains(node)){
                        //tempList.add(node);
                        return DLS(node, goal, depth-1, visited);
                    }
                }
            }
        }else{
            return 0;
        }
        return 0;
    }

1 个答案:

答案 0 :(得分:1)

因此,您尝试实施的算法是Iterative deepening depth-first search

首先,DLS方法中的第一行代码可以在最小数量的移动中找到目标状态。

你有:

   if (depth >= 0) {
            if (current == goal) { //stop program
                System.out.println("REACHED GOAL");
                return -1;
            }

如果电流等于目标状态,则希望深度等于0.如果深度大于0,则需要继续搜索相邻节点。

另外,我不确定你为什么要返回一个int,如果你返回Node对象会更有意义,如果它不等于目标则返回null。

DLS:

  public Node DLS(Node current, int depth) {
        if (depth == 0 && current == goal) {
            return current;
        }
        if (depth > 0) {
            for (Node child : current.findNeighbours()) {
                Node found = DLS(child, depth - 1);
                if (found != null) {
                    return found;
                }
            }
        }
        return null;
    }

IDS方法:

  public Node IDS(Node root) {
        // loops through until a goal node is found
        for (int depth = 0; depth < Integer.MAX_VALUE; depth++) {
            Node found = DLS(root, depth);
            if (found != null) {
                return found;
            }
        }
        // this will never be reached as it 
        // loops forever until goal is found
        return null;
    }

总的来说,你提供的答案并不是太遥远,你必须将findNeighbours()更新为用于查找相邻节点的代码。我的示例使用局部变量作为目标状态,这是一个节点对象,当然,如果愿意,您可以将其作为参数传递。

你可以看到这非常接近伪代码:

function IDDFS(root)
    for depth from 0 to ∞
        found ← DLS(root, depth)
        if found ≠ null
            return found

function DLS(node, depth)
    if depth = 0 and node is a goal
        return node
    if depth > 0
        foreach child of node
            found ← DLS(child, depth−1)
            if found ≠ null
                return found
    return null

旁注:

我建议使用IDAstar algorithm

f(node) = g(node) + h(node)

g(node):从起始节点到当前节点的移动量

h(node):估计达到目标状态的动作次数