算法导论学习笔记之二--分而治之(divide-and-conquer approach)
2014-03-02 17:21
537 查看
如果一个问题当它的规模缩小的时候,问题性质不变,并且问题的规模最小的时候简单可解,就可以采用divide-and-conquer 方法。
divide-and-conquer 分以下4步进行:
攻克: 如果问题足够小,可以直接给出答案
分解: 把问题分解成同样性质的几个子问题
递归:递归调用本算法来解决子问题
合并:把解决好的子问题合在一起,组成原有问题的答案
# 假设问题为p,问题的数据集为A,规模为N
# 解决下标从R到N的所有问题
例 1:用divide-and-conquer方法计算N个数的和
例 2:已知整数数组A, 长度为N, 给出和最大的子数组。(子数组元素在原数组中连续)
divide-and-conquer 分以下4步进行:
攻克: 如果问题足够小,可以直接给出答案
分解: 把问题分解成同样性质的几个子问题
递归:递归调用本算法来解决子问题
合并:把解决好的子问题合在一起,组成原有问题的答案
# 假设问题为p,问题的数据集为A,规模为N
# 解决下标从R到N的所有问题
divide-and-conquer-p(A,R, N) #攻克:问题足够小 if R to N is small enough return Answer #分解:把p分成m个子问题 (N1, N2, ..., Nm) = divide-p(A,R,N) #递归: 解决m个子问题 Answer_N1 = divide-and-conquer-p(A, R, N1) Answer_N2 = divide-and-conquer-p(A, N1+1, N2) ...; Answer_N = divide-and-conquer-p(A, Nm+1, N) #合并:综合m个子问题的答案,给出整个问题的答案 return combine-p(Answer_N1, Answer_N2,..., Answer_N)
例 1:用divide-and-conquer方法计算N个数的和
#分解 def divide_p(A, R, N): return (R + N) / 2 #合并 def combine_p(subsum1, subsum2): return subsum1 + subsum2 def divide_and_conquer_p(A, R, N): if R==N:#攻克 return A[R] #分解 N1 = divide_p(A, R, N) #递归 subsum1 = divide_and_conquer_p(A, R, N1) subsum2 = divide_and_conquer_p(A, N1+1, N) #合并 return combine_p(subsum1, subsum2) A = [10, 9, 8, 7, 6, 5, 4, 3, 2] sum = divide_and_conquer_p(A, 0, 8) print "sum is:", sum
例 2:已知整数数组A, 长度为N, 给出和最大的子数组。(子数组元素在原数组中连续)
# 计算和最大的子数组 def divide_a(low, high): return (low + high) / 2 def combine_a(left_sub, right_sub, cross_sub): if left_sub[2] > right_sub[2] and left_sub[2] > cross_sub[2]: return left_sub elif right_sub[2] > left_sub[2] and right_sub[2] > cross_sub[2]: return right_sub else: return cross_sub def find_max_cross(A, low, high, mid): left_sum = 0 left_max_sum =A[mid] left_max_low = mid for i in range(mid, low-1, -1): left_sum = A[i] + left_sum if left_max_sum < left_sum : left_max_low = i left_max_sum = left_sum right_sum = 0 right_max_sum = A[mid + 1] right_max_high = mid + 1 for i in range(mid + 1, high+1): right_sum = A[i] + right_sum if right_max_sum < right_sum: right_max_high = i; right_max_sum = right_sum; print (left_max_low, right_max_high, left_max_sum + right_max_sum) return (left_max_low, right_max_high, left_max_sum + right_max_sum) def divide_and_conquer_a(A, low, high): #攻克 if low == high: return (low, high, A[low]) #分解 mid = divide_a(low, high) #递归 left_sub = divide_and_conquer_a(A, low, mid) right_sub = divide_and_conquer_a(A, mid+1, high) cross_sub = find_max_cross(A, low, high, mid) #合并 return combine_a(left_sub, right_sub, cross_sub) if __name__ == "__main__": A = [13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7] t = divide_and_conquer_a(A,0,15) print t
相关文章推荐
- [分布式系统学习]阅读笔记 Distributed systems for fun and profit 抽象 之二
- 算法学习笔记--5.merge sort & divide-and-conquer
- 算法导论分而治之学习笔记
- HeadFirst Jquery 学习笔记之jQuery and Ajax
- 学习笔记之二:关于人物mesh文件导入OGRE后人物为黑的情况
- WPF and Silverlight 学习笔记(十二):WPF Panel内容模型、Decorator内容模型及其他
- WPF and Silverlight 学习笔记:索引页
- C++学习笔记(第七章 自定义数据类型 结构体应用 之二)
- WPF and Silverlight 学习笔记(十五):WPF命令(Commands)
- PHP学习笔记之二 php入门知识
- 算法导论学习笔记(3)-习题2.3-7-排序+二分
- 算法导论学习笔记——第10章 基本数据结构
- 数据结构学习笔记——递归(分而治之)
- 机器学习实战笔记之二(k-近邻算法)
- 学习笔记之二获取进程内存
- Programming in Objective-C 学习笔记10——Cocoa, Cocoa Touch and the iOS SDK
- R-CNN学习笔记2:Rich feature hierarchies for accurate object detection and semantic segmentation
- uClinux学习笔记之二 - 将新增应用程序编译进内存镜像文件
- Lua学习笔记之 Type and Values
- 算法导论学习笔记-2