最大子数组问题的不同解法比较

2017/3/24 22:38:54

《算法导论》第四章 分治策略 练习4.1-3 要求比较三种方法的时间走势,找出递归算法和暴力算法的分界点(前期暴力算法会更快)。

该问题有三个常规解法:暴力、分治法、动态规划

 
figure_1-2.png
 
实践代码:
  1. # -*- coding: utf-8 -*-
  2. from time import time
  3. import numpy as np
  4. import matplotlib.pyplot as plt
  5. classMaxSubArraySolution:
  6. def force( self, A ):
  7. l = len(A)
  8. if l is0:return0;
  9. ts =[ A[0]]+[0]*( l -1)
  10. # 以i为结束点,之前所有的元素求和
  11. for i , j in enumerate(A[1:],1):
  12. ts[i]= ts[i-1]+ j
  13. # 设置双指针指向起始位置,依次求和
  14. max_sum = ts[0]
  15. for i , v1 in enumerate(ts[1:]):
  16. for j , v2 in enumerate(ts[i:]):
  17. arr_sum = v2 - ts[i]
  18. max_sum = max(arr_sum , max_sum)
  19. return max_sum
  20. def divide(self , A ):
  21. return self.divideAndConquerHelper( A ,0, len(A)-1)
  22. def divideAndConquerHelper(self , A , low , high):
  23. if low == high :return A[low]
  24. mid =( low + high )/2
  25. left_max = self.divideAndConquerHelper( A , low , mid)
  26. right_max = self.divideAndConquerHelper( A , mid+1, high)
  27. # 包含mid的情况
  28. left_sum , ts = float('-inf'),0
  29. for i in reversed(A[low:mid+1]):
  30. ts=ts+i
  31. left_sum = max( left_sum , ts )
  32. right_sum , ts = float('-inf'),0
  33. for j in A[mid+1:high+1]:
  34. ts=ts+j
  35. right_sum = max( right_sum , ts )
  36. # print left_sum , right_sum
  37. return max( max(left_max , right_max), left_sum+right_sum)
  38. def dp( self , A ):
  39. max_sum , ts =0,0
  40. for i , v in enumerate(A):
  41. ts = ts + v if ts + v >0else0
  42. max_sum = max( max_sum , ts )
  43. return max_sum
  44. if __name__ =='__main__':
  45. scalar = np.logspace(0,4,100)
  46. #scalar = np.linspace(1,2000,20)
  47. so =MaxSubArraySolution()
  48. time_force , time_divide , time_dp =[],[],[]
  49. for sc in scalar:
  50. print sc
  51. start = time()
  52. max_sum = so.force( np.arange(sc))
  53. end = time()
  54. time_force.append( end - start )
  55. #print "force : " , end - start
  56. start = time()
  57. max_sum = so.divide( np.arange(sc))
  58. end = time()
  59. time_divide.append( end - start )
  60. #print "divide : " , end - start
  61. start = time()
  62. max_sum = so.dp( np.arange(sc))
  63. end = time()
  64. time_dp.append( end - start )
  65. #print "dp : " , end - start
  66. #print '---------------------'
  67. plt.plot( scalar , time_force ,'r-', label='force')
  68. plt.plot( scalar , time_divide ,'g-', label='divide')
  69. plt.plot( scalar , time_dp ,'b-', label='dp')
  70. plt.title('Time of Force , Divide , DP')
  71. plt.legend()
  72. plt.tight_layout()
  73. plt.grid()
  74. plt.show()
 
原文地址:https://www.cnblogs.com/flyfatty/p/6619037.html