数学实验

田颢

目录

  • 1 第1章 课程概论
    • 1.1 数学实验课程概论
    • 1.2 为什么要学习数学实验课程
    • 1.3 如何学习数学实验课程
    • 1.4 数学实验课程与其他课程的关系
    • 1.5 课程教材简介
    • 1.6 参考书目
  • 2 第二章 MATLAB软件概览
    • 2.1 第一课: MATLAB简介
    • 2.2 第二课:MATLAB的安装与启动
    • 2.3 第三课 常用命令与技巧
    • 2.4 第四课 程序设计基础
  • 3 第三章 微积分实验
    • 3.1 第一课 函数的图像
    • 3.2 第二课 极限的计算
    • 3.3 第三课 导数
    • 3.4 第四课 积分
    • 3.5 第五课 级数
    • 3.6 第六课 微分方程
  • 4 第四章 线性代数实验
    • 4.1 第一课 多项式的计算
    • 4.2 第二课 矩阵计算
    • 4.3 第三课 线性方程
  • 5 第五章 概率统计实验
    • 5.1 第一课 统计数据
    • 5.2 第二课 参数估计
    • 5.3 第三课 随机模拟
  • 6 第六章 综合实验
    • 6.1 第一课 二分法
    • 6.2 第二课 斐波那契序列
    • 6.3 第三课 数独游戏问题
第三课 数独游戏问题

数独游戏

学会利用MATLAB中的集合交、并、补运算查找特定元素,编写程序.

1 数独游戏简

数独(sudoku)来自日文,但概念源自“拉丁方块”,据说是18世纪瑞士数学家欧拉发明的.数独游戏在日本和欧美很流行,人们把它作为锻炼脑筋的好方法.游戏规则很简单:一个9×9的大棋盘按九宫格的方式划分成9个3×3小棋盘(9个宫).棋盘上已经填写了1到9若干数字,每行、每列以及每宫中填的数字没有重复.我们不妨把这样一个棋盘称为一个“准数独”,如图23.1(a)就是一个准数独,其中“0”表示空格.游戏的玩法是在准数独的所有空格中填进数字1,2,3…,9,要求每行、每列以及每宫中填的数字没有重复.图(b)是图(a)的一个解答.

 

         (a)            (b)

图1 一个简单数独及其解答

2 学习MATLAB命令

集合运算命令

B=unique(A)    A为向量,返回的B是与A元素相同但不重复的向量,且向量元素按顺序排列.

C=union(A,B)    A ,B为向量时返回A,B作为集合的并C=A∪B.

C=intersect(A,B)    A ,B为向量时返回A , B作为集合的交C=A ∩ B.

C=setdiff(A,B)    A ,B为向量时返回A , B作为集合的差C=A\B.

C=ismember(A,B)    A ,B为向量时返回与A同维的向量C ,若A(k)∈B ,则C(k)=1 ,否则C(k)=0.

3 实验内容

【例1】 编写一个数独游戏程序,并用此程序求解图23.1和图23.2给出的数独.

 

图23.2 一个较为复杂的数独

解 对于空格(ij),我们只能填那些第i行、第j行以及空格(ij)所在宫都未出现过的数字.(1)如果发现某一个空格无合适数字可填,则游戏失败;(2)如果某个空格(ij)只有一个数字可填,则此空格必须填这个数字;(3)如果所有空格都有两个以上的数字可填,则有多种选择,但不是每个选择都保证成功,是否成功要填到最后一个空格才见分晓.

下面是根据上面的想法编写的一段数独游戏程序sudoku.m,简单情况(2)下它可以自动完成.复杂情况(3)下,需要人工介入,程序会给予提示,按提示选择填数,顺利的话一次成功;不然,试几次也能成功(读者也可以尝试编写一个完全自动完成游戏的程序,但程序会长很多).

程序sudoku.m;

function  result=sudoku(m)

while 1

   m0=ceil(m/9);

   1=81-sum(sum(m0));

   x=[];flag=1;

   for k=1:1

    for i=1:9

     for j=1:9

      if m(i,j)==0

       k1=ceil(i/3);k2=ceil(j/3),

       m1=m(3k1-2:3k1,3k2-2:3k2);

       a=m(i,:);b=m(:,j)';c(1:9)=m1;

       d=setdiff(1:9,union(union(a,b),c));

       if length(d)==0

        flag=0;break

       elseif  length(d)==1

        m(i,j)=d(1);

        x=[x;[i,j,d(1)]];

       else

        r=i;c=j;choise=d;

       end

      end

     end

     if  flag==0

      break

     end

    end

    if  flag==0

     break

    end

   end

   if  flag==0

    disp('Impossible  to  complete!')

    break

   elseif  all(all(m))==0

    disp('Choose  a number  and  fill  into  the  blank  square,try  again!')

    m

    [r,c]

    choise

    r=input('r=');

    c=input('c=');

    m(r,c)=input('m(r,c)=');

   else

    disp('Success!')

    result=m;

    break

   end

end

对于第一个数独,输入

m=[2 1 0 6 3 0 8 9 0;0 4 0 0 0 7 0 0 5;0 0 0 9 0 0 0 0 7;

0 0 2 0 0 0 0 4 0;4 0 0 1 0 2 0 0 6;0 6 0 0 0 0 1 0 0;

  7 0 0 0 0 3 0 0 0;8 0 0 7 0 0 0 6 0;0 3 5 0 9 4 0 2 1]

运行sudoku(m),结果如图23.1(b)所示.

对于第二个数独,输入

m=[7 0 0 2 5 0 0 9 8;0 0 6 0 0 0 0 1 0;0 0 0 6 1 0 3 0 0;

     9 0 0 0 0 1 0 0 0;0 0 0 0 8 0 4 0 9;0 0 7 5 0 2 8 0 1;

     0 9 4 0 0 3 0 0 0;0 0 0 0 4 9 2 3 0;6 1 0 0 0 0 0 4 0]

运行sudoku(m),在人工选择(9,9)格填7,(8,9)格填6后,程序给出一个答案如图23.3所示,此时答案可能不唯一.

 

图23.3 对应图23.2的数独的一个解答