OptaPlannerの機能をテストする簡単な例を作成しようとしています。以下では、私たちが思いついたことを示します。この例の問題は、問題を解決するための包括的な検索アルゴリズムを選択すると、OptRplannerは、ゼロがValueRangeProviderから利用可能な解決策ではなくても、常にゼロである間違った回答で迅速に終了することです。さらに、PlanningVariableは、ローカル検索が使用されるときとは異なり、解決中に設定されません。OptaPlannerの網羅的検索は、非常に単純な例では機能しません
私たちはOptaPlanner(TSPなど)に付属の例のアルゴリズムを変更しようとしましたが、これはうまくいきました。したがって、私たちの質問は、なぜコードが機能しないのでしょうか?
MyPlanningEntity.java:
import org.optaplanner.core.api.domain.entity.PlanningEntity;
import org.optaplanner.core.api.domain.variable.PlanningVariable;
@PlanningEntity
public class MyPlanningEntity {
@PlanningVariable(valueRangeProviderRefs = {"myListValueRangeProvider"})
private int myPlanningVariable;
public int getMyPlanningVariable() {
return myPlanningVariable;
}
public void setMyPlanningVariable(int myPlanningVariable) {
this.myPlanningVariable = myPlanningVariable;
}
}
MySolution.java:
import org.optaplanner.core.api.domain.solution.PlanningEntityProperty;
import org.optaplanner.core.api.domain.solution.PlanningSolution;
import org.optaplanner.core.api.domain.solution.Solution;
import org.optaplanner.core.api.domain.valuerange.CountableValueRange;
import org.optaplanner.core.api.domain.valuerange.ValueRangeFactory;
import org.optaplanner.core.api.domain.valuerange.ValueRangeProvider;
import org.optaplanner.core.api.score.buildin.simple.SimpleScore;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@PlanningSolution
public class MySolution implements Solution<SimpleScore> {
@PlanningEntityProperty
private MyPlanningEntity myPlanningEntity;
private SimpleScore score;
public MyPlanningEntity getMyPlanningEntity() {
return myPlanningEntity;
}
public void setMyPlanningEntity(MyPlanningEntity myPlanningEntity) {
this.myPlanningEntity = myPlanningEntity;
}
@ValueRangeProvider(id = "myListValueRangeProvider")
public List<Integer> getListValueRange(){
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
return list;
}
@Override
public SimpleScore getScore() {
return score;
}
@Override
public void setScore(SimpleScore simpleScore) {
this.score = simpleScore;
}
@Override
public Collection<?> getProblemFacts() {
return null;
}
}
MyScoreCalculator.java:
import org.optaplanner.core.api.score.Score;
import org.optaplanner.core.api.score.buildin.simple.SimpleScore;
import org.optaplanner.core.impl.score.director.easy.EasyScoreCalculator;
public class MyScoreCalculator implements EasyScoreCalculator<MySolution>{
@Override
public Score calculateScore(MySolution mySolution) {
// The higher the input, the higher the output
int value = mySolution.getMyPlanningEntity().getMyPlanningVariable();
return SimpleScore.valueOf(value);
}
}
ESTest.java:
import org.optaplanner.core.api.solver.Solver;
import org.optaplanner.core.api.solver.SolverFactory;
public class ESTest {
public static void run(){
SolverFactory solverFactory = SolverFactory.createFromXmlResource("resources/myPlanningProblem.xml");
Solver solver = solverFactory.buildSolver();
MySolution mySolution = new MySolution();
MyPlanningEntity myPlanningEntity = new MyPlanningEntity();
mySolution.setMyPlanningEntity(myPlanningEntity);
solver.solve(mySolution);
MySolution bestSolution = (MySolution) solver.getBestSolution();
System.out.println("Best solution: " + bestSolution.getMyPlanningEntity().getMyPlanningVariable());
}
public static void main(String args[]){
run();
}
}
myPlanningProblem.xml:
<?xml version="1.0" encoding="UTF-8"?>
<solver>
<!-- Domain model configuration -->
<scanAnnotatedClasses/>
<scoreDirectorFactory>
<scoreDefinitionType>SIMPLE</scoreDefinitionType>
<easyScoreCalculatorClass>MyScoreCalculator</easyScoreCalculatorClass>
</scoreDirectorFactory>
<!-- THIS DOES NOT WORK STAND ALONE -->
<!--<constructionHeuristic>-->
<!--<constructionHeuristicType>FIRST_FIT</constructionHeuristicType>-->
<!--</constructionHeuristic>-->
<!-- THIS DOES NOT WORK STAND ALONE -->
<exhaustiveSearch>
<exhaustiveSearchType>BRUTE_FORCE</exhaustiveSearchType>
<termination>
<stepCountLimit>100</stepCountLimit>
</termination>
</exhaustiveSearch>
<!-- THIS WORKS BEAUTIFULLY -->
<!--<localSearch>-->
<!--<localSearchType>HILL_CLIMBING</localSearchType>-->
<!--<termination>-->
<!--<secondsSpentLimit>10</secondsSpentLimit>-->
<!--</termination>-->
<!--</localSearch>-->
</solver>
我々は最終OptaPlanner 6.3を使用しています。
14:58:58.742 [main] INFO o.o.core.impl.solver.DefaultSolver - Solving started: time spent (4), best score (0), environment mode (REPRODUCIBLE), random (JDK with seed 0).
14:58:58.745 [main] INFO o.o.c.i.e.DefaultExhaustiveSearchPhase - Exhaustive Search phase (0) ended: step total (0), time spent (7), best score (0).
14:58:58.745 [main] INFO o.o.core.impl.solver.DefaultSolver - Solving ended: time spent (7), best score (0), average calculate count per second (285), environment mode (REPRODUCIBLE).
Best solution: 0
Process finished with exit code 0
徹底的な検索は、ステップのLOTを行いますので、100の 'stepCountLimit'は非常に低いと思われます。あなたはその行を完全に削除できますか?それは重要ではありません:4つの値を持つ1つのエンティティは4^1の解を意味するので、ブルートフォースやブランチとバウンドの場合でも、100ステップをヒットすることはまずありません。 –
また、 'ValueRangeFactory.createIntValueRange(1,5)'を見てメモリを節約してください。 –