我想使用Solver从较大集合的子集中查找目标总和。 (16个数字的10个数字子集)。我对Solver不是很熟悉,而且我不确定设置约束的最佳方法。
我在集合中有5类数字,A,B,C,D,E。16的集合可能包括这些类别的不同组合,但目标子集总数具有定义的组成: A,B,B,C,C,C,(B或C),(B或C),D,E
所以我的问题是,我如何将这些规则引入Solver?
其次,我知道Solver提出了1个解决方案,有没有办法获得最接近目标的一系列解决方案?那么,如果我有一个不能完全产生目标的集合,我可以看到3个最接近目标的解决方案(正负)?
感谢。
答案 0 :(得分:2)
TL / DR - 这是设置问题的一种方法。得到一系列答案,这些答案是关闭"超出了Solver的范围。如果您定义要搜索的其他条件,则可以使用VBA执行此操作。 (编辑 - 为定义的化妆添加设置)
<强>评论强>
似乎没有关于&#34的标准;必须从每个类别&#34;中选择一个数字,或者#34;必须从类别X&#34;中选择一个数字。相反,你有一堆数字,每个都属于一个类别,但你想找到提供一定总数的数字组合 - 然后调查类别。
初始问题设置
根据您在评论中提供的信息,我将以下内容放在一起......
A列(类别)和B列(值)是您提供的信息。 C列(选定)只是0或1. D列(结果)是乘法=B2*C2
填充的。
F2是D列的总和.G2是此总和的目标值(如您所提供)。 H2是计算=(F2-G2)^2
的平方误差。
这是解算器设置......
$H$2
- 计算的平方误差$C$2:$C$17
或列C. $C$2:$C$17 = binary
。这会强制值为0或1. 以下是结果 - 与您报告的内容不同。当我强制你的结果时,我获得了106.61的CalcTotal(可能是某处的转录错误)......
查找近乎结果
Solver是一个优化器,所以它会找到答案&#34;最适合你的目标。
为了给你提供不同的答案,你需要为它提供不同的目标。
例如,您可能希望强制使用C1的解决方案,但仍然最接近您的目标。设置可能如下所示......
......用这个解决方案......
在该示例中,我从&#34;通过更改可变单元格排除了$C$10
:&#34;并且从约束到约束:&#34;领域。完成同样事情的另一种方法是保持原始字段值不变,但添加$C$10 = 1
的附加约束。
或者,作为另一个例子,也许你想要一个从类别B中选择两个值的解决方案。你可以修改设置以包括从每个类别中选择的值的总和,并添加一个约束。这是设置...
......以及相应的结果......
制作算法
如果确定要查找的解决方案范围的标准,则可以设置VBA子循环以设置求解器,获取解决方案,并存储&#34;选择列的结果&#34;审查。
如果你想追踪这个轨道,我建议你看看这个网站上提供的其他解决方案,尝试设置一些内容,并在遇到问题时提出新问题。
修改 - 错过了您的一个标准
我错过了你的陈述 - &#34;目标子集总数有一个明确的构成:A,B,B,C,C,C,(B或C),(B或C),D,E&# 34;
在这种情况下,使用包含每个类别的总和的设置,您可以指定这些约束...
在第一次通过时,它提供了这样的结果:A1,B2,B3,C1,C3,C4,C5,C6,D1,E1,总共106.38。