算法设计分析,分治,贪心算法,动态规划,回溯法总结。

分治算法:

分治算法的基本思想是将一个规模为 n 的问题分解为 k 个规模较小的子问题,这些子问题互相独立且与原问题相同,递归的解这些问题的子问题然后将各个子问题的解合并到原问题的解。
它的一般算法设计模式如下

divide and conquer(P)//划分和解决问题P
{ 
      if(|P|<=n0) adhoc(P) 是分治法中的基本子算法,用于直接解小规模的问题P//|p|表示问题的规模,而n0是一个阈值表示问题P的规模不超过n0师,
      //问题已经容易解出,不用再继续分解。
      divide P into smaller subinstances P1,P2,,,,,Pk//把问题p划分成若干个子问题
      for(i=1; i<=k; i++)
      {
      yi=divide and conquer(Pi);//得到解决的子问题
      }
      rerurn merge(y1,y2,,,,,yk);//合并子问题的的解得到问题的解
      
 }

典型例子:二分搜索查找,快速排序

举一个二分查找的简单代码

int a[10]={1,2,3,4,5,6,7,8,9};//在这里就不排序了给一个有序的数列
int left=0;int left=len-1;//定义最左和最右 如果比最左小、最右大则找不到;
while(left<=right)
{
int mid=(left+right)/2;//这里暂时不考虑溢出
if(mid==k)
return mid;
if(k>a[mid])
left=mid+1;//将最左节点移动到mid+1的位置从数列的右半部分找
else right=mid-1;//从数列的左半部分找
}
   return -1;
动态规划:

相同点
动态规划和分治算法类似,其基本思想也是将待求的解问题分解成若干个子问题,先求解子问题,然后从这些子问题得到原问题的解
不同点 :
与分治算法不通的是,适用于动态规划的去求解决的问题,在分解之后的子问题往往不是相互独立的。在分治算法中有些子问题已经被计算了很多次,浪费了大量的时间,而动态规划就很好的解决了这个问题,例如已经保存了子问题的答案,当再需要使用时,就可以直接调用,避免了大量的重复计算
为了达到这个目的,可以用一个表来记录所有已经解决的子问题的答案,无论子问题是否被用到,只要计算过就填入表中,这就是动态规划的基本思想。

动态规划算法适用于解最优化问题,通常可以按如下几个步骤

(1) 找出最优解的性质,并刻画其结构特征
(2) 递归地定义最优值
(3) 以自底向上的方式计算出最优值
(4) 根据计算最优值是的信息,构造最优解

动态规划算法的基本要素

  1. 最优子结构性质
  2. 子问题重叠性质

典型例子:最长公共子序列,最大字段和,0-1背包问题。

这里有一个0-1背包个人觉得挺好理解的博客

https://blog.csdn.net/mu399/article/details/7722810

贪心算法:

顾名思义贪心算法总是做出在当前看来最好的的选择,也就是说贪心算法并不从整体最优上加以考虑,它所做出的选择只是在某种意义上的局部最优选择。当一个问题具有最优子结构的性质时可以用动态规划来求解,但有些时候贪心算法更加简单,而且效率更高.

典型例子:最小生成树,路径最短等。
特点:总是再当前最好的选择,并不从整体最优上加以考虑,在一些情况下,即使贪心算法不能得到整体最优解,但最终结果却是最优解的很好的近似解。但对范围相当广的许多问题它能产生整体最优解。

基本要素:

1.贪心选择性质
是指所求问题的整体最优解可以通过一系列局部最优的选择,贪心算法所做的贪心选择可以依赖以往所做过的选择,但绝不依赖将来所做的选择。也不依赖于子问题的解。即总是当下,局部最优选择。对于一个具体问题,确定它是否有贪心性质就必须证明每一步所做的贪心选择最终导致问题的整体最优解。
2. 与动态规划的区别:
动态规划以自底向上的方式解决各子问题,而贪心算法则通常以自顶向下的方式进行,以迭代的方式做出相继的贪心选择,每做一次贪心选择就将所求问题简化为规模更小的问题。
3.和分治、动态一样都具有最优子结构的性质

那么具体有什么差别呢:比如下面这个例子:

int a[8]={10,15,20,25}//给定一个有序的物品的重量(这里有序为了直观感受)
int c=40;//给定背包的容量大小
//如果是动态规划算法 最大装入的应该是15,25;刚好装满
//而贪心算法的话应该是10,15.因为做的是局部最优的解,当到20时判断10+15+20>40 因此选择10 15
回溯法:

回溯法呢在这里有总结为:
1.走不通就掉头
2.是一种组织的井井有条的能避免不必要搜索的穷举式算法
3.基本做法就是搜索
4.有通用的解题法,用它可以系统的搜索一个问题的所有解或任一解,在解空间树中,按深度优先搜索,从根节点开始搜索,先判断该节点是否包含问题的解,如果不包含就直接跳过,逐层进入根节点回溯,否则进入子树。回溯法在求解时,只要找到解就立马结束,这种以深度优先方式系统搜索问题的算法称为回溯法,它适用于解组合数较大的问题。

那么什么时候会用到这个算法呢:

1.当需要找出它的解集或者要求回答什么解是满足某些约束条件的最佳解时,需要使用回溯法
2.当需要使用回溯法时,需要明确定义问题的解空间,问题的解空间至少包含问题的一个(最优解)

回溯法基本思想:

回溯法从开始节点(根节点)出发,以深度优先进行搜索,这个节点成为活结点,同时也成为当前的扩展节点,如果在当前扩展节点,不能再向纵深方向移动,则当前扩展节点成为死结点,此时应该往回移动,并且移动到最近的一个活结点,此时这个活结点成为扩展节点。然后继续搜索,重复以上操作。回溯法以这种工作方式递归在解空间中搜索,直到找到要求的解,或解空间中已经没有活结点为止。

另外,在回溯法搜索空间树时,通常采用两种策略避免无效搜索,提高回溯法的搜索效率。其一时用约束函数在扩展节点处减去不满足约束的子树;其二是用限界函数剪去得不到最优解的子树。这两类函数统称为剪枝函数。

典型问题: 装载问题

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值