zoukankan      html  css  js  c++  java
  • 算法导论Ch4

    分治策略

    最大子数组问题

    A = [13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7]

    暴力解法

    分治方法

    将数组划分为两个规模尽量相等的子数组。最大子数组A[i..j]位置必然是:

    完全在A[low,mid];

    完全在A[mid+1,high];

    跨越了中点,因此low<=i<=mid<=j<=high.

    #!/usr/bin/env python

    # -*- coding:UTF-8 -*-

    import math

    A = [13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7]

    def findMaxCrossingSubarray(A,low,mid,high):

        leftSum = -float("inf")

        SUM = 0

        maxLeft = mid

        for i in range(mid,low-1,-1):

            SUM += A[i]

            if SUM > leftSum:

                leftSum = SUM

                maxLeft = i

                

        rightSum = -float("inf")

        SUM = 0

        maxRight = mid+1

        for j in range(mid+1,high+1,1):

            SUM += A[j]

            if SUM > rightSum:

                rightSum = SUM

                maxRight = j

        return (maxLeft,maxRight,leftSum+rightSum)

    def findMaximumSubarray(A,low,high):

        if low == high:

            return (low,high,A[low])

        else:

            mid = math.floor((low+high)/2)

            (leftLow,leftHigh,leftSum)=findMaximumSubarray(A,low,mid)

            (rightLow,rightHigh,rightSum)=findMaximumSubarray(A,mid+1,high)

            (crossLow,crossHigh,crossSum)=findMaxCrossingSubarray(A,low,mid,high)

            if leftSum >= rightSum and leftSum >= crossSum:

                return (leftLow,leftHigh,leftSum)

            elif rightSum >= leftSum and rightSum >= crossSum:

                return (rightLow,rightHigh,rightSum)

            else:

                return (crossLow,crossHigh,crossSum)

    if __name__ == '__main__':

        result = findMaximumSubarray(A,0,len(A)-1)

        print(result)

    线性时间算法

    #!/usr/bin/env python

    # -*- coding:UTF-8 -*-

    A = [13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7]

    '''

    https://www.cnblogs.com/allzy/p/5162815.html

    如果累加和出现小于0的情况,  

    则和最大的子序列肯定不可能包含前面的元素,  

    这时将累加和置0,从下个元素重新开始累加

    '''

    def findMaximumSubarrayLinearAlgo(A):

        maxSum = 0

        thisSum = 0

        maxLeft = 0

        maxRight = 0

        for i in range(0,len(A)):

            thisSum += A[i]

            if thisSum > maxSum:

                maxRight = i

                maxSum = thisSum

            elif thisSum < 0:

                thisSum = 0

                maxLeft = i+1

        return (maxLeft,maxRight,maxSum) if maxSum >0 else None

    if __name__ == '__main__':

        result = findMaximumSubarrayLinearAlgo(A)

        print(result)

    后语

    从暴力解法到分治算法,是学以致用。

    有线性时间算法,提示每个问题可能有更妙的解决办法。

    矩阵乘法

    常规方法

    Strassen算法

    通过中间过程的精妙优化,将运行时间的递归式由(1)变成(2)

        (1)

       (2)

    后语

    就像书上说的,最初可能认为矩阵乘法都要花费时间,但通过看到Strassen算法,才看到算法的精妙。

    求解递归式*

    迭代法

    递归树

    主方法

    Akra-Bazzi方法

  • 相关阅读:
    [Eclipse]GEF入门系列(四、其他功能)
    [Eclipse]GEF入门系列(三、应用实例)
    [Eclipse]GEF入门系列(一、Draw2D)
    打开Win2000的自动补齐功能
    让URLConnection使用代理服务器
    [Eclipse]GEF入门系列(序)
    给表格的单元格增加编辑功能(In place edit)
    设置Eclipse RCP程序的外观和首选项
    利用winrar自动备份重要资料(续,经验技巧)
    终于换了新电脑
  • 原文地址:https://www.cnblogs.com/sunnypoem/p/10864043.html
Copyright © 2011-2022 走看看