Javascript - 获取计算机方程的最小整数解

时间:2018-03-20 02:13:04

标签: javascript math

我在尝试解决编程中的等式时遇到了问题。

想象一下,我有这行代码:

Math.round(((x / 5) + Math.pow(x / 25, 1.3)) / 10) * 10;

给定x = 1000,结果为320。

现在,我如何根据结果解决这个等式?

想象一下,给定结果320我想得到x的最小整数值来解析那行代码。

/*320 =*/ Math.round(((x / 5) + Math.pow(x / 25, 1.3)) / 10) * 10;

由于Math.Round,我正在度过难关。即使表达式是一个线性方程,Math.Round也会为x提供更多的解决方案,所以我想要解决方案的最小整数值。

请注意,x是一个整数,如果我设置x = 999,结果仍为320.

如果我继续降低x,我可以看到984(至少在Chrome 64.0.3282.186中)是这种情况下的正确答案,因为在该表达式/编程行中x的最低值等于320。

4 个答案:

答案 0 :(得分:2)

使用Math.round求解方程只会引入边界条件。

如果:

Math.round(((x / 5) + Math.pow(x / 25, 1.3)) / 10) * 10 = 320

然后:

Math.round(((x / 5) + Math.pow(x / 25, 1.3)) / 10)  = 32

将两边除以10.现在你有:

Math.round(expression) = 32

可以表示为不平等陈述:

31.5 < expression < 32.4999..

表达式等于31.5表示一个边界,表达式等于32.499 ..表示另一个边界。因此,求解边界需要求解:

expression = 31.5 and expression = 32.49999...
((x / 5) + Math.pow(x / 25, 1.3))/10 = 31.5  and 
((x / 5) + Math.pow(x / 25, 1.3))/10 = 32.4999

为x解决这两个问题将为您提供x的有效值范围。现在这只是我不打算做的代数:)

答案 1 :(得分:1)

我猜最有效的方法(虽然有些天真)是遍历所有有效数字并检查谓词。

codeview = $('summernote').summernote('code');
console.log(codeview);
Regx  =  /(\<.*\s*\{\%[^}]*\%\}.*\s*\>)/g;
codeview.replace(Regx,'$1');

现在

function getMinimumIntegerSolution(func, expectedResult){
  for(let i = 0 /*Or Number.MIN_SAFE_INTEGER for -ves*/; i< Number.MAX_SAFE_INTEGER ; i++ ) { 
    if(func(i) === expectedResult)
        return i;
  }
}

这会返回您的期望,984

答案 2 :(得分:0)

因为

定义的功能
f(n) = Math.round(((x / 5) + Math.pow(x / 25, 1.3)) / 10) * 10

是单调的(在这种情况下,增加),你可以做二分搜索。 请注意,我最初使用Java编写了以下代码,它在Javascript中在语法上是不正确的,但希望能够直接转换为后者。

var x0 = 0;
var x1 = 1e6;
var Y = 320d;
var epsilon = 10d;

var x = (x1 - x0) / 2d;
var y = 0;

while (Math.abs(Y - (y = f(x))) > epsilon) {
   if (y > Y) {
      x = (x - x0) / 2d;
   } else {
      x = (x1 - x) / 2d;
   }
   // System.out.println(y + " " + x);
}

while (f(x) < Y)
   ++x;

// System.out.println(Math.round(x) + " " + f(x));

在我的计算机上运行它,让System.out.println取消注释:

490250.0 250000.0
208490.0 125000.0
89370.0 62500.0
38640.0 31250.0
16870.0 15625.0
7440.0 7812.5
3310.0 3906.25
1490.0 1953.125
680.0 976.5625
984 320.0
  • 请注意,最后一个循环递增x保证在不到epsilon步骤内完成。
  • 可以调整x0x1epsilon的值,以便为您的问题提供更好的界限。
  • 如果epsilon的值为&#34;太小&#34;,由于f中发生了舍入,此算法将失败。
  • 此解决方案的复杂性为O(log2(x1 - x0))

答案 3 :(得分:0)

除了@webnetweaver的回答。如果重新排列最终的等式,则会得到一个高阶多项式(13度),这很难用代数方法求解。您可以使用数值方法Newton's method。对于JavaScript中的数值方法,您可以使用numeric.js。您还需要仅为下限(31.5)求解,以便找到最小的整数x,因为函数是单调递增的。有关JavaScript中数值方程求解的信息,请参阅此post

这是使用牛顿方法的解决方案。它使用0作为初始猜测。获得最小整数解只需要五次迭代。

var result = 320;
var d = result - 5;

function func(x) {
  return x / 5 + 0.0152292 * Math.pow(x, 1.3) - d;
}

function deriv(x) {
  return 0.2 + 0.019798 * Math.pow(x, 0.3);
}

var epsilon = 0.001; //termination condition

function newton(guess) {
  var approx = guess - func(guess) / deriv(guess);
  if (Math.abs(guess - approx) > epsilon) {
    console.log("Guess: " + guess);
    return newton(approx);
  } else {
    //round solution up for minimum integer
    return Math.ceil(approx);
  }
}

console.log("Minimum integer: " + newton(0));