我正在尝试通过执行以下操作向我的求解器基础添加基本约束:
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中执行模运算的任何想法?根据文档here,它受到支持。
我将开始使用反射器来挖掘代码,但我想我也会在这里发布它。如果我找到解决方案,我会更新我的问题以包含答案。
答案 0 :(得分: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
答案 1 :(得分: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]正在工作,求解器计算以下决定
a:1, b:3
但是如果我用这个替换最后一个约束
m.AddConstraint(null, "b == Mod[a,2]");
我得到一个OmlParseException(“无法解析OML模型。表达式:Mod [a,2]。”)。我想我们自己在这里,也许我们能做的最好的事情就是坚持使用user141603的答案。