简体   繁体   中英

OptaPlanner: java.lang.IllegalArgumentException

currently i am implementing my second project in OptaPlanner. I am retrieving the following error:

    Exception in thread "main" java.lang.IllegalArgumentException:
    A planning entity is an instance of a entitySubclass (class com.company.Assignment)
    that is not configured as a planning entity.
    If that class (Assignment) (or superclass thereof) is not a entityClass 
    ([class com.company.Car]), check your Solution implementation's annotated methods.
    If it is, check your solver configuration.

My SolverConfig.xml is this:

<?xml version="1.0" encoding="UTF-8"?>
<solver>
<solutionClass>com.company.Planning</solutionClass>
<entityClass>com.company.Car</entityClass>
<scoreDirectorFactory>
    <scoreDefinitionType>HARD_SOFT</scoreDefinitionType>
    <easyScoreCalculatorClass>com.company.PlanningEasyScoreCalculator</easyScoreCalculatorClass>
    <initializingScoreTrend>ONLY_DOWN</initializingScoreTrend>
</scoreDirectorFactory>
<constructionHeuristic>
    <constructionHeuristicType>FIRST_FIT</constructionHeuristicType>
</constructionHeuristic>
<localSearch>
    <termination>
        <secondsSpentLimit>10</secondsSpentLimit>
    </termination>
    <changeMoveSelector>
        <entitySelector>
            <entityClass>com.company.Car</entityClass>
        </entitySelector>
        <valueSelector>
            <variableName>assignment</variableName>
        </valueSelector>
    </changeMoveSelector>
    <acceptor>
        <entityTabuSize>7</entityTabuSize>
    </acceptor>
    <forager>
        <acceptedCountLimit>1000</acceptedCountLimit>
    </forager>
</localSearch>
</solver>

The "Car" class is annotated with "@PlanningEntity". The "Planning" class is annotated with "@PlanningSolution". Tha "Assignment" class is my problem fact. The solution's "@PlanningEntityCollectionProperty" is on a getter that runs a list of "Car".

The "Main" class looks like this:

public class Main {
public static final String SOLVER_CONFIG_XML = "com/company/PlanningSolverConfig.xml";
public static ScoreDirector scoreDirector;
public static void main(String[] args) {
    // Read data from XLS file and initialize the problem
    ReadDataFromXls Reader = new ReadDataFromXls();
    Planning planningSituation = new Planning(Reader.ReadAssignments(),Reader.ReadCars());
    // Build the solver
    Solver solver = SolverFactory.createFromXmlResource(SOLVER_CONFIG_XML).buildSolver();
    // Solve the problem and get the best solution
    solver.solve(planningSituation);
    Planning solvedPlanning = (Planning) solver.getBestSolution();
    // Display the result
    System.out.println("TODO");
}
}

Error message with 6.3.0.CR1 is basically the same + an error concerning SLF4J

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Exception in thread "main" java.lang.IllegalArgumentException: A planning entity is an instance of an entitySubclass (class com.company.Assignment) that is not configured as a planning entity.
If that class (Assignment) (or superclass thereof) is not a entityClass ([class com.company.Car]), check your Solution implementation's annotated methods.
If it is, check your solver configuration.

EDIT: My first project in OptaPlanner was a "One to Many" problem (a project has a developer, a developer can have multiple projects). This project is a "One to One" problem (a car is needed to drive to an assignment, an assignment is reched by a car).

EDIT: I changed the model of my planning problem. Now the class "Assignment" is my "planning entity" and the class "Car" is the "planning fact". The error message ist still the same, besides the fact that "Car" and "Assignment" switched places :)

I bet the Solution's @PlanningEntityCollectionProperty is on a getter that runs a Collection of Assignment (which is not an entity in your case) instead of Car (which is an entity).

The class naming is confusing though. I would rename the class Assignment to Task and the class Car to CarAssignment because anything name assignment is usually the planning entity...

It must be a misconfiguration on your domain model somehow.

You have been totally right! I called this constructor:

    public Planning(List<Car> carList, List<Assignment> assignmentList) {
    this.carList = carList;
    this.assignmentList = assignmentList;
    }

With this arguments:

Planning planningSituation = new Planning(Reader.ReadAssignments(),Reader.ReadCars());

Thanks for helping!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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