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;
}
|