CS Study/CLRS (자료구조 | 알고리즘)

[CLRS] [14-2] Matrix Chain Multiplication

23학번이수현 2024. 11. 27. 15:26

1. Matrix Multiplication (행렬곱)

- 많은 사람들은 알겠지만, 행렬 곱에 대해서 알아가보고 넘어가보자.

- 다음과 같이 행렬 곱을 할 때, (m x k) x (k x n) = (m x n) 꼴로 연산이 되게 된다.

- 여기서 핵심은 k처럼 동일한 숫자가 있어야 한다는 것이다.

- 이를 계산하기위해 3중 for문을 이용한 행렬곱 알고리즘을 이용한다고 생각했을 때 , 연산 횟수는 m*k*n 이된다.

 

 

2. Matrix Chain Multiplication

- 만약 행렬곱이 연속적으로 주어져 있다고 가정하자.

- A*B*C*D

cf) A : 5x4 , B. 4x6, C : 6 x 2 , D : 2x7

- 행렬 곱은 결합법칙이 성립하기 때문에 계산할 수 있는 방법은 다음과 같다.

 

'''

i) (((AB)C)D : 연산횟수 : 5*4*6+5*6*2 + 5*2*7 

ii)((A(BC))D) : 연산횟수 : 4*6*2 + 5*4*2 + 5*2*7

iii) ((AB)(CD)) : 연산횟수 : 5*4*6 + 6*2*7 + 5*6*7

iv) (A((BC)D)) : 연산횟수 : 4*6*2+4*2*7+5*4*7

v) (A(B(CD))) : 연산횟수 : 6*2*7 + 4*6*7 + 5*4*7

'''

- 이러한 5가지 방법중 가장 연산횟수가 작은걸 선택하고자 하는게 이번 문제의 핵심이다.

2.1. Catalan numbers

- 행렬의 개수가 n개이면 연산 하는 가짓수는 C_(n-1) 이 된다.

- 따라서 C(3) = 5가 되기에 5가지 방법이라고 할 수 있다.

 

2.2. DP로 풀어보자.

- 해당 문제를 DP로 풀기위해 공부했던 영상을 공유하고자 한다.(이 영상을 보면서 내가 정리한 내용을 본다면 이해가 수월할 것이다.)

https://www.youtube.com/watch?v=prx1psByp7U

 

2.3. Code(백준)

- 이 문제와 같은 문제가 백준에 업로드되어 있다.

https://www.acmicpc.net/problem/11049

 

- 2.2.에서의 알고리즘을 한번 코드로 구현해보자.

import sys

n = int(sys.stdin.readline())

#d0~dn 까지 저장한 리스트구현 
d = []
for _ in range(n):
    matrix_shape = list(map(int,sys.stdin.readline().split()))
    d.append(matrix_shape[0])
d.append(matrix_shape[1])

#dp matrix 구현
dp_matrix = [[0] * (n+1) for _ in range(n+1)]

#dynamic programming
for dx in range(1,n):
    for i in range(1,n-dx+1):
        j = i+dx
        dp_matrix[i][j] = min([dp_matrix[i][k] + dp_matrix[k+1][j] + d[i-1]*d[k]*d[j] for k in range(i,j)])

print(dp_matrix[1][n])