假设我有一个简单的形式方程式:
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)的运行时间。有没有更好的算法来计算解决方案?
答案 0 :(得分:7)
让我们考虑更普遍的问题
a
和b
,给定正整数n
,找到非负整数对(x,y)
,使a*x + b*y = n
最小x
。 (如果有的话。不需要,例如7*x + 4*y = 5
没有非负x
和y
的解决方案。)在给定任何解决方案的情况下暂时忽略非负性
a*x0 + b*y0 = n
对于某个整数(x0 - k*b, y0 + k*a)
, 所有解决方案的格式为k
。因此x
modulo b
和y
modulo a
的其余部分是解决方案的不变量,我们有
a*x ≡ n (mod b), and b*y ≡ n (mod a)
所以我们需要解决等式a*x ≡ n (mod b)
- 另一个跟随。
让0 < c
为a*c ≡ 1 (mod b)
的整数。您可以通过扩展的欧几里德算法找到它,或者(等效地)在O(log b)步骤中a/b
的连续分数展开。两种算法都自然地产生具有该属性的唯一c < b
。
然后x
的最小候选者是x0
模n*c
的余数b
。
当且仅当x
,然后y
是任具有非感性x0*a <= n
和x0
的解决方案。
当然,对于小x
和x
(如7和4),强力并不比计算y
模a
的倒数慢。
答案 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;