Algorithm 迷宫中的最短路径 我正在开发一个类似于Pacman的游戏:考虑这个迷宫:

Algorithm 迷宫中的最短路径 我正在开发一个类似于Pacman的游戏:考虑这个迷宫:,algorithm,search,graph-algorithm,dijkstra,Algorithm,Search,Graph Algorithm,Dijkstra,每个白色方块都是迷宫中的一个节点,在迷宫中,位于p(比如X)的对象正以从右到左的方向向节点a移动。X不能切换到相反的方向,除非它遇到一个死端,如a。因此,连接P和B的最短路径通过a,因为X不能将其方向反转到最右边的底部节点(称为C)。通用A*算法将输出: 从p到B,先向右走,然后向上走 这是错误的。所以我想:我可以在运行A*之前将C的visted属性设置为true,然后让算法找到路径。显然,这种方法不适用于链接迷宫,除非我允许它重新发现一些节点(问题是:哪些节点?如何区分无用节点?)。我脑海中闪

每个白色方块都是迷宫中的一个节点,在迷宫中,位于p(比如X)的对象正以从右到左的方向向节点a移动。X不能切换到相反的方向,除非它遇到一个死端,如a。因此,连接P和B的最短路径通过a,因为X不能将其方向反转到最右边的底部节点(称为C)。通用A*算法将输出:

从p到B,先向右走,然后向上走

这是错误的。所以我想:我可以在运行A*之前将C的visted属性设置为true,然后让算法找到路径。显然,这种方法不适用于链接迷宫,除非我允许它重新发现一些节点(问题是:哪些节点?如何区分无用节点?)。我脑海中闪过的第一个想法是:使用前面的方法始终跟踪最后访问的手机;如果结果路径不是空的,则完成。否则,当你到达最后一个访问的死胡同时,比如说Y,(这一步后面是A*的失败)转到Y,然后使用标准A*到达目标(我假设迷宫已连接)。我的问题是:这保证永远有效吗?是否有更有效的算法,例如为此目的修改的a*派生算法?你将如何解决这个问题?如果能给出一个解释最优和非最优搜索技术的答案,我将不胜感激(事实上,我不需要最短路径,稍微长一点的路径是好的,但我想知道是否存在像Dijkstra算法那样高效运行的最优算法;如果存在,与非最优算法相比,它的运行时间是多少?)

编辑对于瓦尔多:我添加了3个单元格,以便概括一点:请告诉我我是否有这个想法:


好问题。我可以提出以下方法

在有向图上使用Dijkstra(或A*)算法。迷宫中的每个单元都应该由多个(最多4个)图形节点表示,每个节点表示处于特定状态的访问单元

也就是说,在您的示例中,您可能处于由p表示的单元格中,处于两种状态之一:向左和向右。它们中的每一个都由一个单独的图形节点表示(尽管在空间上是同一个单元)。这两个节点之间也没有直接链接,因为您无法在这个特定的单元中切换方向

根据您的规则,您只能在遇到障碍物时切换方向,这是在表示处于不同状态的相同单元的节点之间放置链接的地方

你也可以把你的图形想象成你的迷宫复制成4层,每一层代表你的pacman的状态。在表示向右移动的层中,您只将链接放置到右侧,也将w.r.t.放置到迷宫的几何体。在有障碍物的单元格中,如果无法向右移动,则可以在不同层中放置指向相同单元格的链接

更新:

关于您在草图中描述的场景。它实际上是正确的,你的想法是对的,但它看起来很复杂,因为你决定在不同的细胞和状态之间建立链接

我建议使用下图:

这样做的目的是分割您的小区间和州际链接。现在有两种边:用蓝色标记的单元间边和用红色标记的状态间边

蓝色边始终连接相邻单元之间相同状态(箭头方向)的节点,而红色边连接同一单元内的不同状态

根据您的规则,遇到障碍物时,状态可能会发生变化,因此,如果没有障碍物,则每个状态节点都是蓝边的来源,如果遇到障碍物(即,无法发射蓝边),则每个状态节点都是红边的来源。因此,我还将状态节点绘制为蓝色和红色


如果根据您的规则,状态转换立即发生,没有延迟/惩罚,则红边的权重为0。否则,您可以为它们指定非零权重,红色/蓝色边缘之间的权重比应与转弯/行驶的时间段比率相对应。

这太完美了!可能有点贵:即使是在加载过程中完成构建,n个单元最多需要4n个节点,再加上最坏情况下A*复杂度是4n,导致搜索速度慢4倍,我认为在实时游戏中应该避免这一点:实际上我不知道,给定1000个单元,游戏是否仍然有响应,是吗?实际上,1000个细胞听起来并不可怕。即使使用标准的Dijkstra,也不会干扰A*,听起来不错。请注意,在搜索过程中,您将有一个访问过的单元格云,以及围绕该云的一层候选单元格。这样,树中最多有4000^(1/2)个节点。因此,复杂性的顺序是4N*log[(4N)^(1/2)]=2N*log(N)P.S。您打算在哪个设备上运行此操作?我在中档安卓平板电脑上运行了一个类似的算法,输入量要大得多——这很好。我在上一代计算机上运行它,这样就可以了……你能再解释一下为什么Nlog(N)会给出复杂性吗?明天我将编辑我的问题,把你的想法应用到迷宫中,所以你可以告诉我如果我得到它…现在我有点困了