python分治算法_Python算法:分治法

本节主要介绍分治法策略,提到了树形问题的平衡性以及基于分治策略的排序算法

本节的标题写全了就是:divide the problem instance, solve subproblems recursively, combine the results, and thereby conquer the problem

简言之就是将原问题划分成几个小问题,然后递归地解决这些小问题,最后综合它们的解得到问题的解。分治法的思想我想大家都已经很清楚了,所以我就不过多地介绍它了,下面摘录些原书中的重点内容。

1.平衡性是树形问题的关键

如果我们将子问题看做节点,将问题之间的依赖关系(dependencies or reductions)看做边,那么我们就得到了子问题图(subproblem graph ),最简单的子问题图就是树形结构问题,例如我们之前提到过的递归树的形式。也许子问题之间有依赖关系,但是对于每个子问题我们都是可以独立求解的,根据我们前面学的内容,只要我们能够找到合适的规约,我们就可以直接使用递归形式的算法将这个问题解决。[至于子问题间有重叠的话我们后面会详细介绍动态规划的方法来解决这类问题,这里我们不考虑]

前面我们学的内容已经完全足够我们理解分治法了,第3节的Divide-and-conquer recurrences,第4节的Strong induction,还有第5节的Recursive traversal

The recurrences tell you something about the performance involved, the induction gives you a tool for understanding how the algorithms work, and the recursive traversal (DFS in trees) is a raw skeleton for the algorithms.

但是,我们前面介绍Induction时总是从 n-1 到 n,这节我们要考虑平衡性,我们希望从 n/2 到 n,也就是说我们假设我们能够解决规模为原问题一半的子问题。

假设对于同一个问题,我们有下面两个解决方案,哪个方案更好些呢?

(1)T(n)=T(n-1)+T(1)+n

(2)T(n)=2T(n/2)+n

如果从时间复杂度来评价的话,前者是O(n2)的,而后者是O(nlgn)的,所以是后者更好些。下图以递归树的形式显示了两种方案的不同

2.典型的分治法

下面是典型分治法的伪代码,很容易理解对吧

# Pseudocode(ish)

def divide_and_conquer(S, divide, combine):

if len(S) == 1: return S

L, R = divide(S)

A = divide_and_conquer(L, divide, combine)

B = divide_and_conquer(R, divide, combine)

return combine(A, B)

用图形来表示如下,上面部分是分(division),下面部分是合(combination)

二分查找是最常用的采用分治策略的算法,我们经常使用的版本控制系统(evision control systems=RCSs)查找代码中发生某个变化是在哪个版本时采用的正是二分查找策略。

Python中bisect模块也正是利用了二分查找策略,其中方法bisect的作用是返回要找到元素的位置,bisect_left是其左边的那个位置,而bisect_right和bisect的作用是一样的,函数insort也是这样设计的。

from bisect import bisect

a = [0, 2, 3, 5, 6

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值