최근 수정 시각 : 2025-09-04 14:38:03

연쇄 행렬 곱셈 알고리즘


1. 설명2. 코드 예시

1. 설명

연쇄 행렬 곱셈(chained matrix multiplication) 문제는 주어진 연쇄 행렬의 곱셈을 할 때, 각 원소의 곱셈 횟수를 최소로 하는 곱셈의 순서를 찾는 최적화 문제이다. 예를 들어, 4개의 행렬을 곱하는 ABCD의 경우를 생각해 보자. 행렬 곱셈은 결합법칙이 성립하므로, 행렬을 곱하는 순서는 상관이 없다.
[math(\displaystyle \begin{aligned}
ABCD = ((AB)C)D = (A(BC))D = (AB)(CD) = A((BC)D) = A(B(CD))
\end{aligned} )]
하지만 각 행렬의 행과 열의 크기에 따라 각 원소를 곱하는 횟수는 서로 달라진다. BOJ의 이 문제를 보면 알 수 있다.

연쇄 행렬 곱셈 알고리즘은 연쇄 형렬 곱셈 문제를 풀어, 가장 효율적으로 행렬을 곱하는 순서를 찾는 알고리즘이다. 이 알고리즘은 동적 계획법메모이제이션으로 풀 수 있는 대표적인 알고리즘으로, 알고리즘 교재에 자주 등장한다.

2. 코드 예시

본 문단에서는 Python으로 작성한 코드만 제시했다. 쉬운 이해를 위해 NumPy를 사용하지 않았다.

연쇄 행렬 곱셈 알고리즘은 먼저 재귀 관계를 찾은 후에 이차원 배열을 이용하여 상향식으로 동적계획법을 적용하는 알고리즘이다.
#!syntax python
def minimum(M:list[list[int]], d:list[int], i:int, j:int) -> tuple[int, int]:
    min_value = float('inf')
    min_k = 0
    for k in range(i, j):
        value  = M[i][k] + M[k + 1][j]
        value += d[i - 1]*d[k]*d[j]
        if value < min_value:
            min_value = value
            min_k = k
    return min_value, min_k

def minmult(d:list[int]) -> tuple[list[list[int]], list[list[int]]]:
    '''연쇄 행렬 곱셈 알고리즘'''
    n = len(d) - 1
    M = [[-1]*(n + 1)]*(n + 1)
    P = [[-1]*(n + 1)]*(n + 1)
    for i in range(1, n + 1):
        M[i][i] = 0
    for diagonal in range(1, n):
        for i in range(1, n - diagonal + 1):
            j = i + diagonal
            M[i][j], P[i][j] = minimum(M, d, i, j)
    return M, P
위의 소스 코드 구현에 대한 상세한 설명은 이 영상에서 볼 수 있다.

분류