我正在使用DFS制作一个迷宫求解器,我想为它实现搜索树,但我对人工智能有点新意,我想在这个问题上提供一些帮助。
首先让我举一个迷宫示例:
char maze[5][9] =
"#########",
"# # #",
"# ## # #",
"# # #",
"#########",
所以我的DFS搜索树应该是这样的:
"#########",
"#12#15 10 11 #",
"#3##14 9 #12 #",
"#456 7 8 #13 #",
"#########",
父母的第一个孩子 - >右侧单元格如果为空
父母的第2个孩子 - >底部单元格如果为空
父母的第3个孩子 - >左侧单元格如果为空
父母的第4个孩子 - > Top Cell如果为空
我的解算器会收到我的迷宫阵列作为参数。我的问题是这些:
第一个问题:这实际上是我的演员要访问节点的方式吗?
第二个问题:在代码中,我需要声明15为10的孩子吗? (在其他情况下,如9和14)
第3个问题:当我的求解器接收到数组时,我是否需要对数组进行预处理并从数组中构造树或者我的演员在他去的时候构建它?
答案 0 :(得分:2)
我还假设“如果解决方案树中已包含节点,那么它是否已在树中”?因为这确实有帮助。
通常情况下,树是隐式的,您只构建实际访问的树的部分,通常在回滚时将其撕下来。
您的求解器会跟踪树中的当前步骤。您可能还想跟踪您在迷宫中探索过的细胞。如果迷宫只有#
和个字符,请使用
*
表示您已访问此求解程序中的单元格。
你从某个地方开始。如果该位置有效,则使用*
对其进行标记,这样您就不会再回到它,并将该位置(例如(1,1)
)添加到路径的“堆栈”中。
现在,您遵循上面写的规则。检查当前位置下的单元格。它是空的吗? (不是#
或*
)如果是,请递归,询问是否找到出路。
如果它找到了出路,请走它找到的路径,在你的当前节点前面,然后返回那条路径。
如果没有,则搜索下一个相邻的单元格(按上面的顺序)。
最后,使用调用它的函数包装上面的递归例程,然后从地图中删除*
标记。
您走的树是隐式编码的。构建树会强制您访问每个节点,而您只想构建必须的部分。
这可以通过多种方式进行优化。您可以通过处理它的“鬼”副本来避免写入地图。您可以通过将堆栈传递给递归版本来避免前置,递归版本会在失败时小心删除任何额外节点,如果成功则将其保留为开启状态。或者你可以使用一个真正的堆栈,并使用一个包装函数对向后进行编码,该函数(在完成所有工作之后)反转路径,使其处于更传统的顺序。