需要帮助理解方程式

时间:2012-09-07 22:39:14

标签: z3 z3py

方程为Pell x*x - 193 * y*y = 1

z3py中的

x = BitVec('x',64)
y = BitVec('y',64)
solve(x*x - 193 * y*y == 1, x > 0, y > 0)

结果:[y = 2744248620923429728, x = 8169167793018974721]

为什么?

P.S。有效答案:[y = 448036604040,x = 6224323426849]

1 个答案:

答案 0 :(得分:8)

可以使用位向量算法来求解丢番图方程。基本思想是使用ZeroExt来避免Pad指出的溢出。例如,如果我们将大小为x的两个位向量yn相乘,那么我们必须将n零位添加到x和{{} 1}}以确保结果不会溢出。也就是说,我们写道:

y

以下Python函数集可用于将任何丢番图方程 ZeroExt(n, x) * ZeroExt(n, y) “安全地”编码为位向量算法。通过“安全”,我的意思是如果有一个解决方案适合用于编码D(x_1, ..., x_n) = 0,...,x_1的位数,那么最终将找到模数资源,如内存和时间。 使用这些函数,我们可以将Pell方程x_n编码为x^2 - d*y^2 == 1。函数eq(mul(x, x), add(val(1), mul(val(d), mul(y, y))))尝试使用pell(d,n)位查找xy的值。

以下链接包含完整示例: http://rise4fun.com/Z3Py/Pehp

话虽如此,使用位向量算法求解Pell方程是非常昂贵的。问题是乘法对于位向量求解器来说真的很难。 Z3使用的编码的复杂性在n上是二次的。在我的机器上,我只设法解决了具有小解的Pell方程。示例:nd = 982d = 980d = 1000。在所有情况下,我使用的d = 1001小于n。我认为对于具有非常大的最小正解的方程式没有希望,例如24我们需要大约100位来编码d = 991x的值。 对于这些情况,我认为专业解算器会表现得更好。

BTW,rise4fun网站有一个小超时,因为它是一个共享资源,用于运行Rise组中的所有研究原型。因此,为了解决非平凡的Pell方程,我们需要在自己的机器上运行Z3。

y