2016-03-30 16 views
2

OptaPlanner'ın yeteneklerini test etmek için basit bir örnek oluşturmaya çalışıyoruz. Aşağıda, neyle ortaya çıktığımızı gösteriyoruz. Örneğimizdeki problem, problemi çözmek için kapsamlı bir arama algoritması seçtiğimizde, OptaPlanner'ın, sıfır değerin ValueRangeProvider'dan alınabilecek olası bir çözüm olmasa bile, her zaman sıfır olan yanlış cevapla hızlı bir şekilde sona ermesidir. Ayrıca, yerel arama kullanıldığında karşıt olarak Planlama Değişkeni ayarlanmamıştır. Çalışılan OptaPlanner (örn. TSP) ile gelen örneklerde algoritmaları değiştirmeye çalıştık. Bu nedenle bizim sorumuz: Neden kodumuz çalışmıyor?OptaPlanner'da Sonlandırıcı Arama çok basit bir örnek üzerinde çalışmıyor

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: Biz Nihai OptaPlanner 6.3 kullanıyorsanız

<?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> 

.

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

araçlarının eksiksiz arama yüzden 100'lük bir 'stepCountLimit' çok düşük görünüyor, adımların bir LOT yapar. Bu çizgiyi tamamen kaldırabilir misin? Bu önemli değil: 4 değeri olan 1 varlık 4^1 çözüm anlamına gelecektir, bu yüzden olası bir şekilde kaba adımlarla veya dallarla ve hatta 100 adımla çarpacağız. –

+0

Ayrıca belleği kaydetmek için 'ValueRangeFactory.createIntValueRange (1,5)' a bakın. –

cevap

3

bir planlama değişken bir Integer değil, bir int olmalıdır:

Bu OptaPlanner bu yapılandırmayla başlatıldığında ne olsun. null olarak başlamalıdır. Eğer 0 olarak başlıyorsa, OptaPlanner zaten'un başlatılmış olduğunu varsaymaktadır ve - varsayılan olarak - bu değişkeni CH veya ES'de yeniden başlatamaz.

Maybe we should ban primitive types for planning variables?

+0

İlkel türlerin yasaklanması harika bir fikirdir. Ancak, "Tamsayı" sürümünü uygularken, Puan Hesaplamada bir "NullPointerExeption" alırız. Bu davayı açık bir şekilde yakalamamız ve çok kötü bir skor vermemiz gerekiyor. Bunu yapmanın daha iyi bir yolu var mı? – Konstantin

+0

Skor hesaplamasında null bir kontrol yapın. Örneğin, drools kurallarında: 'MyEntity (myValue! = Null, $ v: value) olduğunda ... addSoft (- $ v); Sonu ' –