DLX演算法及應用(三)殺手數獨
(馬上就要開學了,抽空把這個坑填上。。。。。。)
先來介紹下什麼是殺手數獨
如圖所示(來源:百度百科),殺手數獨就是在經典數獨的基礎上,又多加了一組限制條件:每一個虛線框稱作一個區,要求區內的數字不能重複,且區內數字總和等於該區左上角的數字。
殺手數獨起始是沒有一個數字的,挺難的= =
好像在哪裡看到這樣一個提問:殺手數獨為什麼叫殺手數獨?---因為是時間的殺手。。。。。= =
正好之前在研究DLX演算法,就想試試能不能將殺手數獨轉換為一個精確覆蓋問題,網上搜了好久也沒有發現相關的資源,估計沒人這麼無聊吧= =,那我就自己試著構造一下吧。
以下正文:
那麼殺手數獨就是在經典數獨的4個限制條件基礎上,新增了一條:
虛線框內數字不重複且和為給出的數字
那麼我們就再新增405列(因為81個格子總和為405),其中將405列分成若干組,每一組就代表了一個虛線框,每一組的列數就為對應虛線框中數字之和
讓我們單獨拿出一個虛線框來考慮:
對於一個包含了{a1,a2,...,an}n個格子和為Sn的虛線框,我們令
Sn = a1+a2+...+an (1 ≤ a1 < a2 < ... < an ≤ 9)
這樣a1最小為max{1, Sn-(n-1)(20-n)/2},最大為[Sn/n - (n-1)/2]下取整
假設其包含了3個格子,和為20,那麼它就對應了20列
可能的情況就為
3+8+9 4+7+9 5+6+9 5+7+8
這樣,任意一個格子都可能是{3,4,5,6,7,8,9}中的一個
但如果第一個格子為3,剩下2個格子就只可能為8、9
如果第一個格子為4,剩下2個格子就只可能為7、9
.....
如何用01矩陣表達這種關係呢?
再觀察下上面的4種情況,發現3、4、5只可能出現在最開始的位置,6只可能跟在5的後面,7可以跟在4或5的後面,8可以跟在3的後面,也可在最後,9只可能在最後
也就是說有1種3、4、5、6、9,2種7、8,也就是說一個格子可能為上述9種可能中的一種,那我們這樣構造:
第一個格子可能為3,前324列和經典數獨的構造方式一樣,在該虛線框對應的列組中,前3列為1
可能為4,前4列為1
可能為5,前5列為1
可能為6,第6~11列為1
可能為7(1),第5~11列為1
可能為7(2),第6~12列為1
可能為8(1),第4~11列為1
可能為8(2),第13~20列為1
可能為9,第12~20列為1
剩下的2個格子同樣如此
再舉個直觀的例子:5 = 1+4、2+3,構造的矩陣如下
... 0 ... 1 ... 1 0 0 0 0 ...
... 0 ... 1 ... 1 1 0 0 0 ...
... 0 ... 1 ... 0 0 1 1 1 ...
... 0 ... 1 ... 0 1 1 1 1 ...
... 1 ... 0 ... 1 0 0 0 0 ...
... 1 ... 0 ... 1 1 0 0 0 ...
... 1 ... 0 ... 0 0 1 1 1 ...
... 1 ... 0 ... 0 1 1 1 1 ...
前2個01列是前324列(其實是前81列)中的2列,用來確定位置,後面5列表示該虛線框
如果先選擇了第1行,那麼根據位置資訊,就會排除掉2~4行,再根據虛線框的資訊,排除掉5、6行,第7行無法完全覆蓋,所以選擇第8行,即1+4
這樣就可以構造出一個若干行,324+405列的01矩陣,再套用我們之前寫好的DLX模板,就可以快速的解決殺手數獨問題了!!
程式碼什麼的麻煩各位去下一下,所需積分0,給我加點資源分吧^_^
下載地址:
殺手數獨例題及程式:
原始碼: