分治算法包含以下步骤:

1、分(divide):将一个大问题分解成若干个子问题,每个子问题的问题规模n更小了,这样就有了好几个待解决的子问题。

2、治(conquer):递归的去解决每个子问题。

3、结合(combine):将每个子问题的解合并成整个大问题的解。

以归并排序(Merge Sort)为例

1、分:将待排序的数组一分为二,该步骤仅花费常数时间

2、治:递归的对每一个子数组进行排序

3、合:将排好序的数组合并起来,该步骤时间花费为O(n)

这样就得到归并排序的时间复杂度递归式:T(n)=2T(n/2)+O(n)=O(nlogn) (求解该递归式参考 如何求解递归式)


二分查找算法(binary search)

二分查找算法的目的是在一个已经排好序的数组中查找一个数x,同样用到了分治策略

1、分:将x与数组的中间元素相比较,时间花费为O(1)

2、治:通过“分”的步骤,得到x所在的子数组序列,于是在该子数组中递归

3、合:nothing

时间复杂度T(n)=T(n/2)+O(1)=O(logn)。这是一个很牛逼的算法,我们知道1K=210,1M=220,1G=230,这就意味着在一千个数中查找一个数,仅需要比较10次,在一百万个数中查找一个数,仅需要比较20次,在10亿个数中查找一个数,仅需要比较30次。


乘方问题(powering a number)

该问题是给定一个数x和一个正整数n,计算x的n次方。朴素算法很简单,就把x乘以n次就可以了,时间复杂度为O(n),现在尝试用分治策略解决该问题。

xn=xn/2*xn/2 如果n是偶数的话,或者xn=x(n-1)/2*x(n-1)/2*x 如果n为奇数的话,这样就将规模为n的问题分解为规模为n/2的问题

1、分:将n次方转换为求[n/2]次方

2、治:递归的求[n/2]次方

3、合:将得到的结果合并为n次方

时间复杂度为T(n)=T(n/2)+O(1)=O(logn) , 对于连乘问题这是最快的方式了。


斐波那契数(Fibonacci numbers)

斐波那契数的定义是:

F0=0

F1=1

Fn=Fn-1+Fn-2

斐波那契数无处不在,当你看到某种水果时,数每次铃声的振动次数时等等,具体可参考“人类文明的斐波那契演进”

朴素算法就是一个递归算法,具体可参考 斐波那契维基百科 那是一个指数级别的算法,时间复杂度为O(xn),其中x是黄金分割数

指数级的算法是个悲剧,多项式的时间才是好的

一种解决办法是自下而上的处理,注意到当计算n-1的斐波那契函数时,n-2的斐波那契数被重复计算了,事实上只需要计算一次就够了

于是,缓存计算过的F0,F1,F2,F3……Fk,这样求Fn的时候只需要将已经求好的前两项相加就可以了,这样运行时间就是线性的T(n)=O(n),但这并不是最好的

另一种解决方法是可以求得斐波那契数的通项公式,参考维基百科,可以看到那是一个求x的n次方的问题,于是正好可以利用上面求乘方问题的分治算法。不过这种计算是不精确的,浮点数的计算有精度问题,用该方法计算的时候很可能丢失一些重要的位。

还有一种算法用到了矩阵的乘法,即平方递归算法

有如下定理:

(后面是矩阵的n次方)

该定理可以用数学归纳法证明,证明过程很简单。这样该问题又变成一个乘方问题,乘法变成了矩阵的乘法,时间复杂度变成了T(n)=O(logn)


矩阵乘法(Matrix Multiplication)

有两个 n行 n列的矩阵方阵A[ai,j],B[bi,j] , 求C[ci,j]=AB , ci,j=Σ ai,kbk,j  

简单的方法是直接求每个ci,j,用时O(n),共有n2个项需要求,总的用时就是O(n3),现在用分治法求矩阵乘法

第一种分治策略是用分块矩阵的乘法

将一个n*n的矩阵分成一个2*2的分块矩阵,每个矩阵块儿都是一个n/2*n/2的子矩阵

假设将C分解成r,s,t,u的四块,A分解成a,b,c,d的四块,B分解成e,f,g,h的四块,那么根据矩阵的乘法

r = ae+bg

s = af+bh

t = ce+dg

u = cf+dh

其中的乘法都是矩阵的乘法,每个矩阵的乘法又可以递归的分解成分块矩阵的乘法,总共分解出8个子矩阵的乘法,然后是4个矩阵的加法,矩阵加法的时间复杂度是n2,矩阵加法不是递归的,那么T(n)=8T(n/2)+n2 , 根据求解递归式中的主方法1可得到T(n)=O(n3) , 时间复杂度没有降下来?囧,看来该方法不行。

再来看另一种分治策略:斯特拉森算法

该算法的关键思路是减少乘法的次数,即对于上面的递归式,将8次乘法降低为7次,即通过7次乘法就能得到他们的乘机,神奇!

参考http://book.51cto.com/art/201008/220275.htm

时间复杂度分析:

1、分:将A和B进行分块分解,然后计算一些加减法,时间花费为O(n2)

2、治:用递归的方法计算p1-p7中的乘积

