选择最大数量的唯一且有效的组合

问题描述 投票:0回答:1

在过去的几天里,我一直在尝试找到一种算法,可以帮助我根据批准的组合列表找到最大数量的唯一组合。 每个组合都是预先定义的一组 1..n 个元素(元素不得重复)。

例如 元素列表(包含可用件数):

元素 数量
A 2
B 3
C 2
D 4
E 2
F 3

批准的组合列表(某个元素出现一次意味着需要 1 个该元素):

组合 元素
C1 A、C、D
C2 C、D、F
C3 E、A
C4 A、F、C

其中,我可以选择{C1,C4}或{C1,C2,C3}。

现在有了一个组合列表,我想优化要选择的组合,以便使用尽可能多的组合(唯一的!),仅包含列表中的元素并且只有这样的数量,即选择 {C1, C4} 代替 {C1, C2, C3}。

我尝试了“贪心”算法,即只要有足够的元素就一一检查组合,但结果很不理想。 ChatGPT 也没有帮助。

有人可以帮忙提供一段代码(Java 或任何其他语言)或至少提供算法的名称,以便我可以进一步查看(我假设这样的问题已经被命名了;))?

java algorithm
1个回答
0
投票

您在这里要解决的一般问题是一个名为 Set Cover 的众所周知问题的概括(也就是说,它更难)。不幸的是,集合覆盖是NP-complete,这意味着实际上没有人知道一种“好的”算法可以在所有问题实例上最优地解决它。已知的 NP 完全问题的最佳算法都是“生成每种可能性并查看它是否是迄今为止最好的”算法,因此它们在输入的某些方面(通常是有效组合的数量,或元素类型)。

如果您正在处理的问题实例非常小,就像您的示例一样,只需尝试所有组合即可正常工作。对于您的示例问题,这应该只需要几毫秒,并且对于最多大约 20 种不同的组合(C1、...、C20)可能是可行的。

针对您的特定问题,最简单的方法是循环遍历所有可能的组合子集,对于每个子集测试您拥有的可用元素数量是否可以满足它。如果有 n 个组合,则它们有 2^n 个可能的子集(因此对于您的示例,2^4 = 16 个可能的子集),并且您可以使用整数中的位来轻松枚举它们:只需使用一个整数循环变量从0到2^n-1,用bit 0(最右边)表示是否包含C1,用bit 1表示是否包含C2,以此类推。

© www.soinside.com 2019 - 2024. All rights reserved.