본문 바로가기

ComputerScience/Algorithm concepts

[C언어] 점화식과 점근적 분석 방법(반복대치,추정후 증명, 마스터 정리)

728x90
쉽게 배우는 알고리즘 책을 참고했습니다.
 

안녕하세요!!

 


점화식

점화식이란? 어떤 함수를 자신과 똑같은 함수를 이용해서 나타내는 것입니다.

다시말해 재귀함수의 구조를 갖는 알고리즘만!! 점화식으로 표현할 수 있다 이말입니다.

재귀함수란?
F(n) = n * F(n - 1)  ; // 팩토리얼
F(n) = F(n - 1) + F(n - 2)  ;  // 피보나치 수
F(n) = F(n/2) + C  ; //데이터를 두가지로 나누는 정렬! 등..

 자기자신을 호출하는 형식을 갖는 것은 재귀함수라고 표현할 수 있습니다. 

 

F(n) = n^2 + n + 1 이런 형식은 쉽게 시간 복잡도를 구할 수 있지만,  자기 자신을 갖는 점화식일 경우에는 점화식의 점근적 분석 방법을 통해서 F(n) = F(n-1)+ ...의 형태를 F(n)  = n+ ...의 형태로 바꾸어야 시간 복잡도를 구할 수 있습니다.

 

예를 들어 

MergeSort(A[],p,r){
	if(p<r) then// 두개 이상의 수가 존재한다면  (상수 시간)
    {  
    	q<-[(p+r)/2]; //q = 반으로 나눈 값 (상수시간)
        MergeSort(A,p,q); // p~ r  까지의 구간중 반 구간인 p~ q까지 정렬 실행  T(n/2)
        MergeSort(A,q+1,r);  //q+1~ r 까지, 남은 배열의 구간을 정렬,   	T(n/2)
        Merge(A,p,q,r); //병합   (후처리 시간)
    }
}

위의 알고리즘을 보시면, MergeSort함수가 있습니다. 이 함수는 만약 배열A가 2개 이상의 구간이 존재한다면, 반으로 나눈 값을 q에 저장후 ( 배열 A 공간=> [p, , , , q,q+1, , , ,r]  ) q를 기준으로 p~q까지, 배열의 개수에 반을 sort할 수 있도록 MergeSort함수를 다시 호출하고, 연이어 나머지 반을 다시 MergeSort함수를 통해 호출을 합니다.

반으로 나누는 값, if(p<r)배열의 크기 판단값은 상수 시간에 해당됩니다.

※ 상수 시간은 점근적 수행 시간에 영향을 미치지 않으므로 제외해도 됩니다!!

따라서 점화식 T(n) 은 MergeSort(A,p,q) , MergeSort(A,q+1,r) => 배열의 크기에 반을 다시 MergeSort()함수로 호출하는 재귀구조형식을 두번 수행하므로 T(n) =2*T(n/2) + C(후처리시간+상수시간) 의 점화식을 갖게 됩니다.

2. 점화식의 점근적 분석 방법

점화식을 알고는 있지만 시간 복잡도의 표현 방법으로 표기를 바로 할 수 없기에 우리는 (1) 반복대치, (2) 추정후 증명, (3) 마스터정리 에 의해 점화식을 함수꼴로 변형해야만 시간 복잡도 표기 방법을 사용할 수 있습니다.

 (1) 반복 대치

 반복대치는 쉽게 말해서 T(n) = T(n-1)+C의 점화식이 있다면, (단 T(1) <=C)

T(n-1) 과, T(n-2), T(n-3)일때의 점화식을 T(n)점화식에 대입해서 (언제까지? T(1)이될 때 까지) 값을 알아가는 과정이라고 생각하시면 됩니다.

 

예를들어 T(n) = T(n -1)+C라는 점화식이 있다면 T(n-1) = T(n-2) +C 이고, T(n-2) = T(n-3) + C임을 구할 수 있습니다.

다시말해 T(n)의 점화식에, n의 자리에 n-1을 대입, n-2을 대입한 결과를 구할 수 있는 것입니다..

따라서    T(n) = T(n-1) + 1C   에 방금 구한 T(n-2)와 T(n-3)을 차례대로 대입하면

             T(n) = T(n-2) + 2C

             T(n) = T(n-3) + 3C    를 얻게됩니다.  특징이 보이시죠?

             T(n) = T(n-4) + 4C   이것을 n -1   -> 1 까지 반복하다보면!!

             T(n) = T(1)+(n-1)C 와 같아집니다. 이때 T(1) =<C이므로

             T(n) = C + nC - C   == nC 임을 얻을 수 있습니다.

             점화식 = 점화식의 꼴에서

             점화식 = n에 대한 다항식으로 바뀌었을 때 비로소 시간 복잡도의 표기 방법을 사용할 수 있습니다.

             따라서 T(n) =O(n)임을 구할 수 있습니다.

 

(2) 추정후 증명

 추정후 증명은 반복대치와는 반대로 먼저 점근적 복잡도를 가정한 다음에 그 가정이 맞는지! 귀납적으로 증명하는 방법입니다.

 예를들어 점화식 T(n) <= 2*T(n/2) + n의 식이 있을 때 우리는 쉽게 이 점화식이 분할정복에 의한 점화식임을 알 수 있습니다. (사실 저도 어렵긴한데,, 저위의 식은 몇번 알고리즘을 파악하다보면 금방 Sorting에 관한 식임을 알 수,,있을것닙니다) 분할정복의 시간 복잡도는 식에 따라서 O(n*logn) 이거나 O(logn)입니다.

하지만 위의  식에서 시간 복잡도는 O(nlogn)이므로

우리는 빅오 표기법의 정의 인 f(n)<=c*g(n)  ,,점근적 상한의 정리를 이용해

T(n)<=c*n*log n을 만족하는 양의 상수 C를 구하게 된다면

이 추정은 증명이 되는 것입니다..

따라서 T(n) = c*n*log n 의 식을 이용해 T(n/2), n/2를 대입하면 T(n/2) =<c*(n/2)*log(n/2)를 구할 수 있고 방금 구한식을 T(n)<=2*T(n/2) + n 여기 형광등 색에 대입한 식 <= C*nlogn을 만족하는 상수 C하나만 구하게 된다면 증명은 성공하는 방법입니다.

 

(3) 마스터 정리

 제가 봤을 땐 반복대치랑 마스터정리가 가장 쉬운 것 같습니다. 특히 마스터 정리는 공식만 알 고 있다면 쉽게 점화식의 복잡도를 구할 수 있기 때문이죠,,

여기서 밑줄친 부분이 가장 중요합니다. 왜냐면 f(n)/h(n)이 리미트 극한으로 갔을 경우 수렴하는지, 발산하는지 ,0으로 수렴하는지 에 따라서 시간 복잡도 표현의 결과가 달라지기 때문입니다. 

lim         f(n)/h(n)의 식에서

n->무한대

 

h(n)이 클 경우 0으로 수렴하고 이때의 T(n) = 빅세타(h(n))이 되고,

f(n)이 클 경우 무한대로 발산하고, 이때의 T(n) = 빅세타(f(n)) 이 됩니다.

만약 f(n)/h(n)이 n / n과 같을 경우 1,2등 상수로 수렴할 경우 T(n) =   빅세타(h(n)logn)의 결과를 얻습니다.

 

다음 글은 점화식을 점근적 분석으로 문제 해결하는 과정으로 찾아오겠습니다!!

 

728x90