如何解决如何检查假定的解决方案会违反哪些约束?
在某些情况下,求解器无法为我的模型找到我认为存在的解决方案。 所以我想填充一个解决方案,然后检查违反了哪个约束。 如何使用 choco-solver 做到这一点?
使用 choco-solver 4.10.6。
解决方法
强制解决
我最终添加了约束来强制变量为我假定的解决方案的值: 例如
// constraints to force given solution
vehicle2FirstStop[0].eq(model.intVar(4)).post();
vehicle2FirstStop[1].eq(model.intVar(3)).post();
nextStop[1].eq(model.intVar(0)).post();
nextStop[2].eq(model.intVar(1)).post();
...
然后
model.getSolver().showContradiction();
if (model.getSolver().solve()) { ....
显示假定解的第一个矛盾,例如
/!\ CONTRADICTION (PropXplusYeqZ(sum_exp_49,mul_exp_51,...
所以下一步是找出诸如 sum_exp_49 之类的术语的来源。
用代码匹配矛盾项
这是一个简单的约束修复,希望能提供足够的信息。我们可以覆盖模型的 post() 和 associates() 方法,以便在发布约束/创建变量时转储 java 源文件名和行号。
Model model = new Model("Vrp1RpV") {
/**
* retrieve the filename and line number of first caller outside of choco-solver from stacktrace
*/
String getSource() {
String source = null;
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
// starts from 3: thread.getStackTrace() + this.getSource() + caller (post() or associates())
for (int i = 3; i < stackTraceElements.length; i++) {
// keep rewinding until we get out of choco-solver packages
if (!stackTraceElements[i].getClassName().toString().startsWith("org.chocosolver")) {
source = stackTraceElements[i].getFileName() + ":" + stackTraceElements[i].getLineNumber();
break;
}
}
return source;
}
@Override
public void post(Constraint... cs) throws SolverException {
String source=getSource();
// dump each constraint along source location
for (Constraint c : cs) {
System.err.println(source + " post: " + c);
}
super.post(cs);
}
@Override
public void associates(Variable variable) {
System.err.println(getSource() + " associates: " + variable.getName());
super.associates(variable);
}
};
这将转储如下内容:
Vrp1RpV2.java:182 post: ARITHM ([prop(EQ_exp_47.EQ.mul_exp_48)])
Vrp1RpV2.java:182 associates: sum_exp_49
Vrp1RpV2.java:182 post: ARITHM ([prop(mul_exp_48.EQ.sum_exp_49)])
Vrp1RpV2.java:182 associates: EQ_exp_50
Vrp1RpV2.java:182 post: BASIC_REIF ([(stop2vehicle[2] = 1) <=> EQ_exp_50])
...
从那里可以看到 sum_exp_49 的来源。
编辑:由于@cprudhom 对 https://gitter.im/chocoteam/choco-solver
的建议添加了 Associates()版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。