Finally, we made a dance links ..
First, let's talk about dancing links, which is probably a magic method to deal with a wide range of coverage issues.
This algorithm processes a model called exact coverage, which means to give you a 01 matrix and requires you to select several rows so that each column has only one
Different from other searches, dancing links searches for the row to be overwritten by each column, and uses a two-way cross-linked list to link all 1 to remove redundancy, the magic effect of improving the running speed is remarkable, with three boxes of one course of treatment ..
Okay. Just now there was a bit of nonsense. (The specific implementation of the dancing links can be referred to in some papers or code)
Let's talk about how DT turns into a precise coverage model.
It can be imagined that the number of choice with a lot of restrictions is nothing more than the exact coverage, that is, the selection of rows with only one restriction condition for each column,
Therefore, we only need to apply these constraints to exact coverage. How can this problem be solved?
Taking 9 Sudoku as an example, in theory, each grid can be filled with 1 ~ 9.
If we enter K in column J of row I to correspond to the row in exact overwrite, after column J of row I is filled with K, row I cannot enter k any more, and column J cannot enter k any more. column G [I, j] cannot enter k any more. In fact, the grid in column J of row I cannot be filled with another number.
This can be thought of as having only one column in exact coverage! Then we enter row I as K, column J as K, and column G [I, j] K and column J of row I correspond to columns with precise and precise coverage, then, put the corresponding column in the row such as K in column J of row I to 1 (that is, fill K in row I, fill K in column J, and fill in column G [I, j] K and column J of row I put this grid column 1), exactly fit all the constraints of the sudoku, you can use the exact coverage model!
Dancing links = efficiency + speed.
In the test of Sudoku, even a lot of optimized direct searches (including the version with State compression optimization mentioned in the training team's paper in a certain year) won't be lifted in front of the dancing links.
Really amazing ~~
Code: (the code is similar, so I will post a 16-digit code here)
PKU 3076
Program syj; {sudoku_dancing links} <br/> const nn = 16; oo = maxlongint SHR 1; <br/> var U, D, L, R, H, TX, ty, TZ: array [0 .. (nn + 1) * NN * 4] of longint; <br/> size: array [1 .. nn * NN * 4] of longint; <br/> map: array [1 .. nn, 1 .. nn] of longint; <br/> n, m, TOT: longint; OK: Boolean; <br/> procedure print; <br/> var I, j: longint; <br/> begin <br/> for I: = 1 to n do begin <br/> for J: = 1 to n do write (CHR (Map [I, j] + 64); <br/> writeln; <Br/> end; <br/> writeln; <br/> // writeln; Inc (TT); <br/> // writeln (TT ); <br/> // close (input); close (output); <br/> // halt; <br/> OK: = true; <br/> end; <br/> Procedure cover (I: longint); <br/> var J, K: longint; <br/> begin <br/> L [R [I]: = L [I]; R [L [I]: = R [I]; J: = d [I]; <br/> while j <> I do begin <br/> K: = R [J]; <br/> while K <> J do begin <br/> U [d [k]: = U [k]; d [U [k]: = d [k]; Dec (size [H [k]); <br/> K: = R [k]; <br/> E Nd; <br/> J: = d [J]; <br/> end; <br/> procedure recover (I: longint ); <br/> var J, K: longint; <br/> begin <br/> L [R [I]: = I; R [L [I]: = I; J: = U [I]; <br/> while j <> I do begin <br/> K: = L [J]; <br/> while K <> J do begin <br/> U [d [k]: = K; d [U [k]: = K; INC (size [H [k]); <br/> K: = L [k]; <br/> end; <br/> J: = U [J]; <br/> end; <br/> procedure DLX; <br/> var I, J, K, Min: longint; <br/> begin <br/> I: = R [0]; min: = OO <br/> while I <> 0 do begin <br/> If size [I] <= min then begin //!! <= <Br/> min: = size [I]; J: = I; <br/> end; <br/> I: = R [I]; <br/> end; <br/> If min = 0 Then exit; <br/> If min = oo then begin <br/> Print; exit; <br/> end; <br/> cover (j); I: = d [J]; <br/> while I <> J do begin <br/> K: = R [I]; Map [TX [I], Ty [I]: = TZ [I]; <br/> while K <> I do begin <br/> cover (H [k]); map [TX [K], Ty [k]: = TZ [k]; <br/> K: = R [k]; <br/> end; <br/> DLX; If OK then exit; <br/> K: = L [I]; Map [TX [I], Ty [I]: = 0; <br/> while K <> I do begin <br/> recover (H [k]); map [TX [K], Ty [k]: = 0; <br/> K: = L [k]; <br/> end; <br/> I: = d [I]; <br/> end; <br/> recover (j); <br/> end; <br/> function calc (I, j: longint): longint; <br/> begin calc: = (I-1) Div M * m + (J + s-1) Div m; end; <br/> procedure Init; <br/> var I, J, K, II, KK: longint; <br/> CC: Char; <br/> begin <br/> tot: = N * n * 4; <br/> for I: = 1 to tot do begin <br/> L [I]: = I-1; R [I]: = I + 1; U [I]: = I; d [I]: = I; <br/> end; <br/> r [0]: = 1; R [tot]: = 0; II: = tot; <br/> for I: = 1 to n do <br/> for J: = 1 to n do <br/> for K: = 1 to n do begin <br/> Inc (TOT); TX [tot]: = I; ty [tot]: = J; TZ [tot]: = K; H [tot]: = (I-1) * n + k; Inc (size [H [tot]); <br/> L [tot]: = tot + 3; R [tot]: = tot + 1; U [tot]: = U [H [tot]; d [tot]: = H [tot]; <br/> d [U [H [tot]: = tot; U [H [tot]: = tot; <br/> Inc (TOT ); TX [tot]: = I; ty [tot]: = J; TZ [tot]: = K; H [tot]: = (J-1) * n + K + N * n; Inc (size [H [tot]); <br/> L [tot]: = tot-1; R [tot]: = tot + 1; U [tot]: = U [H [tot]; d [tot]: = H [tot]; <br/> d [U [H [tot]: = tot; U [H [tot]: = tot; <br/> Inc (TOT ); TX [tot]: = I; ty [tot]: = J; TZ [tot]: = K; H [tot]: = (calc (I, j)-1) * n + K + N * n * 2; Inc (size [H [tot]); <br/> L [tot]: = tot-1; R [tot]: = tot + 1; U [tot]: = U [H [tot]; d [tot]: = H [tot]; <br/> d [U [H [tot]: = tot; U [H [tot]: = tot; <br/> Inc (TOT ); TX [tot]: = I; ty [tot]: = J; TZ [tot]: = K; H [tot]: = (I-1) * n + J + N * n * 3; Inc (size [H [tot]); <br/> L [tot]: = tot-1; R [tot]: = tot-3; U [tot]: = U [H [tot]; d [tot]: = H [tot]; <br/> d [U [H [tot]: = tot; U [H [tot]: = tot; <br/> end; <br/> for I: = 1 to n do begin <br/> for J: = 1 to n do begin <br/> Read (CC ); if cc = '-' Then continue; <br/> K: = ord (CC)-64; <br/> KK: = 4 * (I-1) * n + (J-1) * n + k-1) + II; <br/> for KK: = KK + 1 to KK + 4 Do begin <br/> map [TX [Kk], Ty [Kk]: = TZ [Kk]; <br/> cover (H [Kk]); <br/> end; <br/> readln; <br/> end; <br/> end; <br/> begin <br/> N: = nn; M: = round (SQRT (n )); <br/> while not seekeof do begin <br/> OK: = false; Tot: = 0; <br/> fillchar (size, sizeof (size), 0 ); <br/> fillchar (MAP, sizeof (MAP), 0); <br/> Init; <br/> DLX; <br/> readln; <br/> end; <br/> end. <br/>
Unfortunately, the speed is still a little slower than the weird dynamic version of DLX of SHIELD.
Also, the place where the least one column is selected at a time. If the value <= is about 3000 ms, the value <is MS +.
Because the order of my columns is "row"> "column"> "Palace"> "Grid", it is estimated that the restriction condition card in the back of the palace is tight, and it will be better for all the first selection and next selection, this place has taken me for a long time