减治:
利用了一个问题给定实例的解和同样问题较小实例的解之间的某种关系,常用的有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越来越小,但减小的方式不是常量也不是常因子。插值查找、二叉查找树中的查找及插入都是减可变规模的实例。
分治:
首先,将一个问题划分为同一类型的若干个子问题,子问题最好规模相同;
然后,对子问题求解;
最后,合并这些子问题的解,得到原始问题的解。
分治算法的应用实例有很多,如归并排序,快速排序,二叉树遍历等。
变治:
所谓变治,就是基于变换的方法,首先把问题的实例变得容易求解,然后进行求解,通常,对问题的变换方式有三种:
1.实例化简:变为同样问题的一个更简单的实例;
2.改变表现:变为同样实例的不同表现;
3.问题化简:变为另一个已知算法的问题的实例
基于这种思想的算法也有很多,如预排序(把无序变为有序,然后处理),高斯消去法(把方程组经过初等变换,得到具有特殊性质的方程组),堆和堆排序(利用最大/小堆总是找到最大/小值)。
总结:
1.再解释下上面的图,分治和减治不同的地方是分治分开的两边都要治理,但减治减掉的那部分就不需要了。
2.之前只说分治思想,哪些算法是基于分治法得出的。这还是第一次接触这么细致的概念,总得来分一下什么属于分治、减治和变治。这种思想给了我们动态看问题的启示,以后遇到问题还要多角度变通地去解。
本文来自 谷海燕 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/zhuanzhe117/article/details/76274340?utm_source=copy