解决8字谜题的有效方法是什么?

2023-12-28

8 拼图是一块有 9 个位置的方板,由 8 个编号的图块和一个间隙填充。在任何时候,与间隙相邻的图块都可以移动到间隙中,从而创建新的间隙位置。换句话说,间隙可以与相邻(水平和垂直)的图块交换。游戏的目标是从任意配置的图块开始,然后移动它们以使编号的图块按升序排列,或者沿着棋盘的周边运行,或者从左到右排序,其中 1 在左上角-手的位置。

我想知道什么方法可以有效地解决这个问题?


我将尝试重写之前的答案,并详细说明为什么它是最佳的。

A*算法直接取自维基百科 http://en.wikipedia.org/wiki/A*_search_algorithm is

            function A*(start,goal)
                    closedset := the empty set                 // The set of nodes already evaluated.     
                    openset := set containing the initial node // The set of tentative nodes to be evaluated.
                    came_from := the empty map                 // The map of navigated nodes.
                    g_score[start] := 0                        // Distance from start along optimal path.
            h_score[start] := heuristic_estimate_of_distance(start, goal)
                    f_score[start] := h_score[start]           // Estimated total distance from start to goal through y.
                    while openset is not empty
                    x := the node in openset having the lowest f_score[] value
                    if x = goal
            return reconstruct_path(came_from, came_from[goal])
                    remove x from openset
                    add x to closedset
            foreach y in neighbor_nodes(x)
                    if y in closedset
                    continue
            tentative_g_score := g_score[x] + dist_between(x,y)

                    if y not in openset
                    add y to openset
                    tentative_is_better := true
                    elseif tentative_g_score < g_score[y]
                    tentative_is_better := true
                    else
                    tentative_is_better := false
                    if tentative_is_better = true
                    came_from[y] := x
                    g_score[y] := tentative_g_score
            h_score[y] := heuristic_estimate_of_distance(y, goal)
                    f_score[y] := g_score[y] + h_score[y]
                    return failure

            function reconstruct_path(came_from, current_node)
                    if came_from[current_node] is set
                    p = reconstruct_path(came_from, came_from[current_node])
            return (p + current_node)
                    else
                    return current_node

让我在这里填写所有详细信息。

heuristic_estimate_of_distance is the function Σ d(xi) where d(.) is the Manhattan distance of each square xi from its goal state.

所以设置

            1 2 3
            4 7 6
            8 5 

会有一个heuristic_estimate_of_distance1+2+1=4,因为 8,5 中的每一个都距其目标位置 1,d(.)=1,而 7 距其目标状态 2,d(7)=2。

A* 搜索的节点集被定义为起始位置,后跟所有可能的合法位置。这就是起始位置x如上所述:

            x =
            1 2 3
            4 7 6
            8 5 

那么函数neighbor_nodes(x)产生 2 种可能的合法动作:

            1 2 3
            4 7 
            8 5 6

            or

            1 2 3
            4 7 6
            8   5

功能dist_between(x,y)定义为从状态转换所发生的平方移动数x to y。出于算法的目的,这在 A* 中通常等于 1。

closedset and openset两者都特定于 A* 算法,并且可以使用标准数据结构(我相信优先级队列)来实现。came_from是使用的数据结构 使用函数重建找到的解决方案reconstruct_path谁的详细信息可以在维基百科上找到。如果您不想记住解决方案,则无需实施此解决方案。

最后,我将讨论最优性问题。考虑 A* 维基百科文章的摘录:

“如果启发式函数 h 是可接受的,这意味着它永远不会高估达到目标的实际最小成本,那么如果我们不使用闭集,则 A* 本身就是可接受的(或最优的)。如果使用闭集,则h 也必须是单调的(或一致的),A* 才能达到最优。这意味着对于任何一对相邻节点 x 和 y,其中 d(x,y) 表示它们之间的边的长度,我们必须有: h(x)

因此,足以表明我们的启发式是可接受的且单调的。对于前者(可接受性),请注意,给定任何配置,我们的启发式(所有距离的总和)估计每个方格不仅受到合法移动的约束,并且可以自由地朝其目标位置移动,这显然是一个乐观的估计,因此我们的启发式是可以接受的(或者它永远不会高估,因为达到目标位置总是需要at least与启发式估计一样多的动作。)

单调性要求用文字表述就是: “任何节点的启发式成本(到目标状态的估计距离)必须小于或等于转换到任何相邻节点的成本加上该节点的启发式成本。”

它主要是为了防止出现负循环的可能性,即转换到不相关的节点可能会比实际进行转换的成本减少到目标节点的距离,这表明启发式很差。

在我们的例子中,显示单调性非常简单。根据我们对 d 的定义,任何相邻节点 x,y 都具有 d(x,y)=1。因此我们需要展示

h(x)

这相当于

h(x) - h(y)

这相当于

Σ d(xi) - Σ d(yi) <= 1

这相当于

Σ d(xi) - d(yi) <= 1

根据我们的定义我们知道neighbor_nodes(x)两个邻居节点 x,y 最多可以有一个方格的位置不同,这意味着在我们的总和中

d(xi) - d(yi) = 0

对于除 1 之外的所有 i 值。不失一般性地说,i=k 是这样。此外,我们知道,对于 i=k,节点最多移动了一处,因此它到 目标状态最多只能比前一个状态多 1,因此:

Σ d(xi) - d(yi) = d(xk) - d(yk) <= 1

表现出单调性。这显示了需要显示的内容,从而证明该算法将是最优的(以大 O 表示法或渐近方式)。

请注意,我已经在大 O 表示法方面展示了最优性,但在调整启发式方面仍然有很大的发挥空间。您可以对其添加额外的扭曲,以便更接近地估计到目标状态的实际距离,however你必须做sure启发式总是低估否则你就会失去最优性!

稍后编辑许多卫星

后来(很久)再次阅读这篇文章,我意识到我编写它的方式有点混淆了该算法的最优性的含义。

我试图在这里理解最优性有两个不同的含义:

1) 该算法产生最优解,即给定客观标准的最佳可能解。

2) 该算法使用相同的启发式扩展了所有可能算法的最少状态节点数。

理解为什么需要启发式的可接纳性和单调性来获得 1) 的最简单方法是将 A* 视为 Dijkstra 最短路径算法在图上的应用,其中边权重由迄今为止移动的节点距离加上启发式给出距离。如果没有这两个属性,我们就会在图中出现负边,从而可能出现负循环,并且 Dijkstra 的最短路径算法将不再返回正确答案! (构建一个简单的例子来说服自己。)

2)实际上很难理解。要充分理解这句话的意思,这个说法上有很多量词,比如在谈论其他算法时,一个指的是similar算法如 A* 扩展节点并在没有先验信息(启发式除外)的情况下进行搜索。显然,人们可以构造一个简单的反例,否则,例如神谕或精灵会在每一步告诉你答案。为了深入理解这一陈述,我强烈建议阅读历史部分的最后一段维基百科 https://en.wikipedia.org/wiki/A*_search_algorithm#History以及查看该仔细陈述的句子中的所有引文和脚注。

我希望这能消除潜在读者中剩余的困惑。

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

