五种常用算法理解

2 篇文章 0 订阅
分治法:将问题实例划分成几个较小的子问题(可以递归的划分),然后对这些较小的子问题求解,合并这些较小的子问题,以得到原始问题的解。有点类似Map/Reduce思想。主要区别在于:Map/Reduce的关键是把一个大的任务,拆分成尽可能多的小任务,再合并子任务的解。任务本身往往并不复杂,主要是计算量大,基本做一次水平的拆分就够了。而分治法则是把一个不太容易解决的问题,拆分成几个小点儿的问题(拆分的数量相对较少),再将子问题递归的拆分成更小的子问题,直到某些子问题可以轻松的解决。所以它的本质是垂直的递归的拆分任务。

动态规划:动态规划和分治法有点类似,也是把一个问题递归的拆分成多个子问题,对子问题求解,最后合并,得到原始问题的解。动态规则的特别之处,在于先把每个子问题的结果都计算出来,并缓存结果,这样如果遇到相同的子问题时,无须重复计算,是一种空间换取时间的算法。所以动态规则相比分治法,更适合,拆分子问题不是相互独立的场景。因为遇到相同子问题不需要重新递归计算,效率较高。

下面给出个分治法与动态规划算法的例子:
问题:一个n级的台阶,每次只能走1阶或者2阶,求走到顶层台阶的方法数。
代码实现如下:
package algorithm;

public class Test {

	public static void main(String[] args) {
		long count = 0;
		int n = 40;
		long startTime, endTime;
		
		startTime = System.currentTimeMillis();
		count = divideConquer(n);
		endTime = System.currentTimeMillis();
		
		System.out.println("result: " + count + ",cost: " + (endTime - startTime));
		
		startTime = System.currentTimeMillis();
		count = dynamicProgramming(n);
		endTime = System.currentTimeMillis();
		
		System.out.println("result: " + count + ",cost: " + (endTime - startTime));
	}
	
	public static int divideConquer(int n) {
		if (1 == n) {
			return 1;
		} else if (2 == n) {
			return 2;
		} else {
			return divideConquer(n-1) + divideConquer(n - 2);
		}
	}
	
	public static int dynamicProgramming(int n) {
		int[] f = new int[n];
		f[0] = 1;
		f[1] = 2;
		for (int i = 2; i < n; i++) {
			f[i] = f[i-1] + f[i-2];
		}
		return f[n-1];
	}
}

程序运行结果:
result: 165580141,cost: 359
result: 165580141,cost: 0

从运行结果可以看出,对于包含大量相同子问题时,动态规则要比分治法快得多,因为使用分治法有大量重复递归计算。当台阶数达到50时,分治法已经很难计算出结果,而动态规则仍然很快。

贪心算法:从最小的问题开始,不从整体最优考虑,每次根据当前状态,查找局部最优解,最后得到一个局部最优解,不能用于查找最优解。人们遇到问题时,最容易想到的就是贪心算法,只是可能你不知道它的名字而以。贪心算法没有固定的算法框架,算法设计的关键是贪心策略的选择。该算法比较简单,这里不举例说明。

回溯法:回溯算法是一种低效,类枚举的搜索算法。以深度优先的搜索方式搜索,遇到不满足求解条件,或者到达分支结尾时,就回溯返回,尝试别的路径。回溯法是一种试错的算法,非常通用,许多复杂,规模较大的问题都可以用使用回溯法。

分支限界法:根据某个界值,按照广度优先策略搜索问题的解空间树,裁剪超过界值的分支路径。再根据裁剪后的空间树,搜索想要的路径解。选取的界值越接近最优解,算法的效率越高。我们一般可以先通过一些简单的算法求取这个界值,如贪心算法。
分支限界法和回溯法的对比如下:
求解目标不同:回溯法一般用于找出解空间树中满足条件的所有解,而分支限界法的求解目标往往只是找到一满足条件的解,或者是在所有解中找出最优解。搜索方式不同:回溯法采用深度优先的方式搜索空间树,而分支限界法则以广度优先或以最小耗费(最大效益)优先的方式搜索空间树。
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值