• python实现长链矩阵的高效乘法


    对于矩阵乘法,是在各类工程实践中都会有着广泛应用的方法,但是矩阵乘法存在耗时耗力的缺点,两个相乘的矩阵C=A.B,如果A对应的列数是n,B所对应的行数是n,那么矩阵C中的一个元素的运算过程就是:

    添加图片注释,不超过 140 字(可选)

    矩阵C中i行j列所对应的元素等于矩阵A中的第i行的元素与矩阵B中的第j列的元素分别相乘后再相加的值,这也就可以得出矩阵C的单个元素的计算时间就为O(n),而C中会存在n^2个元素,这也就会导致算出矩阵C的时间复杂度是3次方级别,因此得出的结论就是矩阵乘法的运算时长非常长。

    添加图片注释,不超过 140 字(可选)

    从上图又可以得出如果在多个矩阵相乘的时候,如果相乘的过程中使用结合律,调整矩阵相乘的次序的话,那将会有可能大大提高多个矩阵相乘的效率。

    所以这里就可以考虑使用动态规划来实现多个矩阵相乘的过程,以达到提高效率的目的。而上表中的第四种矩阵相乘的次序是效率最高的,要如何通过动态规划来得到这个次序,也就是矩阵不同的乘法次序可以通过二叉树来展现假设当前有4个矩阵相乘,可以用括号来制定不同的矩阵相乘的次序,可以用二叉树来表达者两种对应乘法次序,例如:

    添加图片注释,不超过 140 字(可选)

    上图所示的矩阵相乘时候对应于二叉树的叶子结点,两个叶子节点的父节点对应于两个矩阵乘积后的矩阵,二叉树的根节点就是多个矩阵相乘后的最终结果。

    使用python实现查找最优矩阵乘积次序的代码实现如下:

    1. import sys
    2. N = 4 #相乘的矩阵数
    3. M = []
    4. M.append((50, 20)) #构造5.2.1节对应的4个矩阵维度
    5. M.append((20, 1))
    6. M.append((1, 10))
    7. M.append((10, 100))
    8. arrange_map = {} #记录给定i和j对应的最优分割k
    9. C = np.zeros((N, N)).astype(int)
    10. for i in range(N):
    11. for j in range(N):
    12. C[i][j] = -1
    13. def compute_c_table(C, i, j):
    14. if i < 0 or i >= N:
    15. return
    16. if j < 0 or j >= N:
    17. return
    18. if i == j:
    19. C[i][j] = 0
    20. if C[i][j] != -1: #当前元素已经计算过
    21. return C[i][j]
    22. cost = sys.maxsize
    23. best_k = i
    24. for k in range(i, j):
    25. first_part_cost = compute_c_table(C, i, k)
    26. second_part_cost = compute_c_table(C, k + 1, j)
    27. if first_part_cost + second_part_cost + M[i][0]*M[k][1]*M[j][1] < cost:
    28. cost = first_part_cost + second_part_cost + M[i][0]*M[k][1]*M[j][1]
    29. best_k = k
    30. C[i][j] = int(cost)
    31. arrange_map[(i, j)] = best_k
    32. return C[i][j]
    33. compute_c_table(C, 0, N-1)
    34. print(C)
    35. print("the best computation time is: ", C[0][N-1])
    36. def print_best_matrix_arrange(arrange_map, i, j):
    37. if i == j:
    38. return "A{0}".format(i)
    39. if j == i + 1:
    40. return "(A{0}*A{1})".format(i, j)
    41. k = arrange_map[(i, j)] #得到矩阵Ai到Aj连乘时的最优分割
    42. left = print_best_matrix_arrange(arrange_map, i, k)
    43. right = print_best_matrix_arrange(arrange_map, k+1, j)
    44. return "({0}*{1})".format(left, right)
    45. arrangement = print_best_matrix_arrange(arrange_map, 0, N-1)
    46. print("the best arrangement is :", arrangement)

  • 相关阅读:
    【Kotlin 协程】协程的挂起和恢复 ① ( 协程的挂起和恢复概念 | 协程的 suspend 挂起函数 )
    python collections 中的 Counter, defaultdict, OrderedDict, namedtuple, deque
    Maven是什么? Maven的概念+作用
    2022暑假牛客多校1 (A/G/D/I)
    【CNN记录】pytorch中argMax、argMin
    LeetCode - 解题笔记 - 215 - Kth Largest Element in an Array
    详细介绍区块链之挖矿
    深圳市工业和信息化局5G产业发展扶持计划操作规程
    设计模式:装饰器模式(C++实现)
    采用ROUANT 方法对 nex-gddp-cmip6 数据进行精度校正
  • 原文地址:https://blog.csdn.net/Mrsawyer/article/details/136296733