数独 -- 合法数独与完全数独

一、数独的介绍

        从2004年底开始,数独游戏在英国变得非常流行。数独(Sudoku)是一个日语单词意思是数字位置之类的单词(或短语)。谜题的理念非常简单;面对一个9 × 9的网格,被分成9个3 × 3的块:

        在其中的一些盒子里,设置者放一些数字1-9:求解者的目的是通过在每个盒子里填一个数字来完成网格,这样每一行,每一列,每个3 × 3的盒子都只包含1-9的每个数字一次。

        在这里,我们讨论枚举所有可能的数独网格的问题。这是一个非常自然的问题,但是,也许令人惊讶的是,这个问题似乎不太可能有一个简单的组合答案。事实上,数独网格只是拉丁方格的特殊情况,拉丁方格的枚举本身就是一个难题,没有已知的一般组合公式。已知9 × 9的拉丁平方数为5524751496156892842531225600 ≈ 5.525 × 10^27。由于这个答案是巨大的,我们需要大大改进我们的搜索,以便能够在合理的计算时间内得到答案。

1、初步观察

我们的目标是计算有效数独网格的数量。在下面的讨论中,我们将把这些块称为B1-B9,它们被标记在这里:

        首先注意,在重新标记之后,我们可以假设左上角的块(B1)是由:

对于任意一个合法数独,我都可以通过1-9数字的一对一映射,将B1块转化为这种标准形式,例如:

    转化为    

按照:4→1、5→2、8→3、1→4、7→5、9→6、2→7、3→8、6→9即可得到这种标准形式

        这种重新标记过程将网格的数量减少了9! = 362880倍。我们被简化为计算左上角是这种标准形式的非数独网格的数量。

        从广义上讲,我们的策略是考虑所有可能的方法来填充块B2, B3,因为B1是上面的规范形式,将问题减少到较小的搜索空间。这形成我们强力搜索的外环。对于内部循环,我们找出所有可能的方法来完成块B2和B3转换为全网格。

2、B2块和B3块

        在这里,我们尝试有效地对B2块和B3块的可能性进行分类。我们将对如何找到一个相对较小的B2块和B3块列表进行长时间的讨论,这将使我们能够给出最终答案。(其中一些缩减也可以应用于B4和B7块,以加快搜索速度,尽管一旦B2/B3固定,许多缩减步骤不能以同样的方式在B4/B7上执行)。

2.1、最上面一排积木

我们想要列出前三个块的所有可能配置,假设第一个块是标准形式。我们来看看第二个块的最上面一行。它要么由(以某种顺序)B1块的第2行或第3行的三个数字组成,要么是两者的混合。我们将这种情况称为“纯净”和“混合”情况。B2块和B3块可能的顶行由下式给出:

图1

(其中{a, b, c}表示数字a, b和c的任意顺序)。

纯净顶行{4,5,6} {7,8,9}可以补全如下:

图2

得到 (3!)^6 【注:一个{}中有3!种排列,B2和B3共6个{}】可能的配置。

然而,混合顶行可以通过多种方式完成;例如,最上面的行{4,5,7} {6,8,9}可以补全为:

图3

其中a, b和c分别代表1,2和3,以某种顺序,给出 3×(3!)^6 种可能的配置(b和c是可互换的,及abc等价acb,所以abc的组合就3种)。

为什么下图红框内是{8, 9, a}

首先我们应该清楚,这个红框初步来看,应该是可以填{1,2,3,8,9},然而第一行和第三行中已经有{8,9}了,所以{8,9}必有,然后{1,2,3}任选其一,所以红框内是{8, 9, a}。同理可分析剩余3组,得到的就是 (图3) 的结果。

我们有2个纯净顶行和18个混合顶行(图1)。

因此,总的来说,我们有2*(3!)^6+18*3*(3!)^6=56*(3!)^6 = 2612736个可能的补全到前三块。

