首页 > 解决方案 > 得到等式的倒数 - JavaScript

问题描述

假设我有这个公式,例如:

function getExperience(level) {
  let a = 0;
  for (let x = 1; x < level; x += 1) {
    a += Math.floor(x + (200 * (2 ** (x / 3))));
  }

  return Math.floor(a / 4);
}


for (var i = 1; i < 100; i++) {
  console.log(`Level ${i}: ${getExperience(i)}`);
}

要获得 50 级所需的经验,您可以:getExperience(50).

但是,您将如何扭转这种情况并获得经验所需的水平?所以,getLevel(20010272)会输出50.

标签: javascriptmath

解决方案


简短的回答

您可以将4.328085 * Math.log(0.00519842 * xp + 1.259921045)其用作相应级别的非常好的近似值。

如果您需要一个确切的值,您可以遍历所有级别,直到找到所需的范围,如this answer中所示。

长答案

稍作修改的功能

我认为不可能为这个函数的逆找到一个精确的、封闭形式的表达式。不过,稍微修改一下应该是可以getExperience(level)的。

  • 首先,您会注意到x增长速度慢得多2 ** (x / 3)
  • 然后,Math.floor对大数没有太大影响。

所以让我们删除它们!这是稍微修改的功能:

function getExperienceEstimate(level) {
  let a = 0;
  for (let x = 1; x < level; x += 1) {
    a += 200 * (2 ** (x / 3));
  }
  return a / 4;
}

这种方法的优点是它现在是一个几何级数,因此可以直接计算总和,无需任何循环:

function getExperienceEstimate(level) {
  let a = 50;
  let r = 2 ** (1 / 3);
  return a * (r**level - r) / (r - 1);
};

getExperienceEstimate(50)返回20011971.993575357,仅比 小 0.0015% getExperience(50)

反函数

根据Wolfram Alpha,这是 的反函数getExperienceEstimate

function getLevelEstimate(xp){
  let a = 50;
  let r = 2 ** (1 / 3);
  return Math.log(xp * (r - 1) / a + r) / Math.log(r);
};

通过一些小的精度损失,您可以进一步简化它:

function getLevelEstimate(xp){
  return 4.328085 * Math.log(0.00519842 * xp + 1.259921045)
};

这只是一个估计,但效果很好,不需要任何循环!

测试

对于 20012272 XP,近似反函数返回50.00006263463371,如果您想找到确切的结果,这应该是一个很好的起点。

function getExperience(level) {
  let a = 0;
  for (let x = 1; x < level; x += 1) {
    a += Math.floor(x + (200 * (2 ** (x / 3))));
  }
  return Math.floor(a / 4);
}

function getLevelEstimate(xp){
  return 4.328085 * Math.log(0.00519842 * xp + 1.259921045)
};

for (var i = 1; i < 100; i++) {
  console.log(`Level ${i} (XP = ${getExperience(i)}). Estimated level : ${getLevelEstimate(getExperience(i))}`);
}


推荐阅读