繁体   English   中英

OptaPlanner中的穷举搜索不适用于非常简单的示例

[英]Exhaustive Search in OptaPlanner does not work on very simple example

我们正在尝试创建一个简单的示例来测试OptaPlanner的功能。 在下面的内容中,我们说明了我们的想法。 我们的示例的问题在于,当我们选择一种穷举搜索算法来解决问题时,即使ValueRangeProvider无法提供零解决方案,OptaPlanner也会以错误的答案迅速终止,该答案始终为零。 此外,与使用本地搜索时相反,在求解过程中未设置PlanningVariable。

我们试图更改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 Final。

当使用此配置启动OptaPlanner时,这就是我们得到的:

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

一个计划变量应该是一个Integer ,而不是一个int 它应该以null开头。 如果以0开头,则OptaPlanner假定它已经初始化,并且-默认情况下-不会在CH或ES中重新初始化该变量。

也许我们应该禁止使用基本类型来计划变量?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM