zoukankan      html  css  js  c++  java
  • 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);
    

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

    在这里插入图片描述

  • 相关阅读:
    AspDotNetStorefront客户化开始
    "超时时间已到。在操作完成之前超时时间已过或服务器未响应。"另一个原因
    转:只打开一个窗口和关闭窗口而不出现提示
    .net 数据格式设置
    SQLServer导出数据表中数据的存储过程
    游标、临时表、嵌套游标使用一列
    转:将图片转换成16进制的代码写入文本
    根据文件后缀返回Http的ContentType类型的函数
    正确配置p6spy后没有日志输出的一个可能的原因
    C99 声明 + 表达式 + 词法 部分Grammar
  • 原文地址:https://www.cnblogs.com/mach-pupil/p/12535363.html
Copyright © 2011-2022 走看看