2016-03-30 10 views
2

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 
+0

徹底的な検索は、ステップのLOTを行いますので、100の 'stepCountLimit'は非常に低いと思われます。あなたはその行を完全に削除できますか?それは重要ではありません:4つの値を持つ1つのエンティティは4^1の解を意味するので、ブルートフォースやブランチとバウンドの場合でも、100ステップをヒットすることはまずありません。 –

+0

また、 'ValueRangeFactory.createIntValueRange(1,5)'を見てメモリを節約してください。 –

答えて

3

計画変数がInteger、ないint次のようになります。

これは、我々がOptaPlannerはこの構成で起動されたときに取得されるものです。それはnullとして開始する必要があります。 0で始まる場合、OptaPlannerはすでにで初期化されているとみなし、デフォルトではその変数をCHまたはESに再初期化しません。

Maybe we should ban primitive types for planning variables?

+0

プリミティブ型の禁止は素晴らしい考えです。 しかし、Integerバージョンを実装すると、スコア計算で 'NullPointerExeption'が得られます。私たちはこの事件を明白に捉え、それに非常に悪いスコアを与える必要があります。これを行うより良い方法はありますか? – Konstantin

+0

スコア計算でヌルチェックを行います。たとえば、droolsルールの場合: 'MyEntity(myValue!= null、$ v:value)then ... addSoft( - $ v);終わり –