【发布时间】:2020-07-09 13:50:08
【问题描述】:
给定1, 2, 3 的幂集,我得到 8 个子集:[]、[1]、[2]、[2,1]、[3]、[3]、[3,1]、[3,2]、[3,2,1]。然后我想生成这个新集合的子集,它们正好是原始集合的 1 个。
我的powerset的powerset中的子集数量是256,但只有8个,其中“1”、“2”和“3”各有1个,分别是:
[
[
[1,2,3]
],
[
[2,3],[1]
],
[
[2],[1,3]
],
[
[3],[1,2]
],
[
[3],[2],[1]
],
[
[],[2],[1,3]
],
[
[],[3],[1,2]
],
[
[],[3],[2],[1]
]
]
有没有一种方法可以在不生成具有 256 个子集的第二个幂集的情况下获得最终集?我正在寻找一种可以扩展到第一组 3 可以有 10 多个元素的方法,因此计算第二个 powerset 效率不高。 请注意,我实际上并不需要有空数组的情况。我的理想答案只包括前 5 个元素。通过专注于 powerset,我可能把自己推到了错误的兔子洞里。它解决了我在 n=7 时遇到的问题,但无法扩展到 n=14。
这是我目前拥有的函数,但是当数组中有 5 个项目时它会失败。我很可能完全从错误的方向来解决这个问题。
function getPowerset(arr) {
return (function ps(list) {
if (list.length === 0) {
return [
[]
];
}
const head = list.pop();
const tail = ps(list);
return [...tail, ...tail.map((e) => [head, ...e])];
})([...arr]).filter(x => x.length);
}
function getCombinationsOfSet(arr) {
const subsets = getPowerset(arr);
const subsetsOfSubsets = getPowerset(subsets);
return subsetsOfSubsets.filter((subset) => {
const flattened = subset.flat();
if (flattened.length !== arr.length) {
return false;
}
let tempArr = [...arr];
for (let part of flattened) {
const index = tempArr.indexOf(part);
if (index === -1) {
return false;
}
tempArr.splice(index, 1);
}
return true;
})
}
console.time('time-taken');
console.log(getCombinationsOfSet([1, 2, 3]));
console.timeEnd('time-taken');
【问题讨论】:
-
您正在寻找将原始集划分为子集(有时包括空子集)的所有方法,对吗?
-
@ScottHunter 是的。理想情况下,我可以获得所有可能的方法来划分原始集合,以便我可以通过评分函数运行每种可能性来选择最好的。对于我的具体用例,我不希望任何子集的总和大于 X,然后我会选择总和与 X 之间差异最小的那个。
-
相信你正在寻找原始集的分区(stackoverflow.com/questions/20530128/…)
标签: javascript combinations permutation powerset