본문 바로가기

Algorithm/알고리즘

유클리드 호제법(Euclidean Algorithm)

"경북대학교 이시형 교수님의 수업을 듣고 작성했습니다."

 

학교에서 고급 문제 해결을 듣다가 새삼 매우 파워풀한 최대공약수 찾는 방법이라서 글을 쓴다

유클리드 호제법이란?

유클리드 호제법(-互除法, Euclidean algorithm) 또는유클리드 알고리즘은 2개의자연수또는 정식(整式)의최대공약수를 구하는알고리즘의 하나이다. 호제법이란 말은 두 수가 서로(互) 상대방 수를 나누어(除)서 결국 원하는 수를 얻는 알고리즘을 나타낸다. 2개의 자연수(또는 정식) a, b에 대해서 a를 b로 나눈나머지를 r이라 하면(단, a>b), a와 b의 최대공약수는 b와 r의 최대공약수와 같다. 이 성질에 따라, b를 r로 나눈 나머지 r'를 구하고, 다시 r을 r'로 나눈 나머지를 구하는 과정을 반복하여 나머지가 0이 되었을 때 나누는 수가 a와 b의 최대공약수이다. 이는 명시적으로 기술된 가장 오래된 알고리즘으로서도 알려져 있으며,기원전 300년경에 쓰인유클리드의 《원론》 제7권, 명제 1부터 3까지에 해당한다.
출처

 

유클리드 호제법은 다음과 같은 사실에 기초한다.

두 수 A와 B(A ≥ B)가 있을 때 A를 A-B로 대체하더라도 두 수의 gcd는 변하지 않는다.

먼저 A=c x p, B=c x q라고 하자. c는 최대공약수(gcd)이고,p와 q는 서로소이다.

그럼 A-B=c x (p - q)이고, B=c x q이므로 c는 여전히 A-B와 B 간의 공약수이다.

하지만 만약 p - q와 q가 서로소가 아니고 1보다 큰 공약수 a를 갖는다면, gcd는 c x a가 되어야 할 것이다.

여기서 p - q와 q가 서로소이며, 1 이외에는 공약수가 없음을 증명하기 위해 모순에 의한 증명을 사용한다. 'p - q와 q가 서로소가 아니고, 1보다 큰 공약수 a를 갖는다'고 가정해보자. 만약 그렇다면 p - q=a x j, q=a x k로 둘 수 있다. 이렇게 둔 후 p - q와 q를 더해보면 p=a x (j + k)가 된다. 즉, p=a x (j + k), q=a x k가 되므로 p와 q는 1보다 큰 공약수 a를 갖게 되므로 p와 q는 서로소라는 사실에 모순이 된다. 따라서 'p-q와 q는 서로소가 아니고 1보다 큰 공약수 a를 갖는다'는 가정은 거짓이며, p-q와 q 또한 서로소여야 한다.

 

이처럼 두 인자 중에서 더 큰 수를 큰 수와 작은 수의 차로 대체하다보면 두 값이 점점 작아져 결국 두 수 모두 gcd인 c가 될 것이다.

long gcd1(long a, long b) {
    if (a == b) return a;
    if (a > b) return gcd1(a - b, b);
    else return gcd1(a, b - a);
}

근데 이렇게 하면 두 인자의 차가 매우 큰 경우에 뺄셈 연산을 많이 수행하야 한다는 단점이 있다.

예를 들어, a=3 x 2000, b=3 x 1이라면 a를 a-b로 대체하는 뺄셈 연산을 1999번 수행해야 할 것이다.

 

그래서 큰 수 A를 A-b로 대체하는 대신, A%B로 대체하면 뺄셈 연산을 여러번 수행할 필요가 없다.

long gcd2(long a, long b) {
    if (b == 0) return a;
    if (a > b) return gcd2(b, a % b);
    else return gcd2(a, b % a);
}

이 방법은 재귀 호출을 사용하기 때문에 함수를 호출하고 반환하는 오버헤드가 있다. 이를 줄이기 위해 반복문을 사용해서 구현하면 더 좋다.

int gcd3(int a, int b) {
    int temp;
    while (b != 0) {
        if (a > b) temp = b; b = a % b; a = temp;
        else b = b % a;
    }
    return a;
}

 

'Algorithm > 알고리즘' 카테고리의 다른 글

[다이나믹 프로그래밍] Chained Matrix Multiplication  (0) 2020.11.29
위상 정렬(Topological Sort)  (0) 2020.09.24
[SSSP(1)] Dijkstra Algorithm  (2) 2020.09.01
정렬(Sorting)  (0) 2020.06.15