计算两个变量单个简单方程解集的算法

时间:2012-05-03 13:40:11

标签: java algorithm math

假设我有一个简单的形式方程式:

7x + 4y = n

其中n由我们选择,x,y和n都是正整数。这是给我们的唯一方程式。在可能的解决方案中,我们需要解决方案(x,y),其中x是最小的。 e.g。

7x + 4y = 14, then (2, 0) is the solution
7x + 4y = 15, then (1, 2) is the solution
7x + 4y = 32, then (4, 1) and (0, 8) are the possible solutions,
of which (0, 8) is the correct solution

我想设计一种算法,以尽可能少的运行时间来计算它。我想到的当前算法是这样的:

Given an input n
Calculate max(x) = n/7
for i = 0 to max(x)
    If the equation 7*i + 4*y = n holds
        return value of i and y
    else
        continue

我认为,这种算法在最坏情况下的行为可以达到O(n)的运行时间。有没有更好的算法来计算解决方案?

4 个答案:

答案 0 :(得分:7)

让我们考虑更普遍的问题

  • 对于两个互质正整数ab,给定正整数n,找到非负整数对(x,y),使a*x + b*y = n最小x。 (如果有的话。不需要,例如7*x + 4*y = 5没有非负xy的解决方案。)

在给定任何解决方案的情况下暂时忽略非负性

a*x0 + b*y0 = n
对于某个整数(x0 - k*b, y0 + k*a)

所有解决方案的格式为k。因此x modulo by modulo a的其余部分是解决方案的不变量,我们有

a*x ≡ n (mod b), and b*y ≡ n (mod a)

所以我们需要解决等式a*x ≡ n (mod b) - 另一个跟随。

0 < ca*c ≡ 1 (mod b)的整数。您可以通过扩展的欧几里德算法找到它,或者(等效地)在O(log b)步骤中a/b的连续分数展开。两种算法都自然地产生具有该属性的唯一c < b

然后x的最小候选者是x0n*c的余数b

当且仅当x,然后y是任具有非感性x0*a <= nx0的解决方案。

当然,对于小xx(如7和4),强力并不比计算ya的倒数慢。

答案 1 :(得分:6)

我们有

7(x-4)+4(y+7)=7x+4y

因此,如果(x,y)是一个解,那么(x-4,y + 7)也是一个解。因此,如果存在解决方案,则存在x <4的解决方案。这就是为什么你只需要测试在恒定时间内运行的x = 0..3。

这可以扩展到ax + by = n形式的任何方程式,你只需要测试x = 0..b-1。

答案 2 :(得分:2)

我建议在Numerical Recipes in C一书中查看Simplex方法。您可以轻松地将C代码视为伪代码并生成Java版本。您想要的单纯形式的版本是“约束单纯形”,它仅处理正值。这本书是available online for free。从第10.8节开始,然后向前阅读。

答案 3 :(得分:1)

O(n):

y=n/4;
while((n-4y)%7!=0 && y!=0){
 y--;
}
x=(n-4y)/7;