zoukankan      html  css  js  c++  java
  • 分治策略

    一.在分治策略中,递归地求解一个问题,在每层递归中应用如下三个步骤:

    二.分治法分析归并排序

    (1)把原数组分成两部分进行处理

    (2)递归求解这两部分

    (3)把求解好的两部分合并起来

    三.二分查找:在数组中查找x的位置

    (1)分:把x和已排序好数组的中间值进行比较

    (2)治:在子数组中递归

    (3)合并:Nothing 

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

    =θ(lgn)

    四.乘方问题:给定x,和n,要求计算xn

    (1)分:n/2(n偶数)或(n-1)/2(n奇数)

    (2)治:xn/2或者x(n-1)/2

    (3)合并:nothing或*x

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

    =θ(lgn)

    五.矩阵乘法

    斐波那契数:F(n)=F(n-1)+F(n-2)其中(n>=2)

    (1)一般矩阵乘法

     1 #矩阵乘法 O(n*3)
     2 def square_matrix_multiply(A,B):
     3     C = []
     4     n = len(A)#A的阶
     5     C = [[0 for col in range(n)] for row in range(n)]#生成n*n的全0矩阵
     6     for i in range(0,n):
     7         for j in range(0,n):
     8             for k in range(0,n):
     9                 C[i][j]=C[i][j]+A[i][k]*B[k][j]#矩阵乘法规则
    10     return C
    11 A=[[1,3],[7,5]]
    12 B=[[6,8],[4,2]]
    13 print(square_matrix_multiply(A, B))
    14 --------------------------------------------
    15 [[18, 14], [62, 66]]
    矩阵乘法

    (2)简单的递归分治

     1 #递归分治法-矩阵乘法
     2 def square_matrix_multiply_recursive(A, B):
     3     n = len(A)
     4     C = [[0 for col in range(n)] for row in range(n)]
     5     if n == 1:
     6         C[0][0] = A[0][0] * B[0][0]
     7     else:
     8         (A11, A12, A21, A22) = partition_matrix(A)
     9         (B11, B12, B21, B22) = partition_matrix(B)
    10         (C11, C12, C21, C22) = partition_matrix(C)
    11         C11 = add_matrix(square_matrix_multiply_recursive(A11, B11), square_matrix_multiply_recursive(A12, B21))
    12         C12 = add_matrix(square_matrix_multiply_recursive(A11, B12), square_matrix_multiply_recursive(A12, B22))
    13         C21 = add_matrix(square_matrix_multiply_recursive(A21, B11), square_matrix_multiply_recursive(A22, B21))
    14         C22 = add_matrix(square_matrix_multiply_recursive(A21, B12), square_matrix_multiply_recursive(A22, B22))
    15         C = merge_matrix(C11, C12, C21, C22)
    16     return C
    17 
    18 #分解矩阵,把矩阵分成4分
    19 def partition_matrix(A):
    20     n = len(A)
    21     n2 = int(n / 2)
    22     #生成四个初始零矩阵
    23     A11 = [[0 for col in range(n2)] for row in range(n2)]
    24     A12 = [[0 for col in range(n2)] for row in range(n2)]
    25     A21 = [[0 for col in range(n2)] for row in range(n2)]
    26     A22 = [[0 for col in range(n2)] for row in range(n2)]
    27     #给这四个矩阵赋值
    28     for i in range(0, n2):
    29         for j in range(0, n2):
    30             A11[i][j] = A[i][j]
    31             A12[i][j] = A[i][j + n2]
    32             A21[i][j] = A[i + n2][j]
    33             A22[i][j] = A[i + n2][j + n2]
    34     return (A11, A12, A21, A22)
    35 
    36 #合并矩阵,把四个矩阵合并为一个
    37 def merge_matrix(A11, A12, A21, A22):
    38     n2 = len(A11)
    39     n = 2 * n2
    40     A = [[0 for col in range(n)] for row in range(n)]
    41     for i in range(0, n):
    42         for j in range(0, n):
    43             if i <= (n2 - 1) and j <= (n2 - 1):
    44                 A[i][j] = A11[i][j]
    45             elif i <= (n2 - 1) and j > (n2 - 1):
    46                 A[i][j] = A12[i][j - n2]
    47             elif i > (n2 - 1) and j <= (n2 - 1):
    48                 A[i][j] = A21[i - n2][j]
    49             else:
    50                 A[i][j] = A22[i - n2][j - n2]
    51     return A
    52 
    53 #添加矩阵,把A 和 B对应添加进一个矩阵C
    54 def add_matrix(A, B):
    55     n = len(A)
    56     C = [[0 for col in range(n)] for row in range(n)]
    57     for i in range(0, n):
    58         for j in range(0, n):
    59             C[i][j] = A[i][j] + B[i][j]
    60     return C
    61 
    62 A=[[1,3],[7,5]]
    63 B=[[6,8],[4,2]]
    64 C=square_matrix_multiply_recursive(A,B)
    65 print(C)
    66 ----------------------------------------------------------
    67 [[18, 14], [62, 66]]
    矩阵乘法-分治思想

    (3)Strassen算法 

     

    六.最大子数组:寻找A中最大的非空连续子数组

     1 #最大子数组
     2 
     3 #求跨越中点的最大子数组
     4 def find_max_crossing_subarray(A, low, mid, high):
     5     # 先求A[low,mid]的最大子数组,一定是【A[i],mid】
     6     left_sum = float("-inf")#目前为止找到的左边的最大和
     7     sum = 0#A【i..mid 】中所有值的和
     8     max_left = 0#左边的最大下标
     9     max_right = 0#右边的最大下标
    10     for i in range(mid, low - 1, -1):
    11         sum = sum + A[i]
    12         if sum > left_sum:
    13             left_sum = sum
    14             max_left = i
    15     #先求A[mid+1,high]的最大子数组,一定是【mid+1,A[j]】
    16     right_sum = float("-inf")
    17     sum = 0
    18     for j in range(mid + 1, high + 1):
    19         sum = sum + A[j]
    20         if sum > right_sum:
    21             right_sum = sum
    22             max_right = j
    23     #返回下标和值
    24     return [max_left, max_right, left_sum + right_sum]
    25 
    26 import math
    27 
    28 #分治法求解最大子数组,返回子数组的左右下标和总值
    29 def find_maximum_subarray(A, low, high):
    30     if high == low:
    31         return (low, high, A[low])
    32     else:
    33         mid = math.floor((low + high) / 2)
    34         #递归求解在左边,在右边和跨中点的最大子数组
    35         [left_low, left_high, left_sum] = find_maximum_subarray(A, low, mid)
    36         [right_low, right_high, right_sum] = find_maximum_subarray(A, mid + 1, high)
    37         [cross_low, cross_high, cross_sum] = find_max_crossing_subarray(A, low, mid, high)
    38         if left_sum >= right_sum and left_sum >= cross_sum:
    39             return [left_low, left_high, left_sum]
    40         elif right_sum >= left_sum and right_sum >= cross_sum:
    41             return [right_low, right_high, right_sum]
    42         else:
    43             return [cross_low, cross_high, cross_sum]
    44 
    45 A=[13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7]
    46 
    47 print(find_maximum_subarray(A, 0, len(A) - 1))
    48 -----------------------------------------------------------------------
    49 [7, 10, 43]
    最大子数组

    七.完全二叉树的网格布局

    规定时间,得到递归式

  • 相关阅读:
    HTTP状态码
    HTTP详解教程 / HTTP 响应头信息 HTTP 响应头信息
    HTTP请求方法
    HTTP 消息结构
    HTTP 简介
    Session 工作原理
    CSS 布局
    css float 浮动
    CSS 布局
    css position定位
  • 原文地址:https://www.cnblogs.com/yu-liang/p/9255995.html
Copyright © 2011-2022 走看看