2017/3/24 22:38:54
《算法导论》第四章 分治策略 练习4.1-3 要求比较三种方法的时间走势,找出递归算法和暴力算法的分界点(前期暴力算法会更快)。
该问题有三个常规解法:暴力、分治法、动态规划
![figure_1-2.png](https://images2015.cnblogs.com/blog/1131331/201703/1131331-20170325233939893-55908644.png)
实践代码:
# -*- coding: utf-8 -*-
from time import time
import numpy as np
import matplotlib.pyplot as plt
classMaxSubArraySolution:
def force( self, A ):
l = len(A)
if l is0:return0;
ts =[ A[0]]+[0]*( l -1)
# 以i为结束点,之前所有的元素求和
for i , j in enumerate(A[1:],1):
ts[i]= ts[i-1]+ j
# 设置双指针指向起始位置,依次求和
max_sum = ts[0]
for i , v1 in enumerate(ts[1:]):
for j , v2 in enumerate(ts[i:]):
arr_sum = v2 - ts[i]
max_sum = max(arr_sum , max_sum)
return max_sum
def divide(self , A ):
return self.divideAndConquerHelper( A ,0, len(A)-1)
def divideAndConquerHelper(self , A , low , high):
if low == high :return A[low]
mid =( low + high )/2
left_max = self.divideAndConquerHelper( A , low , mid)
right_max = self.divideAndConquerHelper( A , mid+1, high)
# 包含mid的情况
left_sum , ts = float('-inf'),0
for i in reversed(A[low:mid+1]):
ts=ts+i
left_sum = max( left_sum , ts )
right_sum , ts = float('-inf'),0
for j in A[mid+1:high+1]:
ts=ts+j
right_sum = max( right_sum , ts )
# print left_sum , right_sum
return max( max(left_max , right_max), left_sum+right_sum)
def dp( self , A ):
max_sum , ts =0,0
for i , v in enumerate(A):
ts = ts + v if ts + v >0else0
max_sum = max( max_sum , ts )
return max_sum
if __name__ =='__main__':
scalar = np.logspace(0,4,100)
#scalar = np.linspace(1,2000,20)
so =MaxSubArraySolution()
time_force , time_divide , time_dp =[],[],[]
for sc in scalar:
print sc
start = time()
max_sum = so.force( np.arange(sc))
end = time()
time_force.append( end - start )
#print "force : " , end - start
start = time()
max_sum = so.divide( np.arange(sc))
end = time()
time_divide.append( end - start )
#print "divide : " , end - start
start = time()
max_sum = so.dp( np.arange(sc))
end = time()
time_dp.append( end - start )
#print "dp : " , end - start
#print '---------------------'
plt.plot( scalar , time_force ,'r-', label='force')
plt.plot( scalar , time_divide ,'g-', label='divide')
plt.plot( scalar , time_dp ,'b-', label='dp')
plt.title('Time of Force , Divide , DP')
plt.legend()
plt.tight_layout()
plt.grid()
plt.show()