编程理论:解决迷宫

2023-11-21

解决迷宫问题有哪些可能的方法?
我有两个想法,但我认为它们不是很优雅。

基地情况:我们有一个矩阵,这个矩阵中的元素以一种代表迷宫的方式排序,有一个入口,一个出口。

我的第一个想法是派一个机器人穿过迷宫,跟随一侧,直到走出迷宫。我认为这是一个非常缓慢的解决方案。

第二个遍历每一个标有 1 的连续项目,检查它可以去哪里(上、右、下、左),选择一种方式并在那里继续其路径。这甚至比第一个还要慢。

当然,如果我让两个机器人在每个连接处都多线程,速度会更快一些,但这也不是最好的方法。

需要有更好的解决方案来让机器人穿过迷宫。

EDIT
首先:感谢您的精彩回答!

我的问题的第二部分是:如果我们有一个多维图该怎么办?是否有特殊的做法,或者 Justin L. 的答案也可用于此?
我认为对于本案来说这不是最好的方法。

第三个问题:
这些迷宫求解器算法中哪一个是最快的? (纯属假设)


你可以把你的迷宫想象成一棵树。



     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 是死胡同,** 是目标。 当然,在你的实际树中,每个节点有可能有多达three孩子们。

您现在的目标只是找到要遍历哪些节点才能找到终点。任何树搜索算法都可以。

查看这棵树,只需从树最深处的 ** 向上“追踪”,就可以很容易地看到正确的解决方案:

A B E H M **

请注意,这种方法变成只是轻微当你的迷宫中有“循环”时,情况会更加复杂(即,当可能时,无需回溯,你可以重新进入已经走过的通道)。查看评论以获得一个不错的解决方案。

现在,让我们看看您提到的应用于这棵树的第一个解决方案。

你的第一个解决方案基本上是深度优先搜索,这确实没那么糟糕。这实际上是一个非常好的递归搜索。基本上,它说,“始终首先采取最右边的方法。如果没有任何东西,则原路返回,直到第一个可以直走或向左走的地方,然后重复。

深度优先搜索将按以下顺序搜索上面的树:

A B D (backtrack) E H L (backtrack) M ** (backtrack) O (backtrack thrice) I
(backtrack thrice) C F (backtrack) G J

注意,一旦找到**就可以停止。

但是,当您实际编写深度优先搜索代码时,使用递归编程让一切变得更加容易。即使迭代方法也有效,而且您无需显式编程如何回溯。查看链接的文章以了解实现。

搜索树的另一种方法是广度优先解决方案,按深度搜索树木。它会按以下顺序搜索上面的树:

A (next level) B C (next level) D E F G (next level)
H I J (next level) L M (next level) ** O

请注意,由于迷宫的性质,广度优先检查的平均节点数量要高得多。广度优先很容易实现,方法是有一个要搜索的路径队列,每次迭代都会从队列中弹出一条路径,通过获取一步后可以变成的所有路径来“爆炸它”,然后放入这些新路径在队列的末尾。没有明确的“下一级”代码命令,这些命令只是为了帮助理解。

其实还有一个整体搜索树的方法的广泛列表。我刚才提到了两种最简单、最直接的方法。

如果你的迷宫非常非常长和深,有循环和疯狂,而且很复杂,我建议A*算法,这是行业标准的寻路算法,它将广度优先搜索与启发式相结合......有点像“智能广度优先搜索”。

它基本上是这样工作的:

  1. 将一条路径放入队列中(您只需走一步直接进入迷宫的路径)。路径的“权重”由其当前长度+距终点的直线距离(可以通过数学计算)给出
  2. 从队列中弹出权重最低的路径。
  3. 将路径“分解”为一步后可能出现的每条路径。 (即,如果您的路径是 Right Left Left Right,那么您的分解路径是 R L L R R 和 R L L R L,不包括非法穿过墙壁的路径)
  4. 如果其中一条路径有目标,那么胜利!否则:
  5. 计算分解后的路径的权重,并将其全部放回队列中(不包括原始路径)
  6. 按权重对队列进行排序,最低的在前。然后从步骤 #2 开始重复