2.2、优化减少外部循环

        在这个阶段,我们有一个B2块和B3块的所有可能性的列表。我们将遍历所有这些可能性,并为每个可能性填充剩余的块以形成有效的数独网格。外部循环将运行可能的B2块和B3块。然而,遍历B2和B3的所有 (2612736 种) 可能性将非常耗时。我们需要某种方法来减少我们必须循环的可能性的数量。我们将在这些块中确定数字的配置,这些配置为完整的网格提供了相同数量的完成方式。有效地,我们定义了B2/B3组态集合上的等价关系,使得同一类中的任意两个元素可以以相同数量的方式完成。

        幸运的是,我们可以应用很多操作来保持数独网格的数量不变。我们已经看到了重新标签的操作。但也有其他的,例如,如果我们交换B2和B3,那么每一种将B2-B3完成为完整网格的方式都会给我们一种将B3-B2完成为完整网格的唯一方式(只需交换B5和B6,以及B8和B9)。事实上,我们可以用任何我们选择的方式排列B1 B2和B3(尽管这改变了B1,但我们可以重新标记使B1回到标准形式)。此外,我们可以以我们希望的任何方式排列任何块中的列,对完整网格中的列执行相同的操作。我们看到B1-B3上有许多操作,这些操作给出了其他可能的顶部块,它们以相同数量的方式完成完整的网格。

2.2.1 辞典编纂的减少

取上面提到的 2612736 种可能性。我们首先将它们分类如下:

        1. 我们首先对B2和B3中的列进行排列,使第一个项按递增顺序排列。

        2. 然后,如果有必要,我们交换B2和B3,这样在字典中B2就会出现在B3之前(“词典顺序”)。

第一步将原本是3!种排列变成了1种递增顺序的排列,有B2和B3两个块,这样,给定任何一个网格,有(3!)^2 = 36 个网格衍生出相同数量的完成方法。

第二步是将B2B3或B3B2变成一种递增词典顺序,及减少两倍。

        总的来说,我们将需要考虑的可能性数量减少了72倍,我们的目录中有 2612736/72=36288 种可能性。这将我们的搜索减少到36288,这是可行的,尽管更多的减少是可取的。

然而,它为我们的缩减提供了一个良好的开端,将我们的目录缩减到可以更好地控制单个条目的大小。

2.2.2 精致的排列和重新标签

        事实上,我们还没有充分利用所有的排列和重新标记的可能性。其思想是遍历36288种可能性的三个块B1-B3的所有排列3!,以及这三个块中所有列的排列3!^3,使每个有6^4 = 1296种可能性。

        然后,我们查看新的第一个块,并重新标记它,使其成为标准形式,类似地重新标记B2和B3,然后对结果使用字典法约简。这再次提供了一个巨大的改进,将目录的大小减少到只有2051个可能的B2/B3对。(这2051对中的绝大多数恰好来自36288种可能性中的18 = 6^4/72。然而,有些是由更少的可能性产生的,因此有必要准确存储36288种可能性中产生给定块的可能性。)但这还不是全部我们可以对构型的三行进行3!种排列。也就是说,我们可以选择这些行的任意排列,然后将B1重新标记为标准形式。这进一步减少了测试区块B2和B3的416种可能性。

上面说的2051种或416种可能性,这些需要进行程序遍历才能得到,不能理解那我举一个例子,你可能就明白了:

现在有两个【B1B2B3】的组合,它们两都是36288中的一种可能。

S1                    S2
123 456 789            123 456 789        
456 789 123            456 978 312
789 231 564            789 312 645

我们可以通过交换1、3两行,然后标准化和B2B3顺序化,使得它们等价
交换S2的1、3两行 R(1,3),得到
789 312 645
456 978 312
123 456 789

然后将B1标准化,得到【1->7,2->8,3->9,4->4,5->5,6->6,7->1,8->2,9->3】
123 978 645
456 312 978
789 456 123

再然后B2、B3首列排序【978->789 645->456 第二列和第三列也要跟着动哦!】
123 789 456
456 123 789
789 564 231

最后将B2与B3首列首个数字排序【7>4 交换B2和B3块】
123 456 789
456 789 123
789 231 564

这个是不是就和S1一样了
所以这就是减少可能组合的过程,全部的36288个我们只有通过程序将它们都找出来

现在你懂的起了吧!

2.2.3 深度优化减少外部循环

虽然这种改进非常有用,但我们能做的削减越多,程序完成得就越快。的确,改善我们的外循环还有更多的可能性。下面是数独格子中最前面三行可能的排列方式:

考虑数字1和4的位置:

让我们重新标记以交换这两个数字:

很容易看出,任何完成这三个方块的网格也完成了相同的三个方块,在B1/B2中,1和4颠倒了:

因此,扩展原始三行的方法数与扩展这三行的方法数相同,因此我们只需计算一次。请注意,对于第2列和第9列中的数字5和8,以及第3列和第6列中的数字6和9,也可以执行相同的操作。我们要求B1的一列中的两个数字在B2/B3的一列中出现在相同的位置(当然,顺序相反)。然后,我们可以交换这些数字的其他两次出现。以下排列允许不少于六对数字:

