1.蛮力法
蛮力法的概述和定义:
蛮力法——简单说是一种简单直接的算法设计策略,也叫作暴力法,枚举法或者穷举法,蛮力法解决问题常常简单粗暴,常常基于问题的描述和所涉及的概念,定义直接求解,逐一列举并且处理问题所涉及的所有情形,然后得到问题的答案。在求解问题的过程中往往依据循环结构来实现。
求解问题所要依据的步骤:
(1)确定扫描和枚举变量。
(2)确定枚举变量的范围,设置相应的循环。
(3)根据问题的描述确定约束的条件,以便找到合理 的解。
2.减治法
利用了一个问题给定实例的解和同样问题较小实例的解之间的某种关系,常用的有n和n-1的关系,有了这种关系我们可以自顶向下地递归求解,也可以自底向上地迭代实现,从较小实例开始求解这一角度来看减治也叫增量法。
减治法的三种方式:
(1).减常量
每次迭代总是从实例中减去一个相同的常量,一般为1。如求an的值,我们从an=an-1*a可以看出n和n-1之间的关系,所以可以得到递归式:
f(n)=f(n-1)*a n>0
f(n)=a n=0
减常量的例子有很多,利用源删除法对无环有向图进行拓扑排序就是很好的例子,即不断重复一件事,在余下的有向图中求出一个源,它是一个没有输入边的顶点,然后把它和从它出发的边都删除,顶点被删除的次序就是拓扑排序问题的一个解。
(2).减常因子
每次迭代总是从实例中减去一个相同的常数因子,因子就是倍数的意思,一般为2,就是减半。还是求an的值,可以先求一半再平方an=(an/2)2,当然跟n的奇偶性有关,如果是奇数就先提出一个a来再减半呗。
减常因子的例子也很多,最经典的莫过于折半查找,这个性能卓越的算法优点在于查找键和数组元素比较的次数大大减少了,每次都缩减为原来的一半。假币问题、俄式乘法、约瑟夫斯问题都是很好的例子。
(3).减可变规模
算法每次迭代时,规模减小的模式都是不同的,也就是说每次都减小,但减小的程度不是确定的,还记得欧几里得算法吧,随着不断求余,n越来越小,但减小的方式不是常量也不是常因子。插值查找、二叉查找树中的查找及插入都是减可变规模的实例。
3.分治
1.首先,将一个问题划分为同一类型的若干个子问题,子问题最好规模相同;
2.然后,对子问题求解;
4.最后,合并这些子问题的解,得到原始问题的解。
分治算法的应用实例有很多,如归并排序,快速排序,二叉树遍历等。
4.变治:
所谓变治,就是基于变换的方法,首先把问题的实例变得容易求解,然后进行求解,通常,对问题的变换方式有三种:
1.实例化简:变为同样问题的一个更简单的实例;
2.改变表现:变为同样实例的不同表现;
3.问题化简:变为另一个已知算法的问题的实例
基于这种思想的算法也有很多,如预排序(把无序变为有序,然后处理),高斯消去法(把方程组经过初等变换,得到具有特殊性质的方程组),堆和堆排序(利用最大/小堆总是找到最大/小值)。
5.动态规划
动态规划原理
基本思想:问题的最优解如果可以由子问题的最优解推导得到,则可以先求解子问题的最优解,在构造原问题的最优解;若子问题有较多的重复出现,则可以自底向上从最终子问题向原问题逐步求解。
动态规划算法的设计步骤:
1.分析优化解的结构
2.递归地定义最优解的代价
3.自底向上地计算优化解的代价保存之,并获取构造最优解的信息
4.根据构造最优解的信息构造优化解
动态规划特点:
1.把原始问题划分成一系列子问题;
2.求解每个子问题仅一次,并将其结果保存在一个表中,以后用到时直接存取,不重复计算,节省计算时间
3.自底向上地计算。
4.整体问题最优解取决于子问题的最优解(状态转移方程)(将子问题称为状态,最终状态的求解归结为其他状态的求解)
6.贪心算法:
贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解。
贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择,选择的贪心策略必须具备无后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关。
基本要素:
一.贪心选择
贪心选择是指所求问题的整体最优解可以通过一系列局部最优的选择,即贪心选择来达到。这是贪心算法可行的第一个基本要素,也是贪心算法与动态规划算法的主要区别。贪心选择是采用从顶向下、以迭代的方法做出相继选择,每做一次贪心选择就将所求问题简化为一个规模更小的子问题。对于一个具体问题,要确定它是否具有贪心选择的性质,我们必须证明每一步所作的贪心选择最终能得到问题的最优解。通常可以首先证明问题的一个整体最优解,是从贪心选择开始的,而且作了贪心选择后,原问题简化为一个规模更小的类似子问题。然后,用数学归纳法证明,通过每一步贪心选择,最终可得到问题的一个整体最优解。
二.最优子结构:
当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构性质。运用贪心策略在每一次转化时都取得了最优解。问题的最优子结构性质是该问题可用贪心算法或动态规划算法求解的关键特征。贪心算法的每一次操作都对结果产生直接影响,而动态规划则不是。贪心算法对每个子问题的解决方案都做出选择,不能回退;动态规划则会根据以前的选择结果对当前进行选择,有回退功能。动态规划主要运用于二维或三维问题,而贪心一般是一维问题
7.回溯法(DFS)
一、基本概念
回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就“回溯”返回,尝试别的路径。
回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。许多复杂的,规模较大的问题都可以使用回溯法,有“通用解题方法”的美称。
二、基本思想
在包含问题的所有解的解空间树中,按照深度优先搜索的策略,从根结点出发深度探索解空间树。当探索到某一结点时,要先判断该结点是否包含问题的解,如果包含,就从该结点出发继续探索下去,如果该结点不包含问题的解,则逐层向其祖先结点回溯。
若用回溯法求问题的所有解时,要回溯到根,且根结点的所有可行的子树都要已被搜索遍才结束。而若使用回溯法求任一个解时,只要搜索到问题的一个解就可以结束。
8.分支限界法(BFS)
一、基本概念
类似于回溯法,也是一种在问题的解空间树T上搜索问题解的算法,但在一般情况下,分支限界法与回溯法的求解目标不同。回溯法的求解目标是找出T中满足约束条件的所有解,而分支限界法的求解目标则是找出满足约束条件的一个解,或是在满足约束条件的解中找出使某一目标函数值达到极大或极小的解,即在某种意义下的最优解。
二、一般过程
由于求解目标不同,导致分支限界法与回溯法在解空间树T上的搜索方式也不相同。回溯法以深度优先的方式搜索解空间树T,而分支限界法则以广度优先或以最小耗费优先的方式搜索解空间树T。
分支限界法的搜索策略:在扩展结点处,先生成其所有的儿子结点(分支),然后再从当前的活结点表中选择下一个扩展对点。为了有效地选择下一扩展结点,以加速搜索的进程,在每一活结点处,计算一个函数值(限界),并根据这些已计算出的函数值,从当前活结点表中选择一个最有利的结点作为扩展结点,使搜索朝着解空间树上有最优解的分支推进,以便尽快地找出一个最优解。
分支限界法常以广度优先或以最小耗费(最大效益)优先的方式搜索问题的解空间树。问题的解空间树是表示问题解空间的一棵有序树,常见的有子集树和排列树。在搜索问题的解空间树时,分支限界法与回溯法对当前扩展结点所使用的扩展方式不同。在分支限界法中,每一个活结点只有一次机会成为扩展结点。活结点一旦成为扩展结点,就一次性产生其所有儿子结点。在这些儿子结点中,那些导致不可行解或导致非最优解的儿子结点被舍弃,其余儿子结点被子加入活结点表中。此后,从活结点表中取下一结点成为当前扩展结点,并重复上述结点扩展过程。这个过程一直持续到找到所求的解或活结点表为空时为止。
三.回溯法与分支限界法的异同
1. 相同点
(1)均需要先定义问题的解空间,确定的解空间组织结构一般是树或图。
(2)在问题的解空间树上搜索问题解。
(3)搜索前均需要确定判定条件,该判断条件用于判断扩展生成的结点是否为可行结点。
(4)搜索过程中必须判断扩展生成的结点是否满足判断条件,如果满足,则保留该扩展生成的结点,否则舍弃。
2. 不同点
(1)搜索目标:回溯法的求解目标是找出解空间树中满足约束条件的所有解,而分支限界法的求解目标是找出满足约束条件的一个解,或是在满足约束条件的解中找出的在某种意义下的最优解。
(2)搜索方式不同:回溯法以深度优先的方式搜索解空间树,而分支限界法是以广度优先或以最小耗费优先的方式。
(3)扩展方式不同:在回溯法搜索中,扩展结点一次生成一个孩子结点,而在分支限界法搜索中,扩展结点一次生成所有的孩子结点