190 lines
6.6 KiB
Typst
190 lines
6.6 KiB
Typst
#set page(
|
||
paper: "a4",
|
||
margin: (x: 2.5cm, y: 2.5cm),
|
||
)
|
||
|
||
// 设置中文字体,根据你本地环境调整,通常推荐宋体或思源宋体
|
||
#set text(
|
||
font: ("Noto Sans CJK SC", "Noto Serif CJK SC", "Noto Sans Mono CJK SC"),
|
||
size: 11pt,
|
||
lang: "zh"
|
||
)
|
||
|
||
// 设置标题样式
|
||
#show heading: it => {
|
||
set text(weight: "bold")
|
||
block(above: 1.5em, below: 1em, it)
|
||
}
|
||
|
||
// 定义题目样式块
|
||
#let question_box(body) = {
|
||
block(
|
||
fill: luma(245),
|
||
stroke: (left: 2pt + gray),
|
||
inset: (x: 1em, y: 0.8em),
|
||
radius: 4pt,
|
||
width: 100%,
|
||
text(style: "italic", body)
|
||
)
|
||
}
|
||
|
||
// 定义答案样式
|
||
#let solution(body) = {
|
||
pad(
|
||
left: 1em,
|
||
top: 0.5em,
|
||
bottom: 1em,
|
||
text(fill: rgb("#000000"), body)
|
||
)
|
||
}
|
||
|
||
// 文档标题
|
||
#align(center)[
|
||
#text(size: 18pt, weight: "bold")[作业 3:约束满足问题 (CSP)]
|
||
]
|
||
|
||
#line(length: 100%, stroke: 0.5pt + gray)
|
||
|
||
= 一、约束满足问题:字母密码算术
|
||
|
||
#question_box[
|
||
在字母密码算术问题中,已知 “SEND + MORE = MONEY”,每个字母代表 0-9 的唯一整数(首位字母 S、M 不能为 0)。其中 “SEND”“MORE”“MONEY” 分别表示由对应字母组成的四位数、四位数和五位数。请基于约束满足问题的框架解决该问题。
|
||
|
||
]
|
||
|
||
== 1. 变量集合
|
||
#question_box[
|
||
(2 分) 该问题的变量集合包含哪些元素?(需考虑加法运算中的进位)
|
||
]
|
||
|
||
#solution[
|
||
该问题的变量集合不仅包含出现的字母,还需包含各列加法产生的进位:
|
||
- *字母变量*:$\{S, E, N, D, M, O, R, Y\}$
|
||
- *进位变量*:$\{C_1, C_2, C_3, C_4\}$
|
||
- $C_1$: 个位 $(D+E)$ 向十位的进位
|
||
- $C_2$: 十位 $(N+R)$ 向百位的进位
|
||
- $C_3$: 百位 $(E+O)$ 向千位的进位
|
||
- $C_4$: 千位 $(S+M)$ 向万位的进位
|
||
]
|
||
|
||
== 2. 关键约束条件
|
||
#question_box[
|
||
(2 分) 写出至少 3 条该问题的关键约束条件(例如变量取值范围约束、加法运算约束等)
|
||
]
|
||
|
||
#solution[
|
||
1. *全局互异约束 (AllDiff)*:
|
||
$S, E, N, D, M, O, R, Y in \{0, dots, 9\}$ 且互不相同。
|
||
2. *首位非零约束*:
|
||
$S != 0$ 且 $M != 0$。
|
||
3. *列加法约束(例如千位和万位)*:
|
||
- 千位列:$S + M + C_3 = O + 10 times C_4$
|
||
- 万位列(最高位):$C_4 = M$
|
||
]
|
||
|
||
== 3. 启发式变量选择
|
||
#question_box[
|
||
(3 分) 若采用 “最少剩余值启发式” (MRV) 选择变量,在问题初始阶段(未赋值任何变量),应优先选择哪个变量进行赋值?请说明理由
|
||
]
|
||
|
||
#solution[
|
||
- *优先选择变量*:$M$ (或 $C_4$)
|
||
- *理由*:
|
||
MRV 策略要求选择当前合法取值最少的变量。两个四位数相加 ($"SEND" + "MORE"$) 最大结果不超 $19998$,因此结果 MONEY 的最高位 $M$ 只能取值 *1*。由于 $M$ 的定义域大小为 1 (最少),应最先被赋值。
|
||
]
|
||
|
||
== 4. 约束传播与更新
|
||
#question_box[
|
||
(3 分) 已知变量 M 的取值已确定为 1,此时需同步更新哪些变量的取值范围?请说明更新依据
|
||
]
|
||
|
||
#solution[
|
||
需根据约束 $S + M + C_3 = O + 10 M$ 同步更新以下变量:
|
||
1. *更新 $O$ 的取值范围为 $\{0\}$*:
|
||
代入 $M=1$,得 $S + 1 + C_3 = O + 10$。因 $S <= 9, C_3 <= 1$,等式左边最大为 10,故右边必须为 10,解得 $O=0$。
|
||
2. *更新 $S$ 的取值范围为 $\{8, 9\}$*:
|
||
由上式简化得 $S + C_3 = 9$。若 $C_3=1 => S=8$;若 $C_3=0 => S=9$。
|
||
3. *更新 $C_4$ 的取值范围为 $\{1\}$*:
|
||
依据约束 $C_4 = M$。
|
||
]
|
||
|
||
#pagebreak()
|
||
|
||
= 二、约束满足问题:医生排班
|
||
|
||
#question_box[
|
||
某医院需安排甲、乙、丙、丁 4 名医生在周一至周五(共 5 天)进行值班,每人每周需值班 2 天,且每天至少有 1 名医生值班。额外要求:
|
||
① 甲不值班周一和周五;
|
||
② 乙的值班日需包含周三;
|
||
③ 丙的两天值班日不能相邻;
|
||
④ 任意两天的值班医生组成不能完全相同。
|
||
]
|
||
|
||
== 1. 变量与定义域
|
||
#question_box[
|
||
(2 分) 该问题的变量、定义域分别是什么?
|
||
]
|
||
|
||
#solution[
|
||
为了满足“每人值班2天”的结构,定义如下:
|
||
- *变量*:$\{ "甲", "乙", "丙", "丁" \}$
|
||
- *定义域*:周一至周五($\{1, dots, 5\}$)中任选 2 天的所有组合。
|
||
- 初始定义域大小为 $C_5^2 = 10$ 种组合。
|
||
- 根据题目特定约束缩减后的初始域:
|
||
- *甲*:$\{ \{2,3\}, \{2,4\}, \{3,4\} \}$ (排除含1, 5)
|
||
- *乙*:$\{ \{1,3\}, \{2,3\}, \{3,4\}, \{3,5\} \}$ (必须含3)
|
||
- *丙*:排除 $\{1,2\}, \{2,3\}$ 等相邻组合。
|
||
- *丁*:所有 10 种组合。
|
||
]
|
||
|
||
== 2. 约束条件形式化
|
||
#question_box[
|
||
(3 分) 用形式化语言描述该问题的所有约束条件(包括隐含约束)
|
||
]
|
||
|
||
#solution[
|
||
设 $V_i$ 为医生 $i$ 的值班日集合,$i in \{"甲", "乙", "丙", "丁"\}$。
|
||
1. *个人约束*:
|
||
- $1 in.not V_"甲" and 5 in.not V_"甲"$
|
||
- $3 in V_"乙"$
|
||
- $forall d_1, d_2 in V_"丙", |d_1 - d_2| > 1$
|
||
2. *覆盖约束*:
|
||
- $union.big_i V_i = \{1, 2, 3, 4, 5\}$
|
||
3. *每日医生组成唯一性约束*:
|
||
- 设 $S_d = \{i | d in V_i\}$ 为第 $d$ 天值班的医生集合。
|
||
- $forall j, k in \{1..5\}, j != k => S_j != S_k$
|
||
]
|
||
|
||
== 3. 启发式变量选择
|
||
#question_box[
|
||
(2 分) 若采用 “最少剩余值启发式” 选择变量,在初始阶段应优先选择哪个变量?请说明理由
|
||
]
|
||
|
||
#solution[
|
||
- *优先选择变量*:*甲*
|
||
- *理由*:
|
||
计算各变量满足自身硬性约束后的剩余合法组合数:
|
||
- *甲*:排除周一、周五,仅剩 $\{ \{2,3\}, \{2,4\}, \{3,4\} \}$,共 *3* 个。
|
||
- *乙*:必须含周三,共 *4* 个。
|
||
- *丙*:排除相邻组合,共 *6* 个。
|
||
- *丁*:无限制,共 *10* 个。
|
||
甲的剩余合法值最少,故优先选择。
|
||
]
|
||
|
||
== 4. 约束传播与剪枝
|
||
#question_box[
|
||
(3 分) 若已知乙的值班日确定为周三和周四,此时需删除哪些变量的取值组合?请列举至少 3 组并说明依据
|
||
]
|
||
|
||
#solution[
|
||
已知 $"乙" = \{3, 4\}$。为满足“任意两天医生组成不能完全相同 ($S_3 != S_4$)”的约束,需避免其他医生对 $S_3$ 和 $S_4$ 做出完全相同的贡献(即不能同时在3, 4号值班)。
|
||
|
||
需删除的取值组合:
|
||
1. *删除变量 甲 的取值 $\{3, 4\}$*。
|
||
依据:若甲选 $\{3,4\}$,且其他医生不区分这两天,会导致周三周四阵容雷同。
|
||
2. *删除变量 丁 的取值 $\{3, 4\}$*。
|
||
依据:同上,防止与乙的排班完全重叠。
|
||
3. *删除变量 丙 的取值 $\{3, 4\}$*。
|
||
依据:尽管丙因“不相邻”约束已不可选此值,但在域更新检查中,该组合因违反唯一性约束被显式标记为不可行。
|
||
]
|