有许多不同的迷宫求解算法,即求解迷宫的自动化方法。随机鼠标、摸墙算法、Pledge和Trémaux的算法被设计为由事先不知道迷宫的旅行者在迷宫内使用,而死胡同填充和最短路径算法被设计为由可以一次看到整个迷宫的人或计算机程序使用。
这是一个朴素的方法,可以由一个非常不聪明的机器人或者一只老鼠来实现。它只是简单地沿着当前的通道前进,直到到达一个交叉点,然后随机决定下一个要遵循的方向。尽管这种方法最终总能找到正确的解决方案,但这种算法可能非常慢。
摸墙算法,穿越迷宫最著名的规则,也称为左手规则或右手规则。如果迷宫是简单连接的,也就是说,它的所有壁都连接在一起或者连接到迷宫的外层边界,那么通过保持一只手与迷宫的一个壁接触,求解器保证不会迷路,并且如果有一个出口,将到达另一个出口;否则,该算法在穿过了与相连的墙段相邻的每个走廊至少一次的情况下将返回到入口。
如果迷宫不是简单连接的(即,如果起点或终点位于由通道环包围的结构的中心,或者路径相互在上方和下方交叉,并且解决方案路径的这些部分被通道环包围),摸墙算法这种方法将无法达到目的。
另一个令人担忧的问题是,在迷宫的入口处应该小心地开始沿着墙走。如果迷宫不是简单连接的,你在迷宫内的任意一点开始沿着墙壁行走,你会发现自己被困在一个单独的墙壁上,墙壁环绕着自己,没有入口或出口。如果摸墙算法开始较晚(从迷宫内部而不是从入口开始),应该尝试标记摸墙算法开始的位置。因为沿着墙走总是会把你带回到你开始的地方,如果你第二次遇到你的起点,你可以得出迷宫不是简单地连接在一起的结论,,你应该换一面还没有沿着墙走的另一面墙。参见下面的Pledge算法,作为摸墙算法的替代方法。
如果更高维的通道可以以确定性的方式投射到2D平面上,则可以在3D或更高维的迷宫中进行摸墙算法。例如,如果在3D迷宫中,可以假设“向上”通道指向西北,而“向下”通道指向东南,则可以应用标准摸墙规则。然而,与2D不同的是,这需要知道当前方向,以确定哪个方向是左边第一个还是右边第一个。
Pledge算法,旨在规避障碍,需要一个任意选择的方向作为优先的方向。当遇到障碍物时,一只手(比如右手)保持沿着障碍物的状态,同时转动的角度被计数(顺时针转动是正的,逆时针转动是负的)。当求解器再次面向原始优先方向,并且转弯的角度和为0时,求解器离开障碍物并继续沿其原始方向移动。
只有当“圈数总和”和“当前航向”都为零时,手才会从墙上移开。这允许算法避免形状像大写字母“G”的陷阱。假设算法在第一面墙左转,并沿着墙绕了整整360度。一个只跟踪“当前航向”的算法会进入一个无限循环,因为它会离开最右边的下壁航向左侧,并再次进入左侧的弯曲部分。Pledge算法不会离开最右边的墙,因为“圈数之和”在该点不为零(注意360度不等于0度)。它一直沿着墙走,最后就在字母形状的下面离开朝着左方出去。
这种算法允许一个带指南针的人从任何有限的二维迷宫的任何内部点找到通往外部出口的路,而不管求解器的初始位置。然而,这种算法在做相反的操作时不起作用,即从迷宫外面的入口找到通往迷宫内某个最终目标的路。
从交叉点开始的路径要么未被走过,要么被标记一次,要么被标记两次。该算法根据以下规则工作:
死胡同填充是一种解决迷宫的算法,它填充所有的死胡同,只留下正确的方法未填充。它可以用于在纸上或计算机程序上解决迷宫,但它对一个未知迷宫中的人没有用处,因为这种方法需要同时观察整个迷宫。方法是1)找到迷宫中的所有死胡同,然后2)从每个死胡同“填充”路径,直到遇到第一个交叉点。请注意,一些通道不会成为死胡同通道的一部分,除非先移除其他死胡同。这里可以看到一段死胡同填充的视频:[1][2]。
死胡同填充不能意外地从终点“切断”起点,因为过程的每一步都保持迷宫的拓扑结构。此外,这个过程不会“太快”停止,因为最终结果不能包含任何死胡同。因此,如果在一个完美的迷宫(没有环的迷宫)上进行死胡同填充,那么只有解决方案会保留下来。如果它是在部分辫子型迷宫(有一些环的迷宫)上完成的,那么所有可能的解决方案都会保留下来,但仅此而已。[3]
如果给出迷宫的全知视图,一个简单的递归算法可以告诉人们如何到达终点。该算法将被赋予一个起始的X和Y值。如果X和Y值不在墙上,该方法将调用所有相邻的X和Y值,确保它以前没有使用过这些X和Y值。如果X和Y值是结束位置的值,它会将该方法的所有先前实例保存为正确的路径。下面是一个Java示例代码:
迷宫路由算法使用曼哈顿距离的概念,并且依赖于网格的属性,当从一个位置移动到任意4个相邻位置时,网格的距离精确地增加/减少1。这是伪代码,没有检测不可到达位置的能力。
Pointsrc,dst;//Sourceanddestinationcoordinates//curalsoindicatesthecoordinatesofthecurrentlocationintMD_best=MD(src,dst);//ItstorestheclosestMDweeverhadtodst//AproductivepathistheonethatmakesourMDtodstsmallerwhile(cur!=dst){if(thereexistsaproductivepath){Taketheproductivepath;}else{MD_best=MD(cur,dst);Imaginealinebetweencuranddst;Takethefirstpathintheleft/rightoftheline;//Theleft/rightselectionaffectsthefollowinghandrulewhile(MD(cur,dst)!=MD_best||theredoesnotexistaproductivepath){Followtheright-hand/left-handrule;//Theoppositeoftheselectedsideoftheline}}
当迷宫有多个解时,求解器可能希望找到从开始到结束的最短路径。有几种算法可以找到最短路径,其中大多数来自图论。一种这样的算法通过实现广度优先搜索来找到最短路径,而另一种算法,A*算法,使用启发式技术。广度优先搜索算法使用队列从开始到到达终点以递增的距离顺序访问单元格。每个被访问的单元都需要记录它与起点的距离,或者哪个更靠近开始的相邻单元导致它被添加到队列中。找到终点位置后,沿着单元格的路径向后回到起点,从而得到最短的路径。最简单形式的广度优先搜索有其局限性,比如在加权图中找到最短路径时。