【问题标题】:Solving a simple linear equation求解一个简单的线性方程
【发布时间】:2015-02-25 05:44:02
【问题描述】:

假设我需要解以下方程,

ax + by = c

其中abc 是已知值,xy 是介于 0 和 10(含)之间的自然数。

除了平凡的解决方案,

for (x = 0; x <= 10; x++)
    for (y = 0; y <= 10; y++)
         if (a * x + b * y == c)
             printf("%d %d", x, y);

...有没有办法有效地找到这个独立系统的所有解决方案?

【问题讨论】:

    标签: algorithm linear-algebra linear-equation


    【解决方案1】:

    在您的情况下,由于 xy 只取 010 之间的值,因此蛮力算法可能是最佳选择,因为它需要更少的时间来实现。

    但是,如果您必须在更大的范围内找到所有积分解 (x, y) 对,您确实应该使用正确的数学工具来解决这个问题。

    您正在尝试求解线性丢番图方程,并且众所周知,当且仅当 ab 的最大公约数 d 除以 c 时,积分解才存在 em>。

    如果解决方案不存在,那么你就完成了。否则,您应该首先应用Extended Euclidean Algorithm 来找到方程ax + by = d 的特殊解。

    根据Bézout's identity,所有其他积分解的形式为:

    其中k 是任意整数。

    但请注意,我们对ax + by = c 的解决方案感兴趣,我们必须将所有(x, y) 对缩放c / d 的系数。

    【讨论】:

      【解决方案2】:

      你只需要遍历 x,然后计算 y。 (x, y) 是一个解,如果 y 是整数,并且在 0 到 10 之间。

      在 C 中:

      for (int x = 0; x <= 10; ++x) {
          double y = (double)(c - ax) / b;
          // If y is an integer, and it's between 0 and 10, then (x, y) is a solution
          BOOL isInteger = abs(floor(y) - y) < 0.001;
          if (isInteger && 0 <= y && y <= 10) {
              printf("%d %d", x, y);
          }
      }
      

      【讨论】:

        【解决方案3】:

        您可以通过直接检查(c-a*x)/b 是否为整数来避免第二个for 循环。

        编辑:由于我在 cmets 中指出的一些粗心疏忽,我的代码没有我希望的那么干净,但它仍然比嵌套的 for 循环快。

        int by;
        for (x = 0; x <= 10; x++) {
            by = c-a*x;                         // this is b*y
        
            if(b==0) {                          // check for special case of b==0
                if (by==0) {
                    printf("%d and any value for y", x);
                }
            } else {                            // b!=0 case
                y  = by/b;                  
                if (by%b==0 && 0<=y && y<=10) { // is y an integer between 0 and 10?
                    printf("%d %d", x, by/b);
                }
            }
        }
        

        【讨论】:

        • y 也需要介于 0 和 10 之间。
        • 当b为0时会发生什么?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多