MATLAB 解数独

数独是一种较为常见的游戏,一般有4乘4、6乘6、9乘9几种,就像下面这种,本文也是主要求解此类数独。

图一

此外还有一些奇形怪状的,如下图两种,均是不规则的,在此并不会涉及,但会在以后发布代码以及过程。

在这里插入图片描述

在这里插入图片描述

首先在MATLAB中新建一个文本文件,用来存放原始数独,用空格间隔开,用‘0’来替代需要填数值的位置,就像下图,然后命名为date.txt即可。

在这里插入图片描述

接下来新建一个脚本文件,命名为Untiltled2.m。在Untiltled2.m中打开文本,并存入变量shudu之中,在调用disp函数,将shuzu变量输出到命令行中。

shudu= textread('date.txt');
disp(shudu);

接下来判断该格子受否可以填入某数字,如第一张图中,第一个格子所填的数,用该满足在该行,该列,以及该小单元内不能有重复,因此,需要对是否有重复进行判断。

首先是进行行判断,要求遍历1~9九个数字,如果在该行中的原始数据已经存在该数字,即返回false,如果没有,即返回true。新建一个函数,命名为chack_hang,用来判断第i行,第j列中是否可以填数值num,返回值是false或者true。

function result= chack_hang( shudu,i,j,num )%定义函数
    result=true;%默认为真,值可以传入,并进行下面的判断
    for lie=1:9
        if shudu(i,lie)==num% 当
            result=false;
            break;
        end
    end
end

再是对列进行遍历,与行遍历的原理相同。

function result= chack_lie( shudu,i,j,num )
    result=true;
    for hang=1:9
        if shudu(hang,j)==num
            result=false;
            break;
        end
    end
end

当对行以及列遍历完成后,在对每一个大格子进行遍历。

function result= chack3_3( shudu,i,j,num )
result=true;
maxhang=floor((i-1)/3)+1;
maxlie=floor((j-1)/3)+1;
hang_to=maxhang*3;
hang_from=hang_to-2;
lie_to=maxlie*3;
lie_from=lie_to-2;
for i=hang_from:hang_to
    for j=lie_from:lie_to
        if shudu(i,j)==num
            result=false;
            break;
        end
    end
end

由于有些数独有主对角线元素不能相同的规定,因此在编写一个控制主对角线元素的函数。

function  result= chack_xie(shudu,i,j,num)
result = true;
if i==j
    for hang=1:9
        if shudu(hang,hang)==num
            result=false;
            break;
        end
    end
end
if i==10-j
    for hang=1:9
        if shudu(hang,10-hang)==num
            result=false;
            break;
        end
    end
end

最后在将前三组的便利组合起来,以便找出所有符合的数字。

function result = chack_all(shudu,i,j,num)
    if chack_hang(shudu,i,j,num)==false
        result=false;
    elseif chack_lie(shudu,i,j,num)==false
        result=false;
    elseif chack3_3(shudu,i,j,num)==false
        result=false;
    elseif chack_xie(shudu,i,j,num)==false %要求主对角线上的元素不能想等
        result=false;
    else 
        result=true;
    end
end

最终通过函数递归调用,来寻找出所有的可能结果。

function jsd(shudu,id)
if id>81
    disp(shudu)
else
    hang=floor((id-1)/9)+1;
    lie=mod(id-1,9)+1;
    if shudu(hang,lie)~=0
        jsd(shudu,id+1);
    else
        for num=1:9
            if chack_all(shudu,hang,lie,num)==true
                shudu(hang,lie)=num;
                jsd(shudu,id+1);
            end
        end
    end
end
end

新建一个脚本文件,在里面调用函数jsd即可。

shudu= textread('date.txt');
disp(shudu);
jsd(shudu,1);

即可求解出数独的解。如上述数独中的求解结果。

在这里插入图片描述

原文地址:https://www.cnblogs.com/mach-pupil/p/12535363.html