麻将纸牌求解算法,需要加速

Posted

技术标签:

【中文标题】麻将纸牌求解算法,需要加速【英文标题】:Mahjong-solitaire solver algorithm, which needs a speed-up 【发布时间】:2009-05-27 07:45:16 【问题描述】:

我正在开发一个麻将纸牌解算器,到目前为止,我做得很好。然而, 它没有我希望的那么快,所以我要求进行任何额外的优化 你们可能知道的技术。

所有的图块都从布局中得知,但解决方案不是。目前,我很少 确保安全移除某些相同瓷砖对的规则(这不会成为可能的解决方案的障碍)。

为了清楚起见,当任何时候都可以拾取瓷砖时,瓷砖是空闲的,而瓷砖是松散的,当它根本不绑定任何其他瓷砖时。

如果有四个可用的免费磁贴,请立即移除它们。 如果可以拾取三块瓷砖,并且其中至少有一块是松散的,则移除未松散的。 如果可以拾取三张牌,而只有一张空闲的牌(两张松动),请移除空闲的一张和随机松动的一张。 如果有三个松散的瓷砖可用,请移除其中的两个(无论哪个都无所谓)。 由于完全相同的图块有四倍,如果剩下两个,请移除它们,因为它们是唯一剩下的。

我的算法递归地在多个线程中搜索解决方案。一旦一个分支完成(到一个没有更多移动的位置)并且它没有导致一个解决方案,它就会将该位置放在一个包含坏的向量中。现在,每次启动新分支时,它都会遍历错误位置以检查该特定位置是否已被检查。 这个过程一直持续到找到解决方案或检查所有可能的位置。

这适用于包含 36 或 72 个图块的布局。但当有更多时, 由于要搜索的位置很多,因此该算法变得几乎毫无用处。

所以,我再次问你们,如果你们中的任何人有好的想法,如何实施更多规则以安全移除瓷砖或任何其他特定的加速算法。

最好的问候, nhaa123

【问题讨论】:

听起来您生成了所有可能的瓷砖移除序列,并排除了那些导致解决方案的序列。这肯定会很慢。 +1 使用正确的麻将纸牌名称,而不仅仅是“麻将”。 【参考方案1】:

我不完全了解您的求解器是如何工作的。当您可以选择移动时,您如何决定首先探索哪种可能性?

如果您选择任意一个,这还不够好 - 基本上只是粗略搜索。您可能需要先探索“更好的分支”。要确定哪些分支“更好”,您需要一个评估位置的启发式函数。然后,您可以使用一种流行的启发式搜索算法。检查这些:

A* 搜索 束搜索

(谷歌是你的朋友)

【讨论】:

是的,这是蛮暴力的,我在这里做的。 ATM,我没有什么可以评估当前位置。我会从谷歌检查你的建议。谢谢。【参考方案2】:

几年前,我写了一个程序,通过偷看解决纸牌麻将牌。我用它检查了 100 万只海龟(在半台计算机上花了一天左右的时间:它有两个核心),似乎其中大约 2.96% 无法解决。

http://www.math.ru.nl/~debondt/mjsolver.html

好的,这不是您问的问题,但您可能会查看代码以找到其中一些迄今为止您还没有想到的修剪启发式方法。该程序使用的内存不超过几兆字节。

【讨论】:

嗨!欢迎来到堆栈溢出。我认为这是一个相当好的答案/评论。我唯一要提到的是,您还应该包含链接中的一些相关文本/代码,以防链接失效。【参考方案3】:

不要使用包含“坏”位置的向量,而是使用具有恒定查找时间而不是线性查找时间的集合。

【讨论】:

【参考方案4】:

如果有 4 个 Tiles 可见但无法拾取,则必须先移除周围的其他 Tiles。路径应该使用你的规则来移除最少的瓦片,朝向这些瓦片,以打开它们。

如果 Tiles 被其他 Tiles 隐藏,则问题没有找到路径的完整信息,需要计算剩余 Tiles 的概率。

非常好的问题!

【讨论】:

以上是关于麻将纸牌求解算法,需要加速的主要内容,如果未能解决你的问题,请参考以下文章

房卡麻将分析系列之"发牌器"算法设计

麻将回溯算法(无癞子)

发布一个麻将作弊器(Qt 绘图实现)

房卡麻将分析系列之"发牌器"算法设计

源码架设教程之麻将AI算法与数据结构棋牌

自己写的带混牌麻将算法