Shidoku求解器matlab代码

时间:2014-06-03 13:51:00

标签: matlab sudoku

我正在尝试在MATLAB中编写一个Shidoku(更小更简单的4x4 Sudoku变体)求解器代码。 我找到了一些soduko解算器(9x9),但我不能修改它们以适合我的问题。例如:

% Solving Sudoku Using Recursive Backtracking

function X = sudoku(X) 
% SUDOKU  Solve Sudoku using recursive backtracking. 
%   sudoku(X), expects a 9-by-9 array X. 
 % Fill in all “singletons”. 
 % C is a cell array of candidate vectors for each cell. 
 % s is the first cell, if any, with one candidate. 
 % e is the first cell, if any, with no candidates. 
 [C,s,e] = candidates(X); 
 while ~isempty(s) && isempty(e) 
    X(s) = C{s}; 
    [C,s,e] = candidates(X); 
 end 
 % Return for impossible puzzles. 
 if ~isempty(e) 
    return 
 end 
 % Recursive backtracking. 
  if any(X(:) == 0) 
    Y = X; 
    z = find(X(:) == 0,1);    % The first unfilled cell. 
    for r = [C{z}]            % Iterate over candidates. 
       X = Y; 
       X(z) = r;              % Insert a tentative value. 
       X = sudoku(X);         % Recursive call. 
       if all(X(:) > 0)       % Found a solution. 
          return 
       end 
     end 
   end 
% ------------------------------ 
   function [C,s,e] = candidates(X) 
      C = cell(9,9); 
      tri = @(k) 3*ceil(k/3-1) + (1:3); 
      for j = 1:9 
         for i = 1:9 
            if X(i,j)==0 
               z = 1:9; 
               z(nonzeros(X(i,:))) = 0; 
               z(nonzeros(X(:,j))) = 0; 
               z(nonzeros(X(tri(i),tri(j)))) = 0; 
               C{i,j} = nonzeros(z)'; 
            end 
         end 
      end 
 L = cellfun(@length,C);   % Number of candidates. 
 s = find(X==0 & L==1,1); 
 e = find(X==0 & L==0,1); 
 end % candidates 
end % sudoku

任何帮助都会有所帮助。

1 个答案:

答案 0 :(得分:1)

只需将问题维度从3减少到2(我现在知道它是“9x9”而不是“3x3”,但是拼图的重要维数是N = 3):

    % SHIDOKU  Solve Shidoku using recursive backtracking. 
    %   shidoku(X), expects a 4-by-4 array X.
    function X = shidoku(X) 

            [C,s,e] = candidates(X); 
            while ~isempty(s) && isempty(e) 
                    X(s) = C{s}; 
                    [C,s,e] = candidates(X); 
            end;

            if ~isempty(e) 
                    return 
            end; 

            if any(X(:) == 0) 
                    Y = X; 
                    z = find(X(:) == 0,1);

                    for r = [C{z}]
                            X = Y; 
                            X(z) = r;
                            X = shidoku(X);
                            if all(X(:) > 0)
                                    return;
                            end;
                    end;
            end;

            % ------------------------------ 
            function [C,s,e] = candidates(X) 
                    C = cell(4,4); 
                    bi = @(k) 2*ceil(k/2-1) + (1:2); 
                    for j = 1:4 
                            for i = 1:4 
                                    if X(i,j)==0 
                                            z = 1:4; 
                                            z(nonzeros(X(i,:))) = 0; 
                                            z(nonzeros(X(:,j))) = 0; 
                                            z(nonzeros(X(bi(i),bi(j)))) = 0; 
                                            C{i,j} = transpose(nonzeros(z)); 
                                    end;
                            end;
                    end;

                    L = cellfun(@length,C);   % Number of candidates. 
                    s = find(X==0 & L==1,1); 
                    e = find(X==0 & L==0,1); 
             end % candidates

    end % shidoku