为已知解决方案添加约束会导致超出范围的异常

时间:2014-06-07 17:57:06

标签: linear-programming solver ms-solver-foundation

我有一个最大化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 == 0FF_quantity == 7一样。但是使用两者,并且其中一个为零,则抛出异常:

  

索引超出了数组的范围。

引擎盖下发生了什么事,这里?我如何指定我想找到&#34; all&#34;针对特定问题的解决方案?

1 个答案:

答案 0 :(得分:8)

(注意:没有新版本的Solver Foundation即将发布 - 它基本上被微软删除了。)

堆栈跟踪表明这是单工解算器预解析程序中的错误。不幸的是, SimplexDirective 没有办法禁用预解决方案(与 InteriorPointDirective 不同)。因此,解决此问题的方法是以不同方式指定固定变量。

删除设置EE_quantityFF_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解算器无法保证立即生成全局最优解决方案。但如果你足够长时间地遍历解决方案,你就会到达那里。