Python algorithm design - matrix chain multiplication

Python algorithm design source code: https://github.com/MakerChen66/Python3Algorithm

Copyright statement: Originality is not easy, this article prohibits plagiarism, reprinting, infringement must be investigated!

1. Matrix chain multiplication

Matrix multiplication is an associative operation. Obviously, for matrices A, B, and C, (AB)C and A(BC) are equivalent, and we can choose the order of operations according to our preferences. In short, the results are the same.

But this is not the case for computers. If we assume that the matrix A=[10,20], B=[20,30], C=[30,40], then in the following two operation sequences, the scalar phase The number of multiplications varies greatly:

(AB)C = 10 * 20*30 + 10 * 30 * 40 = 18000
A(BC) = 20 * 30 * 40 + 10 * 20 * 40 = 32000

We can use the recurrence relation To find the optimal solution we need, first, we need to use a function to get the minimum number of scalar multiplications, then this function can also be used to define the optimal subsection in all cases.

Then use dynamic programming and memorandum method to get the result, the time complexity is O(n³).

Dynamic programming: It is an algorithm strategy that decomposes a problem instance into smaller, similar sub-problems, and stores the solutions of the sub-problems without calculating repeated sub-problems to solve the optimization problem.

Memento method: It is a deformation of the dynamic programming method. Unlike the dynamic programming algorithm, the recursive method of the memorandum method is top-down, while the dynamic programming algorithm is bottom-up.

Python algorithm implementation:

def mult(chain):
    n = len(chain)
    aux = {
    
    (i, i): (0,) + chain[i] for i in range(n)}
    # i: 子链的长度
    for i in range(1, n):
        # j: 子链开始的索引
        for j in range(0, n - i):
            best = float('inf')
            # k: 子链的分割点
            for k in range(j, j + i):
                # 分割点的多个子链
                lcost, lname, lrow, lcol = aux[j, k]
                rcost, rname, rrow, rcol = aux[k + 1, j + i]
                cost = lcost + rcost + lrow * lcol * rcol
                var = '(%s%s)' % (lname, rname)
                # 选择最优解
                if cost < best:
                    best = cost
                    aux[j, j + i] = cost, var, lrow, rcol
    matrixchain =  dict(zip(['cost', 'order', 'rows', 'cols'], aux[0, n - 1]))
    print(matrixchain)

mult([('A', 10, 20), ('B', 20, 30), ('C', 30, 40)])

Output result:
insert image description here
As can be seen from the figure, the optimal solution obtained is (AB)C, which is consistent with what we wrote at the beginning

Note : The zip() function can create an iterator that aggregates elements from various iterators together


2. Source code download

Python algorithm design source code download:

3. Author Info

Author: Xiaohong's Fishing Daily, Goal: Make programming more interesting!

Original WeChat public account: " Xiaohong Xingkong Technology ", focusing on algorithms, crawlers, websites, game development, data analysis, natural language processing, AI, etc., looking forward to your attention, let us grow and code together!

Copyright Note: This article prohibits plagiarism and reprinting, and infringement must be investigated!

Guess you like

Origin blog.csdn.net/qq_44000141/article/details/121801083