分而治之的理解:
分治就是分而治之的意思,清·俞樾《群经平议·周官二》“巫马下士二人医四人”:“凡邦之有疾病者,疕疡者造焉,则使医分而治之,是亦不自医也。”成语分而治之的出处就在这里,不难看出分治就是在一个大而庞杂的问题难以解决时,把它划分成若干个可以解决的子问题。严谨一点的说法就是将原问题划分成若干个规模较小而结构与原命题相同或相似的子问题,然后分别解决这些子问题,最后合并子问题的解,即可得到原问题的解。
在软件工程中,也经常用到分治法,做一个软件项目就好比是吃一个大西瓜,正常人不能一口吃掉一个西瓜,要吃要一口一口的吃,所以我们要用刀分开,在一口一口吃,一个项目可能有若干的需求,团队一下子完成不了,或者不知道从哪里下手;可能知道如何开始了,中间被其他事打扰,回来的时候又不知道如何下手,或者看之前写的代码完全不知为何物。但是,当我们把一个项目拆成若个块,一个一个的解决他们就不用怕这样的问题出现,而不用完成整个项目,工作是变容易了一些,也就是WBS(Work Breakdown Structure)。
分而治之的步骤:
分治从定义上就能看出就是先分再治,不能治就再分直到能治,我们的目标是解决大问题所以最后要归结一下,得到大问题的解。
分治大概分为三步:
,Divide & Conquer(n) //n 为问题规模
{
if n==n(o)//n(0) 为可解子问题的规模
{
solve 子问题;
return(子问题的解);
}
else
{
for 1 to k //分解为较小的 K 个子问题
divide 问题为y1,y2,y3…yk;
Divide & Conquer(yk);
}
T ← merge(y1,y2,...,yk) //合并子问题
return(T)
}
具体的说明我以归并排序这种经典分治思想的排序为例
将序列{66,12,33,57,64,27,18}
按照分治的三步论
1.两两分组,得到四组:{66,12}、{33,57}、{64,27}、{18}\\分
2.组内单独排序得到新序列:{{12,66},{33,57},{27,64},{18}}\\治
3.将新序列分成两组得到{12,66,33,57}、{27,64,18}\\再分
4.组内单独排序得到新序列:{{12,66,33,57},{27,64,18}}\\治
5.将两个子序列合并排序得到新序列{12,18,27,33,57,64,66},算法结束;
利用分治思想我们可以使算法的时间复杂度大大提高,
T(n)= c 若n=1
2T(n/2)+cn 若n>1
而不是插入排序的T(n2)
在逻辑结构上分治很好的对应了递归树
注意:在用分治思想解决问题时多半是用递归的方法也有用非递归的方法,要具体问题具体分析。
在软件工程的日常项目处理中采用分治法一般要
1、分解后的问题结构清晰,从树根到树叶,一目了然,尽量避免盘根错节;
2、逻辑上形成一个大的活动,集成了所有的关键因素包含临时的里程碑和监控点,所有活动全部定义清楚,要细化到人、时间和资金投入。
在我们日常管理项目时,要学会分解任务,只有将任务分解得足够细,足够明了,才能统筹全局,安排人力和财力资源,把握项目的进度。
分治算法的条件
(1)该问题的规模缩小到一定的程度就可以容易地解决, 或直接解决;
(2)该问题可以分解为若干个规模较小的相同或相似子问 题;
(3)利用该问题分解出的子问题的解在一定的条件下可以 合并为该问题的解;
(4)该问题分解出的各个子问题是相互独立的,且各个子问题间不包括公共子问题。
注意:不具备第三条特征,则可以考虑用贪心法或动态规划法如果各子问题是不独立 的则分治法要做许多不必要的工作,重复地解公共的子问题,此时虽然可用分治法,但一般用动态规划法较好。
分治算法的基本点在于“分解”,然而这种由问题的顶部出发进行 递归向下分析的思考方法并非分治算法的唯一思路另一种对于上述方法反方向的思路及非递归的算法采用对于子问题的K聚合L为基点的分治算法同样有其实用价值,同样实施了K由小尺寸的问题的解决导致大尺寸同类问题解决L的分治法思路,在实用上也有其积极意义