점근적 분석과 시간복잡도
04 Oct 2019 | Algorithm알고리즘의 분석
- 알고리즘의 자원사용량 분석
- 자원이란 실행시간, 메모리, 저장장치, 통신 등을 의미한다.
포스팅에서는 공간(메모리)은 실행시간에 비해 상대적으로 저비용이므로 실행시간의 분석에 대해서만 다루겠다.
-
시간복잡도
1) 실행시간은 실행환경에 따라. 달라진다.
- 하드웨어, 운영체제, 언어, 컴파일러 등등
2) 실행시간을 측정하는 대신 연산의 실행 횟수를 카운트 하는게 더 합리적이다.
3) 연산의 실행 횟수는 입력 데이터의 크기에 대한 함수로 표현한다.
4) 데이터의 크기가 같더라도 실제 데이터에 따라 달라진다.
-
예를 들어 정렬 알고리즘을 실행한다고 가정하면
입력 데이터의 정렬 상태에 따라 연산 횟수가 달라진다.- 이 문제로 인해 ‘최악의 경우 시간복잡도’와 ‘평균 시간복잡도’를 사용한다.
- ‘평균 시간복잡도’는 구하기가 쉽지 않은 경우가 많으므로 자주 사용하지 않는다.
- ‘최악의 경우 시간복잡도’가 알고리즘 성능의 하한선을 보장 해주므로 주로 사용한다.
-
-
점근적 분석
1) 점근적 표기법을 사용한다.
- 데이터의 개수 n->∞ 일때, 수행시간이 증가하는 growth rate로 시간복잡도를 표현하는 기법 ex) 4n^2+5n+3 -> O(n^2), Θ(n^2)
2) 유일한 분석법도 아니고 가장 좋은 분석법도 아니다. 다만 간단하며, 알고리즘의 실행환경에 비의존적이다.
-
상수 시간복잡도
int sample(int data[], int n)
{
int k = n/2;
return data[k];
}
n에 상관없이 상수 시간이 소요된다. 시간 복잡도 : O(1)
- 선형 시간복잡도
int sum(int data[],int n)
{
int sum = 0;
for (int i=0; i<n; i++)
{
// 이 알고리즘에서 가장 자주 실행되는 문장이며, 실행 횟수는 항상 n번이다.
// 가장 자주 실행되는 문장의 실행 횟수가 n번이라면 모든 문장의 실행 횟수의 합은 n에 선형적으로 비례한다.
sum = sum + data[i];
}
return sum;
}
시간 복잡도 : O(n)
- 신형 시간복잡도(순차탐색)
int search(int n, int data[], int target)
{
for(int i=0; i<n; i++)
{
if(data[i] == target)
return i;
}
return -1;
}
이 경우 target과 n에 따라 시간복잡도가 달라진다. 최악의 경우는. data 배열의 마지막 인덱스가 target이 존재하는 경우이므로 최악의 경우 시간복잡도 : O(n)
- Quadratic (2차함수)
boolean is_distinct(int n, int data[])
{
for(int i=0; i<n-1; i++)
for(int j=i+1; j<n; j++)
{
if(data[i] == data[j])
return false;
}
return true;
}
최악의 경우 배열에 저장된 모든 원소쌍을 비교하므로 연산의 횟수는 n(n-1)/2. 최악의 경우 시간복잡도 : O(n^2)