2017-08-10 31 views
0

熟悉optaplanner我創建了一個簡單的測試項目。我只有一個解決方案和一個實體類。實體只有0到9之間的一個值。應該只有奇數,總和應該小於10(這只是我提出的一些隨機約束)。OptaPlaner簡單的例子不能找到可行的解決方案

由於分數我使用一個簡單的HardSoftScore。下面是代碼:

public class TestScoreCalculator implements EasyScoreCalculator<TestSolution>{ 

    @Override 
    public HardSoftScore calculateScore(TestSolution sol) { 
     int hardScore = 0; 
     int softScore = 0; 
     int valueSum = 0; 

     for (TestEntity entity : sol.getTestEntities()) { 
      valueSum += entity.getValue() == null? 0 : entity.getValue(); 
     } 

     // hard Score 
     for (TestEntity entity : sol.getTestEntities()) { 
      if(entity.getValue() == null || entity.getValue() % 2 == 0) 
       hardScore -= 1; // constraint: only odd numbers 
     } 
     if(valueSum > 10) 
      hardScore -= 2; // constraint: sum should be less than 11 

     // soft Score 
     softScore = valueSum; // maximize 

     return HardSoftScore.valueOf(hardScore, softScore); 
    } 
} 

,這是我的配置文件:

<?xml version="1.0" encoding="UTF-8"?> 
<solver> 
    <!-- Domain model configuration --> 
    <scanAnnotatedClasses/> 

    <!-- Score configuration --> 
    <scoreDirectorFactory> 
    <easyScoreCalculatorClass>score.TestScoreCalculator</easyScoreCalculatorClass> 
    </scoreDirectorFactory> 

    <!-- Optimization algorithms configuration --> 
    <termination> 
    <secondsSpentLimit>30</secondsSpentLimit> 
    </termination> 
</solver> 

出於某種原因OptaPlanner不能找到一個可行的解決方案。它終止於LS step (161217), time spent (29910), score (-2hard/10soft), best score (-2hard/10soft)...和解決方案9 1 0 0。 所以hardScore是-2,因爲這兩個0不是奇數。例如,可能的解決方案是7 1 1 1。爲什麼是這樣 ?這應該是一個非常簡單的例子...

(當我設置開始值7 1 1 1它這種解決方案和(0hard/10soft)分數應該如何終止)


編輯:

實體類

@PlanningEntity 
public class TestEntity { 
    private Integer value; 

    @PlanningVariable(valueRangeProviderRefs = {"TestEntityValueRange"}) 
    public Integer getValue() { 
     return value; 
    } 

    public void setValue(Integer value) { 
     this.value = value; 
    } 

    @ValueRangeProvider(id = "TestEntityValueRange") 
    public CountableValueRange<Integer> getStartPeriodRange() { 
     return ValueRangeFactory.createIntValueRange(0, 10); 
    } 

} 

解決方案類

@PlanningSolution 
public class TestSolution { 
    private List<TestEntity> TestEntities; 
    private HardSoftScore score; 

    @PlanningEntityCollectionProperty 
    public List<TestEntity> getTestEntities() { 
     return TestEntities; 
    } 

    public void setTestEntities(List<TestEntity> testEntities) { 
     TestEntities = testEntities; 
    } 

    @PlanningScore 
    public HardSoftScore getScore() { 
     return score; 
    } 

    public void setScore(HardSoftScore score) { 
     this.score = score; 
    } 

    @Override 
    public String toString() { 
     String str = ""; 
     for (TestEntity testEntity : TestEntities) 
      str += testEntity.getValue()+" "; 
     return str; 
    }  
} 

主程序類

public class Main { 

    public static final String SOLVER_CONFIG = "score/TestConfig.xml"; 

    public static int printCount = 0; 

    public static void main(String[] args) { 
     init(); 
    } 

    private static void init() { 
     SolverFactory<TestSolution> solverFactory = SolverFactory.createFromXmlResource(SOLVER_CONFIG); 
     Solver<TestSolution> solver = solverFactory.buildSolver(); 

     TestSolution model = new TestSolution(); 
     List<TestEntity> list = new ArrayList<TestEntity>(); 
//  list.add(new TestEntity(){{setValue(7);}}); 
//  list.add(new TestEntity(){{setValue(1);}}); 
//  list.add(new TestEntity(){{setValue(1);}}); 
//  list.add(new TestEntity(){{setValue(1);}}); 
     for (int i = 0; i < 4; i++) { 
      list.add(new TestEntity()); 
     } 
     model.setTestEntities(list); 


     // Solve the problem 
     TestSolution solution = solver.solve(model); 

     // Display the result 
     System.out.println(solution); 
    } 

} 
+0

請問您可以附上您使用的解決方案/實體源和一堆數據集嗎? –

回答

1

它陷在一個局部最優,因爲沒有移動,從實體需要1和它給另一個實體。隨着自定義移動你可以添加。 這些類型的動作只適用於數值範圍(這很少見,通常值範圍是僱員列表等),但它們應該可以直接存在(隨意爲它們創建一個jira)。

無論如何,獲得良好解決方案的另一種方法是添加<exhaustiveSearch/>,繞過本地搜索,因此本地最優。但是這並不好。

+0

啊好吧我想我明白什麼是問題...生病嘗試與自定義移動 – MrWoffle