分治法

分治法(Devide and Conquer)的设计思想是,将一个难以直接解决的大问题,分割成一些规模较小的几个相似问题,以便各个击破,分而治之。

算法设计思想

    分治法求解问题的过程是,将整个问题分解成若干个小问题后分而治之。如果分解得到的子问题相对来说还太大,则可反复使用分支策略将这些子问题分成更小的同类型子问题,直至成生出方便求解的子问题,必要时逐步合并这些子问题的解,从而得到问题的解。

    由算法思路可知,分治法求解很自然地可以用一个递归过程来表示。可以这样说,分治方法就是一种找大规模问题与小规模问题关系的方法,是递归设计方法的一种具体策略。分治法的基本步骤在每一层递归上都有3个步骤:

    1、分解:将原问题分解为若干规模较小,相互独立,与原问题形式相同的子问题;

    2、解决:若子问题规模较小而容易被解决,则直接解决,否则再继续分解为更小的子问题,知道容易解决;

    3、合并:将已求解的各个子问题的解逐步合并为原问题的解。

    有时候问题分解后,不必求解所有的子问题,也就不必做第三步的操作,例如折半查找。多数问题需要所有子问题的解,并由子问题的解使用恰当的方法合并成为整个问题的解,例如归并排序。

适用分治法策略的问题

    当求解一个输入规模为n且取值又相当大的问题时,用蛮力策略效率一般得不到保证。若问题能满足以下几个条件,就能用分治法来提高解决问题的效率。

    1、能将这n个数据分解成k个不同的子集合,且得到k个子集合是可以独立求解的子问题,其中1<k<=n;

    2、分解所得到的子问题与原问题具有相似的结构,便于利用递归或循环机制;

    3、在求出这些子问题的解之后,就可以推解出原问题的解。

算法框架

    分治法的一般算法设计模式如下:

Devide_and_Conquer(n)                //n为问题规模
{
    if (n<=n0)                        //n0为子问题规模
    {
        解子问题;
        return (子问题的解);
    }
    for (i=1;i<=k;i++)                //分解为较小的k个子问题P1,P2,…,Pk
    {
        分解原问题为更小的子问题Pi;
        yi=Devide_and_Conquer(|Pi|);//递归解决Pi,|Pi|为Pi的规模
    }
    T=Merge(y1,y2,…,yk);            //合并子问题
    return (T);
}

    其中|P|表示问题P的规模;n0为一阈值,表示当问题P的规模不超过n0时,问题已容易直接解出,不必再继续分解。算法Merge(y1,y2,…,yk)是该分治法中的合并子算法,用于将P的子问题P1,P2,...,Pk的相应的解y1,y2,...,yk合并为P的解。在一些问题中不需要这一步,如折半查找、二叉排序树查找等算法。

 

posted on 2014-06-21 14:02  熊小熊-chris  阅读(1093)  评论(0编辑  收藏  举报

导航