扩展欧几里德算法解线性方程ax+by=c

来源:互联网 发布:mac表情包快捷键 编辑:程序博客网 时间:2024/06/05 06:04

问题:ax+by=c,已知a、b、c,求解使该等式成立的一组x,y。其中a、b、c、x、y均为整数

a,b的最大公约数为gcd(a,b)。如果c不是gcd(a,b)的倍数,则该等式无解,因为等式左边除以gcd(a,b)是整数,而等式右边除以gcd(a,b)后为小数。

因此,只有当c是gcd(a,b)的倍数的时候,该等式有解。这样,可以通过计算使ax1+by1=gcd(a,b)成立的x1、y1,然后有x=(c/gcd(a,b))*x1,y=(c/gcd(a,b))*y1,得到x,y。

问题就被转换为求使ax+by=gcd(a,b)成立的一组x,y。这可以用扩展欧几里德算法求解。如下:

如果b为零,则gcd(a,b)=a,那么x=1,y=0为一组解。

如果b不为零,根据欧几里德定理,可以设

ax1+by1=gcd(a,b)=gcd(b,a%b)=bx2+(a%b)y2=bx2+(a-(a/b)*b)y2

化简后有x1=y2,y1=x2-(a/b)y2。因此x1,y1依赖于x2,y2,同理依次类推递归调用求出x3,y3,x4,y4……,类似于辗转相除,直到b=0时,求出xn,yn,便可以推出x1,y1的值。

扩展欧几里德算法:

// 扩展欧几里德算法,解gcd(a, b) = ax + by
// 结果存储在x,y中,用户调用时保证a、b、c都是整数
// 返回a,b的最大公约数
int extended_euclid(int a, int b, int &x, int &y)
{
    
if(b == 0// gcd(a, b) == a
    {
        x 
= 1;
        y 
= 0;
        
return a;
    }
    
int n = extended_euclid(b, a%b, x, y);
    
int tmp = x;
    x 
= y;
    y 
= tmp - static_cast<int>(a/b)*y;
    
return n;
}

用户调用linear_equation求解线性方程:

// 等式ax+by=c,已知a、b、c,求x和y。
// 解该线性方程等同于解同余式ax = c(mod b)
// 返回值表示是否有解,true有解,false无解
bool linear_equation(int a, int b, int c, int &x, int &y)
{
    
int n = extended_euclid(a, b, x, y);
    
if(c%n)
        
return false;
    
int k = c/n;
    x 
*= k;
    y 
*= k;
    
return true;
}

linear_equation函数也可以用来解同余式ax=c(mod b)。

由ax=c(mod b),可以得到ax = mb+r;c = nb+r。化简可以得到ax+(n-m)b=c。调用linear_equation可以求出x。

 

 

原创粉丝点击