double prevActEndTime = newVehicleDepartureTime;
boolean pickupShipmentLoopBroken = false;
//pickupShipmentLoop
List<TourActivity> activities = currentRoute.getTourActivities().getActivities();
for(int i=0;i<activities.size();i++){
ConstraintsStatus pickupShipmentConstraintStatus = hardActivityLevelConstraint.fulfilled(insertionContext, prevAct, pickupShipment, activities.get(i), prevActEndTime);
if(pickupShipmentConstraintStatus.equals(ConstraintsStatus.NOT_FULFILLED)){
double nextActArrTime = prevActEndTime + transportCosts.getTransportTime(prevAct.getLocationId(), activities.get(i).getLocationId(), prevActEndTime, newDriver, newVehicle);
prevActEndTime = CalculationUtils.getActivityEndTime(nextActArrTime, activities.get(i));
prevAct = activities.get(i);
continue;
}
else if(pickupShipmentConstraintStatus.equals(ConstraintsStatus.NOT_FULFILLED_BREAK)){
pickupShipmentLoopBroken = true;
break;
}
double additionalPickupICosts = softActivityConstraint.getCosts(insertionContext, prevAct, pickupShipment, activities.get(i), prevActEndTime);
double pickupAIC = calculate(insertionContext,prevAct,pickupShipment,activities.get(i),prevActEndTime);
TourActivity prevAct_deliveryLoop = pickupShipment;
double shipmentPickupArrTime = prevActEndTime + transportCosts.getTransportTime(prevAct.getLocationId(), pickupShipment.getLocationId(), prevActEndTime, newDriver, newVehicle);
double shipmentPickupEndTime = CalculationUtils.getActivityEndTime(shipmentPickupArrTime, pickupShipment);
pickupContext.setArrivalTime(shipmentPickupArrTime);
pickupContext.setEndTime(shipmentPickupEndTime);
pickupContext.setInsertionIndex(i);
insertionContext.setRelatedActivityContext(pickupContext);
double prevActEndTime_deliveryLoop = shipmentPickupEndTime;
boolean deliverShipmentLoopBroken = false;
//deliverShipmentLoop
for(int j=i;j<activities.size();j++){
ConstraintsStatus deliverShipmentConstraintStatus = hardActivityLevelConstraint.fulfilled(insertionContext, prevAct_deliveryLoop, deliverShipment, activities.get(j), prevActEndTime_deliveryLoop);
if(deliverShipmentConstraintStatus.equals(ConstraintsStatus.FULFILLED)){
double additionalDeliveryICosts = softActivityConstraint.getCosts(insertionContext, prevAct_deliveryLoop, deliverShipment, activities.get(j), prevActEndTime_deliveryLoop);
double deliveryAIC = calculate(insertionContext,prevAct_deliveryLoop,deliverShipment,activities.get(j),prevActEndTime_deliveryLoop);
double totalActivityInsertionCosts = pickupAIC + deliveryAIC
+ additionalICostsAtRouteLevel + additionalPickupICosts + additionalDeliveryICosts;
if(totalActivityInsertionCosts < bestCost){
bestCost = totalActivityInsertionCosts;
pickupInsertionIndex = i;
deliveryInsertionIndex = j;
}
}
else if(deliverShipmentConstraintStatus.equals(ConstraintsStatus.NOT_FULFILLED_BREAK)){
deliverShipmentLoopBroken = true;
break;
}
//update prevAct and endTime
double nextActArrTime = prevActEndTime_deliveryLoop + transportCosts.getTransportTime(prevAct_deliveryLoop.getLocationId(), activities.get(j).getLocationId(), prevActEndTime_deliveryLoop, newDriver, newVehicle);
prevActEndTime_deliveryLoop = CalculationUtils.getActivityEndTime(nextActArrTime, activities.get(j));
prevAct_deliveryLoop = activities.get(j);
}
if(!deliverShipmentLoopBroken){ //check insertion between lastAct and endOfTour
ConstraintsStatus deliverShipmentConstraintStatus = hardActivityLevelConstraint.fulfilled(insertionContext, prevAct_deliveryLoop, deliverShipment, end, prevActEndTime_deliveryLoop);
if(deliverShipmentConstraintStatus.equals(ConstraintsStatus.FULFILLED)){
double additionalDeliveryICosts = softActivityConstraint.getCosts(insertionContext, prevAct_deliveryLoop, deliverShipment, end, prevActEndTime_deliveryLoop);
double deliveryAIC = calculate(insertionContext,prevAct_deliveryLoop,deliverShipment,end,prevActEndTime_deliveryLoop);
double totalActivityInsertionCosts = pickupAIC + deliveryAIC
+ additionalICostsAtRouteLevel + additionalPickupICosts + additionalDeliveryICosts;
if(totalActivityInsertionCosts < bestCost){
bestCost = totalActivityInsertionCosts;
pickupInsertionIndex = i;
deliveryInsertionIndex = activities.size();
}
}
}
//update prevAct and endTime
double nextActArrTime = prevActEndTime + transportCosts.getTransportTime(prevAct.getLocationId(), activities.get(i).getLocationId(), prevActEndTime, newDriver, newVehicle);
prevActEndTime = CalculationUtils.getActivityEndTime(nextActArrTime, activities.get(i));
prevAct = activities.get(i);
}
if(!pickupShipmentLoopBroken){ //check insertion of pickupShipment and deliverShipment at just before tour ended
ConstraintsStatus pickupShipmentConstraintStatus = hardActivityLevelConstraint.fulfilled(insertionContext, prevAct, pickupShipment, end, prevActEndTime);
if(pickupShipmentConstraintStatus.equals(ConstraintsStatus.FULFILLED)){
double additionalPickupICosts = softActivityConstraint.getCosts(insertionContext, prevAct, pickupShipment, end, prevActEndTime);
double pickupAIC = calculate(insertionContext,prevAct,pickupShipment,end,prevActEndTime);
TourActivity prevAct_deliveryLoop = pickupShipment;
double shipmentPickupArrTime = prevActEndTime + transportCosts.getTransportTime(prevAct.getLocationId(), pickupShipment.getLocationId(), prevActEndTime, newDriver, newVehicle);
double shipmentPickupEndTime = CalculationUtils.getActivityEndTime(shipmentPickupArrTime, pickupShipment);
double prevActEndTime_deliveryLoop = shipmentPickupEndTime;
pickupContext.setArrivalTime(shipmentPickupArrTime);
pickupContext.setEndTime(shipmentPickupEndTime);
pickupContext.setInsertionIndex(activities.size());
insertionContext.setRelatedActivityContext(pickupContext);
ConstraintsStatus deliverShipmentConstraintStatus = hardActivityLevelConstraint.fulfilled(insertionContext, prevAct_deliveryLoop, deliverShipment, end, prevActEndTime_deliveryLoop);
if(deliverShipmentConstraintStatus.equals(ConstraintsStatus.FULFILLED)){
double additionalDeliveryICosts = softActivityConstraint.getCosts(insertionContext, prevAct_deliveryLoop, deliverShipment, end, prevActEndTime_deliveryLoop);
double deliveryAIC = calculate(insertionContext,prevAct_deliveryLoop,deliverShipment,end,prevActEndTime_deliveryLoop);
double totalActivityInsertionCosts = pickupAIC + deliveryAIC
+ additionalICostsAtRouteLevel + additionalPickupICosts + additionalDeliveryICosts;
if(totalActivityInsertionCosts < bestCost){