扩展欧几里得算法求解模线性方程
2016-06-23 00:40
141 查看
求解模线性方程组
求解线性不定方程组
ax + by = c
先求出一组解, 然后考虑如何表示通解, 设d = gcd(a, b), 假设c不是d的倍数, 则左边是d的倍数而右边不是, 则方程无解, 所以方程有解当且仅当d | c.
设c = c’ * d, 我们先考虑方程 ax + by = d, 这样由扩展gcd便可求出一组解 (x’, y’), 则(c’x’, c’y’)就是原方程的一组解,然后考虑通解:
假设有两组解(x1, y2) , (x2, y2), 有 ax1 + by1 == ax2 + by2 = c, 移项得: a(x1 - x2) == b(y2 - y1), 消去d后有 a’(x1 - x2) == b’(y2 - y1),
此时a’ 和 b’ 互素, 所以(x1 - x2)一定是b’的倍数, 而(y2 - y1)一定是a’的倍数, 由此可得到通解:给一组特解(x, y), 通解为(x - kb’, y + ka’).
求解模线性方程
ax = b(mod n)
其实方程等价于 ax - ny = b, 标准模线性方程,但是得考虑剩余系。
算法导论上有两个定理:
定理一:设d = gcd(a, n), 假定对整数x’, y’, 有d = ax’ + ny’, 如果d | b, 则方程ax = b(mod)有一个解的值为x0, 满足:、
x0 = x'(b / d)(mod n)
定理二:假设方程ax = b(mod n)有解, x0是方程的任意一个解, 则方程对模n恰有d个不同的解, 分别为: xi = x0 + i * (n / d), 其中 i = 1,2,3……d - 1
有了这两个定理, 解方程就不难了。
代码实现
扩展欧几里得算法
ll exgcd(ll a,ll b,ll &x,ll &y) { if(b==0) { x=1; y=0; return a; } ll r=exgcd(b,a%b,x,y); ll t=x; x=y; y=t-a/b*y; return r; }
求解模线性方程求的的只是一组解给一组特解(x, y), 通解为(x - kb’, y + ka’).改代码返回满足x>0&&y>0的最小解。
bool linear_equation(ll a,ll b,ll c,ll &x,ll &y) { ll d=exgcd(a,b,x,y); if(c%d) return false; ll k=c/d; x*=k; y*=k; //求得的只是其中一组解 ll b1 = b/d; ll a1 = a/d; ll i = 0; //cout<<x<<" "<<y<<endl; if(y<0){ while (y<=0){ y+=a1; x-=b1; } } while (y-a1>=0){ y-=a1; x+=b1; } if(y>=0&&x>=0){ return true; } else{ return false; } }
相关文章推荐
- php7 扩展类的写法[2]
- php7 类的方法传参[3]
- php7 读取php.ini[4]
- 书评:《算法之美( Algorithms to Live By )》
- 动易2006序列号破解算法公布
- C#递归算法之分而治之策略
- C#、ASP.NET通用扩展工具类之TypeParse
- Lua编程示例(二):面向对象、metatable对表进行扩展
- Windows Powershell扩展类型系统
- Ruby实现的矩阵连乘算法
- C#插入法排序算法实例分析
- C#算法之大牛生小牛的问题高效解决方法
- C#算法函数:获取一个字符串中的最大长度的数字
- 超大数据量存储常用数据库分表分库算法总结
- C#数据结构与算法揭秘二
- C#、ASP.NET通用扩展工具类之LogicSugar
- C#冒泡法排序算法实例分析
- 算法练习之从String.indexOf的模拟实现开始
- C#算法之关于大牛生小牛的问题
- SQL Server下几个危险的扩展存储过程