Reputation: 41
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 30, that I try to maximize. So normally the solver should give me a value of 30.
My code is as follows :
Planning entity and planning variable :
@PlanningEntity
public class variable {
@PlanningVariable(valueRangeProviderRefs = "xRange")
private Integer x;
public variable() {
}
public Integer getX() {
return x;
}
public void setX(Integer 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, 30);
}
@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("maximum", HardSoftScore.ONE_SOFT,variable::getX);
}
}
Main :
public class SimpleApp {
private static final Logger LOGGER = LoggerFactory.getLogger(SimpleApp.class);
public static void main(String[] args) {
SolverFactory<Planningsolution> solverFactory = SolverFactory.create(new SolverConfig()
.withSolutionClass(Planningsolution.class)
.withEntityClasses(variable.class)
.withConstraintProviderClass(SimpleConstraintProvider.class)
.withTerminationSpentLimit(Duration.ofSeconds(10)));
// Load the problem
Planningsolution problem = new Planningsolution();
// Solve the problem
Solver<Planningsolution> solver = solverFactory.buildSolver();
Planningsolution solution = solver.solve(problem);
// Visualize the solution
System.out.println("solution: " + display(solution) + "\n" + "score: " + solution.getScore());;
}
public static Integer display(Planningsolution solution) {
variable var = new variable();
return var.getX();
}
}
logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="appender" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d [%t] %-5p %m%n</pattern>
</encoder>
</appender>
<logger name="org.optaplanner" level="info"/>
<root level="warn">
<appender-ref ref="appender"/>
</root>
</configuration>
The output i get is :
solution: null score: 0hard/0soft
Upvotes: 1
Views: 323
Reputation: 5682
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.
Upvotes: 0