【问题标题】:Same result for two arrays of counters of different algorithms不同算法的两个计数器数组的结果相同
【发布时间】:2016-10-31 18:09:26
【问题描述】:

我正在尝试构建一个程序,在 15 人游戏中比较算法 BFS、DFS、A*(具有两个启发式)的笔画数。

我的计数器对 BFS 和 DFS 以及 A* 的两个计数器数组的计数相同。然而,我实际上使用了来自主(项目类)的四个不同数组,并且我为这些笔画分配了四个不同的变量。

在我看来,不正确的代码部分是一个 while 循环,它尽可能地探索一个顶点的儿子(对于 BFS)或发现每个后续节点(对于 BFS)。最重要的区别是代码的最后一行是 frontier.push(child);,对于 DFS,或 frontier.add(child);用于 BFS。

每进入循环,笔画数就递增一次

number_of_strokes_DFS+=1;

number_of_strokes_BFS+=1;

当我们找到最终状态时,我们将结果添加到笔画数数组中:

array_number_of_strokes_dfs.add(number_of_strokes_DFS);

array_number_of_strokes_bfs.add(number_of_strokes_BFS);

最后是有罪的代码(实际上只有 DFS,因为 BFS 真的很像,除了最后一行)。

 while(!frontier.isEmpty()){
        number_of_strokes_DFS+=1;
     if(System.currentTimeMillis()-startTime>10000)break;
     // We remove the current state from the frontier
     current_state = frontier.pop();
     // We get all possible actions from the current state
     actions = current_state.getActions();
     // We add the current state to already explored nodes
     explored_nodes.add(current_state);
     //System.out.println(current_state);
     path.add(current_state);

     // we found the goal
     if(goal_test(current_state)){
         /*for(State visited :path){
         System.out.println(visited);
     }*/
            array_number_of_strokes_dfs.add(number_of_strokes_DFS);
         System.out.println("nombres de coups DFS"+number_of_strokes_DFS);
         number_of_strokes_DFS=0;
         return current_state;
     }

     // We create every child
     for (Action action : actions){
         //System.out.println("action : " + action);
         // we get a child from the execution of the current_state
         State child = current_state.execute(action);
         //System.out.println("we executed the action");
         if(!explored_nodes.contains(child)&&!frontier.contains(child)){
             // This child not being already explored nor int the frontier we add it to the last one
             frontier.push(child);
         }
     }

 }
    array_number_of_strokes_dfs.add(-1);

    return finalState;

}

当我让 array_number_of_strokes_dfs.add(number_of_strokes_DFS); 时,这是实际问题,例如,我总是得到与数组中的 BFS 相同的结果。它可能发生一次,但不是每次都发生! 而如果我添加一个零

array_number_of_strokes_dfs.add(0);

我确实看到了区别......

你有什么想法吗?

结果如下:

strokes BFS : [3, 27, 27, 26, 26, 2631, 7]
strokes DFS[3, 27, 27, 26, 26, 2631, 7]

【问题讨论】:

  • frontier 的类型是什么?
  • @Ishamael 嗨!它是一个状态堆栈Stack<State> frontier = new Stack<State>(); 它写在我在算法函数中显示的循环的上方。

标签: java arrays algorithm breadth-first-search depth-first-search


【解决方案1】:

如果frontierStack 或类似的东西,那么add 类似于push,所以你的BFS 实际上也在进行深度优先搜索。如果您确实想在开头插入(如果您在每次迭代中使用pop 元素,您想要做的事情),您想调用.add(0, elem)(注意0 - 要插入的索引)而不是.add(elem),这样实际上是在开头插入的。

【讨论】:

  • 非常感谢!对于两个 A* 算法,我有一个类似的问题,其中放置了错误的瓷砖数量和曼哈顿距离启发式。我应该再问一个问题吗?
  • 可以确定的是,DFS 必须使用第一个找到的节点进行搜索,因此必须使用 .add(0, elem),不是吗?
  • 不是你的情况。请注意,在每次迭代中,您都会从堆栈中弹出。弹出获取最后一个元素。对于 dfs,您希望首先处理新元素,因此您需要将它们添加到末尾(推送)。对于 bfs,您希望它们最后被处理,因此您需要将它们添加到开头(在位置 0 处添加)
  • 关于A*,原因很可能不同,所以单独报价是有意义的
  • 好的,我会的!我想知道使用带有添加和删除的队列是否对 BFS 有意义?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-19
  • 1970-01-01
  • 2022-01-09
  • 1970-01-01
相关资源
最近更新 更多