我有一个最大化EE + FF的线性优化目标,其中EE和FF各自包含一些C和D.
通过我编写的代码,我可以让求解器找到:
EE_quantity: 0, FF_quantity: 7
...但我知道还有另一种解决方案:
EE_quantity: 1, FF_quantity: 6
为了验证其他有效解决方案的用户输入,我为EE和FF添加了约束。所以我在下面的代码中添加了EE_quantity == 0, FF_quantity == 7
,这是一个可运行的示例:
SolverContext c2 = SolverContext.GetContext();
Model m2 = c2.CreateModel();
p.elements = elements_multilevel_productmix();
Decision C_quantity = new Decision(Domain.IntegerNonnegative, "C_quantity");
Decision D_quantity = new Decision(Domain.IntegerNonnegative, "D_quantity");
Decision EE_quantity = new Decision(Domain.IntegerNonnegative, "EE_quantity");
Decision FF_quantity = new Decision(Domain.IntegerNonnegative, "FF_quantity");
m2.AddDecisions(C_quantity, D_quantity, EE_quantity, FF_quantity);
m2.AddConstraints("production",
6 * C_quantity + 4 * D_quantity <= 100,
1 * C_quantity + 2 * D_quantity <= 200,
2 * EE_quantity + 1 * FF_quantity <= C_quantity,
1 * EE_quantity + 2 * FF_quantity <= D_quantity,
EE_quantity == 0,
FF_quantity == 7
);
m2.AddGoal("fixed_EE_FF", GoalKind.Maximize, "EE_quantity + FF_quantity");
Solution sol = c2.Solve(new SimplexDirective());
foreach (var item in sol.Decisions)
{
System.Diagnostics.Debug.WriteLine(
item.Name + ": " + item.GetDouble().ToString()
);
}
Solver Foundation似乎并不喜欢这种特定的组合。使用EE_quantity == 1, FF_quantity == 6
很好,就像使用EE_quantity == 0
或FF_quantity == 7
一样。但是使用两者,并且其中一个为零,则抛出异常:
索引超出了数组的范围。
引擎盖下发生了什么事,这里?我如何指定我想找到&#34; all&#34;针对特定问题的解决方案?
答案 0 :(得分:8)
(注意:没有新版本的Solver Foundation即将发布 - 它基本上被微软删除了。)
堆栈跟踪表明这是单工解算器预解析程序中的错误。不幸的是, SimplexDirective 没有办法禁用预解决方案(与 InteriorPointDirective 不同)。因此,解决此问题的方法是以不同方式指定固定变量。
删除设置EE_quantity
和FF_quantity
的最后两个约束,并在创建Decision对象时将上限和下限分别设置为0和7。这相当于您想要表达的内容,但似乎避免了MSF错误:
Decision EE_quantity = new Decision(Domain.IntegerRange(0, 0), "EE_quantity");
Decision FF_quantity = new Decision(Domain.IntegerRange(7, 7), "FF_quantity");
MSF单纯形求解器与许多混合整数求解器一样,只返回最优解。如果您希望MSF返回所有解决方案,请更改为约束编程解算器( ConstraintProgrammingDirective )。如果您查看Solution.GetNext()
的文档,您应该弄清楚如何执行此操作。
当然,CP解算器无法保证立即生成全局最优解决方案。但如果你足够长时间地遍历解决方案,你就会到达那里。