2023. 7. 12. 15:31ㆍAlgorithm
이번 글에서는, divide-and-conquer 기법을 활용한 유명 알고리즘에 대해 살펴볼 것이다.
1. Quicksort
Problem
정렬 문제다. 즉, 크기가 n인 배열(=S)을 정렬하는 문제다.
Algorithm
- pivot item(=S[0])으로 배열 S를 partition(=분할)한다.
- pivot item보다 작으면 pivot 왼쪽으로 이동
- pivot item보다 크면 pivot 오른쪽으로 이동
- 분할된 2개 부분 배열을 각각 정렬한다. (만약, 부분 배열을 더 분할할 수 있다면, 재귀를 통해 정렬한다.)
- 정렬된 부분 배열 2개와 pivot item을 연결시켜, original 배열을 정렬한다.
Analysis
base operation: pivot item과 S[i]간의 비교 연산
input size: n(=size of array)
worst-case time complexity (already sorted):
W(n)=W(0)+W(n−1)+n−1=n(n−1)2∈Θ(n2)
average-case time complexity (randomly shuffled):
A(n)=∑np=11n[A(p−1)+A(n−p)]+n−1=2n∑np=1A(p−1)+n−1=1.38(n+1)lgn∈Θ(nlgn)
2. Stressen's Matrix Multiplication Algorithm
Problem
행렬 곱 연산
Algorithm
- 행렬 A, B를 각각 4개의 부분 행렬(A11,A12,A21,A22 and B11,B12,B21,B22)로 나눈다.
- 분할된 부분 행렬의 합을 가지고 행렬 곱 연산을 진행한다. (만약, 부분 행렬의 합을 더 나눌 수 있다면, 재귀를 통해 행렬 곱 연산을 한다.)
- M1=(A11+A22)(B11+B22)
- M2=(A21+A22)B11
- M3=A11(B12−B22)
- M4=A22(B21−B11)
- M5=(A11+A12)B22
- M6=(A21−A11)(B11+B12)
- M7=(A12−A22)(B21+B22)
- 7개 행렬(M1∼M7)을 기반으로 , A, B의 행렬 곱 연산을 진행한다.
[M1+M4−M5+M7M3+M5M2+M4M1+M3−M2+M6]
Analysis 1
base operation: 행렬 곱
input size: n (=A,B의 행, 열의 개수)
every-case time complexity:
T(n)=7T(n2)=nlg7≈n2.81∈Θ(n2.81)
Analysis 2
base operation: 행렬 합 및 차
input size: n (=A, B의 행, 열의 개수)
every-case time complexity:
T(n)=7T(n2)+18(n2)2=6nlg7−6n2≈6n2.81−6n2∈Θ(n2.81)
행렬 곱은 적어도 Θ(n2)의 시간 복잡도를 갖고 있으며, 이를 만족하는 알고리즘은 아직 발견되지 않았다.
3. Multiplication of Large Integers
Problem
n자리수 정수 u, v의 곱 연산
Algorithm
- n자리수 정수를 2개 n/2자리수 정수로 표현(or 분할)한다.
(u=x×10n/2+y,v=w×10n/2+z) - n/2자리수 정수의 곱 연산을 진행한다. (만약, n/2자리수 정수를 더 분할할 수 있다면, 재귀를 통해 곱 연산을 한다.)
- x×w
- (x+y)×(w+z)
- yz
- n/2자리수 정수의 곱 연산을 기반으로, u와 v의 곱 연산을 진행한다.
uv=xw×10n+[(x+y)(w+z)−(xw+yz)]×10n/2+yz
Analysis
base operation: 한자리 숫자 조작(=manipulation)
input size: n(= u, v의 자리수)
worst-case time complexity:
W(n)=3W(n2)+cn=cnlg3≈n1.58∈Θ(n1.58)
4. RSelect (=randomize)
Problem
kth order statistic problem 즉, 크기가 n인 배열(=S)에서 k번째로 작은 item을 찾는 문제다.
이는 정렬 문제보다 쉬운 문제다.
Algorithm
- pivot item(=S[0])으로 배열 S를 partition(=분할)한다.
- pivot item보다 작으면 pivot 왼쪽으로 이동
- pivot item보다 크면 pivot 오른쪽으로 이동
- 만약 pivot index(=j)가 k일 경우, pivot item 반환. 그렇지 않으면,
- k가 pivot index보다 작다면, 왼쪽 부분 배열에서 k번째로 작은 item을 찾는다.
- k가 pivot index보다 크다면, 오른쪽 부분 배열에서 k−j번째로 작은 item을 찾는다.
- 만약, 부분 배열을 더 분할할 수 있다면, 재귀를 통해 item을 찾는다.
- 부분 배열에서 찾은 item이 solution이다.
Analysis
base operation: pivot item과 S[i]간의 비교 연산
input size: n(=size of array)
worst-case time complexity (already sorted):
W(n)=W(n−1)+n−1=n(n−1)2∈Θ(n2)
average-case time complexity (randomly shuffled):
A(n)=1n∑np=1A(p−1)+n−1=(n−1)(1+1/2+1/4+⋯)≈2n∈Θ(n)
5. DSelect (=deterimistic)
Problem
kth order statistic problem 즉, 크기가 n인 배열(=S)에서 k번째로 작은 item을 찾는 문제다.
Algorithm
- pivot(=MoM)을 구한다.
- 크기가 5인 부분 배열의 중앙값을 모두 구해, 중앙값 집합(m=(m1,m2,⋯,mn/5))을 만든다.
- m의 중앙값(=Median-of-Median)을 구한다. 즉, m에서 m/5번째로 작은 item을 찾는다. (만약, m을 더 나눌 수 있다면, 재귀를 통해 MoM을 구한다.)
- 만약 MoM index(=j)가 k일 경우, MoM item 반환. 그렇지 않으면,
- k가 pivot index보다 작다면, 왼쪽 부분 배열에서 k번째로 작은 item을 찾는다.
- k가 pivot index보다 크다면, 오른쪽 부분 배열에서 k−j번째로 작은 item을 찾는다.
- 만약, 부분 배열을 더 분할할 수 있다면, 재귀를 통해 item을 찾는다.
- 이때, 3n10<j<7n10을 만족한다.
- 부분 배열에서 찾은 item이 solution이다
Analysis
base operation: pivot item과 S[i]간의 비교 연산
input size: n(=size of array)
worst-case time complexity (already sorted):
W(n)=n+W(n/5)+n−1+W(7n10)∈Θ(n)
'Algorithm' 카테고리의 다른 글
[Algorithm Part 3] 5. Dynamic Programming algorithms (0) | 2023.07.14 |
---|---|
[Algorithm Part 3] 4. Dynamic Programming (0) | 2023.07.13 |
[Algorithm Part 3] 2. Divide-and-Conquer (0) | 2023.07.07 |
[Algorithm Part 3] 1. Introduction (0) | 2023.07.06 |
[Algorithm Part 2] 11. Reduction (0) | 2023.06.29 |