解决8字谜题的有效方法是什么? 的相关文章

  • 从日志文件中获取前 100 个 URL

    我的一位朋友在接受采访时被问到以下问题 谁能告诉我如何解决它 我们有一个相当大的日志文件 大约 5GB 日志文件的每一行都包含一个用户在我们网站上访问过的 URL 我们想要找出用户访问最多的 100 个 URL 怎么做 如果我们有超过 10
  • 使用C标准数学库精确计算标准正态分布的CDF

    标准 C 数学库不提供计算标准正态分布 CDF 的函数 normcdf 然而 它确实提供了密切相关的函数 误差函数 erf 和互补误差函数 erfc 计算 CDF 的最快方法通常是通过误差函数 使用预定义常量 M SQRT1 2 来表示 d
  • 检索受“rowspan”影响的行的列索引的最有效方法是什么?

    考虑下表 table thead tr th th th A th th B th th C th tr thead tbody tr th 1 th td Apples td td Oranges td td Pears td tr tb
  • 高维最近邻搜索的最佳数据结构

    我实际上正在处理高维数据 50 000 100 000 个特征 并且必须对其执行最近邻搜索 我知道随着维度的增长 KD 树的性能很差 而且我还了解到 一般来说 所有空间分区数据结构都倾向于对高维数据执行详尽的搜索 此外 还有两个重要事实需要
  • 固定大小集以包含给定集的最大数量

    我有大约 1000 组尺寸 1 4 1 3 3 5 6 4 5 6 7 5 25 42 67 100 是否有可能找到包含最大数量的给定集合的大小为 20 的集合 检查每一个100 80 20 集 效率低下 我不太确定这是 NP 完全的 考虑
  • 我需要一个支持高效随机访问和 O(k) 插入和删除的容器

    我再次尝试问同样的问题question https stackoverflow com questions 3808708 delete parts of a dynamic array and grow other 但我最终提出了一个不同
  • 如何求小于给定数的最大2次方

    我需要找到小于给定数字的最大 2 次幂 我陷入困境 找不到任何解决方案 Code public class MathPow public int largestPowerOf2 int n int res 2 while res lt n
  • 在 C++ 中通过引用传递 std 算法谓词

    我正在尝试从 a 中删除元素std list并保留已删除元素的一些统计信息 为此 我使用列表中的remove if 函数 并且我有一个谓词 我想使用这个谓词来收集统计数据 这是谓词的代码 class TestPredicate privat
  • 将字符串中的“奇怪”字符转换为罗马字符

    我需要能够将用户输入仅转换为 a z 罗马字符 不区分大小写 所以 我感兴趣的角色只有26个 然而 用户可以输入他们想要的任何 形式 的字符 西班牙语 n 法语 e 和德语 u 都可以包含用户输入中的重音符号 这些重音符号会被程序删除 我已
  • 关于在字典中查找所有有效单词的算法问题

    给定一个字典 只是一个字符串列表 您收到来自外部来源的未知数量的信件 给定字母串 您将如何列出您可以通过这些字母的任意组合组成的所有有效单词 来自字典 因此 如果您收到 applead 你应该找到apple bad pad lead等 我知
  • C 埃及分数

    古埃及人仅使用以下形式的分数1 n因此任何其他分数都必须表示为这些单位分数的总和 而且 所有单位分数都是不同的 在C或Java中使任何分数成为埃及分数 总和越少越好 的好方法是什么 可以使用什么算法 分支定界 a 例如 3 4 1 2 1
  • 带路径压缩算法的加权 Quick-Union

    有一种 带路径压缩的加权快速联合 算法 代码 public class WeightedQU private int id private int iz public WeightedQU int N id new int N iz new
  • 使用多级解决方案计算二维网格中的最近邻

    我有一个问题 在 x y 大小的网格中 我提供了一个点 并且我需要找到最近的邻居 在实践中 我试图在 pygame 中找到距离光标最近的点 该点跨越颜色距离阈值 计算如下 sqrt rgb1 0 rgb2 0 2 rgb1 1 rgb2 1
  • 异或交换可以扩展到两个以上的变量吗?

    我一直在尝试将异或交换扩展到两个以上的变量 例如n变量 但我没有得到比这更好的地方3 n 1 对于两个整型变量x1 and x2你可以像这样交换它们 swap x1 x2 x1 x1 x2 x2 x1 x2 x1 x1 x2 所以 假设你有
  • 计算两点之间的最短路线

    过去几周我一直在开发一款多人 HTML5 游戏 使用nodejs and websockets 我已经被这个问题困扰了一段时间 想象一下 我用数组实现了这个平铺地图 如下所示 1 or 棕色瓷砖 路上有障碍物 玩家无法通过 0 or 绿色瓷
  • shell脚本中关联数组的时间复杂度

    我想知道在 shell 脚本中使用关联数组时如何构造 实现 另外 我想知道基于 shell 脚本的关联数组的时间复杂度是否是最佳的 因为我们可以使用字母和数字作为它们各自的键 编辑 他们使用什么哈希函数 如果您使用关联数组 则不能通过 使用
  • 具有 2 个属性的背包算法。如何在 3d 数组中实现它?

    当有超过 1 个属性时 我无法理解背包问题 当有 1 个属性时 我必须编写一个使用具有 2 个属性的背包算法的程序 老师告诉我们 它必须在 3d 数组中完成 错误的实现将导致 O 2 n 处理时间 我无法想象这样的数组会是什么样子 假设这是
  • 如何从迭代器推导连续内存

    不知何故 本土stl copy VC Dinkumware 上的算法表明它可以使用memcpy 可以轻松复制的数据 一个凡人能做到这一点吗 假设每个元素都是普通可复制的 random access iterator 是否意味着连续内存 标准
  • Florian 的 Grisu2 算法如何工作?

    我遇到了一个关于将 double 转换为 ascii 的问题 经过搜索 我得到了 Florian 的论文 使用整数快速准确地打印浮点数 http www cs tufts edu nr cs257 archive florian loits
  • 在java中使用BUBBLE SORT对二维字符串数组进行排序

    类似的问题已经被问过 但从来没有关于二维字符串数组 因此在尝试了很长时间之后我找不到我想要的 我正在尝试使用 BubbleSort 对 java 中的 2D 字符串数组进行排序 作为输入 我收到一个二维字符串数组 一个表 以及您应该排序的

随机推荐

  • Git 初学者:权威的实用指南

    Locked 这个问题及其答案是locked help locked posts因为这个问题是题外话 但却具有历史意义 目前不接受新的答案或互动 好吧 看完后PJ Hyett 的这篇文章 https stackoverflow com qu
  • 角度错误“没有 InjectionToken ORIGIN_URL 的提供程序!”

    我正在尝试通过以下方式制作一个具有 ngx translate 功能的 Angular 应用程序this https medium com letsboot translate angular 4 apps with ngx transla
  • X509Certificate2 p12 是否需要存储?

    运行以下代码时出现问题 X509Certificate2 cert new X509Certificate2 C file p12 password X509KeyStorageFlags Exportable RSACryptoServi
  • PWA 调试 chrome“添加到主屏幕”按钮不执行任何操作

    我正在尝试将 添加到主屏幕 提示功能添加到我的网站 现在我已经阅读了谷歌开发者文章并且我已经设置好了一切 现在 如果我尝试使用 Chrome 开发工具 gt 应用程序 gt 清单中的 添加到主屏幕 按钮手动将页面添加到主屏幕 则不会发生任何
  • Google Guava 的 CacheLoader loadAll() 方法实现问题

    我有兴趣知道 google guava 11 0 库中引入的 loadAll 方法实现的有效方式是什么 下面是描述加载所有方法实现扩展的代码根据 CachesExplained 的示例 LoadingCache
  • 如何根据条件语句更改 gridview 单元格的背景颜色?

    好吧 我显然还没有向谷歌提供正确的查询 否则我现在就已经发现了 我希望这个论坛上的人可以帮助我 因此 我有一个数据表 我根据数据读取器添加行 该数据读取器从在数据库上执行的 SQL 查询获取其信息 到目前为止 一切都很好 现在 其中一列称为
  • 使用 compass 配置 zurb Foundation-sass - 如何让它工作并在项目中使用它?

    我是 sass 和 zurb 基础的新手 我过去通过 codekit 使用过 bootstrap less 并且一直在尝试使用 sass 版本foundation sass但无法成功配置它 通过使用 zurb 的 gem 的命令行或使用 c
  • 根据发件人、主题和今天的日期搜索 Outlook 电子邮件

    我应该会收到一封包含该主题的电子邮件 Testing Protocol from email protected cdn cgi l email protection 每天 有没有办法搜索我的 Outlook 收件箱以确定当天是否收到了包含
  • Objective C 术语:渠道和代表

    我无法理解 iPhone 如何处理事件的渠道概念 帮助 代表们也让我困惑 请问有人愿意解释一下吗 Outlets 在 Interface Builder 中 是类中的成员变量 设计器中的对象在运行时加载时会被分配 这IBOutlet宏 这是
  • 通过 NFC 标签共享 Wifi 凭证,无需特殊应用程序

    我正在寻找一种方法来创建 NFC 标签 该标签可以共享我的网络的 wifi 凭证 而我的客人无需在手机上安装任何特殊的 NFC 应用程序 手机自带的应用程序除外 我一直在研究 NFC Tag Writer WifiTap NFC Task
  • 使用 get_or_create 返回多个对象

    我正在编写一个小的 django 命令来将数据从 json API 端点复制到 Django 数据库中 此时我实际上创建了对象obj created model objects get or create filters 我得到一个Mult
  • Laravel 验证错误消息字符串

    我想将 laravel 验证错误数组转换为逗号分隔的字符串 这是在 ios 应用程序的 api 服务中使用的 以便iOs开发者可以轻松处理错误消息 I tried valArr foreach validator gt errors as
  • 保护 Web API 免受未经授权的应用程序的侵害

    我正在开发一个使用大量 AJAX 与服务器通信的网页 反过来 服务器具有广泛的 REST JSON API 公开 Web 客户端调用的不同操作 该网站可供匿名用户和经过身份验证的用户使用 正如您所料 经过身份验证的用户发出的 Web 服务调
  • WKWebKit:没有 dataDetectorTypes 参数

    In UIWebView 很容易添加UIDataDetectorTypes到一个视图 myUIWebView dataDetectorTypes UIDataDetectorTypePhoneNumber 等等 然而 WKWebView似乎
  • 如何正确保护使用应用内购买和本地数据库的应用程序

    我目前正在为 Android 开发一款益智游戏 我希望完成后具有以下功能 免费玩 支持广告 因此需要有效的互联网连接 如果无法显示广告则无法玩 应用内购买选项可删除广告和连接检查 应用内购买附加内容 然而我意识到有很多问题源于我的要求 拥有
  • 将缩写词替换为其值 Python

    我正在努力清理一些包含大量首字母缩略词的文本 因此 我制作了一本包含一些示例及其值的字典 但是我遇到了一些问题 下面的示例代码 def acr text acr dict ft feet mi michigan for word abr i
  • Microsoft.AspNetCore.Mvc.NewtonsoftJson 6.0.2 与 net5.0 不兼容

    我正在 Mac 上使用 Visual Studio 2019 尝试启动 REST API 项目 尝试安装 NewtonsoftJson 6 0 2 时立即陷入困境 我只是在学习教程 正在使用的 NewtonsoftJson 版本是 3 1
  • 基于 C# 的规则语言示例?

    您能否提供一个用 C 编写的规则定义语言的好示例 Java 人有JESS http herzberg ca sandia gov C 有什么好东西吗 此页面显示了 C 中的开源规则引擎的一些示例 http csharp source net
  • 如何在 CAKEPHP 中访问 GET 请求?

    如何在 CAKEPHP 中访问 GET 请求 如果我在 url 中传递一个变量 http samplesite com page key1 value1 key2 value2 我应该使用 GET 还是 this gt params 来获取
  • 解决8字谜题的有效方法是什么?

    8 拼图是一块有 9 个位置的方板 由 8 个编号的图块和一个间隙填充 在任何时候 与间隙相邻的图块都可以移动到间隙中 从而创建新的间隙位置 换句话说 间隙可以与相邻 水平和垂直 的图块交换 游戏的目标是从任意配置的图块开始 然后移动它们以