【问题标题】:Why IDA* Is Faster Than A* But Why IDA* Visit More Nodes That A*?为什么 IDA* 比 A* 快,但为什么 IDA* 访问的节点比 A* 多?
【发布时间】:2019-12-05 23:56:51
【问题描述】:

我将 ida* 用于 8 拼图,我的朋友也使用 a* (具有相同的曼哈顿距离 huristic)。

我计算了 20 个示例和我朋友算法的算法平均值,我的算法的平均时间比我朋友的算法快得多,但我访问的平均节点比我朋友的要多得多。

这怎么可能?谁能解释一下我不明白的地方。

这是我的搜索算法

public Set<String> ida(Node startNode) {
        visitedNodes.clear();
        Node initNode = startNode;
        int fValueMin;
        /*fValueMin depth to run the program.
        IDA* method being called iteratively until the depth reaches*/
        for (fValueMin = initNode.getfValue(); fValueMin < 100; fValueMin++) {
            visitedNodes.clear();
            pathNodes.clear();
            // Depth First search 
            Node nextNode = dfs(startNode, fValueMin, visitedNodes);
            /*Verifying the returned is goal state or not. If it is goal the goal exit loop*/
            if (nextNode != null && nextNode.equals(CommonConstants.goalState)) {
                System.out.println("Goal state Found");
                System.out.println("Nodes Visited:" + visited);
                return pathNodes.keySet();
            }
            // System.out.println("Iteration:" + fValueMin);
        }
        System.out.println("Number of Nodes Visited:" + visited);
        return null;
    }

这是我朋友的搜索算法

private ActionSequence AStar(){
        System.out.println("AStar Search Started"); 
        boolean find=false; 
        QNode current; 

        do{
            current=queue.removeFirst(); 
            if(queue.size%1==0){
                try{
                    BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(FileDescriptor.out),"ASCII"), 32);

                    out.write("*********************************************************************************\n\n");
                    out.write("Queue: "+queue.size+"    Depth: "+(current.element.depth+1)+"   price: "+(current.price));
                    out.write(printState(current.element.state)); 
                    out.write("\n\n\n");

                    out.flush();
                    //out.close();
            }catch(IOException gg){}
            }

            if(problem.Goal_Test(current.element.state)){
                find=true; 
            }else{
                if(current.element.action!='d'){

                        PSTNode up_child=Expand(current.element,'u'); 
                        if(up_child.state[11]==1){
                            tree.addNodeUp(up_child,  current.element);
                            QNode up_child_qn= new QNode(up_child,null, null);
                            queue.addSort(up_child_qn);
                        }

                }

                if(current.element.action!='u'){

                        PSTNode down_child=Expand(current.element,'d');
                        if(down_child.state[11]==1){
                            tree.addNodeDown(down_child,  current.element);
                            QNode down_child_qn= new QNode(down_child,null, null);
                            queue.addSort(down_child_qn);
                        }

                }

                if(current.element.action!='r'){

                        PSTNode left_child=Expand(current.element,'l');
                        if(left_child.state[11]==1){
                            tree.addNodeLeft(left_child,  current.element);
                            QNode left_child_qn=new QNode(left_child,null, null);
                            queue.addSort(left_child_qn);
                        }

                }


                if(current.element.action!='l'){

                        PSTNode right_child=Expand(current.element,'r');
                        if(right_child.state[11]==1){
                            tree.addNodeRight(right_child,  current.element);
                            QNode right_child_qn= new QNode(right_child,null, null);
                            queue.addSort(right_child_qn);
                        }

                }
            }


        }while(!find); 
        System.out.println("*******************************founded*******************************************\n\n");             
            System.out.println("Queue: "+queue.size+"    Depth: "+(current.element.depth+1)); 
            System.out.println(printState(current.element.state)); 
            System.out.println("\n\n\n");

        return Path2Root(current.element); 
    }

【问题讨论】:

  • 显然,您的实现每单位时间探索更多节点。如果不向我们展示这两种实现的代码,我们就不能说更多了。
  • @kaya3 我编辑了我的答案,但我认为我的问题是 Ida* 的工作。
  • 这些都不可重现;它们都依赖于未在此处声明的变量(例如visitedNodesqueue)和方法。
  • @kaya3 我知道因为我应该声明所有不能在这里完成的变量,但是 ida* 访问的节点比 a* 多吗?如果它访问更多节点,为什么它会更快。
  • 如果您的问题不是关于单个实现,而是关于整个算法,则有一个单独的 Stack Exchange 站点用于理论计算机科学,Computer Science; SO 试图以具体细节为基础,提出狭窄的问题并专注于明确定义的问题。

标签: algorithm search artificial-intelligence


【解决方案1】:

IDA* 迭代打开搜索边界,因此会多次访问许多节点。而 A* 更多地位于 BFS 端,根据实现的不同,您很可能只会访问搜索区域中的每个节点一次。这就是 IDA* 访问的节点比 A* 多的原因。在运行时间方面,A* 需要一些优先级队列来引导搜索,NLogN 的复杂性就在那里。

【讨论】:

  • 在你的解释中,我理解 IDA* 访问每个节点不止一个,但第二部分关于更快,我不明白为什么它比 A* 更快
  • 在A*中,应该有一个优先级队列,用于维护下一级搜索树构建中首先展开哪个节点。每次将某些内容推送到队列时,都需要 LogN 时间来确保优先级队列有效(堆属性)。从理论上讲,两种算法应该具有相同的运行时间复杂度。在实践中,基于 DFS 的 (IDA*) 算法可能会因为实现、缓存的局部性而表现更好。
  • 感谢您的解释。
  • 您能提供学习 IDA* 的资源吗?我更喜欢伪代码,我不想要递归版本。我需要这个来理解它是如何表达的......
猜你喜欢
  • 2014-06-01
  • 1970-01-01
  • 2016-01-06
  • 2015-01-18
  • 2021-02-02
  • 1970-01-01
  • 1970-01-01
  • 2016-06-02
  • 2021-11-24
相关资源
最近更新 更多