18. matrix multiplication2 [9 2 주차]

Posted by aliontory on January 15, 2024 · 31 mins read

18. Matrix Multiplication2 [9-2 주차]

2024 1 14일 일요일

오전 1:55

<Matrix Multiplication2>

행렬 A1, A2, , An의 곱을 구하자.

(각 행렬의 크기는 p0 x p1, p1 x p2, , pn-1 x pn 이다)

행렬의 곱은 결합 법칙이 성립하므로 연산 순서가 다양하다.

 

Ai * Aj 는 총 pi-1 * pi * pj 번의 스칼라 곱 연산이 필요하다. 이는 행렬을 곱하는 데 드는 비용이다. -> 숫자 pi는 다음 계산에서 없어짐.

안쪽 숫자가 큰 행렬 곱을 먼저 계산하면 큰 숫자가 다시 계산되지 않으므로, 더 빠르게 계산할 수 있다. 행렬의 곱의 최소 비용을 동적 프로그래밍을 통해 구해 보자.

 

Ai Aj의 괄호를 최적으로 묶었을 때, Ak Ak+1에서 나누어진다고 가정한다. (, 마지막 곱은 Aik * Ak+1j 가 된다.)

Ai Aj의 괄호를 최적으로 묶는 경우에서 Ai Ak의 괄호를 묶는 방법, Ai Ak의 괄호를 최적으로 묶는 방법이어야 한다. 만약 그렇지 않다면, Ai Aj Ai Ak의 괄호를 묶는 방법최적으로 대체하면 더 좋은 답이 나와 모순이 발생한다.

마찬가지 이유로, Ai Aj를 최적으로 묶는 방법에서 Ak+1 Aj의 괄호를 묶는 방법최적이다.

-> 큰 문제의 최적해부분 문제의 최적해를 포함. 최적 부분 구조

 

D[i, j]를 행렬 Ai부터 Aj까지를 곱할 때의 최소 비용이라 하면, 다음이 성립한다.

D[i, i] = 0

D[i, j] = D[i, k] + D[k+1, j] + pi-1 * pk * pj  (i < j)

 

문제는 k의 값이 무엇인지를 알 수 없다는 것이다. 따라서 k i일 때, i+1일 때, , j-1일 때의 답을 모두 구해야 한다. 그중 최소가 되는 값이 진짜 답이다. 이에 따라 다음 점화식을 세울 수 있다.

 

k로 나눠지는 경우를 모두 확인하면, 전체 답을 구하는데 지수 시간이 걸린다. 이는 행렬의 괄호를 묶는 모든 경우의 수를 전부 확인하는 방법보다 나을 게 없다.

 

여기서 주의해야 할 점은 부분 문제가 중복되는 경우가 많다는 것이다. 예를 들어, D[1, 10]을 구하는 과정에서 D[1, 3]D[1, 4]가 계산되는데, D[1, 4]를 구하는 과정에서 D[1, 3]이 다시 계산된다. 따라서 이차원 배열 D를 생성하고, D[i][j] D[i, j]를 저장해 가져다 씀으로써, 재귀 호출이 중복되는 것을 방지하자.

 

다음으로, 재귀 호출 과정에서 값들이 어떤 순서로 계산되는지 파악하자. 맨 처음으로 계산되는 것은 길이가 1인 행렬의 곱, 즉 하나의 행렬에 대한 비용이다. 행렬 하나에 대해서는 곱셈 연산을 할 게 없으므로 비용이 0이다.

for(i = 1 to n)

D[i][i] = 0;

 

다음으로, 길이가 2인 곱이 연산된다.

for(i = 1 to n-1)

D[i][i+1] = pi-1 * pi * pi+1

 

이제 길이가 L인 곱이 연산된다. L 2부터 n까지 차례대로 연산된다.

for(i = 1 to n-L+1)

j = i+L-1;

D[i][j] =

 

 

전체 코드는 다음과 같다.

 

int M(int p[], int n) {

int D[n+1][n+1];

for (i=1; i<=n; i++)

D[i][i] = 0;

 

for (L=2; L<=n; L++) {

for (i=1; i<=n-L+1; i++) {

j = i + L -1;

minival = ;

for (k=i; k<=j-1; k++)

minival = min(minival, D[i][k] + D[k+1][j] + (p[i-1] * p[k] * p[j]) );

D[i][j] = minival;

}

}

return D[1][n];

}

 

루프가 세 번 중첩되어 있고, 각 루프 인덱스는 최대 n-1개의 값을 가지므로, 시간복잡도는 O(n3)이다.

 

OneNote에서 작성되었습니다.