Excel解算器从数字集的子集中查找目标和

时间:2017-01-14 17:51:16

标签: excel excel-vba solver vba

我想使用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个最接近目标的解决方案(正负)?

感谢。

1 个答案:

答案 0 :(得分:2)

TL / DR - 这是设置问题的一种方法。得到一系列答案,这些答案是关闭"超出了Solver的范围。如果您定义要搜索的其他条件,则可以使用VBA执行此操作。 (编辑 - 为定义的化妆添加设置)

<强>评论

似乎没有关于&#34的标准;必须从每个类别&#34;中选择一个数字,或者#34;必须从类别X&#34;中选择一个数字。相反,你有一堆数字,每个都属于一个类别,但你想找到提供一定总数的数字组合 - 然后调查类别。

初始问题设置

根据您在评论中提供的信息,我将以下内容放在一起......

enter image description here

A列(类别)和B列(值)是您提供的信息。 C列(选定)只是0或1. D列(结果)是乘法=B2*C2填充的。

F2是D列的总和.G2是此总和的目标值(如您所提供)。 H2是计算=(F2-G2)^2的平方误差。

这是解算器设置......

enter image description here

  • 设置目标:设置为$H$2 - 计算的平方误差
  • To:设置为Min。您可以选择Value Of:0,但如果没有确切答案,则可能会失败。
  • 通过更改可变单元格:设置为$C$2:$C$17或列C.
  • 受制约约束:包括$C$2:$C$17 = binary。这会强制值为0或1.
  • 选择解决方法:设置为进化。 GRG Nonlinear有时可以解决这类问题,但它比Evolutionary需要更长的时间。

以下是结果 - 与您报告的内容不同。当我强制你的结果时,我获得了106.61的CalcTotal(可能是某处的转录错误)......

enter image description here

查找近乎结果

Solver是一个优化器,所以它会找到答案&#34;最适合你的目标。

为了给你提供不同的答案,你需要为它提供不同的目标。

例如,您可能希望强制使用C1的解决方案,但仍然最接近您的目标。设置可能如下所示......

enter image description here

......用这个解决方案......

enter image description here

在该示例中,我从&#34;通过更​​改可变单元格排除了$C$10:&#34;并且从约束到约束:&#34;领域。完成同样事情的另一种方法是保持原始字段值不变,但添加$C$10 = 1的附加约束。

或者,作为另一个例子,也许你想要一个从类别B中选择两个值的解决方案。你可以修改设置以包括从每个类别中选择的值的总和,并添加一个约束。这是设置...

enter image description here

......以及相应的结果......

enter image description here

制作算法

如果确定要查找的解决方案范围的标准,则可以设置VBA子循环以设置求解器,获取解决方案,并存储&#34;选择列的结果&#34;审查。

如果你想追踪这个轨道,我建议你看看这个网站上提供的其他解决方案,尝试设置一些内容,并在遇到问题时提出新问题。

修改 - 错过了您的一个标准

我错过了你的陈述 - &#34;目标子集总数有一个明确的构成:A,B,B,C,C,C,(B或C),(B或C),D,E&# 34;

在这种情况下,使用包含每个类别的总和的设置,您可以指定这些约束...

  • $ G $ 4 = 1
  • $ G $ 5&lt; = 4
  • $ G $ 5&gt; = 2
  • $ G $ 6&lt; = 5
  • $ G $ 6&gt; = 3
  • $ G $ 7 = 1
  • $ G $ 8 = 1

在第一次通过时,它提供了这样的结果:A1,B2,B3,C1,C3,C4,C5,C6,D1,E1,总共106.38。