|
|
1
154
你可以把迷宫想象成一棵树。 A
/ \
/ \
B C
/ \ / \
D E F G
/ \ \
H I J
/ \
L M
/ \
** O
(which could possibly represent)
START
+ +---+---+
| A C G |
+---+ + + +
| D B | F | J |
+---+---+ +---+---+
| L H E I |
+---+ +---+---+
| M O |
+ +---+
FINISH
(ignoring left-right ordering on the tree)
其中每个节点都是路径的连接点。D、I、J、L和O是死胡同,目标是**。 当然,在实际的树中,每个节点都有可能拥有 三 孩子们。 现在,您的目标只是找到要遍历哪些节点才能找到完成点。任何一种树搜索算法都可以。 从树的最深处的**可以很容易地看到正确的解决方案:
注意,这种方法 只有轻微 更复杂的是,当你在迷宫中有“循环”(也就是说,如果可能的话,没有回溯,你就重新进入一个你已经穿过的通道)。检查注释以获得一个好的解决方案。 现在,让我们看看您提到的第一个解决方案,应用于此树。 您的第一个解决方案基本上是 Depth-First Search 这还不错。实际上这是一个很好的递归搜索。基本上,它说,“总是先采用最右边的方法。如果什么都没有的话,回溯到第一个地方,你可以直行或左行,然后重复。 深度优先搜索将按以下顺序搜索上述树:
请注意,找到**后可以立即停止。 但是,当您实际对深度优先搜索进行编码时,使用 递归编程 使一切变得更容易。即使是迭代方法也可以工作,而且您永远不必显式地编程如何回溯。查看链接的文章以了解实现。 另一种搜索树的方法是 Breadth-First 解决方案,按深度搜索树。它将按以下顺序搜索上面的树:
请注意,由于迷宫的性质,宽度优先检查节点的平均数量要高得多。宽度优先是很容易实现的,它有一个要搜索的路径队列,每次迭代都会从队列中弹出一条路径,“分解它”,方法是在一个步骤之后获取它可以转化为的所有路径,并将这些新路径放在队列的末尾。没有明确的“下一级”命令来编码,而这些命令只是用来帮助理解。 事实上,有一个整体 expansive list of ways to search a tree . 我刚刚提到了两种最简单、最直接的方法。 如果你的迷宫非常,非常长和深,并且有环形和疯狂,并且很复杂,我建议 A* 算法,这是行业标准的寻路算法,它结合了广度优先搜索和启发式搜索…有点像“智能广度优先搜索”。 它基本上是这样工作的:
那就是 A* 这是我特别强调的,因为它或多或少是行业标准的寻路算法 全部的 寻路的应用,包括从地图的一个边缘移动到另一个边缘,同时避开非公路路径或山脉等。由于它使用了 最短可能距离启发式 这给了它“智慧”。A*是如此的通用,因为在任何问题上,如果你有一个最短的可能距离启发式可用(我们的是容易的——直线),你可以应用它。 但是 值得注意的是 不 你唯一的选择。 事实上, wikipedia category of tree traversal algorithms 仅列出97个!(最好的仍然在 this page 链接较早) 对不起,长度=P(我喜欢闲聊) |
|
|
2
13
有很多迷宫求解算法: http://en.wikipedia.org/wiki/Maze_solving_algorithm http://www.astrolog.org/labyrnth/algrithm.htm#solve 对于机器人来说, Tremaux's algorithm 看起来很有前途。 |
|
|
3
11
一个有趣的方法,至少我觉得它有趣,是使用细胞自动机。简而言之,由3个“墙”单元包围的“空间”单元变成“墙”单元。在最后,剩下的空间单元只有在通往出口的路线上。 如果你看贾斯汀在他的答案中写的树,你会发现叶节点有三个墙。修剪这棵树直到你有一条路。 |
|
|
4
4
如何从矩阵中构建一个图,并使用广度优先搜索、深度优先搜索或dijkstras算法? |
|
|
5
4
这是我最喜欢的算法之一…
|
|
|
6
3
这是一个非常简单的表示来模拟C++中的迷宫。
|
|
|
7
2
只是一个想法。为什么不以蒙特卡洛的方式在那里扔一些机器人呢?
让我们称第一代僵尸为gen0。
我们只将机器人程序与gen0保持距离,因为gen0有一些连续的道路:
我们在新的随机点中运行一个新的gen1机器人程序,然后我们尝试将gen1机器人程序的道路与gen0机器人程序的道路连接起来,看看我们是否从开始到结束都有一条连续的道路。 所以对于genn,我们尝试连接gen0,gen1,…,genn-1形式的僵尸。 当然,一代人只持续有限的时间。
我不知道该算法的复杂性是否会证明对小数据集是可行的。
|
|
|
8
1
我的大学毕业典礼上也遇到了类似的问题。SCI。课程。我们提出的解决方案是沿着左手边的墙(右手边的墙也会起作用)。这是一些伪代码
基本上就是这样。复杂的部分是跟踪你的面向哪个方向,并根据这个方向找出你左边的网格位置。它适用于我提出的任何测试用例。有趣的是,教授们的解决方案是:
这对于大多数简单的迷宫都很有效,但在如下迷宫中失败:
以S和E为起点和终点。 如果有什么东西跟不上墙,你就得把你去过的地方列一个清单,这样当你陷入死胡同时,你可以在必要的时候回溯,这样你就不会陷入循环。如果你沿着墙走,就没有必要跟踪你去过的地方。虽然你找不到穿过迷宫的最佳路径,但你总能通过迷宫。 |
|
|
9
1
如果机器人能跟踪到它的位置,那么它就知道它以前是否去过某个位置,那么深度优先搜索就是显而易见的算法。您可以通过一个敌对的论点来证明,不可能比深度优先搜索获得更好的最坏情况性能。 如果你可以使用机器人无法实现的技术,那么广度优先搜索对于许多迷宫可能会更好,就像Dijkstra在图中找到最短路径的算法一样。 |
|
|
10
1
有很多算法,很多 不同的设置 指定哪种算法是最好的。 这只是一个关于有趣环境的想法: 假设您具有以下属性…
然后你可以设计一个自动识别系统…
|
|
|
11
0
与所有有关堆栈溢出的问题的答案相同;) 使用vi! http://www.texteditors.org/cgi-bin/wiki.pl?Vi-Maze 看到一个文本编辑器解决一个ASCII迷宫真的很有意思,我相信Emacs的人有一个等价物。 |
|
|
12
0
|
|
|
13
0
求解迷宫的最佳方法是使用连通性算法,如联合查找(union find),它是假设路径压缩完成的准线性时间算法。 联合查找是一种数据结构,它告诉您一个集合中的两个元素是否是可传递连接的。 为了利用联合查找数据结构来解决迷宫问题,首先利用邻接数据构建联合查找数据结构。然后压缩联合查找。为了确定迷宫是否可解,对入口和出口值进行了比较。如果它们有相同的值,那么它们是相连的,迷宫是可解的。最后,为了找到一个解决方案,您从入口开始,并检查与每个邻居关联的根。一旦找到与当前单元格具有相同根目录的以前未访问的邻居,就访问该单元格并重复该过程。 这种方法的主要缺点是,如果有多条路径,它不会告诉你迷宫中最短的路径。 |
|
|
14
0
不是专门针对您的情况,但我在发现 Lee's algorithm 很容易快速编码。它不是所有情况下最有效的,但很容易启动。这里是 one 我参加了一个竞赛。 |
|
|
daign · 在三种墙的简单迷宫中走动的数据结构 8 年前 |
|
|
RADMRA · 使用2D数组和堆栈在java中构建迷宫 9 年前 |
|
|
Madmenyo · 递归回溯迷宫有时会留下瓦片 11 年前 |
|
|
Rbutler93 · 是否可以将结构存储到链接列表中? 11 年前 |