那就是A*,我特别强调了它,因为它或多或少是行业标准的寻路算法all寻路的应用程序,包括从地图的一个边缘移动到另一个边缘,同时避开越野路径或山脉等。它工作得很好,因为它使用了最短可能距离启发式,这赋予了它“智能”。 A* 的用途如此广泛,因为对于任何问题,如果您有可用的最短距离启发式(我们的很简单 - 直线),您就可以应用它。

BUT值得注意的是,A* 是not你唯一的选择。

事实上,树遍历算法的维基百科类别仅列出97个! (最好的仍然会在这一页之前链接)

抱歉,篇幅太长了=P(我倾向于胡言乱语)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

编程理论:解决迷宫 的相关文章

  • 分词统计方法

    我想解决分词问题 从没有空格的长字符串中解析单词 例如我们想要从中提取单词somelongword to some long word 我们可以通过字典的动态方法来实现这一点 但我们遇到的另一个问题是解析歧义 IE orcore gt or
  • 对二进制二维矩阵进行排序?

    我在这里寻找一些指示 因为我不太知道从哪里开始研究这个 我有一个二维矩阵 每个单元格中有 0 或 1 例如 1 2 3 4 A 0 1 1 0 B 1 1 1 0 C 0 1 0 0 D 1 1 0 0 我想对其进行排序 使其尽可能 上三角
  • 以小于 O(n^2) 的复杂度计算两个数组中的互质对数量

    我在挑战中遇到了这个问题 有两个数组 A 和 B 的大小均为 N 我们需要返回对的计数 A i B j 其中gcd A i B j 1 and A i B j 我只能想到暴力方法 它超出了少数测试用例的时间限制 for int i 0 i
  • 如何验证无锁算法?

    从理论上讲 至少应该可以对无锁算法进行暴力验证 只有这么多的函数调用组合 是否有任何工具或正式推理过程可以实际证明无锁算法是正确的 理想情况下它还应该能够检查竞争条件和 ABA 问题 注意 如果你知道一种方法来证明一点 例如 只证明它不受
  • 计算 Adamic-Adar 的快速算法

    我正在研究图形分析 我想计算一个 N N 相似度矩阵 其中包含每两个顶点之间的 Adamic Adar 相似度 为了概述 Adamic Adar 让我从以下介绍开始 给定邻接矩阵A无向图的G CN是两个顶点的所有公共邻居的集合x y 两个顶
  • 如何返回 Solidity 中的结构数组?

    我正在为以太坊智能合约设计一个解决方案bidding 用例包括保留名称 例如 myName 并分配给一个地址 然后 人们可以竞标该名称 在本例中为 myName 可以有多个名称发生多次此类出价 struct Bid address bidO
  • StackOverflowError 计算 BigInteger 的阶乘?

    我正在尝试编写一个Java程序来计算大数的阶乘 它似乎BigInteger无法容纳这么大的数量 下面是我编写的 简单的 代码 public static BigInteger getFactorial BigInteger num if n
  • 给定一个点向量(可能无序),找到多边形(不是凸包)

    我目前有一个点向量 vector
  • 用于计算三角函数、对数或类似函数的算法。仅限加减法

    我正在修复 Ascota 170 古董机械可编程计算机 它已经开始工作了 现在我正在寻找一种算法来展示其功能 例如计算三角或对数表 或类似的东西 不幸的是 从数学运算来看 计算机只能进行整数的加减法 从 1E12到1E12的55个寄存器 甚
  • 如何在单向链表(一次遍历中)中从尾部获取第 n 个节点?

    所以我在一次考试中得到了这个问题 如何从单链表的尾部获取第 n 个节点 每个节点都有一个值和一个下一个 指向下一个值的指针 我们得到这个 getNodeFromTail Node head int x 所以我的做法是通过遍历一次来求出列表的
  • 填充体积算法

    我有一个具有一定尺寸长度 宽度 高度的盒子 我有不同长度 宽度 高度的物品 是否有现有的算法可以确定放入盒子中的最佳物品 这称为装箱 切割库存 背包问题 并且是 NP 难问题 一般来说 您只能通过使用启发式方法获得近似解 请参见示例 htt
  • 计算字符串的所有子串中子序列的出现次数

    我想编写一个算法来计算字符串的所有子字符串中字符子序列 不相交 出现的总数 下面是一个例子 字符串 jabcohnnyjohnny 后续 约翰尼 包含子序列的子字符串 jabcohnny jabcohnnyj jabcohnnyjo jab
  • 自动跟踪算法

    我正在尝试写一个simple跟踪例程来跟踪电影中的某些点 本质上我有一系列 100 帧长的电影 在黑暗背景上显示一些亮点 我每帧有大约 100 150 个点 它们在电影的过程中移动 我想跟踪它们 所以我正在寻找一些有效的 但可能不会过度实施
  • Python Pandas:沿一列比较两个数据帧,并返回另一个数据帧中两个数据帧的行内容

    我正在处理两个 csv 文件并作为数据框 df1 和 df2 导入 df1 有 50000 行 df2 有 150000 行 我想将 df2 的 时间 与 df1 求时间差并返回所有列的值 对应相似的行 保存在df3中 时间同步 例如 35
  • 数独算法,暴力破解[关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 我正在尝试
  • 分而治之算法找到两个有序元素之间的最大差异

    给定一个整数数组 arr 找出任意两个元素之间的差异 使得较大的元素出现在 arr 中较小的数字之后 Max Difference Max arr x arr y x gt y 例子 如果数组是 2 3 10 6 4 8 1 7 那么返回值
  • 我应该对算法使用递归还是记忆化?

    如果我可以选择使用递归或记忆来解决问题 我应该使用哪一个 换句话说 如果它们都是可行的解决方案 因为它们提供了正确的输出并且可以在我正在使用的代码中合理地表达 那么我什么时候会使用其中一个而不是另一个 它们并不相互排斥 您可以同时使用它们
  • 如何光栅化旋转矩形(通过 setpixel 在 2d 中)

    我有四个 2d 顶点 A B C D 的旋转矩形 我需要在像素缓冲区中 有效地 光栅化 绘制它 使用 setpixel x y 颜色 怎么做 我正在尝试使用一些代码 例如 convertilg a b c d do up down left
  • 求先递增后递减列表的最大值和最小值

    我尝试用谷歌搜索这个问题 但没有取得太大成功 我确信这个问题或类似问题有一个技术名称 但我似乎找不到答案 给定一个列表L整数 即严格递增 然后严格递减 找到该列表的最大值和最小值 例如 L可能 1 2 3 4 5 4 3 2 or 2 4
  • 如何计算 3D Morton 数(交织 3 个整数的位)

    我正在寻找一种快速计算 3D Morton 数的方法 这个网站 http www graphics stanford edu seander bithacks html InterleaveBMN有一个基于幻数的技巧来处理 2D Morto

随机推荐

  • 如何将通过模板创建的单独网格沿其列/行对齐?

    我认为在这种情况下一张图胜过一千个字 XAML
  • SSL 与客户端证书重新协商导致服务器缓冲区溢出

    我编写了一个 Java 客户端应用程序 该应用程序使用客户端证书通过 HTTPS 连接到 Apache Web 服务器 并向服务器执行文件的 HTTP PUT 对于小文件它可以正常工作 但对于大文件就会崩溃 Apache 服务器日志显示以下
  • Gruntwiredep:app 找不到 Bower 包

    运行后 yo ionic from https github com diegonetto generator ionic 然后启动grunt serve我有这个 Running wiredep app wiredep task Canno
  • 从数组中查找最小和最大数字,最小值始终为 0

    该程序首先询问用户要存储在数组中的元素数量 然后询问数字 这是我的代码 static void Main string args Console Write How many numbers do you want to store in
  • 系统 D-Bus 不允许使用 conf 文件打出所有权

    我正在尝试创建一个在系统总线上运行的守护程序服务 其中从该服务发送和接收的权限应该对任何人完全开放 此服务不关心安全性 当我尝试使用 QtDbus 注册服务 使用 PyQt 时 出现以下错误 Connection 1 0 is not al
  • NPE 在 JAX-RS 中抛出编组实体

    我有一个使用 JPA 实体类的 JAX RS Web 服务 我有一个这样的资源类 Path entity public class MyEntityResource GET Produces MediaType APPLICATION XM
  • 这个成员指针语法是什么?

    include
  • 如何编写 bash 脚本来在进程终止时重新启动该进程?

    我有一个 python 脚本 它将检查队列并对每个项目执行操作 checkqueue py while True check queue do something 如何编写一个 bash 脚本来检查它是否正在运行 如果没有 则启动它 大致如
  • 从 NSURL 转换为 NSURLRequest 时丢失 /

    我正在我的 iPhone 应用程序中执行 HTTP Post 我发送到服务器的参数之一是 URL 问题是 当我从 NSURL 转换为 NSURLRequest 时 字符串http www slashdot org变为 http www sl
  • jquery 父容器的宽度

    如何设置 DOP ThumbnailGallery Container 以具有父容器的宽度 DOP ThumbnailGallery Container Container width Container width 我尝试了这种方式 但它
  • 将字符串数组转换为向量的最佳方法?

    正如标题所示 将字符串数组转换为向量的最佳方法是什么 Thanks 调用使用现有集合 在本例中为数组 的 Vector 构造函数来初始化自身 String strings Here Are Some Strings Vector
  • 从字符串中删除多个单词的更好方法?

    bannedWord Good Bad Ugly def RemoveBannedWords toPrint database statement toPrint for x in range 0 len database if banne
  • 基于范围的 for 循环可以在一定范围内工作

    如果我有范围 两个迭代器对 有没有一种方法可以为使用范围而不是原始数组或容器编写 for every 循环 像这样的东西 auto rng std equal range v begin v end 1984 for const auto
  • 如何阻止 jQuery UI 选项卡内的 SWF 重新加载

    我在 jQuery UI 选项卡中有一个 SWF 影片 我遇到的问题是 每次我从该选项卡单击到另一个选项卡 然后单击返回时 SWF 都会重新加载 我可以检查 DOM 并看到当我单击离开时包含 SWF 的 div 仍然在 DOM 中 所以我不
  • 如何以相对方式使用 setwd?

    我们的团队在 git 存储库中使用 R 脚本 这些脚本在 Mac 和 Windows 有时还有 Linux 机器上的多人之间共享 这往往会导致脚本顶部出现一堆非常烦人的行 如下所示 path lt C data work project a
  • 本地安装的 TTF 会覆盖 Google 字体

    我正在使用 Google Fonts 中的 Ubuntu 字体 我的样式表 body font family ubuntu arial 它可以工作 但如果安装同名的字体 Ubuntu 它会覆盖 Google Fonts 中的字体 是否可以强
  • 何时使用 MySQLdb 关闭游标

    我正在构建一个 WSGI Web 应用程序 并且有一个 MySQL 数据库 我正在使用 MySQLdb 它提供用于执行语句和获取结果的游标 获取和关闭游标的标准做法是什么 特别是 我的光标应该持续多长时间 我应该为每笔交易获取一个新的游标吗
  • XNA Alpha 混合使纹理的一部分透明

    我想做的是在 XNA 中使用 alpha 混合来使绘制的纹理的一部分透明 例如 我将屏幕清除为某种颜色 比如说蓝色 然后我画一个红色的纹理 最后 我绘制一个纹理 该纹理只是从中心完全透明到边缘完全黑色的径向渐变 我想要的是之前绘制的红色纹理
  • 如何在 iOS 上使用 Google Drive API 处理电子表格

    我正在尝试编写一个 iPhone 应用程序 将其数据库存储在 Google 电子表格中 我按照 DrEdit 的例子here它使用 Drive API 将纯文本文件读取 写入 Google Drive 我正在尝试修改示例应用程序以使用电子表
  • 编程理论:解决迷宫

    解决迷宫问题有哪些可能的方法 我有两个想法 但我认为它们不是很优雅 基地情况 我们有一个矩阵 这个矩阵中的元素以一种代表迷宫的方式排序 有一个入口 一个出口 我的第一个想法是派一个机器人穿过迷宫 跟随一侧 直到走出迷宫 我认为这是一个非常缓