【问题标题】:BFS function correctness?BFS 函数正确性?
【发布时间】:2017-02-16 06:33:02
【问题描述】:

问题是使用 bfs 函数构建/找到 peg solitare 游戏的解决方案。给你一个包含起始状态的节点,从这个状态节点扩展成更多的状态(它的子节点)。一旦找到包含目标状态的节点,该函数应该停止。

public void search(){
    bfs.add(StartGoal);
while(!bfs.isEmpty()) {
    node = bfs.poll();  
    if(node.isGoal()){System.out.println("success"); return;}
    node.expand();
    for(MyNode m : node.childs){
        if(!m.isGoal()){
            m.setVisited();
            bfs.add(m);}}
        node.setVisited();
    }

expand 函数,启动子链表并根据下一个可能的棋盘状态创建子节点。

public void expand(){
    if(childs != null) return;//already expanded do nothing
    else{
    childs= new LinkedList<MyNode>();
    for(BoardState b: state.nextStates())
        childs.add(new MyNode(this, b));}   
}

我运行了代码并对其进行了多次改进。一旦队列达到大小 3+ 百万,它会由于空间不足而崩溃。我的问题是:这最终会奏效吗?代码正确吗?

这是我的第一篇文章,如果我在很好地格式化问题时很抱歉。 谢谢。

【问题讨论】:

    标签: algorithm breadth-first-search


    【解决方案1】:

    您的代码不正确。我看到了两个大错误,或者可能是一个具有两个主要后果的大错误和一个小错误。可能还有其他我看不到的错误,肯定还有其他需要改进的地方。第一个错误是

        if(!m.isGoal()){
            m.setVisited();
            bfs.add(m);}}
    

    您明确地从不将目标状态添加到队列中。

    第二个错误是你从不测试一个节点是否被访问过。这可能与第一个错误相同,因为看起来它们可以通过相同的修复来修复:

    if (!m.isVisited()) {
    

    第三个错误是您仅在处理第一个子节点后才标记访问过的节点。如果节点没有子节点,您将永远不会标记访问过的节点,并且如果节点可能将自己作为子节点,您将在扩展父节点之前将子节点添加到队列中。这不会影响结果的正确性,但可能会影响您的效率。

    【讨论】:

      猜你喜欢
      • 2023-04-06
      • 1970-01-01
      • 2012-11-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-03
      • 2022-01-05
      • 1970-01-01
      相关资源
      最近更新 更多