查找总计等于N(javascript)的所有值组合

时间:2020-09-20 11:37:08

标签: javascript node.js

我正在计算某种化学,为此我需要组合总计等于N的值。我有以下数组,每个数组的值不能超过X

Array:
索引|最大值
0 | 370
1 | 185
2 | 740
3 | 277.5
4 | 277.5
5 | 1850
6 | 925
7 | 1850

我需要一个函数,该函数将从每个数组索引中计算出所有可能的值组合,总计为1850。

例如
0 | 77.00
1 | 700.00
2 | 50.00
3 | 300.00
4 | 700.00
5 | 15.00
6 | 7.00
7 | 1.00
总计= 1850

预先感谢您的帮助

1 个答案:

答案 0 :(得分:1)

这是一种方法。

  • 按升序对数组进行排序(以使分布有些公平-因为我们将首先循环执行,以顺序结束并选择数字,所以较大的数字可能会掩盖较小的数字,从而有机会)
  • 为结果准备一个新数组(初始化为0)
  • 对于已排序数组中的每个条目,我们将采用一些随机值,直到(总和达到)为止-在此示例中,我们将减少一些计数器变量以跟踪(pointsLeft)。将随机选取的数字添加到结果数组中的指定索引处(结果数组索引应遵循原始数组的顺序-而不是排序的顺序)
  • 如果没有pointsLeft,则表示结果数组中的项等于所需的总和。所以我们只返回结果数组。

const testArray = [
  370,
  185,
  740,
  277.5,
  277.5,
  1850,
  925,
  1850,
]

function getRandomInt(min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

function getCombination(values, pointsLeft) {
  let sorted = values.map((x, i) => {
    return [x, i]
  }).sort((a, b) => a[0] - b[0]); // sorted from small -> large - keeping the original index

  const result = new Array(values.length).fill(0)

  while (pointsLeft > 0) {
    for (const [_, [value, original_index]] of sorted.entries()) {
      someRandomValueToSubtract = getRandomInt(1, value / 2)
      if (pointsLeft - someRandomValueToSubtract < 0) continue
      pointsLeft -= someRandomValueToSubtract
      result[original_index] += someRandomValueToSubtract
    }
  }

  return result
}

const x = getCombination(testArray, 1850)

console.log("ITEMS:", x)

console.log("SUM:", x.reduce(function(a, b) {
  return a + b;
}, 0))
.as-console-wrapper { max-height: 100% !important; top: 0; }

相关问题