[每隔一段时间,我的构建时间就会从5s跃升到200左右。有时即使我在相同的时间内同时获得17个左右的数据,也无法获得任何解决方案。
是否可以停止求解器,检查是否有解决方案,如果可以,请继续,否则重新启动,也许更改了约束?
这是我到目前为止所得到的:
SMF.limitTime(solver, 60000);
solver.set(new ObjectiveManager<IntVar, Integer>(score, ResolutionPolicy.MINIMIZE, false));
solver.findSolution();
if(solver.isFeasible() == ESat.TRUE){
System.out.println("first solution found");
SMF.limitTime(solver, 180000);
solver.nextSolution();
} else {
//restart
}
do{
if(solver.isFeasible() == ESat.TRUE){
System.out.println(score.getValue());
}
}while(solver.nextSolution());
try {
solver.restoreLastSolution();
} catch (ContradictionException e) {
throw new UnsupportedOperationException("restoring the last solution ended in a failure");
} finally {
solver.getEngine().flush();
}
但是使用的限制仍然是一分钟,并且在找到第一个解决方案之后并没有增加到三分钟。
有没有办法做到这一点?以及如何重新启动求解器?
一个相关的问题:如果确实有解决方案,请还原该解决方案,但我认为再花一点时间就能得到更好的解决方案,我可以以此解决方案作为起点来启动求解器吗?
就我而言,这可行:
Solver solver = model.getSolver();
solver.removeAllStopCriteria(); // This is necessary to set a new time
solver.limitTime( newTime );
为什么我需要这个?我看到改组我的输入后,它有时会很快找到第一个解决方案。因此,我只想在短时间内(即5秒钟)找到第一个解决方案,否则请取消输入,将其改编,然后重试。找到第一个解决方案后,我想继续尝试进行优化,但是现在要花更长的时间,比如说20分钟。
我的代码是这样的:
Model createModel(input); // Method to create a fresh new model with some input
void shuffleInput(input); // Shuffles input
for (int retry = 0; retry < 100; retry++) {
// First solution finding retry loop
shuffleInput(input);
ParallelPortfolio portfolio = new ParallelPortfolio();
for (int modelIndex = 0; modelIndex < 6; modelIndex++) {
portfolio.addModel( createModel(input)));
}
if ( portfolio.solve() ) {
// Found first solution, try to find better one
for (Model model: portfolio.getModels()) {
// Increment time limit
model.getSolver().removeAllStopCriteria();
model.getSolver().limitTime( "1200s");
}
while (portfolio.solve()) {
// Record current best solution! - Use Solution object
// https://choco-solver.readthedocs.io/en/latest/3_solving.html#recording-solutions
}
// Here we should have our best solution until now already recorded in a "Solution" object
break;
}
}