3、和:将这些计算组合起来得到c1-c4,时间花费为O(n2)

T(n) = 7T(n/2)+O(n2)  属于主方法中的方法1,得到T(n)约等于O(n2.81),比立方级的算法好了一点,但也不是最好的。目前已知最好的矩阵乘法算法的时间复杂度大约是O(n2.376),不过该算法只是纯理论上的改进,还无法投入实用。


转载于:https://www.cnblogs.com/web-application-security/archive/2012/06/15/divide_and_conquer.html

分治法 divide and conquer相关推荐

  1. 分治法 Divide and Conquer思想及实际应用

    分治思想 Divide and Conquer,即为分治法,基于分支递归的一种解决问题的思想方法. 分治分治,"分而治之"的意思,就是把一个复杂的原问题分成一个或多个相同子问题,而 ...

  2. java分治法求数列的最大子段和_同事为进大厂天天刷Java面试题,面试却履败!究其原因竟是它在捣鬼。...

    写在前面 疫情过后,招聘与求职受影响到底有多大?我不知道,但我的真实感受是,即使有疫情的影响,最近还是持续有朋友来跟我说他们今年工作的新动向.有人跳槽去了大厂,有人下定决心出来创业,也有人还在观望,等 ...

  3. 分治法(divide conquer algorithm)的理解

    二分搜索中的合并 combination(所谓合并 combination,更像是取代),当前子问题的结果(最终搜索的结果)直接就是上一步大问题的结果: 1. 递归与分治 一旦找到从给定问题到其较小规 ...

  4. 从合并排序算法看“分治法”

    本文内容 分治策略 分治步骤 从合并排序看"分治策略" 分治策略 分治法(divide-and-conquer),"分治法策略"是一种很重要的算法.顾名思义,& ...

  5. 算法中的递归分析和分治法的原理

    分析递归算法三种方法 替换法.迭代法.通用法(master method) 作用:分析递归算法的运行时间 分治算法 将一个问题分解为与原问题相似但规模更小的若干子问题,递归地解这些子问题,然后将这些子 ...

  6. 程序员的算法课(13)-分治法

    一.什么是分治 [百度百科]分治法((Divide and Conquer))可以通俗的解释为:把一片领土分解,分解为若干块小部分,然后一块块地占领征服,被分解的可以是不同的政治派别或是其他什么,然后 ...

  7. 算法与数据结构-分治法

    分治法 分治法的思想 将原问题分解为几个规模较小但类似于原问题的子问题,递归地求解这些子问题,然后再合并这些子问题的解来建立原问题的解. 分治模式在每层递归时都有三个步骤: 分解(Divide):将原 ...

  8. 演算法 - 分治法(Divide-and-Conquer)

    排版真的乱到一个 ¥*@#&? 一,Divide-and-Conquer(分治法) 二,Recurrences(递归) 1,替代法(Substitution method) 2,Tree Me ...

  9. 五大常用算法之四:分治法

    分治法和动态规划有点像,都是分解成子问题 中科大的张署老师课件很清楚,摘录如下: 1.什么是分治法 当求解的问题较复杂或规模较大时,不能立刻得到原问题的解,但这些问题本身具有这样的特点,它可以分解为若 ...

最新文章

  1. delphi之http通讯
  2. 计算机视觉与深度学习 | 基于MATLAB 深度学习工具实现简单的数字分类问题(卷积神经网络)
  3. 任何抛开业务谈大数据量的sql优化都是瞎扯
  4. Mongo集群分片部署实践(4.2版本)
  5. 如何构建真实世界可用的 ML 模型?
  6. 递增运算符练习(JS)
  7. java中的==和equals的区别
  8. windows 问题排查
  9. ZOJ 3792 Romantic Value 最小割(最小费用下最小边数)
  10. chrome扩展程序安装_如何在Windows上删除“由企业策略安装”的Chrome扩展程序
  11. 深夜读萧红《呼兰河传》
  12. Ubuntu 8.04中文智能拼音输入法
  13. 31、【栈和队列】判断链表是否为中心对称(C++版)
  14. 原生js以及jQuery删除节点
  15. 吐槽智能手机上那些不爽的事
  16. GameofMir引擎架设传奇服务器【4:架设微端】
  17. 数码相机摄影修复技术DxO PureRAW中文
  18. 基于arduino的ESP32 学习笔记(六)LVGL文件系统移植,中文字库和图片显示
  19. 深度学习:生成式对抗网络,让机器在博弈中实现“自我成长”
  20. Fluent_Python_Part4面向对象,08-ob-ref,对象引用、可变性和垃圾回收

热门文章

  1. 微信支付商户号的调研
  2. Project2016创建WBS并且进行相关设置
  3. oracle表的时区怎么查,ORACLE中的时区(time zone)
  4. android相机拉伸解决办法
  5. SSH常见问题及其解决方法
  6. 永琳的竹林迷径(path)
  7. 人事工作中的Python运用——离职证明生成器
  8. 2017华为算法大赛总结
  9. HTML5 之 Frame Frameset Noframes 标签
  10. 麒麟操作系统之光盘刻录