Sunday, December 25, 2011

Less boilerplate in Planner: Generic MoveFactory

The recently released Drools Planner 5.4.0.Beta1 includes 2 Generic MoveFactories. That means it's no longer required to implement  a MoveFactory and Move to use a local search optimization algorithm such as Tabu Search or Simulated Annealing.

For example, the MachineReassignment example configures Tabu Search like this:

  <localSearch>
    <selector>
      <selector>
        <moveFactoryClass>org.drools.planner.core.move.generic.GenericChangeMoveFactory</moveFactoryClass>
      </selector>
      <selector>
        <moveFactoryClass>org.drools.planner.core.move.generic.GenericSwapMoveFactory</moveFactoryClass>
      </selector>
    </selector>
    <acceptor>
      <propertyTabuSize>5</propertyTabuSize>
    </acceptor>
    <forager>
      <minimalAcceptedSelection>1000</minimalAcceptedSelection>
    </forager>
  </localSearch>

Notice that there is no MachineReassignment specific code in there whatsoever. But if I wanted to, I could easily mix in a custom MoveFactory implementation too.

Planner comes with 2 generic move factories out of the box:
  • GenericChangeMoveFactory: A GenericChangeMove changes 1 planning variable of 1 planning entity to another planning value. For example: Given course C1 in room R1 and period P1, change its room to room R2.
  • GenericSwapMoveFactory: A GenericSwapMove swaps all the planning variables of 2 planning entities. For example: Given course C1 in room R1 and period P1 and Course C2 in room R2 and period P2, put course C1 in room R2 and period P2 and put course C2 in room R1 and period P1.
They are slightly slower than a custom implementation, but equally scalable.