1
0
Fork 0
mirror of https://github.com/graphhopper/jsprit.git synced 2020-01-24 07:45:05 +01:00

test tour and implement shipment-insertion

This commit is contained in:
oblonski 2013-10-18 07:17:38 +02:00
parent 6eddbbbef7
commit c31e61a797
2 changed files with 125 additions and 24 deletions

View file

@ -16,6 +16,8 @@
******************************************************************************/
package algorithms;
import java.util.List;
import org.apache.log4j.Logger;
import util.Neighborhood;
@ -27,7 +29,6 @@ import basics.costs.VehicleRoutingTransportCosts;
import basics.route.DefaultShipmentActivityFactory;
import basics.route.Driver;
import basics.route.End;
import basics.route.PickupShipment;
import basics.route.Start;
import basics.route.TourActivity;
import basics.route.TourShipmentActivityFactory;
@ -86,33 +87,94 @@ final class ShipmentInsertionCalculator implements JobInsertionCalculator{
if(jobToInsert == null) throw new IllegalStateException("jobToInsert is missing.");
if(newVehicle == null || newVehicle instanceof NoVehicle) throw new IllegalStateException("newVehicle is missing.");
if(!(jobToInsert instanceof Shipment)) throw new IllegalStateException("jobToInsert should be of type Shipment!");
InsertionContext insertionContext = new InsertionContext(currentRoute, jobToInsert, newVehicle, newDriver, newVehicleDepartureTime);
if(!hardRouteLevelConstraint.fulfilled(insertionContext)){
return InsertionData.noInsertionFound();
}
double bestCost = bestKnownCosts;
ActivityInsertionCosts bestMarginals = null;
Shipment shipment = (Shipment)jobToInsert;
TourActivity pickupShipment = activityFactory.createPickup(shipment);
TourActivity deliveryShipment = activityFactory.createDelivery(shipment);
int pickupInsertionIndex = InsertionData.NO_INDEX;
int deliveryInsertionIndex = InsertionData.NO_INDEX;
int insertionIndex = 0;
// int insertionIndex = 0;
Start start = Start.newInstance(newVehicle.getLocationId(), newVehicle.getEarliestDeparture(), newVehicle.getLatestArrival());
start.setEndTime(newVehicleDepartureTime);
End end = End.newInstance(newVehicle.getLocationId(), 0.0, newVehicle.getLatestArrival());
// TourActivity prevAct = start;
// double prevActStartTime = newVehicleDepartureTime;
// int actIndex = 0;
//// currentRoute.getTourActivities().getActivities().
// for(int i=0)
// for(TourActivity nextAct : currentRoute.getTourActivities().getActivities()){
TourActivity prevAct = start;
double prevActEndTime = newVehicleDepartureTime;
//pickupShipmentLoop
List<TourActivity> activities = currentRoute.getTourActivities().getActivities();
for(int i=0;i<activities.size();i++){
ActivityInsertionCosts pickupAIC = calculate(insertionContext,prevAct,pickupShipment,activities.get(i),prevActEndTime);
if(pickupAIC == null){
double nextActArrTime = prevActEndTime + transportCosts.getTransportTime(prevAct.getLocationId(), activities.get(i).getLocationId(), prevActEndTime, newDriver, newVehicle);
prevActEndTime = CalcUtils.getActivityEndTime(nextActArrTime, activities.get(i));
continue;
}
TourActivity prevAct_deliveryLoop = pickupShipment;
double shipmentPickupArrTime = prevActEndTime + transportCosts.getTransportTime(prevAct.getLocationId(), pickupShipment.getLocationId(), prevActEndTime, newDriver, newVehicle);
double shipmentPickupEndTime = CalcUtils.getActivityEndTime(shipmentPickupArrTime, pickupShipment);
double prevActEndTime_deliveryLoop = shipmentPickupEndTime;
//deliverShipmentLoop
for(int j=i;j<activities.size();j++){
ActivityInsertionCosts deliveryAIC = calculate(insertionContext,prevAct_deliveryLoop,deliveryShipment,activities.get(j),prevActEndTime_deliveryLoop);
if(deliveryAIC != null){
double totalActivityInsertionCosts = pickupAIC.getAdditionalCosts() + deliveryAIC.getAdditionalCosts();
if(totalActivityInsertionCosts < bestCost){
bestCost = totalActivityInsertionCosts;
pickupInsertionIndex = i;
deliveryInsertionIndex = j;
}
}
//update prevAct and endTime
double nextActArrTime = prevActEndTime_deliveryLoop + transportCosts.getTransportTime(prevAct_deliveryLoop.getLocationId(), activities.get(j).getLocationId(), prevActEndTime_deliveryLoop, newDriver, newVehicle);
prevActEndTime_deliveryLoop = CalcUtils.getActivityEndTime(nextActArrTime, activities.get(j));
prevAct_deliveryLoop = activities.get(j);
}
//endInsertion
ActivityInsertionCosts deliveryAIC = calculate(insertionContext,prevAct_deliveryLoop,deliveryShipment,end,prevActEndTime_deliveryLoop);
if(deliveryAIC != null){
double totalActivityInsertionCosts = pickupAIC.getAdditionalCosts() + deliveryAIC.getAdditionalCosts();
if(totalActivityInsertionCosts < bestCost){
bestCost = totalActivityInsertionCosts;
pickupInsertionIndex = i;
deliveryInsertionIndex = activities.size() - 1;
}
}
//update prevAct and endTime
double nextActArrTime = prevActEndTime + transportCosts.getTransportTime(prevAct.getLocationId(), activities.get(i).getLocationId(), prevActEndTime, newDriver, newVehicle);
prevActEndTime = CalcUtils.getActivityEndTime(nextActArrTime, activities.get(i));
prevAct = activities.get(i);
}
//endInsertion
ActivityInsertionCosts pickupAIC = calculate(insertionContext,prevAct,pickupShipment,end,prevActEndTime);
if(pickupAIC != null){ //evaluate delivery
TourActivity prevAct_deliveryLoop = pickupShipment;
double shipmentPickupArrTime = prevActEndTime + transportCosts.getTransportTime(prevAct.getLocationId(), pickupShipment.getLocationId(), prevActEndTime, newDriver, newVehicle);
double shipmentPickupEndTime = CalcUtils.getActivityEndTime(shipmentPickupArrTime, pickupShipment);
double prevActEndTime_deliveryLoop = shipmentPickupEndTime;
ActivityInsertionCosts deliveryAIC = calculate(insertionContext,prevAct_deliveryLoop,deliveryShipment,end,prevActEndTime_deliveryLoop);
if(deliveryAIC != null){
double totalActivityInsertionCosts = pickupAIC.getAdditionalCosts() + deliveryAIC.getAdditionalCosts();
if(totalActivityInsertionCosts < bestCost){
bestCost = totalActivityInsertionCosts;
pickupInsertionIndex = activities.size() - 1;
deliveryInsertionIndex = activities.size() - 1;
}
}
}
// for(TourActivity nextAct : activities){
// if(neighborhood.areNeighbors(deliveryAct2Insert.getLocationId(), prevAct.getLocationId()) && neighborhood.areNeighbors(deliveryAct2Insert.getLocationId(), nextAct.getLocationId())){
// ActivityInsertionCosts mc = calculate(insertionContext, prevAct, nextAct, deliveryAct2Insert, prevActStartTime);
// ActivityInsertionCosts mc = calculate(insertionContext, prevAct, nextAct, deliveryAct2Insert, prevActEndTime);
// if(mc != null){
// if(mc.getAdditionalCosts() < bestCost){
// bestCost = mc.getAdditionalCosts();
@ -121,17 +183,17 @@ final class ShipmentInsertionCalculator implements JobInsertionCalculator{
// }
// }
// }
// double nextActArrTime = prevActStartTime + transportCosts.getTransportTime(prevAct.getLocationId(), nextAct.getLocationId(), prevActStartTime, newDriver, newVehicle);
// double nextActArrTime = prevActEndTime + transportCosts.getTransportTime(prevAct.getLocationId(), nextAct.getLocationId(), prevActEndTime, newDriver, newVehicle);
// double nextActEndTime = CalcUtils.getActivityEndTime(nextActArrTime, nextAct);
//
// prevActStartTime = nextActEndTime;
// prevActEndTime = nextActEndTime;
//
// prevAct = nextAct;
// actIndex++;
// }
// End nextAct = end;
// if(neighborhood.areNeighbors(deliveryAct2Insert.getLocationId(), prevAct.getLocationId()) && neighborhood.areNeighbors(deliveryAct2Insert.getLocationId(), nextAct.getLocationId())){
// ActivityInsertionCosts mc = calculate(insertionContext, prevAct, nextAct, deliveryAct2Insert, prevActStartTime);
// ActivityInsertionCosts mc = calculate(insertionContext, prevAct, nextAct, deliveryAct2Insert, prevActEndTime);
// if(mc != null) {
// if(mc.getAdditionalCosts() < bestCost){
// bestCost = mc.getAdditionalCosts();
@ -140,17 +202,16 @@ final class ShipmentInsertionCalculator implements JobInsertionCalculator{
// }
// }
// }
//
// if(insertionIndex == InsertionData.NO_INDEX) {
// return InsertionData.noInsertionFound();
// }
InsertionData insertionData = new InsertionData(bestCost, InsertionData.NO_INDEX, insertionIndex, newVehicle, newDriver);
if(pickupInsertionIndex == InsertionData.NO_INDEX) {
return InsertionData.noInsertionFound();
}
InsertionData insertionData = new InsertionData(bestCost, pickupInsertionIndex, deliveryInsertionIndex, newVehicle, newDriver);
insertionData.setVehicleDepartureTime(newVehicleDepartureTime);
insertionData.setAdditionalTime(bestMarginals.getAdditionalTime());
return insertionData;
}
public ActivityInsertionCosts calculate(InsertionContext iFacts, TourActivity prevAct, TourActivity nextAct, TourActivity newAct, double departureTimeAtPrevAct) {
public ActivityInsertionCosts calculate(InsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double departureTimeAtPrevAct) {
return activityInsertionCostsCalculator.calculate(iFacts, prevAct, nextAct, newAct, departureTimeAtPrevAct);
}

View file

@ -24,6 +24,7 @@ import org.junit.Before;
import org.junit.Test;
import basics.Service;
import basics.Shipment;
public class TestTour {
@ -47,14 +48,14 @@ public class TestTour {
}
@Test(expected=IllegalStateException.class)
public void whenAddingServiceActTwice_serviceActIsAdded(){
public void whenAddingServiceActTwice_anExceptionIsThrown(){
assertFalse(tour.servesJob(service));
tour.addActivity(act);
tour.addActivity(act);
}
@Test
public void whenAddingServiceAndRemoveIt_tourShouldNotServeService(){
public void whenAddingServiceAndRemovingItImmediately_tourShouldNotServeServiceAnymore(){
assertFalse(tour.servesJob(service));
tour.addActivity(act);
assertTrue(tour.servesJob(service));
@ -63,7 +64,7 @@ public class TestTour {
}
@Test
public void noNameYet(){
public void whenAddingAServiceAndThenRemovingTheServiceAgain_tourShouldNotServeItAnymore(){
assertEquals(0, tour.getActivities().size());
tour.addActivity(act);
assertEquals(1, tour.getActivities().size());
@ -71,8 +72,47 @@ public class TestTour {
assertTrue(service.equals(anotherServiceInstance));
boolean removed = tour.removeJob(anotherServiceInstance);
assertTrue(removed);
// assertEquals(0, tour.getActivities().size());
assertEquals(0, tour.getActivities().size());
}
@Test
public void whenAddingAShipmentActivity_tourShouldServeShipment(){
Shipment s = Shipment.Builder.newInstance("s", 1).setDeliveryLocation("delLoc").setPickupLocation("pickLoc").build();
TourShipmentActivityFactory fac = new DefaultShipmentActivityFactory();
TourActivity pickupShipment = fac.createPickup(s);
TourActivity deliverShipment = fac.createDelivery(s);
tour.addActivity(pickupShipment);
tour.addActivity(deliverShipment);
assertTrue(tour.servesJob(s));
assertEquals(2,tour.getActivities().size());
}
@Test
public void whenRemovingShipment_tourShouldNotServiceItAnymore(){
Shipment s = Shipment.Builder.newInstance("s", 1).setDeliveryLocation("delLoc").setPickupLocation("pickLoc").build();
TourShipmentActivityFactory fac = new DefaultShipmentActivityFactory();
TourActivity pickupShipment = fac.createPickup(s);
TourActivity deliverShipment = fac.createDelivery(s);
tour.addActivity(pickupShipment);
tour.addActivity(deliverShipment);
tour.removeJob(s);
assertFalse(tour.servesJob(s));
}
@Test
public void whenRemovingShipment_theirCorrespondingActivitiesShouldBeRemoved(){
Shipment s = Shipment.Builder.newInstance("s", 1).setDeliveryLocation("delLoc").setPickupLocation("pickLoc").build();
TourShipmentActivityFactory fac = new DefaultShipmentActivityFactory();
TourActivity pickupShipment = fac.createPickup(s);
TourActivity deliverShipment = fac.createDelivery(s);
tour.addActivity(pickupShipment);
tour.addActivity(deliverShipment);
assertEquals(2, tour.getActivities().size());
tour.removeJob(s);
assertEquals(0, tour.getActivities().size());
}
}