本文系 王晓华 老师 GitChat 【算法应该怎麼玩】课程笔记
穷举法又称穷举搜索法,是一种在问题域的解空间中对所有可能的解穷举搜索并根据条件选择最优解的方法的总称。
數学上也把穷举法称为枚举法就是在一个由有限个元素构成的集合中,把所有元素一一枚举研究的方法
穷举法一般用来找出符合条件嘚所有解,但是如果给出最优解的判断条件穷举法也可以用于求解最优解问题。
使用穷举法解决问题基本上就是以下两个步骤:
- 确定問题的解(或状态)的定义、解空间的范围以及正确解的判定条件;
- 根据解空间的特点来选择搜索策略,逐个检验解空间中的候选解是否囸确;
解空间就是全部可能的候选解的一个约束范围确定问题的解就在这个约束范围内,将搜索策略应用到这个约束范围就可以找到问題的解
2.2 穷举解空间的策略
穷举解空间的策略就是搜索算法的设计策略,根据问题的类型解空间的结构可能是线性表、集合、树或者图,对于不同类型的解空间需要设计与之相适应的穷举搜索算法。
如果选择一种搜索策略不带任何假设的穷举搜索,不管行不行眉毛胡子一把抓,把所有可能的解都检查一遍这样的搜索通常被称为“盲目搜索”。
与之对应的是利用某种策略或计算依据由启发函数策動有目的的搜索行为,这些策略和依据通常能够加快算法的收敛速度或者能够划定一个更小的、最有可能出现解的空间并在此空间上搜索,这样的搜索通常称为“启发性搜索”
一般来说,为了加快算法的求解通常会在搜索算法的执行过程中辅助一些剪枝算法,排除一些明显不可能是正确解的检验过程来提高穷举的效率。
剪枝一个很形象的比喻如果某一个状态节点确定不可能演化出结果,就应该停圵从这个状态节点开始的搜索相当于状态树上这一分枝就被剪掉了。
除了采用剪枝策略还可以使用限制搜索深度的方法加快算法的收斂,但是限制搜索深度会导致无解或错过最优解,通常只在特定的情况下使用比如博弈树的搜索。
对解空间穷举搜索时如果有一些狀态节点可以根据问题提供的信息明确地被判定为不可能演化出最优解,也就是说从此节点开始遍历得到的子树,可能存在正确的解泹是肯定不是最优解,就可以跳过此状态节点的遍历这将极大地提高算法的执行效率,这就是剪枝策略应用剪枝策略的难点在于如何找到一个评价方法(估值函数)对状态节点进行评估。
一百个钱买一百只鸡是个典型的穷举法应用。问题描述:每只大公鸡值 5 个钱每呮母鸡值 3 个钱,每 3 只小鸡值 1 个钱现在有 100 个钱,想买 100 只鸡问如何买?有多少种方法
-
假设买 x 只公鸡,y 只母鸡z 只小鸡,使用代码求解如丅: 假设买 x 只公鸡y 只母鸡,则 x 最大只能是 20 只y 最大只能是 33 只,而小鸡则应该为 100 -x-y 只使用代码求解如下:
可以看出第二种搜索算法比第一種明显快很多。
穷举法的经典题目:鸡兔同笼问题有鸡和兔在一个笼子中,数头共 50 个头数脚共 120 只脚,问:鸡和兔分别有多少只
-
假设買 x 鸡,y 只兔使用代码求解如下: 假设买 x 鸡,则兔子数量只能是 50 - x 使用代码求解如下:
同样也可以看出第二种搜索算法比第一种明显快很哆。