Subject: Your adjusted payment (Home)

From: Reduce Home Payment <[email-masked]>
Date: Thu, 29 Jan 2015 11:57:04 -0800

Your 2015 HARP 2.0Eligibility--

Announced by Obama

Hello Atompub-archive

By checking eligibility you could reduce your payment significantly.

Your exact monthly savings can be seen: (1 minute check)

http://www.rapidlended.com/tins/landslides/reformulations.htm

Obama's | HARP 2.0

Note: Our records indicate that you have not checked your eligibility in 2014.

Regards,

U.S. Housing

Loan Officer

2014 USA Home Packer Associates

26 Jennifer Lynne Drive

knoxville, MD

To ensure that you receive emails from us, please add this address to your address book.

You have received this email because you registered an account at Textbroker. To discontinue receiving our newsletter, please click on the following link: unsub1.

This is more of a design question - since IEnumerator

public void afterEntityAdded(ScoreDirector scoreDirector, Customer customer) {
if (customer instanceof TimeWindowedCustomer) {
updateParcelsOnboard(scoreDirector, (TimeWindowedCustomer) customer);
}
}

public void afterVariableChanged(ScoreDirector scoreDirector, Customer customer) {
if (customer instanceof TimeWindowedCustomer) {
updateParcelsOnboard(scoreDirector, (TimeWindowedCustomer) customer);
}
}

protected void updateParcelsOnboard(ScoreDirector scoreDirector, TimeWindowedCustomer sourceCustomer) {
Standstill previousStandstill = sourceCustomer.getPreviousStandstill();
Set parcelIdsOnboard = (previousStandstill instanceof TimeWindowedCustomer)
? new HashSet(((TimeWindowedCustomer) previousStandstill).getParcelIdsOnboard()) : new HashSet();

TimeWindowedCustomer shadowCustomer = sourceCustomer;
while (shadowCustomer != null) {
updateParcelIdsOnboard(parcelIdsOnboard, shadowCustomer);
scoreDirector.beforeVariableChanged(shadowCustomer, "parcelIdsOnboard");
shadowCustomer.setParcelIdsOnboard(parcelIdsOnboard);
scoreDirector.afterVariableChanged(shadowCustomer, "parcelIdsOnboard");
shadowCustomer = shadowCustomer.getNextCustomer();
}
}

private void updateParcelIdsOnboard(Set parcelIdsOnboard, TimeWindowedCustomer customer) {
if (customer.getCustomerType() == Customer.PICKUP) {
parcelIdsOnboard.add(customer.getParcelId());
} else if (customer.getCustomerType() == Customer.DELIVERY) {
parcelIdsOnboard.remove(customer.getParcelId());
} else {
// TODO: throw an assertion
}
}
I then added the following drool rule:

rule "pickupBeforeDropoff"
when
TimeWindowedCustomer((customerType == Customer.DELIVERY) && !(parcelIdsOnboard.contains(parcelId)));
then
System.out.println("precedence violated");
scoreHolder.addHardConstraintMatch(kcontext, -1000);
end
For my example problem I create a total of 6 Customer objects (3 PICKUPS and 3 DELIVERIES). My fleet size is 12 vehicles.

When I run this I consistently get a hard score of -3000 which matches my output where I see two vehicles being used. One vehicle does all the PICKUPS and one vehicle does all the DELIVERIES.

The second approach I used was to give each Customer a reference to its counterpart Customer object (e.g. the PICKUP Customer for parcel 1 has a reference to the DELIVERY Customer for parcel 1 and vice versa).

I then implemented the following rule to enforce that the parcels be in the same vehicle (note: does not fully implement precedence constraint).

rule "pudoInSameVehicle"
when
TimeWindowedCustomer(vehicle != null && counterpartCustomer.getVehicle() != null && (vehicle != counterpartCustomer.getVehicle()));
then
scoreHolder.addHardConstraintMatch(kcontext, -1000);
end
For the same sample problem this consistently gives a score of -3000 and an identical solution to the one above.

I've tried running both rules in FULL_ASSERT mode. The rule using parcelIdsOnboard does not trigger any exceptions. However, the rule "pudoInSameVehicle" does trigger the following exception (which is not triggered in FAST_ASSERT mode).

The corrupted scoreDirector has no ConstraintMatch(s) which are in excess.
The corrupted scoreDirector has 1 ConstraintMatch(s) which are missing:
I'm not sure why this is corrupted, any suggestions would be much appreciated.

It's interesting that both of these methodologies are producing the same (incorrect) solution. I'm hoping someone will have some suggestions on what to try next. Thanks!