2

我正在尝试通过执行以下操作向我的求解器基础添加一个基本约束:

model.AddConstraint("c1", x % y == 0);

我收到一个编译错误,提示“运算符 '%' 不能应用于 'Microsoft.SolverFoundation.Services.Decision' 和 'Microsoft.SolverFoundation.Services.Decision' 类型的操作数”。

这是有道理的,因为许多运算符不受支持。但是,许多不受支持的运算符(sin、cos、tan 等)可用作 Model 类的特定方法,如下所示:

model.AddConstraint("c1", Model.Sum(x,y) == 0);

如果我将“Sum”替换为“Mod”,则没有可用的方法。

关于如何在 Solver Foundation 中执行模运算的任何想法?根据此处的文档,它是受支持的。

我将开始使用反射器来挖掘代码,但我想我也会在这里发布它。如果我找到解决方案,我将更新我的问题以包含答案。

4

2 回答 2

0

真的很有趣,我想在 SO 上写完全相同的问题 :-)

我发现在http://msdn.microsoft.com/en-us/library/ff818505(v=vs.93).aspx为 OML 语言定义了 Mod 运算符。

AddConstraint 方法有一个重载,它接受表达式字符串(我猜是 OML 表达式?)而不是 Term。不幸的是,我不知道正确的格式,但是一旦我们掌握了诀窍,我们也可以使用所有其他运算符。

编辑

看起来并非 API 中描述的每个 OML 表达式都有效。例如,

SolverContext sc = SolverContext.GetContext();
Model m = sc.CreateModel();

m.AddDecision(new Decision(Domain.IntegerRange(0,10), "a"));
m.AddDecision(new Decision(Domain.IntegerRange(0, 10), "b"));

m.AddConstraint(null, "a > 0");
m.AddConstraint(null, "b == Plus[a,2]");

在这种情况下,Plus[x,y] 正在工作,求解器计算以下决策

甲:1,乙:3

但是如果我用这个替换最后一个约束

m.AddConstraint(null, "b == Mod[a,2]");

我收到 OmlParseException(“无法解析 OML 模型。表达式:Mod[a,2]。”)。我想我们在这里只能靠自己了,也许我们能做的最好的事情就是坚持 user141603 的答案。

于 2012-12-10T07:47:20.373 回答
0

我在http://msdn.microsoft.com/en-us/library/ff525341(v=vs.93).aspx上没有看到 Mod ,但这里有一个解决方法:

Model.Floor(Model.Quotient(x,y))==Model.Ceiling(Model.Quotient(x,y))

仅当 x/y 是整数时才成立,因此 x%y==0。

还有其他方法可以组合允许的运算符来检查它是否可整。我最喜欢的(尽管由于浮点精度我不推荐它)是

Model.Sin(Math.PI*Model.Quotient(x,y))==0 
于 2012-12-09T17:14:20.400 回答