【问题标题】:Shortest path in a maze迷宫中的最短路径
【发布时间】:2018-03-24 20:32:46
【问题描述】:

我正在开发一款类似于吃豆人的游戏:考虑一下这个迷宫:

每个白色方块都是迷宫中的一个节点,其中位于 P 的对象(例如 X)正以从右到左的方向向节点 A 移动。 X 不能切换到它的相反方向,除非它遇到像 A 这样的死胡同。因此,连接 P 和 B 的最短路径通过 A,因为 X 不能将其方向反转到最右下角的节点(称为 C)。一个常见的 A* 算法会输出:

从P到B先向右,再向上;

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

编辑对于 Valdo:我添加了 3 个单元格以便概括一下:如果我明白了,请告诉我:

【问题讨论】:

    标签: algorithm search graph-algorithm dijkstra


    【解决方案1】:

    好问题。我可以建议以下方法。

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

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

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

    您也可以将您的图表视为复制到 4 层的迷宫,每层代表您的 pacman 的状态。在代表向右移动的层中,您只放置向右的链接,也 w.r.t.到迷宫的几何形状。在无法向右移动的有障碍物的单元格中,您可以在不同层放置指向相同单元格的链接。

    更新:

    关于您在草图中描述的场景。这实际上是正确的,您的想法是正确的,但它看起来很复杂,因为您决定在不同的单元格和状态之间放置链接。

    我建议如下图:

    这个想法是拆分您的单元间和州际链接。现在有 2 种边:inter-cell,用蓝色标记,inter-state,用红色标记。

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

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

    如果根据您的规则状态转换立即发生,没有延迟/惩罚,则红色边缘的权重为 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) 给出吗?
    • 明天我将编辑我的问题,将你的想法草图应用到迷宫中,这样你就可以告诉我是否明白了......现在我有点困了
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    相关资源
    最近更新 更多