【问题标题】:Algorithm to compute solution set of single simple equation with two variables计算具有两个变量的单个简单方程的解集的算法
【发布时间】:2012-05-13 00:59:25
【问题描述】:

假设我有一个简单的公式:

7x + 4y = n

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

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)。有没有更好的算法来计算解?

【问题讨论】:

  • 你说 If the equation 7*i + 4*y = n holds 我是从循环中得到的,但是 y 是什么?
  • X 和 Y 是否有上限?如果是这样,那么二进制搜索就是您的成功之道。
  • 您可能想了解linear integer programming。您的问题绝对是广义问题的一个特定实例,但我很好奇您面临的简化问题是否有有效的解决方案。
  • @Betlista 我有 raised the issue on meta 如果你想进一步评论的话

标签: java algorithm math


【解决方案1】:

我们有

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

所以如果 (x, y) 是一个解,那么 (x-4,y+7) 也是一个解。因此,如果有一个解决方案,那么就有一个 x

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

【讨论】:

  • 我认为方程式可以改变。有什么只是一个样本。
  • 如果方程是 ax+by=n 的形式,那么如果有一个解,那么就有一个 x
  • 你的想法是好的和真实的(我认为),但答案不够丰富。如果我是你,我会编辑答案并添加更多信息和解释。如果您这样做,一些反对者可能会取消对您的反对。无论如何,我为它 +1,以引领潮流。
  • 谢谢你的建议,我会做的。
  • 很棒的解决方案(y)
【解决方案2】:

让我们考虑更一般的问题

  • 对于两个互质的正整数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。所以 xbya 的余数是解的不变量,我们有

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 的最小候选者是n*cb 的余数x0

问题有一个非负xy 的解当且仅当x0*a <= n,然后x0 是出现在任何非负xy 的解中的最小非负x .

当然,对于像7和4这样小的ab,蛮力并不比计算a取模b的倒数慢。

【讨论】:

    【解决方案3】:

    我建议查看 Numerical Recipes in C 书中的 Simplex 方法。您可以轻松地将 C 代码视为伪代码并制作 java 版本。您想要的单纯形的版本是“约束单纯形”,它只处理正值。这本书是available online for free。从第 10.8 节开始并继续阅读。

    【讨论】:

    • Simplex 方法很棒。
    【解决方案4】:

    O(n):

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

    【讨论】:

    • 为什么要调用整数?如果 n 是 int,则 n/4 也是。此外,为了提高效率,您应该从 x 开始,因为它的上限更小。
    • 我把它变成了通用的......当结果不是整数时,有些编程语言会将除法转换为浮点数。
    • 所以你决定让你的代码在除发言权之外的所有方面都与 Java 相关。
    • 好吧,你让我到了那里。我不确定在这种情况下的 java 行为,因为我也使用其他语言进行开发。为什么我们讨论这个而不是算法?为什么不自己写一个答案,而不是批评别人的代码?
    • 因为我要写的内容与您已经拥有的内容太接近了。我正试图激励你清理它。
    猜你喜欢
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 2023-01-05
    • 1970-01-01
    • 2020-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多