我在8数码问题上使用了IDA*算法,我的朋友也在这个问题上使用了A*算法(使用相同的曼哈顿距离启发式)。
我计算了我在20个示例上的算法平均值和朋友的算法平均值,我的算法在时间上的平均值比朋友的算法快很多,但我在访问的节点平均值上却比朋友的多很多。
这是怎么可能的?有人能解释一下我哪里没有理解吗?
这是我的搜索算法
public Set<String> ida(Node startNode) { visitedNodes.clear(); Node initNode = startNode; int fValueMin; /*fValueMin是运行程序的深度。 IDA*方法被迭代调用,直到深度达到*/ for (fValueMin = initNode.getfValue(); fValueMin < 100; fValueMin++) { visitedNodes.clear(); pathNodes.clear(); // 深度优先搜索 Node nextNode = dfs(startNode, fValueMin, visitedNodes); /*验证返回的是否为目标状态。如果是目标状态,则退出循环*/ if (nextNode != null && nextNode.equals(CommonConstants.goalState)) { System.out.println("找到目标状态"); System.out.println("访问的节点数:" + visited); return pathNodes.keySet(); } // System.out.println("迭代次数:" + fValueMin); } System.out.println("访问的节点总数:" + visited); return null; }
这是我朋友的搜索算法
private ActionSequence AStar(){ System.out.println("AStar搜索开始"); 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.size+" 深度: "+(current.element.depth+1)+" 价格: "+(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("*******************************找到*******************************************\n\n"); System.out.println("队列: "+queue.size+" 深度: "+(current.element.depth+1)); System.out.println(printState(current.element.state)); System.out.println("\n\n\n"); return Path2Root(current.element); }
回答:
IDA*通过迭代的方式扩展搜索边界,因此许多节点会被访问多次。而A*更偏向于广度优先搜索,根据实现方式的不同,很可能在搜索区域内每个节点只访问一次。这就是为什么IDA*访问的节点比A*多的原因。在运行时间方面,A*需要一个优先队列来引导搜索,其复杂度为NLogN。