该方法的扩展允许我们识别具有大小为2 × k(分别为k × 2)的子矩形的任意两个配置,其条目由具有相同数字的两列(分别为行)组成。

仅对2x2个子矩形使用此技巧将416个等价类减少到174个。使用2 × 3,3 × 2和4 × 2矩形可将这个列表减少到只有71个类。

这就完成了我们对区块B2和B3的讨论。

2.3、外部B1B2B3块的结论

编写了一个lua程序,生成所有36288个按字典顺序约简的配置,然后基于上述等价关系构建等价关系,即确定这些等价关系生成的关系的自反性、对称性和传递性外壳。然后程序生成一个代表类的列表和每个等价类的大小。实际上,选择的代表是对应等价类的字典顺序最小的成员。在最初的计算中,并非所有这些等价都实现了;我们将外部循环减少到运行306个类。随后,这些程序又在71名代表中进行了一次运行。得到的答案是一样的。

以下是71个类:

[456789,789123,123456]、[456789,789123,123465]、[456789,789123,123564]
[456789,789123,132465]、[456789,789123,132546]、[456789,789123,132564]
[456789,789123,231564]、[456789,789123,231645]、[456789,789132,123546]
[456789,789132,132546]、[456789,789132,213456]、[456789,789132,213546]
[456789,789132,213645]、[456789,789132,213654]、[456789,789132,231546]
[456789,789132,231564]、[456789,789132,231645]、[456789,789231,123645]
[456789,789231,132546]、[456789,789231,231564]、[456789,789231,231645]
[456789,789231,312456]、[456789,798132,213546]、[456789,798132,213645]
[456789,798132,231546]、[456789,798213,213564]、[456789,798213,213654]
[456789,897312,312564]、[457689,189237,263145]、[457689,189237,263154]
[457689,189237,263514]、[457689,189237,362145]、[457689,189237,362154]
[457689,189273,263145]、[457689,189273,263154]、[457689,189273,263514]
[457689,189273,362154]、[457689,189273,623154]、[457689,189273,632154]
[457689,189273,632514]、[457689,189327,362145]、[457689,189723,623145]
[457689,189723,623154]、[457689,189723,623514]、[457689,189723,632154]
[457689,189732,623514]、[457689,198723,236514]、[457689,198723,326514]
[457689,198723,632514]、[457689,198732,632514]、[457689,289137,361245]
[457689,289137,361254]、[457689,289137,631524]、[457689,289173,163452]
[457689,289173,613245]、[457689,289173,613254]、[457689,289731,163245]
[457689,289731,613254]、[457689,289731,613542]、[457689,298137,316245]
[457689,298137,316254]、[457689,298713,316245]、[457689,389271,612534]
[457689,389712,612345]、[457689,398217,126345]、[457689,398217,612345]
[457689,398721,126345]、[457689,398721,216354]、[457689,398721,612345]
[457689,891723,236514]、[457689,893271,216354]

看不懂是吧,我教你

对于[457689,893271,216354]

结果为

B2   B3

457 689

893 271

216 354

B1不用说当然是标准形式啦,完整的是

 B1  B2  B3

123 457 689

456 893 271

789 216 354

3、内循环

3.1、左侧的块:B4和B7

        对左列的完全相同的分析给出了左三列的可能补全数为56 x(3!)6 = 2612736(再次假设左上角的块是规范形式)。同样,我们可以对B4的行进行排列,或对B7的行进行排列,或交换B4和B7,使用词典法约简方法将其减少72倍至36288。上述一些缩减方法可用于进一步缩减B4/B7目录的规模。

        然而,在这个阶段,我们已经充分减少了B2/B3目录的大小,因此不需要对B4/B7目录进行完全优化。实际上,编写程序的第一作者认为,只对B4和B7的720个可能的第一列(第一列中剩余数字{2,3,5,6,8,9}的所有排列)运行循环更简单。同样,通过重新排序B4和B7的行,并在必要时交换B4和B7,我们将这些第一列的可能性减少到只有10种,而不存储其余的数据。如前所述,此时预测的运行时间非常低——在单个PC上只有几个小时——因此,通过循环处理所有区块B4和B7的可能性目录所获得的可能的加速,通过上面列出的一些方法减少,几乎不值得实现。

3.2、内部循环的策略

在此阶段,填充最上面的三个块B1-B3,以及块B4和B7的第一列。第一作者编写了一个回溯算法,运行按以下顺序输入数字的可能性:

