1、分治法
分治法的设计思想是,将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之
分治策略是:对于一个规模为n的问题,若该问题可以容易地解决(比如说规模n较小)则直接解决,否则将其分解为k个规模较小的子问题,这些子问题互相独立且与原问题形式相同,递归地解这些子问题,然后将各子问题的解合并得到原问题的解。这种算法设计策略叫做分治法。
分治法所能解决的问题一般具有以下几个特征:
1) 该问题的规模缩小到一定的程度就可以容易地解决
2) 该问题可以分解为若干个规模较小的相同问题,(前提)
3) 利用该问题分解出的子问题的解可以合并为该问题的解;(最关键的一点)
4) 该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子子问题。
上述的第一条特征是绝大多数问题都可以满足的,因为问题的计算复杂性一般是随着问题规模的增加而增加;第二条特征是应用分治法的前提它也是大多数问题可以满足的,此特征反映了递归思想的应用;第三条特征是关键,能否利用分治法完全取决于问题是否具有第三条特征,如果具备了第一条和第二条特征,而不具备第三条特征,则可以考虑用贪心法或动态规划法。第四条特征涉及到分治法的效率,如果各子问题是不独立的则分治法要做许多不必要的工作,重复地解公共的子问题,此时虽然可用分治法,但一般用动态规划法较好。
二、【动态规划法】
最优化原理:
1951年美国数学家R.Bellman等人,根据一类多阶段问题的特点,把“多阶段决策”问题变换为一系列互相联系的“单阶段问题”,然后逐个加以解决。而且一些静态模型,只要人为地引进“时间”因素,分成时段,就可以转化成多阶段的动态模型,用动态规划方法去处理。与此同时,他提出了解决这类问题的“最优化原理”(Principle of optimality):“一个过程的最优决策具有这样的性质:即无论其初始状态和初始决策如何,其今后诸策略对以第一个决策所形成的状态作为初始状态的过程而言,必须构成最优策略”。简言之,一个最优策略的子策略,对于它的初态和终态而言也必是最优的。这个“最优化原理”如果用数学化一点的语言来描述的话,就是:假设为了解决某一优化问题,需要依次作出n个决策D1,D2,…,Dn,如若这个决策序列是最优的,对于任何一个整数k,1 < k < n,不论前面k个决策是怎样的,以后的最优决策只取决于由前面决策所确定的当前状态,即以后的决策Dk+1,Dk+2,…,Dn也是最优的。
最优化原理是动态规划的基础,能采用动态规划求解的问题都需要满足一定的条件:
(1) 问题中的状态必须满足最优化原理;大问题的最优解可以由小问题的最优解推出,这个性质叫做“最优子结构性质”。
(2) 问题中的状态必须满足无后效性。所谓的无后效性是指:“下一时刻的状态只与当前状态有关,而和当前状态之前的状态无关,当前的状态是对以往决策的总结”。“未来与过去无关”,这就是无后效性。
动态规划法的应用:1.动态规划求0/1背包问题 2.最长公共子串问题的实现 3. 用动态规划实现导弹拦截 4.最大化投资回报问题的实现
使用动态规划求解问题,最重要的就是确定动态规划三要素:问题的阶段,每个阶段的状态以及从前一个阶段转化到后一个阶段之间的递推关系。确定了动态规划的这三要素,整个求解过程就可以用一个最优决策表来描述,最优决策表是一个二维表,其中行表示决策的阶段,列表示问题状态,表格需要填写的数据一般对应此问题的在某个阶段某个状态下的最优值(如最短路径,最长公共子序列,最大价值等),填表的过程就是根据递推关系,从1行1列开始,以行或者列优先的顺序,依次填写表格,最后根据整个表格的数据通过简单的取舍或者运算求得问题的最优解。
三、【贪心算法】
所谓贪心算法是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解。贪心算法不是对所有问题都能得到整体最优解,但对范围相当广泛的许多问题他能产生整体最优解或者是整体最优解的近似解。
贪心算法是在原问题上先做贪心选择,然后得到一个子问题,再求解子问题。(求解子问题的过程,就是一个不断贪心选择的过程)
贪心算法应用:1.最小生成树之Prim算法 2. 最小生成树之kruskal算法3. 贪心算法在背包中的应用 4.汽车加油问题之贪心算法
动态规划与分治的不同:
a、动态规划适用于分解得到的子问题往往不是相互独立的,而分治法子问题是相互独立的。
b、动态规划通常用于求解最优化问题,在这类问题中可能有多个可行解,最终得到的是其中一个最优解。分治得到的不是最优解。
贪心与动态规划的不同:
a)动态规划是先分析子问题,再做选择。而贪心算法则是先做贪心选择,做完选择后,生成了子问题,然后再去求解子问题。
b)动态规划每一步可能会产生多个子问题,而贪心算法每一步只会产生一个子问题。
c)动态规划的关键是状态转移方程,即如何由以求出的局部最优解来推导全局最优解;全局最优解中一定包含某个局部最优解,但不一定包含前一个局部最优解,因此需要记录之前的所有最优解;
贪心算法中,作出的每步贪心决策都无法改变,因为贪心策略是由上一步的最优解推导下一步的最优解,而上一部之前的最优解则不作保留。
d)贪心的做法是自顶向下的,而动态规划的解法是自底向上的。
比如还是找钱问题,动态规划的求解就是找一元如何找的最少,找两元如何找的最少,找三元如何找的最少,并且每次算当前找的最少的钱都使用了之前计算的各自的最优解,从之前所有子集的最优解中找到最优解。
同时由于每次都记录了每个子问题的最优解,不用每次都重新求子问题的最优解,而是直接使用,就会比暴力解法快很多。
e)、 1)、贪心算法是动态规划的一种特例,贪心算法能解决的问题动态规划一定能解决。动态规划能解决的问题,贪心不一定能够解决
2)、贪心的复杂度低,动态规划的复杂度高
四、【回溯算法】
回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。
回溯法应用:1.回溯法之数的划分 2.回溯法求解 运动员最佳配对问题 3.回溯法解决汽车加油次数最少问题 4. 用回溯法找出n个自然数中取r个数的全排列
四、【分支限界算法】
基本思想 :分支限界法常以广度优先或以最小耗费(最大效益)优先的方式搜索问题的解空间树。
在分支限界法中,每一个活结点只有一次机会成为扩展结点。活结点一旦成为扩展结点,就一次性产生其所有儿子结点。在这些儿子结点中,导致不可行解或导致非最优解的儿子结点被舍弃,其余儿子结点被加入活结点表中。 此后,从活结点表中取下一结点成为当前扩展结点,并重复上述结点扩展过程。这个过程一直持续到找到所需的解或活结点表为空时为止
分支限界法与回溯法的不同:
(1)求解目标:回溯法的求解目标是找出解空间树中满足约束条件的所有解,而分支限界法的求解目标则是找出满足约束条件的一个解,或是在满足约束条件的解中找出在某种意义下的最优解。
(2)搜索方式的不同:回溯法以深度优先的方式搜索解空间树,而分支限界法则以广度优先或以最小耗费优先的方式搜索解空间树。
分支限界法应用:1.分支限界法之装载问题 2. 分支限界法之布线问题 3. 分支限界法之0 1背包问题 4. 分支限界法之旅行售货员问题