유클리드 호제법 증명
📂정수론유클리드 호제법 증명
알고리즘
두 정수 a≥b 에 대해 gcd(a,b) 는 다음과 같이 구할 수 있다.
의사코드
알고리즘: 유클리드 호제법 | | |
---|
In | 정수 a,b 가 주어진다. | |
1. | r0←a | |
2. | r1←b | |
3. | while ri+1=0 | |
4. | 다음이 성립하도록 qi 와 새로운 ri+1를 계속 구한다.ri−1=ri⋅qi+ri+1,(ri>ri+1) | |
5. | i←i+1 | |
6. | end while | |
Out | a 와 b 의 최대공약수 gcd(a,b) 를 얻는다. | |
정리
ri<ri+1 에 대해 점화식 ri−1=qi+1⋅ri+ri+1 을 만족시키는 a:=r−1 와 b:=r0 를 정의하자. rn+1=0 을 만족시키는 n 에 대해 a,b 의 최소공배수는 다음과 같다.
rn=gcd(a,b)
이 알고리즘은 많아도 2log2(b)+1 번 안에 답을 구할 수 있다.
설명
이른바 유클리드 호제법euclidean Algorithm으로 알려진 이 알고리즘은 최대공약수를 매우 효율적으로 구할 수 있게 해준다. 일일이 소인수분해를 하지 않고도 답을 내기 때문에 숫자가 커질수록 더욱 빛을 발한다.
위에서 정리된 알고리즘은는 순수하게 유클리드의 방식을 그대로 옮겨놓은 것일 뿐, 코드는 더 쉽게 짤 수 있다.
증명
a=r0=b=r1=ri=rt−1=b⋅q1+r1r2⋅q2+r3⋮ri+1⋅qi+1+ri+2⋮rt⋅qt
이라고 하자. 주어진 조건인
ri−1=ri⋅qi+ri+1,(ri>ri+1)
에서 ri−1 와 ri 의 약수는 ri+1 의 약수이기도 함을 알 수 있다. 따라서
gcd(ri−1,ri)=gcd(ri,ri+1)
이다. 한편 rt−1=rt⋅qt,(rt+1=0) 를 생각해보면
gcd(rt−1,rt)=gcd(rt⋅qt,rt)=rt
이제 소요 시간, 즉 소요되는 횟수를 구해보자. 그에 앞서 ri+2<21ri 임을 보여야한다.
- ri+1≤21ri 일 경우
ri+2<ri+1≤21ri - ri+1>21ri 일 경우
ri=ri+1⋅1+ri+2
이므로
ri+2=ri−ri+1<ri−21ri≤21ri
다. 정리하면
ri+2<21ri
이고, 위 부등식에 의해
b=r1>2⋅r3>22⋅r5>⋯>2k⋅r2k+1
이다. 정리하면
b>2k⋅r2k+1
한편 2k≥b 이므로 r2k+1<1 이어야하고, 그 말은 곧
r2k+1=0
이다. 또한 t+1≤2k+1 이므로
t≤2k
다시 말해 알고리즘을 끝내는데 걸리는 총 횟수는 t 보다 작거나 같고,
t≤2k=2(k−1)+2<2log2(b)+2
이므로 소요되는 횟수는 많아도 다음과 같다.
2log2(b)+1
■
구현
아래는 유클리드 호제법을 R 코드로 작성한 것이다. 첫번째는 알고리즘을 그대로 옮겨놓은 버전이고, 아랫쪽은 쓸모없는 부분을 쳐내고 깔끔하게 정리한 버전이다.
gcd<-function(a,b)
{
if (b>a) {i=b; b=a; a=i;}
i=2
r=numeric(0)
r[1]=b
r[2]=a%%b
while(r[i]!=0)
{
r[i+1]=r[i-1]%%r[i]
i=i+1
}
return(r[i-1])
}
gcd <- function(a, b) {
if (b>a) {i=b; b=a; a=i;}
while(b) {
temp = b
b = a %% b
a = temp
}
return(a)
}