일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- nontrivial solution
- recursive algorithms
- linear dependence
- solutions of matrix equation
- python
- 배열 섞기
- one-to-one
- Big-Oh notation
- 재귀함수
- trivial solution
- 빅오 표기법
- Big-O 예제
- homogeneous linear system
- nonhomogeneous linear system
- Big Omega
- matrix-vector product
- Big Theta
- Big-Oh 예제
- 이진 탐색
- 일차변환
- 코틀린 Hello World!
- 빅오메가
- 알고리즘 분석의 실례
- matrix fo a linear transformation
- matrix trnasformations
- itertools
- 랜덤 순서 배열
- 코틀린 시작하기
- NumPy
- 빅세타
- Today
- Total
코딩 연습
Big-Oh Notation (빅-오 표기법) 본문
프로그램의 실행시간을 흔히 시간복잡도(time complexity)라고 말한다. 알고리즘의 분석에 있어서 이 시간복잡도를 입력 자료의 크기 $n$ 의 함수로 나타내는 것이 일반적이다. 예를 들어, 다음과 같은 파이썬 코드가 있다고 하자.
def find_max(input_data):
maximum = input_data[0]
for element in input_data:
if element > maximum:
maximum = element
return maximum
위의 파이썬 코드는 리스트 형태로 주어지는 input_data 의 요소 중 그 값이 가장 큰 것을 반환하는 함수 find_max 를 나타낸다. 이때 이 코드의 실행시간은 중간에 있는 for-loop 에 가장 큰 영향을 받게 되리라는 것을 생각할 수 있다. input_data 가 $n$ 개의 요소를 포함하는 리스트라고 할 때 for-loop 는 $n$ 번 반복되게 되므로 결국 이 코드의 실행시간에 가장 큰 영향을 주는 것은 바로 input_data 의 크기인 $n$ 이라고 할 수 있다. 따라서 이 코드의 시간복잡도는 $n$ 에 비례한다고 말할 수 있는 것이다.
그러나 이렇게 단순히 $n$ 에 비례한다고 말하는 것보다는 좀 더 수학적인 표현을 사용하는 것이 폼나 보일 것이고, 그래서 나온 것이 바로 "Big-Oh" 표기법 이라는 것이다. (앞으로는 "빅오"라는 표현을 쓰도록 하겠다.)
함수 $f(n)$ 과 $g(n)$ 의 자연수를 양의 실수로 대응시키는 함수라고 할 때, 다음을 만족시키는 양의 상수 $c>0$ 와 정수 $n_0 \ge 1$ 이 존재하면 "$ f(n)$ is $O(g(n))$" 혹은 "$f(n) \in O(g(n))$" 이라고 쓰고, "$f(n)$ is big-Oh of $g(n)$" 혹은 "$f(n)$ is order of $g(n)$"으로 읽는다. $$f(n) \le c g(n), \text{ for } n \ge n_0$$
다음 그림을 보면 빅오 표기법을 좀 더 쉽게 이해할 수 있을 것이다.
예를 들어, 함수 $8n+5$ 의 경우 $(c, \; n_0)$ 를 $(9, \; 5)$ 혹은 $(13, \; 1)$ 등으로 나타낼 수 있으므로 $O(n)$ 이 된다. 따라서 위에서 봤던 find_max 알고리즘의 경우도 $O(n)$ 으로 나타낼 수 있다.
그렇다면 $f(n)=5n^4 +3n^3 + 2n^2 +4n+1$ 과 같이 복잡한 함수를 빅오 표기법으로 나타내면 어떻게 될까? 이때는 $n$ 이 증가함에 따라 가장 빠른 속도로 증가하는 놈에게 관심을 집중시켜야 한다. 즉, $n$ 이 커질수록 $1 \le n \le n^2 \le n^3 \le n^4$ 이므로 $n^4$ 에 만 관심을 집중시키면 된다. 이렇게 하면 $$5n^4 + 3n^3 +2n^2 + 4n +1 \le (5+4+2+5+1)n^4 = 15n^4$$ 이므로 $c=15, \;\; n_0 =1$ 로 결정할 수 있고, 결국 주어진 함수 $f(n)$ 은 $O \left ( n^4 \right )$ 로 표기할 수 있다.
이것을 일반적인 $n$ 에 대한 다항함수로 확장시켜서 생각하면 $$f(n)=a_0 + a_1 n + \cdots + a_d n^d \;\; (a_d >0)$$ 에 대하여 $$a_0 + a_1 n + a_2 n^2 + \cdots + a_d n^d \le \left ( |a_0| + |a_1| + |a_2| + \cdots + |a_n| \right ) n^d$$ 이므로 $c= |a_0| + |a_1| + |a_2| + \cdots + |a_n| , \;\; n_0 = 1$ 로 결정하면 함수 $f(n)$ 은 $O \left (n^d \right )$ 로 표기할 수 있다.
그렇다면 $O(n)$ 으로 표시되는 알고리즘과 $O \left ( n^2 \right ) $로 표시되는 알고리즘 중 어느 것이 더 좋다고 할 수 있을까? 당연히 $O(n)$ 으로 표현되는 알고리즘이 더 좋다고 할 수 있을 것이다. 단순화해서 생각하면 프로그램의 실행시간이 $n$ 에 비례하는가 $n^2$ 에 비례하는가의 문제이기 때문이다.
빅오 표기법에서는 이렇듯 함수의 증가 속도에 따라서 다음의 7가지 함수들을 사용한다. $$1, \;\; \log n, \;\; n, \;\; n^2 , \;\; n^3 , \;\; 2^n$$ 왼쪽에서부터 살펴보면, 상수함수, 로그함수, 선형함수, 로그 선형함수, 이차함수, 삼차함수, 지수함수가 된다. 이것들의 그래프를 보면 나열된 순서대로 증가 속도가 큰 것을 확인할 수 있다. 아래 함수들의 그래프를 보면 그 증가 속도의 대소관계를 파악하기 쉬울 것이다.
다만 위 그래프에서 착각하지 말아야 할 것은 $n$ 의 값이 커지면 커질수록 $2^n$ 의 증가속도가 $n^3$ 의 증가속도보다 훨씬 빠르다는 것이다. $n=10$ 인 경우만 보더라도 $ 10^3 < 2^{10}$ 이고 그 이후로는 더욱더 큰 격차를 보이면서 $2^n$ 이 빠르게 증가한다. 실제로 위 7개 함수의 함숫값들을 비교하면 다음과 같다.
결국 위 함수들의 증가속도는 $n \to \infty$ 인 상황에서 비교하는 것이 맞다고 할 수 있다.
이와 같은 사실을 토대로 다음과 같은 결과를 얻을 수 있다.
$5n^2 +3n \log n + 2n + 5$ is $O \left (n^2 \right )$
$20n^3 +10n \log n +5$ is $ O \left (n^3 \right )$
$3 \log n +2$ is $O(\log n)$
$2^{n+2}$ is $O \left (2^n \right )$
참고로 다음과 같이 Big-Omega 와 Big-Theta 도 생각할 수 있다.
Big-Omega
함수 $f(n)$ 과 $g(n)$ 의 자연수를 양의 실수로 대응시키는 함수라고 할 때, 다음을 만족시키는 양의 상수 $c>0$ 와 정수 $n_0 \ge 1$ 이 존재하면 "$ f(n)$ is $\Omega (g(n))$" 이라고 쓰고, "$f(n)$ is big-Omega of $g(n)$" 으로 읽는다. $$f(n) \ge c g(n), \text{ for } n \ge n_0$$
Big-Theta
함수 $f(n)$ 과 $g(n)$ 의 자연수를 양의 실수로 대응시키는 함수라고 할 때, 다음을 만족시키는 양의 상수 $c'>0, \; c''>0$ 와 정수 $n_0 \ge 1$ 이 존재하면 "$ f(n)$ is $\Theta (g(n))$" 이라고 쓰고, "$f(n)$ is big-Theta of $g(n)$" 으로 읽는다. $$ c'g(n) \le f(n) \le c'' g(n), \text{ for } n \ge n_0$$
대충 감을 잡았겠지만 빅오는 알고리즘의 최악의 성능을, 빅오메가는 알고리즘의 최고의 성능을, 빅쎄타는 좀더 정확한 알고리즘의 성능을 표시해 준다. 이 중에서 빅오 표기법을 주로 사용하는 이유는 '가장 최악인 상황에서도 최소 이 정도의 성능은 보장된다' 라는 의미를 담고 있기 때문이다.
<참고> Big-Oh Notation 실례
'알고리즘' 카테고리의 다른 글
이진 탐색 알고리즘 (binary search algorithm) (0) | 2017.05.06 |
---|---|
알고리즘 분석의 실례 (Big-Oh Notation 실례) (0) | 2017.05.05 |
(재귀함수) $n!$ ($n$ 의 계승) 구하기 (0) | 2017.04.29 |
(재귀함수) 자(ruler)의 눈금 그리기 (1) | 2017.04.29 |
N-queens 문제 (0) | 2016.03.31 |