julia常用矩阵函数_用Julia玩数独——从入门到索然无味

e54c801dd2f517861a2aa7667b5a1f96.png

刷电影的时候被网页推了个数独游戏的广告,入坑后发现的确是个杀时间的好东西。

数独(sudoku)的基本规则是:在9x9的格子盘里,给定初始的几个格子的数字,需要在剩余空格里填上1到9之间的整数,最后保证每一行、每一列还有每一个3x3的九宫格里都是1至9的数字。其他形式的数独(比如对角线数独、锯齿数独等)都是在这个规则基础上衍生的。

我下了个手机APP,从最简单的开始玩,界面难度是这样的

d27d49994b78078943d776cbeb760486.png

一共有43个空格,占比53.1%,将近一半。

中级难度是这样的

fb03f9799646e871428a22cd56e9d2a0.png

一共有51个空格,占比63%。

hard模式是这样的

0f28951d839134d64491ffbcecb30f7d.png

一共56个空格,占比69%

专家难度是这样的

3ce07ea902e29a2382ccfb84119a27ab.png

有58个空格,占比72%

以上都是我随机开的局,具体数据可能会有变化,但总体趋势是空格占比越高,难度越大。不过各个数字的具体分布也同样决定了难度,但这个不好统计。

因为我以前只听说过,但从来没玩过,所以一开始玩简单的,大概每把需要10-15分钟才能搞定。既然是杀时间来玩的,我就比较喜欢learning by doing的过程,不参考网上的技巧,大概总结出了一个套路流程:

【1】找到开局给出的最小数字N(通常是1),N所在的九宫格不可能再有N了,但与该九宫格纵向或横向平行的九宫格里一定有且仅有一个N。所以通过排除同行同列只能有一个N的方法,在平行的三个九宫格里如果有两个九宫格都有N,那么可以确定第三个九宫格里N的行或列,然后如果运气好的话,有些空已经在一开始就填上了,或者利用非平行的九宫格里的数字N排除一些空格,就可以确定这个九宫格里N的位置。
【2】用上面的方法把能看到的所有N都试一遍,没法进一步确定更多N的位置了,就N+1,然后重复【1】,直到N>9。

【3】前两步走完,应该能填很多空了,可以继续从N=1开始,也可以从空格最少的行或列开始,比如该列有两个空格,还缺少n和m两个数,那么再考虑同一个九宫格内、同一行、同一列里只能有个一个n或m,逐一排除可能性,直至填满所有空格。

用这个套路后,简单模式我基本都在五分钟内搞定,最快不到两分半,统计数据为

4f63bc78cc5e99af265c0d223033264b.png

medium模式也可以在十分钟内搞定了

6fca564e11fc4076f4f9c3aa12ac4c16.png

但对于hard模式和expert模式,我明显遇到了瓶颈,这个套路方法好像不太有效唉,很多时候甚至无从下手,从我下面的两个统计数据也可以看到

b80de79d8cf327907d64a27ec25b9122.png

hard模式每把至少耗我半个小时,有时候是我解不出来主动放弃了。。。更别提expert模式了

6e4a4f08380fcbbfaa365ffcafea6997.png

但为什么最难的expert模式里我的最好成绩还不到五分钟?事实上,在尝试了几个小时都解不出一个expert模式后,我陷入深深的自我怀疑,然后痛定思痛,决定用Julia直接干。

这不就是一个路径优化问题嘛,而Julia中就有JuMP.jl、GLPK.jl这些包,专门用来解决各种优化问题。所以我可以根据游戏规则设计相应的求解函数,然后将每把开局输入到一个矩阵,空格全用0代替,硬核地得到结果。

(Julia代码可以在我的GitHub里找到:https://github.com/SteveShelnanMa/Slove_Sudoku)

以上图中的expert难度为例,给定的开局是:

7b5dae0efd5f5353f79c4a1b4c39bd63.png

然后带入函数内运算

bd0bb34476872cd26b19c8571558fd96.png

输出结果为

191658b5f059737d84db459a22aa776a.png

把这个结果填到我的数独游戏里,然后就

46cb42ec93f47ece83f9a77d00c36c4a.png

现在Julia把这个数独变成了一个比手速的游戏,索然无味。

这一刻,我彻底失去了对数独的兴趣。。。

(文章来自我的个人微信公众号:眀斋士大夫)


版权声明:本文为weixin_35850219原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。