扩展欧几里得算法详解
生活随笔
收集整理的這篇文章主要介紹了
扩展欧几里得算法详解
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
本篇將附上擴展歐幾里得算法的思想與推導;
對于一個方程(a*x+b*y=gcd(a,b))來說,我們可以做如下的推導:
設有(a*x_1+b*y_1=gcd(a,b));
同時我們有(b*x_2+(a\%b)*y_2=gcd(b,a\%b));
對于這個方程組,我們希望知道的是(x_1,x_2,y_1,y_2)之間的關系,這樣我們才可以遞歸解決這個問題
我們觀察(b*x_2+(a\%b)*y_2)這個式子,我們可以將((a\%b))寫作((a-lfloorfrac{a}{b}floor*b)),將括號打開常數(a,b)合并,合并之后的結果為(a*y_2+b*(x_2-lfloorfrac{a}{b}floor*y_2)))
由于歐幾里得算法的原理(gcd(a,b)==gcd(b,a\%b)),我們將兩式子聯立,對比系數即可得到(x_1=y_2,y_1=x_2-lfloorfrac{a}{b}floor*y_2)
這個遞歸的邊界是什么呢?我們知道,當樸素歐幾里得到達邊界時,(return gcd(a,0)=a),那么邊界條件就是對(a*x_0+b*y_0=a)求解,很顯然,此時(x_0=1,y_0=0)
當我們遞歸求出了一個方程的特解時,如何求出這個方程的通解呢?
方程(a*x+b*y=gcd(a,b))中,如果將x加上一個常數(k_1,y)減去一個常數(k_2),仍然保持原方程成立,那么(x+k_1,y-k_2)就是方程的一個新解,這個k應該如何選擇呢?
實際上很簡單,(a*(x+k_1)+b*(y+k_2)=gcd(a,b)),打開括號,(a*x+a*k_1+b*y-b*k_2=gcd(a,b));
我們保證原方程成立,就需要(a*k_1==b*k_2),那么顯然(k_1=b,k_2=a)是一種合理的情況,但是這樣是無法包含所有整數解的,因為我們加上的這個值并非是最小值
那我們應該加上什么值才行呢?我們發現當(a*k_1==b*k_2=t*lcm(a,b))可以保證得到所有解,于是每次尋找解就可以分別在(x)加上(frac{b}{gcd(a,b)},在y減去frac{a}{gcd(a,b)})就可以了
對于方程(a*x+b*y=c)我們又該如何求解?我們發現如果((c\%gcd(a,b)!=0))那么這個方程是無解的,而如果(gcd(a,b)*t==c),我們就可以按上面的方法求解之后對我們的解乘上一個(t(t=frac{c}{gcd(a,b)}))
(code:)
int exgcd(int a,int b,int &x1,int &y1)
{
if(!b)
{
x1=1,y1=0;
return a;
}
int x2,y2;
int d=exgcd(b,a%b,x2,y2);
x1=y2,y1=x2-(a/b)*y2;
return d;
}
總結
以上是生活随笔為你收集整理的扩展欧几里得算法详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用SAP云平台Portal servi
- 下一篇: 如何使用号簿助手备份通讯录