俄罗斯方块AI - 解释广度优先搜索问题

时间:2013-05-29 20:55:27

标签: java algorithm breadth-first-search

我正在将俄罗斯方块作为一个有趣的侧面项目(不是家庭作业),并希望实现AI,以便计算机可以自己玩。我听说这样做的方法是使用BFS搜索可用的位置,然后创建最合理的放置位置的总分...

但我无法理解算法。到目前为止,我理解的方式是:

1)将节点添加到ArrayList

  • nodeList.add(n nodes)

2)连接节点

  • 使用邻接矩阵:adjMatrix[sizeOfNodeList][sizeOfNodeList]
  • 传递节点进行连接:例如connectNode(nodeA, nodeB);,其中调用:connectNode(Node from, Node to)

    int fromNode=nodesList.indexOf(from);
    int toNode=nodesList.indexOf(to);
    
    //connect node A to B and B to A, set that i,j position = 1
    adjMatrix[fromNode][toNode]=1;
    adjMatrix[toNode][fromNode]=1;
    

enter image description here

在邻接矩阵中连接节点后......

3)循环遍历节点队列,并将访问者添加到队列

  • 创建新队列:Queue q = new LinkedList();
  • rootNode添加到队列:q.add(rootNode)
  • 将已访问的标记设置为true:rootNode.visited(true)

这是我不理解的部分......

  • 当队列不为空时......您应该创建一个新节点并将其设置为等于Queue的已移除节点:Node n = (Node)q.remove()

但是如果您要向其添加节点q.add(rootNode)q.add(child),那么什么时候它会变空?

  • 接下来,检查子节点=未访问的子节点并且不为空,while((child=getUnvisitedChildNode(n))!=null),您应该更改子访问状态= true,然后将其添加到队列{{1} } ...但你不是在做这一切q.add(child)吗?那么,如果您要添加while(!q.isEmpty()),那么它什么时候会为空呢?

我的队列q的目的是什么?是结果队列吗?

由于

2 个答案:

答案 0 :(得分:3)

您的队列q包含您尚未访问过的节点。您应该只添加尚未访问过的队列q节点。这样它就会变空,你已经探索过的节点不会重新进入列表。

以图片为例,您只能使用节点q启动A。您将A标记为已访问。这就是你的开始。

您的循环将包括删除队列q上的第一个节点,在本例中为A,并添加所有连接到A且尚未连接的节点访问了。换句话说,您将遍历A矩阵的行,并发现BCD已连接到A。对于每个人,如果visited()返回false,则会将其添加到q并标记为已访问。在此次传递中,qBCD,而A-D的所有q都将被访问过()为真。

在下一次迭代中,B上的第一个节点将为A。您将对其进行出列,并将其与EFA相关联。由于true在您致电visited()时会返回q,因此您不会将其添加到E。将添加FC并将其标记为已访问。

如果您继续,则会将DEFq出列,而不会向q.isEmpty()添加任何内容,因为所有节点都已经被访问过。之后,true将返回{{1}}并且您的循环结束。

答案 1 :(得分:1)

队列是您的待办事项列表。它是接下来要处理的节点列表。

当您在树/图的叶子上处理完要处理的子项时,队列将变为空。