Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 无法确定我的IDA*实现是否存在缺陷或效率低下_Java_Search_Artificial Intelligence_Sliding Tile Puzzle - Fatal编程技术网

Java 无法确定我的IDA*实现是否存在缺陷或效率低下

Java 无法确定我的IDA*实现是否存在缺陷或效率低下,java,search,artificial-intelligence,sliding-tile-puzzle,Java,Search,Artificial Intelligence,Sliding Tile Puzzle,我实现了迭代深化a-star搜索(用于8字谜问题,但可以接受其他问题),并在输入上运行它。它运行了两个小时都没有成功。对于接近目标节点的简单输入,它可以正常工作。其他人已经为这一投入工作。我不确定我的实现是效率低下还是陷入无限循环 java$ida /** Accepts start node root and string identifying whihc heuristic to use * h1 is number of misplaced tiles and h2

我实现了迭代深化a-star搜索(用于8字谜问题,但可以接受其他问题),并在输入上运行它。它运行了两个小时都没有成功。对于接近目标节点的简单输入,它可以正常工作。其他人已经为这一投入工作。我不确定我的实现是效率低下还是陷入无限循环

java$ida

    /** Accepts start node root and string identifying whihc heuristic to use
      * h1 is number of misplaced tiles and h2 is Manhattan distance
      */
    private Node ida(Node root, final String h) {
     PriorityQueue<DNode> frontier = new PriorityQueue<DNode>(10, new Comparator<DNode>(){
        @Override
        public int compare(DNode n1, DNode n2) {
            if(h == "h1") {
                if(n1.depth + h1(n1.node) > n2.depth + h1(n2.node)) return 1;
                if(n1.depth + h1(n1.node) < n2.depth + h1(n2.node)) return -1;
                return 0;
            }
            if(h == "h2") {
                if(n1.depth + h2(n1.node) > n2.depth + h2(n2.node)) return 1;
                if(n1.depth + h2(n1.node) < n2.depth + h2(n2.node)) return -1;
                return 0;
            }
            return 0;
        }});
    ArrayList<Node> explored = new ArrayList<Node>();
    Node soln = null;
    DNode start = new DNode(root, 1);
    frontier.add(start);
    int d = 0;
    int flimit = (h == "h1" ? h1(start.node) : h2(start.node));
    int min = flimit;
    while(true) {
        DNode dn = frontier.poll();
        if(dn == null) {
            frontier.add(start);
            d = 0;
            flimit = min;
            continue;
        }
        d = dn.depth;
        Node n = dn.node;
        //n.print();
        if(goalCheck(n)){
            return n;
        }
        for(int i = 0;i < ops.length;i++) {
            String op = ops[i];
            if(n.applicable(op)) {
                soln = n.applyOp(op);
                int h_cost;
                if(h == "h1") h_cost = h1(soln);
                else h_cost = h2(soln);
                if(!checkDup(explored,soln) && d + 1 + h_cost < flimit) {
                    frontier.add(new DNode(soln, d + 1));
                    DNode least = frontier.peek();
                    min = least.depth + (h == "h1" ? h1(least.node) : h2(least.node));
                }
            }
        }
        explored.add(n);
        max_list_size = Math.max(max_list_size, frontier.size() + explored.size());
    }
}
目标国:

1 3 4 
8 6 2 
7 - 5
(曾为1438670752工作) 我没有包括Node.java,因为我非常确定它在运行其他搜索算法(如best first、dfs)后可以工作。很难提供SCCE,所以我只是想寻求帮助,找出ida实现中任何明显的错误


编辑:已解决问题,但仍试图在无法达到目标时确定终止条件。IDA*没有保存已探索节点的列表,因此我如何知道我是否已覆盖了整个解决方案空间?

您的
checkDup
功能效率非常低。我建议使用
哈希集
: 您的函数在集合的大小上具有线性成本,而
HashSet的
contains
方法具有恒定成本

java中的字符串与
equals
进行比较:


可能还有其他问题,但这是我在快速检查您的代码后发现的两个最明显的问题。

我计算新flimit的方法有一个错误。在其他情况下,它并没有引起问题,因为后继对象的限制不会导致它无限循环。此外,条件f(当前节点)n2.depth+h1(n2.node))应返回1; if(n1.depth+h1(n1.node)n2.depth+h2(n2.node))返回1; if(n1.depth+h2(n1.node)如果(d+1+h_按照建议使用哈希集并进行尝试会产生成本。我不是在比较字符串,而是比较整数,因此这不是一个bug。强制性的8字谜注释:请注意,只有一半的开始状态是可解的,在考虑调试代码之前,请确保您没有尝试解决其中一个。是的,目标节点是rea夏布利斯:这是一个十字柱吗。
1 2 3 
8 - 4
7 6 5
1 3 4 
8 6 2 
7 - 5
private Node ida(Node root, final String h) {
    PriorityQueue<DNode> frontier = new PriorityQueue<DNode>(10, new Comparator<DNode>(){
        @Override
        public int compare(DNode n1, DNode n2) {
            if(h == "h1") {
                if(n1.depth + h1(n1.node) > n2.depth + h1(n2.node)) return 1;
                if(n1.depth + h1(n1.node) < n2.depth + h1(n2.node)) return -1;
                return 0;
            }
            if(h == "h2") {
                if(n1.depth + h2(n1.node) > n2.depth + h2(n2.node)) return 1;
                if(n1.depth + h2(n1.node) < n2.depth + h2(n2.node)) return -1;
                return 0;
            }
            return 0;
        }});
    ArrayList<Node> explored = new ArrayList<Node>();
    Node soln = null;
    DNode start = new DNode(root, 1);
    frontier.add(start);
    int d = 0;
    int flimit = (h == "h1" ? h1(start.node) : h2(start.node));
    int min = flimit;
    while(true) {
        DNode dn = frontier.poll();
        if(dn == null) {
            explored.clear();
            frontier.add(start);
            d = 0;
            flimit = min;
            continue;
        }
        d = dn.depth;
        Node n = dn.node;
        //n.print();
        if(goalCheck(n)){
            return n;
        }
        min = Integer.MAX_VALUE;
        for(int i = 0;i < ops.length;i++) {
            String op = ops[i];
            if(n.applicable(op)) {
                soln = n.applyOp(op);
                int h_cost;
                if(h == "h1") h_cost = h1(soln);
                else h_cost = h2(soln);
                if(!checkDup(explored,soln))    {
                    if(d + 1 + h_cost <= flimit) {
                        frontier.add(new DNode(soln, d + 1));
                    }
                    else {
                        if(d + 1 + h_cost < min)min = d + 1 + h_cost; 
                    }
                }
            }
        }
        explored.add(n);
        max_list_size = Math.max(max_list_size, frontier.size() + explored.size());
    }
}