这个顺序是基于观察到每个数独方格也是一个拉丁方格。为了保持较低的分支因子,最好从剩余最短的列或行开始创建条目。

这被证明是一种非常有效的方法,在一台PC上耗尽了给定配置的区块B2和B3的可能性,只需不到2分钟。

二、研究结果简写

存在No = 6670903752021072936960≈6.671 x10^21个有效数独网格。去掉9!和72^2来自块B2和B3的顶行的重新标记和字典化缩减。在块B4和B7的左列中,这就留下了3546146300288 = 2^7 x 27704267971的排列,最后一个因子是素数。

三、最后的最后

数独是一个很有趣的益智游戏,很早我就喜欢它了,这也是我研究它的原因,我们现在只是完成了合法数独生成,但是我们还需要研究如何解题,这才是最重要的,以及如何生成一个让大家头疼的数独题,也是只得我们研究学习的,后面我也会继续对解数独和创建数独题进行思考研究。有兴趣的小伙伴也可以一起进群来讨论学习。

群名称:美丽的数独_sudoku

群   号:922514302

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/267354.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

前端未死,顺势而生

随着人工智能和低代码的崛起,“前端已死”的声音逐渐兴起。前端已死?尊嘟假嘟?快来发表你的看法吧! 一、“前端已死”因何而来? 在开始讨论之前,首先要明确什么是“前端”。 所谓前端,主要涉及…

vue使用ElementUI搭建精美页面入门

ElementUI简直是css学得不好的同学的福音 ElementUI官网: Element - The worlds most popular Vue UI framework 安装 在vue文件下,用这个命令去安装Element UI。 npm i element-ui -S step1\先切换到vue的目录下去,注意这里面的WARN不是…

每日一题:LCR 095.最长公共子序列(DP)

题目描述: 给定两个字符串 text1 和 text2,返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 ,返回 0 。 一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些…

R语言基础 | 安徽某高校《统计建模与R软件》期末复习

第一节 数字、字符与向量 1.1 向量的赋值 c<-(1,2,3,4,5) 1.2 向量的运算 对于向量&#xff0c;我们可以直接对其作加&#xff08;&#xff09;&#xff0c;减&#xff08;-&#xff09;&#xff0c;乘&#xff08;*&#xff09;&#xff0c;除&#xff08;/&#xff09…

使用Python实现发送Email电子邮件【第19篇—python发邮件】

文章目录 &#x1f47d;使用Python实现发送Email电子邮件&#x1f3b6;实现原理&#x1f3c3;Python实现发送Email电子邮件-基础版&#x1f46b;实现源码&#x1f646;源码解析 &#x1f487;Python实现发送Email电子邮件-完善版&#x1f46b;实现源码&#x1f646;源码解析&am…

随机无限采集JK妹妹高清壁纸下载HTML网页源码

源码介绍 美图网站千千万&#xff0c;美图自己说了算&#xff01;本源码由宋佳乐博客 开发&#xff0c;首页图片做了浏览器窗口自适应&#xff0c;最大化占满PC浏览器和移动浏览器的窗口&#xff0c;并且防止出现滚动条。 功能介绍 首页图片设置了4个点击功能区&#xff0c;…

【数据结构入门精讲 | 第十一篇】一文讲清树

在上一篇中我们进行了排序算法的专项练习&#xff0c;现在让我们开始树的知识点讲解。 目录 树二叉搜索树二叉排序树哈夫曼树折半查找判定树kruskal算法、prim算法、最小生成树完全二叉树 树 树是一种非线性的数据结构&#xff0c;也是一种表示一对多关系的数据结构&#xff0…

Flink CDC 1.0至3.0回忆录

Flink CDC 1.0至3.0回忆录 一、引言二、CDC概述三、Flink CDC 1.0&#xff1a;扬帆起航3.1 架构设计3.2 版本痛点 四、Flink CDC 2.0&#xff1a;成长突破4.1 DBlog 无锁算法4.2 FLIP-27 架构实现4.3 整体流程 五、Flink CDC 3.0&#xff1a;应运而生六、Flink CDC 的影响和价值…

Python 数据分析 Matplotlib篇 plot设置线条样式(第2讲)

Python 数据分析 Matplotlib篇 plot设置线条样式(第2讲)         🍹博主 侯小啾 感谢您的支持与信赖。☀️ 🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ�…

算法基础之完全背包问题

完全背包问题 核心思想&#xff1a;集合表示&#xff1a; f[i][j]表示前i种物品 总容量不超过j的最大价值 求f[i][j]时 分为选0、1、2……n个第i种物品 n种情况 每种情况为 f[i][j-kv] (取k个第i种物品) 即f[i][j] max(f[i-1][j] , f[i-1][j-v]w,f[i-1][j-2v]2w….f[i-1][j-k…

【自用】Ubuntu20.4从Vivado到ddr200t运行HelloWorld

【自用】Ubuntu20.4新系统从输入法到ddr200t运行HelloWorld 一、编辑bashrc二、Vivado2022.2安装三、编译蜂鸟E203自测样例1. 环境准备2. 下载e203_hbirdv2工程文件3. 尝试编译自测案例1. 安装RISC-V GNU工具链2. 编译测试样例 4. 用vivado为FPGA生成mcs文件1.准备RTL2.生成bit…

Centos 7.9安装Oracle19c步骤亲测可用有视频

视频介绍了在虚拟机安装centos 7.9并安装数据库软件的全过程 视频链接&#xff1a;https://www.zhihu.com/zvideo/1721267375351996416 下面的文字描述是安装数据库的部分介绍 一.安装环境准备 链接&#xff1a;https://pan.baidu.com/s/1Ogn47UZQ2w7iiHAiVdWDSQ 提取码&am…

贝叶斯球快速检验条件独立

贝叶斯球 定义几个术语&#xff0c;描述贝叶斯球在一个结点上的动作&#xff1a; 通过&#xff08;pass through&#xff09;&#xff1a;从当前结点的父结点方向过来的球&#xff0c;可以访问当前结点的任意子结点&#xff08;父->子&#xff09;。从当前节点的子结点方向…

基于电商场景的高并发RocketMQ实战-NameServer内核原理剖析、Broker 主从架构与集群模式原理分析

&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308; 【11来了】文章导读地址&#xff1a;点击查看文章导读&#xff01; &#x1f341;&#x1f341;&#x1f341;&#x1f341;&#x1f341;&#x1f341;&#x1f3…

Prometheus介绍和安装

Prometheus介绍和安装 1. Prometheus介绍 Prometheus&#xff08;普罗米修斯&#xff09;是一个最初在SoundCloud上构建的监控系统。自2012年成为社区开源项目&#xff0c;拥有非常活跃的开发人员和用户社区。为强调开源及独立维护&#xff0c;Prometheus于2016年加入云原生云…

指标体系构建-03-交易型的数据指标体系

参考&#xff1a; 本文参考 1.接地气的陈老师的数据指标系列 2.科普 | 零售行业的数据指标体系及其含义、应用阶段 3.”人货场”模型搞懂没&#xff1f;数据分析大部分场景都能用&#xff01; 4.一分钟读懂广告投放各计费CPM、CPC等&#xff08;公式推导干货&#xff09; 5.AA…

mysql 数据编译安装以及参数说明 安装包下载

目录 MySQL 官网地址官网下载源码包安装步骤修改密码 MySQL 官网地址 https://dev.mysql.com/doc/ 官网下载源码包 安装步骤 # 所需要的依赖及安装mysql的包" [rootmysql_source ~]# yum -y install ncurses ncurses-devel openssl-devel bison libgcrypt gcc gcc-c ma…

前缀和+单调双队列+贪心:LeetCode2945:找到最大非递减数组的长度

本文涉及知识点 C算法&#xff1a;前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频 单调双队列 贪心 题目 给你一个下标从 0 开始的整数数组 nums 。 你可以执行任意次操作。每次操作中&#xff0c;你需要选择一个 子数组 &#xff0c;并将这个子数组用它所…

AcWing 1238. 日志统计(双指针,滑动窗口)

题目&#xff1a; 1238. 日志统计 - AcWing题库 数据范围 输入样例&#xff1a; 7 10 2 0 1 0 10 10 10 10 1 9 1 100 3 100 3输出样例&#xff1a; 1 3 思路&#xff1a;双指针 代码&#xff1a; #include<iostream> #include<cstdio> #include<cmath>…

如何从 Android 手机免费恢复已删除的通话记录/历史记录?

有一个有合作意向的人给我打电话&#xff0c;但我没有接听。更糟糕的是&#xff0c;我错误地将其删除&#xff0c;认为这是一个骚扰电话。那么有没有办法从 Android 手机恢复已删除的通话记录呢&#xff1f;” 塞缪尔问道。如何在 Android 上恢复已删除的通话记录&#xff1f;如…