ユークリッドの互除法の証明
📂整数論ユークリッドの互除法の証明
アルゴリズム
二つの整数a≥bに対して、gcd(a,b)は以下のように求めることができる。
疑似コード
アルゴリズム:ユークリッドの互除法 | | |
---|
入力 | 整数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 | |
出力 | aとbの最大公約数gcd(a,b)を得る。 | |
定理
ri<ri+1に対して、ri−1=qi+1⋅ri+ri+1の漸化式を満たすa:=r−1とb:=r0を定義しよう。rn+1=0を満たすnの最小公倍数は以下の通りである。
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)
}