搜索深度优先剪枝
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
10
定义 Hk 为队友需对第 k 号队员支援的高度, 对1号队员,H1 = 3;对2号队员,H2 = 2; 对3号队员,H3 = 1;4号队员不需他人支援,H4 = 0。 令 need(k) 表示 k 个人登山,保证 1人登顶所需给养; 令 take(k) 表示 k 个人登山共携带的给养; 令 d(k) 表示 k 个人一共差多少给养。 还是用图1的情况来说明上述参数的计算方法。 k = 1,让1号队员独自一人登山 need(1) = 2 * N = 2 * 4 = 8 take(1) = M = 5 d(1) = need(1) – take(1) = 8 – 5 = 3 1号队员如果单枪匹马登顶,缺3天给养, 因此需别人支援,要计算需队友支援的高度 H1 = d(1) / 1 = 3
take(k) d(k) 支援高度 说明 48 0 0 48 剪枝 剪枝 剪枝 剪枝 剪枝 25 7 3 33 11 3 剪枝 剪枝 剪枝
22
k 登山者 3 4 4 3 3 1#4#3# 1#4#3#5# 1#4#3#6# 1#4#5# 1#4#6#
2
编程要求:用键盘输入天数N(N<10)、俱乐部人 数P(P<10)之后,依次输入E[k]和M[k],k=1, 2, …, P, 分别输出两个登山组队计划, 计划1,要求参加登山的人数最少,在满足这一条 件之下消耗的总给养量最少。 计划2,要求消耗的总给养量最少。 输出的内容是:有多少队员参加登山,消耗的总 给养量,在出发时每人分别携带多少给养,每人分别 在出发几天后返回(几天后开始下山)。题目数据保 证有解。 【输入格式】第1行为2个小于10的整数N和P, 两个 整数之间有一个空格。第2行为P个整数,分别是 E[1],E[2],…,E[P], 相邻两整数之间有一个空格。第3行 为P个整数,分别是M[1],M[2],…,M[P], 相邻两整数之 间有一个空格。
21
k 4 4 4 4 4 4 2 3 4 4 4
登山者 1#3#4#2# 1#3#4#5# 1#3#4#6# 1#3#5# 1#3#6# 1#3#4#5# 1#4# 1#4#2# 1#4#2#3# 1#4#2#5# 1#4#2#6#
need(k) 48 50 50 50 50 50 32 44 56 62 62
9
因此,2号队员上山走3天,再下山走3天,自己要消 耗6天的给养,可是自己只能携带5天的给养,当然还需 要3号支援他。可以这样计划:2号队员上山时,第1天 由4号队员供给;第2天由3号队员供给;第3天将1份给 养支援给1号队员,自己用掉1份给养。到了高度3之后, 用还剩下的3份给养安全下山。 同理,在计划3号队员的行程时,要考虑1号和2号队 员的情况:1号和2号队员都需要在第2天得到3号队员的 支援,因此只需3号队员上山走2天,下山走2天。3号队 员上山的第 1天使用4 号队员支援给他的给养;在第 2 天,3号队员将自己携带的给养1份给1号队员,另1份给 2号队员,自己消耗1份;走到高度2后,带着2份给养下 山,走2天回到山脚。 同理,计划4号队员的行程时,考虑前3个队员需他 支援的时间,都是在上山的第1天。因此,4号队员只需 跟着大家走1天上山,然后独自再走1天下山。
教学目标 深度优先搜索的一般步骤 如何剪枝 如何编程 内容要点 复杂问题如何切入 化简思维 深度优先搜索的一般步骤 写好问题 攀登一座高山,假定匀速前进,从山脚登到山 顶需走 N天,下山也需 N天。山上没有水和食 品,给养要靠登山队员携带,而每个队员所携 带的给养量要少于他登顶再返回山脚所消耗的 给养量。因此,一定要组成一个登山队,在多 人支援的情况下,保证有一个人登顶。 现在登山俱乐部有P个人待选,我们将P个人依 次编号为 k=1, 2, …, P,令E[k] 表示编号为k的 人每日消耗的给养量,M[k]表示编号为k的人 最多可携带的给养量。登山计划要求所组成的 登山队所有成员同时出发,其中一些人分别在 启程若干天后返回,最终保证出发N天后至少 有一人登顶,出发 2N 天后所有人都已返回山 脚,无人滞留山上。
16
可以采用深度优先策略来搜索可能 的组队计划。题目要求输出不同条件下 的最优解,所以在实际搜索过程中,不 一定要枚举所有可能的登山组队情况。 例如在搜索给养总消耗量最小的组队计 划时,若挑选某队员进行支援,发现因 此计算得到的队伍给养总消耗量已经大 于之前某个成功登顶计划的总消耗量, 那就不用再枚举之后的支援者了。
6
为了便于分析,图1画出了用上述数据组队登山的 思路图。 4 下 返回高度 1 1 山
3 3
2
2
1 1
2 3 4
2
2
3
1
2 2
3 4
3
1
上 4 1 山0 1号队员
3
4
4 0
2号队员
3号队员
4号队员
7
1#2#3#的支援点 h 1#2#的支援点 1#的支援点 4 3 2 1 2 1 3 4 0 0 1 2 3 4 5 6 7 8 4人登山的高度与时间图
11
k = 2,让1号队员与2号队员携手登山, 2号队员只需上到H1高度,故 need(2) = need(1) + 2 * H1 = 8 + 2 * 3 = 14 take(2) = 2 * M = 2 * 5 = 10 d(2) = need(2) – take(2) = 14 – 10 = 4 两个人登山共缺4份给养,分属两人,每人缺 2天,故需队友支援的高度为 H2 = d(2) / 2 = 4 / 2 = 2 k = 3,让1号、2号和3号队员一起登山, 3号队员只需上到H2高度 need(3) = need(2) + 2 * H2 = 14 + 2 * 2 = 18 take(3) = 3 * M = 3 * 5 = 15 d(3) = need(3) – take(3) = 18 – 15 = 3
t
8
在图中,山高是以(路程)天为单位的。山顶的 高度是4天的路程。在1号队员上下山的示意图中,每 个方块代表一天的路程,1号队员被选中为登顶者,用 4天路程上山,再用4天路程下山。如果完全自食其力 的话,1号队员需要自带8天的给养,而题目限定的每 人最多携带给养量M = 5。因此,没有同伴支援的话, 1号队员是无法登顶的。从1号登顶后能安全下山考虑, 下山只有他一个人,只能自己携带给养。因此,在做 计划时让1号队员上山时,从山脚(高度0)到高度3使 用同伴的给养。过了高度3之后再吃自带的给养。在图 中小方块内所填的数字,表示在这一天的路程中由该 号队员供应给养。从图可见1号队员上山的第一天(从 高度0至高度1)由4号队员提供给养;上山的第2天 (从高度1至高度2)由3号队员提供给养;上山的第3 天(从高度2至高度3)由2号队员提供给养;上山的第 4天(从高度3至高度4)吃自己的给养;登顶成功之后, 下山的4天也均自食其力。从1号队员登顶的过程需要2 号队员支援的情况看,1号队员需要在第3天吃2号队员 携带的给养,这就意味着2号队员要跟1号一起爬到高 度3之后才能下山。
18
【输入样例】 66 山高为6(天的路程) 122233 7 8 17 18 22 25 队员 每日消耗给养 自带给养 1# 1 7 2# 2 8 3# 2 17 4# 2 18 5# 3 22 6# 3 25
19
k 1 2 2 3 4 5
登山者 k人需 k个人带 k人差 对k人需 need(k) take(k) d(k) 支援高度 说明 1# 12 7 5 5 1#2# 2#走不到高度5 1#3# 32 24 8 3 1#3#2# 44 32 12 3 1#3# 56 50 6 1 2#4# 5人组队 1#3#2# 62 62 0 0 总消耗62 4#5#
15
在前面登山计划的计算过程中,当挑选第 k个人作为支援者时,认为他的登山高度为 Hk-1,并计算下一个支援者的登山高度为Hk, 算法隐含着Hk-1≥Hk。因为计算过程中认为第k 个人的总消耗量为2 * Hk-1* Ek, 如果Hk-1<Hk的话,队伍的总消耗量计算 就不正确,从而迭代计算得到的支援高度也不 正确。若第k个人刚巧独立登至Hk-1并消耗完自 带给养,则前面的迭代计算将得到 Hk-1=Hk, 虽然实际上没有起到支援的作用,但迭代过程 的计算还是正确的。因此,在已知需支援高度 为H时,并不是任选一名队员都可作为支援者 的,支援者应保证 H * E < M 。
20
k 登山者 need(k) take(k) d(k) 支援高度 说明 5 1#3#2# 4#6# 62 4 1#3# 62 2#5# 4 1#3# 62 2#6# 3 1#3#4# 44 4 1#3#4# 48 2# 不小于62 剪枝 不小于62 剪枝 不小于62 剪枝 42 48 2 0 1 0 4人组队 总消耗48
4
【输入样例】 66 122233 7 8 17 18 22 25 【输出样例】 2 42 18 24 63 3 38 18 17 3 631 输出表明: 计划1中有2个人组队,分别携带18和24的给养量, 分别在出发6天和3天之后返回; 计划2中有3个人组队,分别携带18、17和3的给养 量,分别在出发后6天、3天和1天之后返回。
12
三个人登山共缺3份给养,分属三人,每人缺1 天,故需队员支援的高度为 H3 = d(3) / 3 = 1 k = 4,让1号、2号、3号和4号组队登山, 4号队员只需上到H3高度
need(4) = need(3) + 2 * H3 = 18 + 2 * 1 = 20
take(4) = 4 * M = 20 d(4) = need(4) – take(4) = 20 – 20 = 0 说明四人一起登山所需和所用相等,可以 保证一人登顶,其他人也可安全返回。 我们可以将上述计算数据归纳成表1。
3
【输出格式】第1行到第3行为计划1 的内容,第1行有两个整数,前者是参加 登山人数Q1,后者是消耗的总给养量。 第2行是Q1个整数,表示Q1个人在出发 时每人携带的给养。第3 行是Q1个整数, 表示Q1个人中的每个人在出发几天后返 回。第4行到第6行为计划2的内容,第4 行有两个整数,前者是参加登山人数Q2, 后者是消耗的总给养量。第5行是Q2个 整数,表示Q2个人在出发时每人携带的 给养。第6行是Q2个整数,表示Q2个人 中的每个人在出发几天后返回。
5
《登山人选》解题思路 当我们遇到一道难题时,先要想到:一、 可不可以先从一个较简单的情况分析起,把难 度先降低一些,等从中总结出规律性的认识后, 再回到原题的要求上来;二、能不能先从一个 特殊的例子分析起,再推广到一般情况。 为了简化问题,理出思路,可先将问题化 简为:每人所能携带的给养量相同,且每人每 天消耗的给养量也相同,选择一座不高的山, 用一组人数不多的具体数据。比如有如下一组 数据: N=4 从山脚到山顶需4天路程 P=6 登山俱乐部成员人数 E=1 每人每天消耗的给养量 M=5 每人最多携带的给养量
13
表 1
k 1 2 3 4
登山者 k个人所需 k个人所带 k个人所差 对k个人需 need(k) take(k) d(k) 支援高度 1# 8 5 3 3 1#2# 14 10 4 2 1# 2# 18 15 3 1 3# 1# 2# 20 20 0 0 3# 4#
14
以上是简单情况下的解题思路,由 于每个队员的携带量与消耗量相同,所 以实际上计算的是给养如何分配。 现在将难度加大到题目的要求,即 要考虑每个队员的携带量与消耗量各不 相同的情况。沿用前面的思路,现在需 要明确区分谁是登顶者?谁第一支援? 谁第二支援?……
17
表2给出了题目示例数据下给养消耗 总量最小的登山计划的部分计算过程, 相应的搜索树如图2所示。在图2中,搜 索树的根结点是虚设的,视作第0层;第 1层结点表示登顶者;第2层结点表示第 一支援;第3层结点表示第二支援;…… 表2和图2中,红色表示该队员无法提供 支援,绿色表示找到一个当前的最优解, 粉红色表示搜索至该队员时进行剪枝。
定义 Hk 为队友需对第 k 号队员支援的高度, 对1号队员,H1 = 3;对2号队员,H2 = 2; 对3号队员,H3 = 1;4号队员不需他人支援,H4 = 0。 令 need(k) 表示 k 个人登山,保证 1人登顶所需给养; 令 take(k) 表示 k 个人登山共携带的给养; 令 d(k) 表示 k 个人一共差多少给养。 还是用图1的情况来说明上述参数的计算方法。 k = 1,让1号队员独自一人登山 need(1) = 2 * N = 2 * 4 = 8 take(1) = M = 5 d(1) = need(1) – take(1) = 8 – 5 = 3 1号队员如果单枪匹马登顶,缺3天给养, 因此需别人支援,要计算需队友支援的高度 H1 = d(1) / 1 = 3
take(k) d(k) 支援高度 说明 48 0 0 48 剪枝 剪枝 剪枝 剪枝 剪枝 25 7 3 33 11 3 剪枝 剪枝 剪枝
22
k 登山者 3 4 4 3 3 1#4#3# 1#4#3#5# 1#4#3#6# 1#4#5# 1#4#6#
2
编程要求:用键盘输入天数N(N<10)、俱乐部人 数P(P<10)之后,依次输入E[k]和M[k],k=1, 2, …, P, 分别输出两个登山组队计划, 计划1,要求参加登山的人数最少,在满足这一条 件之下消耗的总给养量最少。 计划2,要求消耗的总给养量最少。 输出的内容是:有多少队员参加登山,消耗的总 给养量,在出发时每人分别携带多少给养,每人分别 在出发几天后返回(几天后开始下山)。题目数据保 证有解。 【输入格式】第1行为2个小于10的整数N和P, 两个 整数之间有一个空格。第2行为P个整数,分别是 E[1],E[2],…,E[P], 相邻两整数之间有一个空格。第3行 为P个整数,分别是M[1],M[2],…,M[P], 相邻两整数之 间有一个空格。
21
k 4 4 4 4 4 4 2 3 4 4 4
登山者 1#3#4#2# 1#3#4#5# 1#3#4#6# 1#3#5# 1#3#6# 1#3#4#5# 1#4# 1#4#2# 1#4#2#3# 1#4#2#5# 1#4#2#6#
need(k) 48 50 50 50 50 50 32 44 56 62 62
9
因此,2号队员上山走3天,再下山走3天,自己要消 耗6天的给养,可是自己只能携带5天的给养,当然还需 要3号支援他。可以这样计划:2号队员上山时,第1天 由4号队员供给;第2天由3号队员供给;第3天将1份给 养支援给1号队员,自己用掉1份给养。到了高度3之后, 用还剩下的3份给养安全下山。 同理,在计划3号队员的行程时,要考虑1号和2号队 员的情况:1号和2号队员都需要在第2天得到3号队员的 支援,因此只需3号队员上山走2天,下山走2天。3号队 员上山的第 1天使用4 号队员支援给他的给养;在第 2 天,3号队员将自己携带的给养1份给1号队员,另1份给 2号队员,自己消耗1份;走到高度2后,带着2份给养下 山,走2天回到山脚。 同理,计划4号队员的行程时,考虑前3个队员需他 支援的时间,都是在上山的第1天。因此,4号队员只需 跟着大家走1天上山,然后独自再走1天下山。
教学目标 深度优先搜索的一般步骤 如何剪枝 如何编程 内容要点 复杂问题如何切入 化简思维 深度优先搜索的一般步骤 写好问题 攀登一座高山,假定匀速前进,从山脚登到山 顶需走 N天,下山也需 N天。山上没有水和食 品,给养要靠登山队员携带,而每个队员所携 带的给养量要少于他登顶再返回山脚所消耗的 给养量。因此,一定要组成一个登山队,在多 人支援的情况下,保证有一个人登顶。 现在登山俱乐部有P个人待选,我们将P个人依 次编号为 k=1, 2, …, P,令E[k] 表示编号为k的 人每日消耗的给养量,M[k]表示编号为k的人 最多可携带的给养量。登山计划要求所组成的 登山队所有成员同时出发,其中一些人分别在 启程若干天后返回,最终保证出发N天后至少 有一人登顶,出发 2N 天后所有人都已返回山 脚,无人滞留山上。
16
可以采用深度优先策略来搜索可能 的组队计划。题目要求输出不同条件下 的最优解,所以在实际搜索过程中,不 一定要枚举所有可能的登山组队情况。 例如在搜索给养总消耗量最小的组队计 划时,若挑选某队员进行支援,发现因 此计算得到的队伍给养总消耗量已经大 于之前某个成功登顶计划的总消耗量, 那就不用再枚举之后的支援者了。
6
为了便于分析,图1画出了用上述数据组队登山的 思路图。 4 下 返回高度 1 1 山
3 3
2
2
1 1
2 3 4
2
2
3
1
2 2
3 4
3
1
上 4 1 山0 1号队员
3
4
4 0
2号队员
3号队员
4号队员
7
1#2#3#的支援点 h 1#2#的支援点 1#的支援点 4 3 2 1 2 1 3 4 0 0 1 2 3 4 5 6 7 8 4人登山的高度与时间图
11
k = 2,让1号队员与2号队员携手登山, 2号队员只需上到H1高度,故 need(2) = need(1) + 2 * H1 = 8 + 2 * 3 = 14 take(2) = 2 * M = 2 * 5 = 10 d(2) = need(2) – take(2) = 14 – 10 = 4 两个人登山共缺4份给养,分属两人,每人缺 2天,故需队友支援的高度为 H2 = d(2) / 2 = 4 / 2 = 2 k = 3,让1号、2号和3号队员一起登山, 3号队员只需上到H2高度 need(3) = need(2) + 2 * H2 = 14 + 2 * 2 = 18 take(3) = 3 * M = 3 * 5 = 15 d(3) = need(3) – take(3) = 18 – 15 = 3
t
8
在图中,山高是以(路程)天为单位的。山顶的 高度是4天的路程。在1号队员上下山的示意图中,每 个方块代表一天的路程,1号队员被选中为登顶者,用 4天路程上山,再用4天路程下山。如果完全自食其力 的话,1号队员需要自带8天的给养,而题目限定的每 人最多携带给养量M = 5。因此,没有同伴支援的话, 1号队员是无法登顶的。从1号登顶后能安全下山考虑, 下山只有他一个人,只能自己携带给养。因此,在做 计划时让1号队员上山时,从山脚(高度0)到高度3使 用同伴的给养。过了高度3之后再吃自带的给养。在图 中小方块内所填的数字,表示在这一天的路程中由该 号队员供应给养。从图可见1号队员上山的第一天(从 高度0至高度1)由4号队员提供给养;上山的第2天 (从高度1至高度2)由3号队员提供给养;上山的第3 天(从高度2至高度3)由2号队员提供给养;上山的第 4天(从高度3至高度4)吃自己的给养;登顶成功之后, 下山的4天也均自食其力。从1号队员登顶的过程需要2 号队员支援的情况看,1号队员需要在第3天吃2号队员 携带的给养,这就意味着2号队员要跟1号一起爬到高 度3之后才能下山。
18
【输入样例】 66 山高为6(天的路程) 122233 7 8 17 18 22 25 队员 每日消耗给养 自带给养 1# 1 7 2# 2 8 3# 2 17 4# 2 18 5# 3 22 6# 3 25
19
k 1 2 2 3 4 5
登山者 k人需 k个人带 k人差 对k人需 need(k) take(k) d(k) 支援高度 说明 1# 12 7 5 5 1#2# 2#走不到高度5 1#3# 32 24 8 3 1#3#2# 44 32 12 3 1#3# 56 50 6 1 2#4# 5人组队 1#3#2# 62 62 0 0 总消耗62 4#5#
15
在前面登山计划的计算过程中,当挑选第 k个人作为支援者时,认为他的登山高度为 Hk-1,并计算下一个支援者的登山高度为Hk, 算法隐含着Hk-1≥Hk。因为计算过程中认为第k 个人的总消耗量为2 * Hk-1* Ek, 如果Hk-1<Hk的话,队伍的总消耗量计算 就不正确,从而迭代计算得到的支援高度也不 正确。若第k个人刚巧独立登至Hk-1并消耗完自 带给养,则前面的迭代计算将得到 Hk-1=Hk, 虽然实际上没有起到支援的作用,但迭代过程 的计算还是正确的。因此,在已知需支援高度 为H时,并不是任选一名队员都可作为支援者 的,支援者应保证 H * E < M 。
20
k 登山者 need(k) take(k) d(k) 支援高度 说明 5 1#3#2# 4#6# 62 4 1#3# 62 2#5# 4 1#3# 62 2#6# 3 1#3#4# 44 4 1#3#4# 48 2# 不小于62 剪枝 不小于62 剪枝 不小于62 剪枝 42 48 2 0 1 0 4人组队 总消耗48
4
【输入样例】 66 122233 7 8 17 18 22 25 【输出样例】 2 42 18 24 63 3 38 18 17 3 631 输出表明: 计划1中有2个人组队,分别携带18和24的给养量, 分别在出发6天和3天之后返回; 计划2中有3个人组队,分别携带18、17和3的给养 量,分别在出发后6天、3天和1天之后返回。
12
三个人登山共缺3份给养,分属三人,每人缺1 天,故需队员支援的高度为 H3 = d(3) / 3 = 1 k = 4,让1号、2号、3号和4号组队登山, 4号队员只需上到H3高度
need(4) = need(3) + 2 * H3 = 18 + 2 * 1 = 20
take(4) = 4 * M = 20 d(4) = need(4) – take(4) = 20 – 20 = 0 说明四人一起登山所需和所用相等,可以 保证一人登顶,其他人也可安全返回。 我们可以将上述计算数据归纳成表1。
3
【输出格式】第1行到第3行为计划1 的内容,第1行有两个整数,前者是参加 登山人数Q1,后者是消耗的总给养量。 第2行是Q1个整数,表示Q1个人在出发 时每人携带的给养。第3 行是Q1个整数, 表示Q1个人中的每个人在出发几天后返 回。第4行到第6行为计划2的内容,第4 行有两个整数,前者是参加登山人数Q2, 后者是消耗的总给养量。第5行是Q2个 整数,表示Q2个人在出发时每人携带的 给养。第6行是Q2个整数,表示Q2个人 中的每个人在出发几天后返回。
5
《登山人选》解题思路 当我们遇到一道难题时,先要想到:一、 可不可以先从一个较简单的情况分析起,把难 度先降低一些,等从中总结出规律性的认识后, 再回到原题的要求上来;二、能不能先从一个 特殊的例子分析起,再推广到一般情况。 为了简化问题,理出思路,可先将问题化 简为:每人所能携带的给养量相同,且每人每 天消耗的给养量也相同,选择一座不高的山, 用一组人数不多的具体数据。比如有如下一组 数据: N=4 从山脚到山顶需4天路程 P=6 登山俱乐部成员人数 E=1 每人每天消耗的给养量 M=5 每人最多携带的给养量
13
表 1
k 1 2 3 4
登山者 k个人所需 k个人所带 k个人所差 对k个人需 need(k) take(k) d(k) 支援高度 1# 8 5 3 3 1#2# 14 10 4 2 1# 2# 18 15 3 1 3# 1# 2# 20 20 0 0 3# 4#
14
以上是简单情况下的解题思路,由 于每个队员的携带量与消耗量相同,所 以实际上计算的是给养如何分配。 现在将难度加大到题目的要求,即 要考虑每个队员的携带量与消耗量各不 相同的情况。沿用前面的思路,现在需 要明确区分谁是登顶者?谁第一支援? 谁第二支援?……
17
表2给出了题目示例数据下给养消耗 总量最小的登山计划的部分计算过程, 相应的搜索树如图2所示。在图2中,搜 索树的根结点是虚设的,视作第0层;第 1层结点表示登顶者;第2层结点表示第 一支援;第3层结点表示第二支援;…… 表2和图2中,红色表示该队员无法提供 支援,绿色表示找到一个当前的最优解, 粉红色表示搜索至该队员时进行剪枝。