2

I have a linear optimization goal to Maximize EE+FF, where EE and FF each consist of some C and D.

With code I've written, I can get solver to find:

EE_quantity: 0, FF_quantity: 7

...but I know there to be another solution:

EE_quantity: 1, FF_quantity: 6

In order to validate user input for other valid solutions, I added a constraint for both EE and FF. So I added the EE_quantity == 0, FF_quantity == 7 in the code below, which is a runnable example:

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()
    );
}

It seems that Solver Foundation really doesn't like this specific combination. Using EE_quantity == 1, FF_quantity == 6 is fine, as is using just EE_quantity == 0 or FF_quantity == 7. But using both, AND having one of them being zero, throws an exception:

Index was outside the bounds of the array.

What is going on under the hood, here? And how do I specify that I want to find "all" solutions for a specific problem?

4

1 回答 1

8

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

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

删除设置EE_quantity和的最后两个约束,FF_quantity而是在创建决策对象时将上限和下限分别设置为 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 求解器不能保证立即产生全局最优解。但是,如果您对解决方案进行足够长的迭代,您就会到达那里。

于 2014-06-10T22:59:43.360 回答