【问题标题】:efficientely derive what elements of an array have been summed有效地推导出数组的哪些元素已求和
【发布时间】:2020-10-05 14:18:11
【问题描述】:

我有一个输入数组,如下所示:

const dels = [ // up to 50 possible
  {no: 491, weight: 1348},
  {no: 492, weight: 694},
  {no: 1054, weight: 4104},
  {no: 1181, weight: 2636},  // *
  {no: 2096, weight: 4084},
  {no: 2201, weight: 4064},
  {no: 2296, weight: 2364},
  {no: 2365, weight: 1670},
  {no: 2632, weight: 4084},
  {no: 2891, weight: 2424},
  {no: 3051, weight: 2414},  // *
];

我还有一个总和数组,如下所示:

const sums = [5050, 24836]; // up to 4 possible

结构是固定的,但数量未知(来自外部来源)。

我知道sums 数组的每个数字都是另一个数组的一些weight 成员的总和(每个dels 项只计算一次)。

所以可以假设:

const sumDels = dels.reduce((a,i) => a + i.weight, 0);
const sumSums = sums.reduce((a,i) => a + i, 0);
sumDels === sumSums // is true

sumDels.every(x => x.weight > 0) // is true

什么算法可以有效地为我提供导致给定总和的可能组合?

可能的结果如下所示:

const goodResult = [ // <-- array of possible combinations (theretically, there could be more than one)
  [                  // <-- `dels` array mapped with `sumIdx`
    {no: 491, sumIdx: 1},
    {no: 492, sumIdx: 1},
    {no: 1054, sumIdx: 1},
    {no: 1181, sumIdx: 0},  // *
    {no: 2096, sumIdx: 1},
    {no: 2201, sumIdx: 1},
    {no: 2296, sumIdx: 1},
    {no: 2365, sumIdx: 1},
    {no: 2632, sumIdx: 1},
    {no: 2891, sumIdx: 1},
    {no: 3051, sumIdx: 0},  // *
  ]
];

如果我没记错的话,一个天真的解决方案会尝试所有排列,但 sums.length==4 和 dels.length==50 是 1267650600228229401496703205376 种可能的组合... ;-)

【问题讨论】:

标签: javascript arrays algorithm


【解决方案1】:

正如 cmets 中所建议的,这被称为 subset sum problem,我了解到通常没有其他方法可以尝试所有组合,同时在组合已被确定为错误时尽早退出。

这让我找到了another Stackoverflow answer,它有一个很好的递归实现。

虽然它只处理一个总和(我的 sums 数组最多可以达到 4 个数字),但它是完整解决方案的一个很好的起点。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-11-11
    • 1970-01-01
    • 2022-01-13
    • 1970-01-01
    • 2018-05-04
    • 2017-06-06
    • 2019-06-01
    相关资源
    最近更新 更多