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


    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()
     
  • 相关阅读:
    C++结构体中sizeof
    sizeof()的用法
    XStream和Json
    省市联动
    ajax
    配置文件的读取
    JSP标签库
    字符串函数参数传入传出(去空格)
    字符串函数参数传入传出(字符串反转)
    opendir,readdir,closedir
  • 原文地址:https://www.cnblogs.com/flyfatty/p/6619037.html
Copyright © 2020-2023  润新知