IBM ILOG Dispatcher User's Manual > Developing Dispatcher Applications > Developing Your Own First Solution Heuristics > Using the Dispatcher First Solution Framework > Creating the decision maker class

Now, you create IloPDPDecisionMakerI, a specialized decision maker class for PDP problems. It will use the decision class PDPDecision that you just created. You will define three member functions: init, getBestDecision, and getBestSerialDecision.

class PDPDecisionMakerI : public IloFSDecisionMakerI {
private:
  IloVehicle _current;

  IloFSDecisionI* getBestSerialDecision();
public:
  PDPDecisionMakerI(IloDispatcher dispatcher);

  virtual void init();
  virtual IloFSDecisionI* getBestDecision();
};

The member function init iterates on all visit pairs that are extracted in the dispatcher and, for each visit, looks for all vehicles that can be assigned to these visits. For each compatible set (vehicle, pickup, delivery) it then does two things. First, it decides whether or not it is worth creating a PDPDecision decision for the set. If the set (vehicle, pickup, delivery) is not "interesting" then no decision is created and this possibility will not be considered by the first solution framework. If the set is "interesting," then this decision is stored.

PDPDecisionMakerI
::PDPDecisionMakerI(IloDispatcher dispatcher)
  : IloFSDecisionMakerI(dispatcher),
    _current(0) {}

void PDPDecisionMakerI::init() {
  _current = 0;
//  cout << "starting PDP decision maker init()"<< endl;
  IloDispatcher dispatcher(getDispatcher());
  IloEnv env = dispatcher.getEnv();

  // iterate on all posted ordered sequences.
  for (IloDispatcher::OrderedVisitPairIterator vpiter(dispatcher);
       vpiter.ok(); ++vpiter) {
    IloVisit pickup = vpiter.getPickup();
    IloVisit delivery = vpiter.getDelivery();
    IlcIntVar pickupVclVar = dispatcher.getVehicleVar(pickup);
    IlcIntVar deliveryVclVar = dispatcher.getVehicleVar(delivery);
    for (IloDispatcher::VehicleIterator
           vehIter(dispatcher); vehIter.ok(); ++vehIter) {
      IloVehicle vehicle = *vehIter;
      IlcInt vehIndex = dispatcher.getIndex(vehicle);
      if ( pickupVclVar.isInDomain(vehIndex) &&
           deliveryVclVar.isInDomain(vehIndex) ) {
        IloFSDecisionI* decision =
          new (env) PDPDecision(vehicle, pickup, delivery);
        storeDecision(decision);
      }
    }
  }
  //cout << "end PDP decision maker init()"<< endl;
}


The member function getBestDecision is the implementation of the virtual member function defined in the abstract IloNADecisionMakerI class. In this example, the extension mode is serial. Therefore, the decision maker fills vehicles one at a time, and this member function returns the best decision concerning the currently open vehicle. At the beginning, no vehicle is open, and the member function returns the best decision among all possible decisions. Afterwards, the decision's vehicle becomes the current vehicle, and only decisions registered with this vehicle are considered. When the vehicle is full, the decision maker looks again for the best global decision and chooses a new current decision, or terminates.

IloFSDecisionI* PDPDecisionMakerI::getBestDecision() {
  //return getBestGlobalDecision();
  return getBestSerialDecision();
}


IloFSDecisionI* PDPDecisionMakerI::getBestSerialDecision() {
  IloFSDecisionI * d = 0;
  if ( 0 != _current.getImpl() ) {
    d = getBestVehicleDecision(_current);
  }
  if ( 0 == d ) {
    IloFSDecisionI * bestVehicleDecision = getBestVehicleDecision();
    if ( 0 != bestVehicleDecision ) {
      IloSingleVehicleFSDecisionI * vehDecision =
        (IloSingleVehicleFSDecisionI*)bestVehicleDecision;
      _current = vehDecision->getVehicle();
      d = bestVehicleDecision;
    } else {
      _current = 0;
    }
  }
  return d;
}