[知识点] 3.3 搜索优化

总目录 > 3 搜索 > 3.3 搜索优化

前言

本来记忆化搜索是归为搜索改进算法的,不过似乎也属于剪枝的一种,于是还是搬到这里来好了。

子目录列表

1、为什么需要优化

2、剪枝

3、记忆化搜索

4、最优性剪枝

5、可行性剪枝

 

3.3 搜索优化

1、为什么需要优化

在最开始我们就提到,搜索算法适用性很广,在不清楚正确算法,没有思路,或者时间紧迫的情况下,大部分题目都可以进行“暴力搜索”。当然,比起正确的算法,搜索的效率是低下的,OI 赛制中得分往往不会超过 30 分,ICPC 赛制中往往是不可取的。但搜索真的就卑微地拘泥于捡漏吗?也不然。搜索的普适性,同时反映出其过程是无脑而有冗余的,我们可以对其进行一些优化,使其效率提高。

 

2、剪枝

搜索优化和 3.2 五种改进搜索算法 中提及的改进搜索算法是有区别的。改进的搜索算法本质上是不同的算法,和普通的 DFS / BFS 相比框架已经发生较大的改变;而搜索优化是在原有框架进行的,一般是直接在原搜索代码中增加一些 break 或 continue 型的语句,以跳过一些必然不会得到答案的情况,这种操作俗称为“剪枝”。

剪枝,很好理解的一个词。路边种下的树木随着年轮的生长枝叶逐渐繁多,园林工人会对其一些枝叶进行修剪,或为了调整生长方向使其端庄而立,或为了减少结果量使其果实质量提升,总而言之是通过外力对树木生长的一种“优化”。不剪枝,树木同样能够长大,但随着生长可能出现诸多不够理想的情况;不剪枝,搜索同样能够得到结果,但受到效率低下的影响,得分可能也会不够理想。

那么对于搜索的剪枝有些什么具体的方式呢?一般我们将其分为三种 —— 记忆化搜索,最优性剪枝,可行性剪枝。下面一一进行分析。

 

3、记忆化搜索

① 大致思路

搜索过程中出现曾经出现过的状态,并且到达该状态之后的搜索过程与到达该状态前的搜索过程无关,即无后效性,可以直接停止搜索,回溯。通过一个记录数组来记录这个状态是否出现,以规避多次计算相同状态而做无用功。形式和迷宫问题中的访问标记相像,但其目的有区别。设置访问标记的目的是防止出现死循环,本质上仍是普通的搜索;记忆化搜索的目的则是提高效率。

② 举例

具体请参见 4.1 动态规划基础 / 记忆化搜索

 

4、最优性剪枝

① 大致思路

搜索过程中当前的解比之前得到的解更差时,可以直接停止搜索并回溯。直接在递归时判断一下当前值与当前最优解的大小关系即可。这里可以联系图论中的 8.5  最短路 问题。

② 举例

题目需要通过搜索来计算从 A 到 B 耗时最短的方案,在之前的搜索中得到方案一耗时为 10,完成当前步骤后耗时达到 12,则直接停止搜索,因为继续搜索不可能成为最优解。

 

5、可行性剪枝

① 大致思路

搜索过程中当前得到的解已经不满足题目要求,可以直接停止搜索并回溯。直接在递归时判断一下当前值与条件范围内下限值即可。这一类剪枝可以联系迭代加深 DFS 来理解。对于迭代加深 DFS,每次限制搜索深度,相当于每次调整下限值,当前深度超过限制深度即返回,也算是一种可行性剪枝。

② 举例

题目需要通过搜索来计算带着 100 刀去超市购物的小红最多可以购买多少钱的商品,购买当前物品后总共花费 618 刀,则直接停止搜索,因为已经破费了,不再满足题目要求。

 

6、总结

上面只是对剪枝的思路进行分类,实际上剪枝是很灵活的,因题而异,尺度也是可大可小,需要自行把控。

posted @ 2020-06-15 23:37  jinkun113  阅读(320)  评论(0编辑  收藏  举报