Smart Matrix Multiplication

In a dreadful Algebra class, Deeparaj was asked to multiply out 32 matrices in general form.

Deeparaj knew that to multiply two matrices of order l × m l \times m and m × n m \times n , he had to make l m n lmn multiplications. Since the result is independent of the order in which the matrices are multiplied (as long as they are in the same sequence), Deeparaj figured out the way to minimize the number of multiplications that were needed.

Can you find the number of multiplications he performed?

Data


Input Format

  • The input consists of n + 1 n+1 lines, where n n is the number of matrices.
  • The following input
1
2
3
4
5
d1
d2
.
.
d(n+1)

corresponds to n n matrices of dimensions d 1 × d 2 , d 2 × d 3 , , d n × d n + 1 d_1 \times d_2, d_2 \times d_3, \ldots, d_n \times d_{n+1} .

Example

  • Input:
1
2
3
4
10
30
5
60

  • Output: 4500

  • Explanation: The matrices are m 1 , m 2 , m 3 m_1, m_2, m_3 of dimensions 10 × 30 , 30 × 5 , 5 × 60 10 \times 30, 30 \times 5, 5 \times 60 . Multiplying them in the order ( m 1 × m 2 ) × m 3 (m_1 \times m_2) \times m_3 is the best you can do, and it takes 10 × 30 × 5 + 10 × 5 × 60 = 4500 10 \times 30 \times 5 + 10 \times 5 \times 60 = 4500 multiplications.


The answer is 6450.

This section requires Javascript.
You are seeing this because something didn't load right. We suggest you, (a) try refreshing the page, (b) enabling javascript if it is disabled on your browser and, finally, (c) loading the non-javascript version of this page . We're sorry about the hassle.

1 solution

Ivan Koswara
Nov 24, 2016

Let the matrices be M 1 , M 2 , , M n M_1, M_2, \ldots, M_n in order. Suppose a 0 , a 1 , a 2 , , a n a_0, a_1, a_2, \ldots, a_n be positive integers such that the dimension of matrix M i M_i is a i 1 × a i a_{i-1} \times a_i .

Note that the last product formed must be of the form M 1 M 2 M i M_1 M_2 \ldots M_i multiplied by M i + 1 M i + 2 M n M_{i+1} M_{i+2} \ldots M_n for some i [ 1 , n 1 ] i \in [1, n-1] . The first term is an a 0 × a i a_0 \times a_i matrix, and the second term is an a i × a n a_i \times a_n matrix, so the cost of this multiplication is a 0 a i a n a_0 a_i a_n . Additionally, we need to add the cost of finding each term. The good thing is that the cost of finding each term is independent from each other, so we want to minimize the cost of each term (so that the sum is also as small as possible). This means each term itself is the same problem but with a smaller size. This means we can use dynamic programming to solve it.

The idea is as follows. Suppose we have the optimal cost to compute the product M i M i + 1 M j M_i M_{i+1} \ldots M_j for all i , j i,j except ( i , j ) = ( p , q ) (i,j) = (p,q) . Let f ( i , j ) f(i,j) be this cost. If we want to compute M p M p + 1 M q M_p M_{p+1} \ldots M_q as the product of M p M p + 1 M i M_p M_{p+1} \ldots M_i times M i + 1 M i + 2 M q M_{i+1} M_{i+2} \ldots M_q , the total cost is f ( p , i ) + f ( i + 1 , q ) + a p 1 a i a q f(p,i) + f(i+1,q) + a_{p-1} a_i a_q . We want to minimize this, so we can simply iterate over all valid i i :

f ( p , q ) = min i [ p , q 1 ] f ( p , i ) + f ( i + 1 , q ) + a p 1 a i a q f(p,q) = \min_{i \in [p,q-1]} f(p,i) + f(i+1,q) + a_{p-1} a_i a_q

And how do we find the values of f ( p , i ) f(p,i) and f ( i + 1 , q ) f(i+1,q) ? Easy, just use the same thing! Note that i p , q ( i + 1 ) < q p i-p, q-(i+1) < q-p ; the difference of the two arguments is smaller. The base case is f ( p , p ) = 0 f(p,p) = 0 for all p p , because the product of one matrix is just the same matrix, no multiplication required. Thus we can now construct the algorithm: we compute f ( p , q ) f(p,q) one by one, starting from one with smallest q p q-p (namely 0, the base case above) until we reach q p = n 1 q-p = n-1 , where we will find the value of f ( 1 , n ) f(1,n) .

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
a = [30, 13, 16, 32, 2, 6, 19, 11, 19, 16, 27, 7, 18, 1, 32, 21, 12, 3, 8, 2, 29,
     28, 2, 24, 4, 13, 13, 1, 3, 22, 25, 14]
n = len(a) - 1
f = dict()

for p in range(1, n+1): f[p, p] = 0
for diff in range(1, n):
    for start in range(1, n-diff+1):
        f[start, start+diff] = min(f[start, i] + f[i+1, start+diff] + a[start-1]*a[i]*a[start+diff]
                                   for i in range(start, start+diff))

print(f[1, n])
# 6450

Great writeup and explanation!

Calvin Lin Staff - 4 years, 6 months ago

This is a very nice solution. What is the complexity of the solution in terms of the number of matrices?

Agnishom Chattopadhyay - 4 years, 6 months ago

Log in to reply

The complexity is O ( n 3 ) O(n^3) . For a given d i f f diff , we compute f[start, i] + f[i+1, start+diff] + a[start-1]*a[i]*a[start+diff] for ( n d i f f ) d i f f (n-diff) \cdot diff times (the loop for start and the loop for i ). That computation is constant time, so for a given d i f f diff , it takes O ( ( n d i f f ) d i f f ) O((n-diff) \cdot diff) time. Summing over all d i f f diff , the time taken is

O ( 1 ( n 1 ) + 2 ( n 2 ) + + ( n 1 ) ( 1 ) ) = O ( ( 1 + 2 + + n ) n ( 1 2 + 2 2 + + n 2 ) ) = O ( 1 2 n 3 1 6 n 3 ) = O ( 1 3 n 3 ) = O ( n 3 ) \begin{aligned} O(1(n-1) + 2(n-2) + \ldots + (n-1)(1)) &= O((1+2+\ldots+n) \cdot n - (1^2 + 2^2 + \ldots + n^2)) \\ &= O \left( \frac{1}{2} n^3 - \frac{1}{6} n^3 \right) \\ &= O \left( \frac{1}{3} n^3 \right) \\ &= O(n^3) \end{aligned}

Ivan Koswara - 4 years, 6 months ago

Log in to reply

Yes. Another hacky (but maybe not reliable) way to see this is that the dp table is two dimensional whereas we are accessing n entries at each step.

Agnishom Chattopadhyay - 4 years, 6 months ago

0 pending reports

×

Problem Loading...

Note Loading...

Set Loading...