23. 최장 공통 부분 수열(lcs) [10 2주차]

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

23. 최장 공통 부분 수열(LCS) [10-2주차]

2024 1 14일 일요일

오전 2:58

<최장 공통 부분 수열(LCS)>

X = ACCGGTCGACGTAAGCCGGCCAA,
Y = TTTCCCACTCGTGTCGACGTGTAAGCCTTAAGGCCAA
 

두 개의 DNA 순서열 (sequence)이 있을 때, 두 개가 얼마나 유사한지를 측정하는 일이 자주 발생한다.

 

이 때 이 둘이 얼마나 유사한지를 측정할 때, 둘의 LCS를 구하여 이것이 길면 길수록 둘은 더 유사하다고 할 수 있다.

 

LCS를 정의하기 위해, 먼저 부분서열(subsequence)를 정의한다.

 

  • 부분서열 : 주어진 서열에서 일부 문자를 삭제한 뒤, 남은 문자들을 순서대로 연결한 서열
  • X Y의 공통 부분서열 : X의 부분 서열이면서 Y의 부분 서열이 되는 것.
  • LCS : 공통 부분서열 중 가장 긴 것

 

LCS를 구하기 위해, X의 모든 부분 서열에 대해 Y의 모든 부분 서열을 비교하는 브루트포스 방법을 시도할 수 있다. X의 모든 부분 서열을 구하는 것만 해도, 경우의 수가 mC0 + mC1 + + mCm = 2m으로 지수 시간이 걸린다.

동적계획법을 통해 LCS를 구하는 방법을 알아보자

 

 

<동적계획법으로 LCS 구하기>

LCS(i, j) x[1..i], y[1..j]의 최장 공통 부분 수열 길이로 정의한다.

z[1..k] LCS가 저장된 문자열이라 가정한다.

이때, LCS의 점화식은 편집 거리 점화식과 비슷한 방식으로 구해진다.

 

x y의 마지막 문자부터 서로 비교하여 LCS를 구할 때, 다음 세 가지 경우를 생각해 볼 수 있다.

 

1.     x[m] == y[n]인 경우

해당 문자를 LCS에 추가하고 x[1..n-1] y[1..m-1] LCS를 구한다.

LCS(n, m) = LCS(n-1, m-1) + 1,    z[k] == x[m] == y[n]

2.     x[m] != y[n], z[k] != y[n]인 경우

y[n]를 버리고 x[1..m] y[1..n-1] LCS를 구한다.

LCS(n, m) = LCS(m, n-1)

3.     x[m] != y[n], z[k] != x[m]인 경우

x[m]를 버리고 x[1..m-1] y[1..n] LCS를 구한다.

LCS(n, m) = LCS(m-1, n)

 

2, 3번의 경우, 더 큰 값을 LCS(i, j)에 저장하면 된다.

이를 일반화하여 점화식을 세우면 다음과 같다.

 

 

점화식이 편집 거리 식과 비슷하다. change연산의 경우가 없고 min이 아니라 max를 구해야 한다.

 

편집 거리를 구할 때와 마찬가지로, 점화식을 이용해 아래와 같이 2차원 배열을 만들어 LCS를 구할 수 있다.

change연산의 경우가 없으므로 문자가 서로 같은 경우에만 대각선 방향 연산을 할 수 있다. 문자가 서로 같으면 대각선 방향 연산 비용 + 1, 다르면 나머지 두 연산 중 max를 선택.

 

OneNote에서 작성되었습니다.