Home > Net >  Optaplanner : Initializing planning variable problem
Optaplanner : Initializing planning variable problem

Time:08-27

I am new to Optaplanner and to get familiar with it I tried to run a simple code. The idea is I have one single planning variable of type integer, that has a range between 1 and 3, that I try to maximize. So normally the solver should give me a value of 3.

When I run my main method, I get this error :

Exception in thread "main" java.lang.IllegalStateException: The entityClass (class domain.variable) has a @PlanningVariable annotated member (field private int domain.variable.x) that returns a primitive type (int). This means it cannot represent an uninitialized variable as null and the Construction Heuristics think it's already initialized. Maybe let the member (variable.x) return its primitive wrapper type instead.

My code is as follows :

Planning entity and planning variable :

@PlanningEntity 
public class variable {

    @PlanningVariable(valueRangeProviderRefs = "xRange")    
    private int x;

    public variable() { 
    }

    public variable(int x) {
        this.x = x;
    }   
    public int getX() {
        return x;
    }
    public void setX(int x) {
        this.x = x;
    }
 }

Planning solution

@PlanningSolution
public class Planningsolution {

   @PlanningEntityProperty
   private variable variable;   

    @ValueRangeProvider(id="xRange")
    public CountableValueRange<Integer> getxRange(){
        return ValueRangeFactory.createIntValueRange(1, 3);
    }
    
    @PlanningScore
    private HardSoftScore score;
    
    public Planningsolution() {
    }

    public variable getVariable() {
        return variable;
    }

    public void setVariable(variable variable) {
        this.variable = variable;
    }

    public HardSoftScore getScore() {
        return score;
    }

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

Constraint Provider

public class SimpleConstraintProvider implements ConstraintProvider {
     @Override
        public Constraint[] defineConstraints(ConstraintFactory constraintFactory) {
            return new Constraint[] {
                    // Hard constraints
                    maxValue(constraintFactory),

            };
     }
            
         private Constraint maxValue (ConstraintFactory constraintFactory) {
                
                return constraintFactory.forEach(variable.class)
                        .reward("Between", HardSoftScore.ONE_SOFT,variable::getX);
                    }
}

My question is how to initialize my planning variable.

CodePudding user response:

In order for planning variables to be initializable, they must be able to accept null as a value. Java primitive types (such as int) are not capable of doing that, therefore your planning variable needs to be an Integer. The error message even tells you to do that, although the wording is a bit cryptic.

As a side note, I think we should be able to handle this situation better. If people don't want null in there, we should not force them. Something to consider for future development.

  • Related