Sudoku solving algorithms
想着写个数独吧!
然后网上一搜一堆代码就不想写了……
(醒醒不能这样)
基本思路和https://github.com/shenxgan/sudoku类似
然后代码库
https://github.com/Birdy-C/Algorithm-Code-Collection/tree/master/algorithm/Sudoku
基本思路
[1] 确定这一行已经确认的数字对这个格子造成的约束
[2] 判断每一行/列/框是不是只有一个地方能填这个数字
这两个都满足之后取最小的分支进行递归(比较懒不想写迭代了)
解法
由一个81维的int数组记录可能性。
每一个int,二进制11111111表示9个数字都可能出现,001000000表示这个数字确定为7。
对于每个数字做对应的横线、总线、格子的三次范围限定。
对这九个数字,除去该数字,求出其他八个数字的或表示可能的数字canHave、求出其他八个数字中值确定的或表示已经确定的值mustHave。
比方说这一行是 1 2 3 4 5 6 7 (8或9) _
那么对于 _ 这个位置求解,canHave的值就是(二进制) 111111111, mustHave就是 001111111。
然后利用这个限制前面的[1][2]两个条件。
由mustHave可以直接限制条件[1].
由canHave可以判断条件[2],即如果canHave不是11111111的话,那么那个欠缺的格子一定由 _ 这个位置补上。
但是由以上还是不够解出所有的解的……所以接下来就是递归了。
取出无法确定的格子里可能数量最小的一个比如是第5格,它可能是填4或者7.
那么就开两个分支,一支设置这一格为4,一支设置不为4(这样它会发现这个格子只能是7)。然后对这两支分别求解并且统计解的数量。
其他
最麻烦的是运算符优先级!给了我一万个bug!要打人了!
启发式随机搜索
https://en.wikipedia.org/wiki/Sudoku_solving_algorithms
维基上介绍的随机搜索算法其实很想试试但是脑补了一下怎么感觉那么不靠谱……
错误是怎么计算的,取横纵格子最高的一个咩。
想不到很好的”Shuffle”的方式。
现在能想到的只有:
给每一行随机的填上1-9.统计纵向和框的错误率之和。然后Shuffle是交换一行的格子的值。
但是感觉不知道会不会陷入局部最优……而数独这种局部最优没有任何意义。
偏偏直接递归写出来效率还行那就,就这样吧……
生成数独
一开始觉得我都写完了生成还不简单咩……然后后来发现还真没那么简单……
发现几个大型的网站上的数独(测了几个)都是只有唯一解的。
反正这个再说好了(躺平)
求出来的解的数量没有做很认真严肃的校验(大概或许可能是对的吧)