拉丁方与数独算法优化

21、证明除了1阶拉丁方外,不存在奇数阶的反对角拉丁方,然后说明如何修改拉丁方生成过程(LatinSquare)以得到反对角拉丁方生成过程(AntidiagonalLatinSquare),该过程可用于生成任意阶n的所有反对角拉丁方。

只有奇数阶方阵的对角线在中心方格相交。因此,方阵的四个角应该相同,这就禁止了除1阶方阵之外的任何方阵成为拉丁方,因为四个角不重合但包含相同的值。

为了只得到反对角拉丁方,一种解决方案是修改过程 LatinSquare ,在 for 循环开始后引入与函数 Satisf 相关的条件语句,形式为:

CorrectNWSEDiag(r, c, j) and CorrectSWNEDiag(r, c, j)

22、数独游戏:游戏目的是用数字填充一个九宫格正方形,该正方形被细分为同样数量的边长为三的相同正方形(称为区域),使得每行、每列和每个区域都恰好包含一次从 1 到 9 的数字。游戏开始时,一些数字(称为已揭示方格)已经就位。请提出一个枚举结构 X,定义其属性。关于循环变量将遍历的集合,我们能得出什么结论?

枚举结构 X 定义在笛卡尔积上,模式为 AllTI,布局类似 T2D 以体现 X 定义域的二维性质。对于循环变量 j 的集合,需排除当前行、列和所在区域已有的值,即遍历 1 到 9 中除去 X[r, 1 到 c - 1]、X[1 到 r - 1, c] 以及 X[((r - 1) / 3) * 3 + 1 到 r - 1, ((c - 1) / 3) * 3 + 1 到 c - 1] 值域的部分。

23、编写程序Sudoku1(无已揭示方块)的代码以及调用程序。大约有7×10²¹个解。估算该程序在典型当前处理器上的计算时间。

程序 Sudoku1 的代码如下:

1. procedure Sudoku1(r, c) pre
2. r ∈ 1 .. 9 and c ∈ 1 .. 9
3. begin
4. for j parcourant 1 .. 9 - codom
   
   
   
   
   
   
   
   
   
   X[r, 1 .. c - 1] ∪ X[1 .. r - 1, c] ∪
   X
   
   
   
   
   
   
   
   r - 1
   3
   · 3 + 1 .. r - 1,
   c - 1
   3
   · 3 + 1 .. c - 1
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   do
5.    X[r, c] ← j;
6.    if r = 9 and c = 9 then
7.      write(X)
8.    else
9.      if c = 9 then
10.       Sudoku1(r + 1, 1)
11.     else
12.       Sudoku1(r, c + 1)
13.     end if
14.   end if
15. end for
16. end

调用程序如下:

1. variables
2. X ∈ 1 .. 9 × 1 .. 9 → 1 .. 9
3. begin
4.   Sudoku1(1, 1)
5. end

粗略的实验评估估计该程序的执行时间约为 190亿年 ,这超过了通常认为的宇宙年龄!

24、在大多数实际使用的编程语言中,不具备遍历一个不完整区间(带有“空洞”)的特性。假设之前有一个Sudoku1过程利用了该特性,现在基于此修改Sudoku1过程以得到一个高效版本的Sudoku2(建议避免在X内部进行顺序搜索)。

为了提高效率,定义一个由三个布尔表 H V R 组成的数据结构(其属性强化了现有不变量),通过直接访问快速给出答案。具体而言:

  • H[r, j] (分别地, V[j, c] )为真,当且仅当值 j 未在第 r 行(分别地,第 c 列)中使用。
  • R[r, c, j] 为真,当且仅当 j 未在包含方格 (r, c) 的区域中使用。

以下是 Sudoku2 过程代码:

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值