Saturday, June 29, 2013

JudCon, Summit and Misc Presentation Slides (2013)

I've done a number of presentations recently. I've finally got around to uploading them to SlideShare, with videos in some cases. Here are the links

Drools talks
Drools 6.0 (Red Hat Summit 2013)
Drools 6.0 (Judcon 2013)
Drools 6.0 (Camel One 2013)

UberFire Talks
UberFire (Newcastle 2013)
UberFire (Judcon 2013)

Mark

Friday, June 21, 2013

Shadow variables, PlanningVariableListener and bi-directional variables

Most types of custom constraints are relatively straightforward to implement in OptaPlanner. There was one notorious exception: time windows for vehicle routing. But OptaPlanner 6.0.0.Beta4 supports shadow variables, which make that a lot easier to implement.

A shadow variable is a variables who's correct value can be deduced from the state of the genuine planning variables. Even though such a variable violates the principle of normalization by definition, in some use cases it can be very practical to use a shadow variable. For example in vehicle routing with time windows: the arrival time at a customer for a vehicle can be calculated based on the previously visited customers of that vehicle (and the known travel times between 2 locations).

PlanningVariableListener



To update the shadow variable(s) correctly, we can annotate a PlanningVariableListener on the genuine planning variable:

    @PlanningVariable(..., variableListenerClasses = {VehicleUpdatingVariableListener.class, ArrivalTimeUpdatingVariableListener.class})
    ...
    public Standstill getPreviousStandstill() {
        return previousStandstill;
    }



Bi-directional variables


OptaPlanner reuses that system internally to provide support for bi-directional variables (like JPA), currently only for chained variables:

    @PlanningVariable(mappedBy = "previousStandstill")
    Customer getNextCustomer();


So if OptaPlanner changes the previousStandstill side, it automatically also changes the nextCustomer side accordingly.