19.2. Planning Values and Value Ranges
19.2.1. ValueRangeProvider
If you have a @ValueRangeProvider that returns a collection of numbers (for example List<Integer> or List<BigDecimal>), then you should switch to a ValueRange, which uses less memory and offers additional opportunities.
For example:
@ValueRangeProvider(id = "delayRange")
public List<Integer> getDelayRange() {
List<Integer> = new ArrayList<Integer>(5000);
for (int i = 0; i < 5000; i++) {
delayRange.add(i);
}
return delayRange;
}Is changed to:
@ValueRangeProvider(id = "delayRange")
public CountableValueRange<Integer> getDelayRange() {
return ValueRangeFactory.createIntValueRange(0, 5000);
}
The annotation @ValueRangeProvider has been moved into another package, from:
import org.optaplanner.core.api.domain.value.ValueRangeProvider;
to
import org.optaplanner.core.api.domain.valuerange.ValueRangeProvider;
19.2.2. Planning Variables
The interface PlanningVariableListener has been renamed to VariableListener.
Previously in *.java :
public class VehicleUpdatingVariableListener implements PlanningVariableListener<Customer> {
Now in *.java :
public class VehicleUpdatingVariableListener implements VariableListener<Customer> {The class AbstractPlanningVariableListener has been removed.
Previously in *.java :
public class VehicleUpdatingVariableListener extends AbstractPlanningVariableListener<Customer> {
Now in *.java :
public class VehicleUpdatingVariableListener implements VariableListener<Customer> {
The VariableListener is now declared on the shadow side, instead of the @PlanningVariable side. This way, Business Rules Planner recognizes the shadow variables, and all shadow variables are declared in a consistent matter. Furthermore, it allows a shadow variable to based on other shadow variable.
Previously in *.java :
@PlanningVariable(valueRangeProviderRefs = {"vehicleRange", "customerRange"},
graphType = PlanningVariableGraphType.CHAINED,
variableListenerClasses = {VehicleUpdatingVariableListener.class, ArrivalTimeUpdatingVariableListener.class})
public Standstill getPreviousStandstill() {
return previousStandstill;
}
public Vehicle getVehicle() {
return vehicle;
}
public Integer getArrivalTime() {
return arrivalTime;
}
Now in *.java :
@PlanningVariable(...)
public Standstill getPreviousStandstill() {
return previousStandstill;
}
@CustomShadowVariable(variableListenerClass = VehicleUpdatingVariableListener.class,
sources = {@CustomShadowVariable.Source(variableName = "previousStandstill")})
public Vehicle getVehicle() {
return vehicle;
}
@CustomShadowVariable(variableListenerClass = ArrivalTimeUpdatingVariableListener.class,
sources = {@CustomShadowVariable.Source(variableName = "previousStandstill")})
public Integer getArrivalTime() {
return arrivalTime;
}There is now out-of-the-box support for a shadow variable representing the anchor of a chained variable. For example, in a VRP each Customer (= entity) needs to know to which Vehicle (= anchor) it belongs. This declarative support allows build-in selectors to reuse that knowledge without duplicating the calculation.
Previously in *.java :
@PlanningEntity
public class Customer implements Standstill {
@PlanningVariable(...)
public Standstill getPreviousStandstill() {...}
@CustomShadowVariable(variableListenerClass = VehicleUpdatingVariableListener.class,
sources = {@CustomShadowVariable.Source(variableName = "previousStandstill")})
public Vehicle getVehicle() {...}
}
public class VehicleUpdatingVariableListener implements VariableListener<Customer> {
...
}
Now in *.java :
@PlanningEntity
public class Customer implements Standstill {
@PlanningVariable(...)
public Standstill getPreviousStandstill() {...}
@AnchorShadowVariable(sourceVariableName = "previousStandstill")
public Vehicle getVehicle() {...}
}To scale VRP cases, Nearby Selection is critical. It is now finally completely supported and documented.

Where did the comment section go?
Red Hat's documentation publication system recently went through an upgrade to enable speedier, more mobile-friendly content. We decided to re-evaluate our commenting platform to ensure that it meets your expectations and serves as an optimal feedback mechanism. During this redesign, we invite your input on providing feedback on Red Hat documentation via the discussion platform.