javascript - 有效地推导出数组的哪些元素已被求和
问题描述
我有一个输入数组,如下所示:
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 可能的组合,如果我没记错的话...... ;-)
解决方案
正如评论中所建议的,这被称为子集和问题,我了解到通常没有其他方法可以尝试所有组合,同时在组合已经被确定为错误时尽早退出。
这让我得到了另一个 Stackoverflow 答案,它有一个很好的递归实现。
虽然它只处理一个总和(我的sums
数组最多可以达到 4 个数字),但它是完整解决方案的一个很好的起点。
推荐阅读
- node.js - 处理本地网络访问的节点 API url 与本地部署的 MEAN 应用程序的远程访问
- javascript - 当组件在视图中滚动时如何更改组件的状态?
- kotlin - 在 IDEA 中调试 Kotlin Coroutines 时如何查看局部变量值?
- variables - 如何在剧本开始之前打印所有额外变量
- android - Flutter 的 main() 方法何时/何地从 Android 和 iOS 端调用?
- postgresql - PostgreSQL - 在 JSONPath 比较表达式中使用的索引 JSON 字段
- reactjs - NextJS Amplify:数据在第一页刷新时返回null,数据在快速刷新后显示
- php - 如何检测用户如何访问 php 中的页面?(来自表格或直接)
- reactjs - AWS Cognito 自定义登录重定向在单页应用程序中不起作用
- django - 使用 Django 过滤器并使用 CSV 导出数据