mirror of
https://github.com/graphhopper/jsprit.git
synced 2020-01-24 07:45:05 +01:00
clean shipment insertion
This commit is contained in:
commit
d6c316fdca
3 changed files with 90 additions and 118 deletions
|
|
@ -120,23 +120,36 @@ final class ShipmentInsertionCalculator implements JobInsertionCostsCalculator{
|
||||||
|
|
||||||
TourActivity prevAct = start;
|
TourActivity prevAct = start;
|
||||||
double prevActEndTime = newVehicleDepartureTime;
|
double prevActEndTime = newVehicleDepartureTime;
|
||||||
boolean pickupShipmentLoopBroken = false;
|
|
||||||
|
//loops
|
||||||
|
int i = 0;
|
||||||
|
boolean tourEnd = false;
|
||||||
//pickupShipmentLoop
|
//pickupShipmentLoop
|
||||||
List<TourActivity> activities = currentRoute.getTourActivities().getActivities();
|
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);
|
while(!tourEnd){
|
||||||
|
TourActivity nextAct;
|
||||||
|
if(i < activities.size()){
|
||||||
|
nextAct = activities.get(i);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
nextAct = end;
|
||||||
|
tourEnd = true;
|
||||||
|
}
|
||||||
|
// logger.info("activity: " + i + ", act-size: " + activities.size());
|
||||||
|
ConstraintsStatus pickupShipmentConstraintStatus = hardActivityLevelConstraint.fulfilled(insertionContext, prevAct, pickupShipment, nextAct, prevActEndTime);
|
||||||
if(pickupShipmentConstraintStatus.equals(ConstraintsStatus.NOT_FULFILLED)){
|
if(pickupShipmentConstraintStatus.equals(ConstraintsStatus.NOT_FULFILLED)){
|
||||||
double nextActArrTime = prevActEndTime + transportCosts.getTransportTime(prevAct.getLocation(), activities.get(i).getLocation(), prevActEndTime, newDriver, newVehicle);
|
double nextActArrTime = prevActEndTime + transportCosts.getTransportTime(prevAct.getLocation(), nextAct.getLocation(), prevActEndTime, newDriver, newVehicle);
|
||||||
prevActEndTime = CalculationUtils.getActivityEndTime(nextActArrTime, activities.get(i));
|
prevActEndTime = CalculationUtils.getActivityEndTime(nextActArrTime, nextAct);
|
||||||
prevAct = activities.get(i);
|
prevAct = nextAct;
|
||||||
|
i++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if(pickupShipmentConstraintStatus.equals(ConstraintsStatus.NOT_FULFILLED_BREAK)){
|
else if(pickupShipmentConstraintStatus.equals(ConstraintsStatus.NOT_FULFILLED_BREAK)){
|
||||||
pickupShipmentLoopBroken = true;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
double additionalPickupICosts = softActivityConstraint.getCosts(insertionContext, prevAct, pickupShipment, activities.get(i), prevActEndTime);
|
double additionalPickupICosts = softActivityConstraint.getCosts(insertionContext, prevAct, pickupShipment, nextAct, prevActEndTime);
|
||||||
double pickupAIC = calculate(insertionContext,prevAct,pickupShipment,activities.get(i),prevActEndTime);
|
double pickupAIC = calculate(insertionContext,prevAct,pickupShipment, nextAct,prevActEndTime);
|
||||||
|
|
||||||
TourActivity prevAct_deliveryLoop = pickupShipment;
|
TourActivity prevAct_deliveryLoop = pickupShipment;
|
||||||
double shipmentPickupArrTime = prevActEndTime + transportCosts.getTransportTime(prevAct.getLocation(), pickupShipment.getLocation(), prevActEndTime, newDriver, newVehicle);
|
double shipmentPickupArrTime = prevActEndTime + transportCosts.getTransportTime(prevAct.getLocation(), pickupShipment.getLocation(), prevActEndTime, newDriver, newVehicle);
|
||||||
|
|
@ -148,13 +161,29 @@ final class ShipmentInsertionCalculator implements JobInsertionCostsCalculator{
|
||||||
insertionContext.setRelatedActivityContext(pickupContext);
|
insertionContext.setRelatedActivityContext(pickupContext);
|
||||||
|
|
||||||
double prevActEndTime_deliveryLoop = shipmentPickupEndTime;
|
double prevActEndTime_deliveryLoop = shipmentPickupEndTime;
|
||||||
boolean deliverShipmentLoopBroken = false;
|
|
||||||
|
/*
|
||||||
|
--------------------------------
|
||||||
|
*/
|
||||||
//deliverShipmentLoop
|
//deliverShipmentLoop
|
||||||
for(int j=i;j<activities.size();j++){
|
int j = i;
|
||||||
ConstraintsStatus deliverShipmentConstraintStatus = hardActivityLevelConstraint.fulfilled(insertionContext, prevAct_deliveryLoop, deliverShipment, activities.get(j), prevActEndTime_deliveryLoop);
|
boolean tourEnd_deliveryLoop = false;
|
||||||
|
while(!tourEnd_deliveryLoop){
|
||||||
|
|
||||||
|
// for(int j=i;j<activities.size();j++){
|
||||||
|
TourActivity nextAct_deliveryLoop;
|
||||||
|
if(j < activities.size()) {
|
||||||
|
nextAct_deliveryLoop = activities.get(j);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
nextAct_deliveryLoop = end;
|
||||||
|
tourEnd_deliveryLoop = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConstraintsStatus deliverShipmentConstraintStatus = hardActivityLevelConstraint.fulfilled(insertionContext, prevAct_deliveryLoop, deliverShipment, nextAct_deliveryLoop, prevActEndTime_deliveryLoop);
|
||||||
if(deliverShipmentConstraintStatus.equals(ConstraintsStatus.FULFILLED)){
|
if(deliverShipmentConstraintStatus.equals(ConstraintsStatus.FULFILLED)){
|
||||||
double additionalDeliveryICosts = softActivityConstraint.getCosts(insertionContext, prevAct_deliveryLoop, deliverShipment, activities.get(j), prevActEndTime_deliveryLoop);
|
double additionalDeliveryICosts = softActivityConstraint.getCosts(insertionContext, prevAct_deliveryLoop, deliverShipment, nextAct_deliveryLoop, prevActEndTime_deliveryLoop);
|
||||||
double deliveryAIC = calculate(insertionContext,prevAct_deliveryLoop,deliverShipment,activities.get(j),prevActEndTime_deliveryLoop);
|
double deliveryAIC = calculate(insertionContext,prevAct_deliveryLoop,deliverShipment, nextAct_deliveryLoop,prevActEndTime_deliveryLoop);
|
||||||
double totalActivityInsertionCosts = pickupAIC + deliveryAIC
|
double totalActivityInsertionCosts = pickupAIC + deliveryAIC
|
||||||
+ additionalICostsAtRouteLevel + additionalPickupICosts + additionalDeliveryICosts;
|
+ additionalICostsAtRouteLevel + additionalPickupICosts + additionalDeliveryICosts;
|
||||||
if(totalActivityInsertionCosts < bestCost){
|
if(totalActivityInsertionCosts < bestCost){
|
||||||
|
|
@ -164,61 +193,19 @@ final class ShipmentInsertionCalculator implements JobInsertionCostsCalculator{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(deliverShipmentConstraintStatus.equals(ConstraintsStatus.NOT_FULFILLED_BREAK)){
|
else if(deliverShipmentConstraintStatus.equals(ConstraintsStatus.NOT_FULFILLED_BREAK)){
|
||||||
deliverShipmentLoopBroken = true;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
//update prevAct and endTime
|
//update prevAct and endTime
|
||||||
double nextActArrTime = prevActEndTime_deliveryLoop + transportCosts.getTransportTime(prevAct_deliveryLoop.getLocation(), activities.get(j).getLocation(), prevActEndTime_deliveryLoop, newDriver, newVehicle);
|
double nextActArrTime = prevActEndTime_deliveryLoop + transportCosts.getTransportTime(prevAct_deliveryLoop.getLocation(), nextAct_deliveryLoop.getLocation(), prevActEndTime_deliveryLoop, newDriver, newVehicle);
|
||||||
prevActEndTime_deliveryLoop = CalculationUtils.getActivityEndTime(nextActArrTime, activities.get(j));
|
prevActEndTime_deliveryLoop = CalculationUtils.getActivityEndTime(nextActArrTime, nextAct_deliveryLoop);
|
||||||
prevAct_deliveryLoop = activities.get(j);
|
prevAct_deliveryLoop = nextAct_deliveryLoop;
|
||||||
}
|
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
|
//update prevAct and endTime
|
||||||
double nextActArrTime = prevActEndTime + transportCosts.getTransportTime(prevAct.getLocation(), activities.get(i).getLocation(), prevActEndTime, newDriver, newVehicle);
|
double nextActArrTime = prevActEndTime + transportCosts.getTransportTime(prevAct.getLocation(), nextAct.getLocation(), prevActEndTime, newDriver, newVehicle);
|
||||||
prevActEndTime = CalculationUtils.getActivityEndTime(nextActArrTime, activities.get(i));
|
prevActEndTime = CalculationUtils.getActivityEndTime(nextActArrTime, nextAct);
|
||||||
prevAct = activities.get(i);
|
prevAct = nextAct;
|
||||||
}
|
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.getLocation(), pickupShipment.getLocation(), 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){
|
|
||||||
bestCost = totalActivityInsertionCosts;
|
|
||||||
pickupInsertionIndex = activities.size();
|
|
||||||
deliveryInsertionIndex = activities.size();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if(pickupInsertionIndex == InsertionData.NO_INDEX) {
|
if(pickupInsertionIndex == InsertionData.NO_INDEX) {
|
||||||
return InsertionData.createEmptyInsertionData();
|
return InsertionData.createEmptyInsertionData();
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
package jsprit.core.problem.solution.route.activity;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by schroeder on 20/05/15.
|
||||||
|
*/
|
||||||
|
public interface TimeWindows {
|
||||||
|
|
||||||
|
public Collection<TimeWindow> getTimeWindows(double time);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -2,9 +2,24 @@
|
||||||
<problem xmlns="http://www.w3schools.com"
|
<problem xmlns="http://www.w3schools.com"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3schools.com vrp_xml_schema.xsd">
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3schools.com vrp_xml_schema.xsd">
|
||||||
<problemType>
|
<problemType>
|
||||||
<fleetSize>INFINITE</fleetSize>
|
<fleetSize>FINITE</fleetSize>
|
||||||
</problemType>
|
</problemType>
|
||||||
<vehicles>
|
<vehicles>
|
||||||
|
<vehicle>
|
||||||
|
<id>v2</id>
|
||||||
|
<typeId>vehType2</typeId>
|
||||||
|
<startLocation>
|
||||||
|
<id>loc</id>
|
||||||
|
</startLocation>
|
||||||
|
<endLocation>
|
||||||
|
<id>loc</id>
|
||||||
|
</endLocation>
|
||||||
|
<timeSchedule>
|
||||||
|
<start>0.0</start>
|
||||||
|
<end>1.7976931348623157E308</end>
|
||||||
|
</timeSchedule>
|
||||||
|
<returnToDepot>true</returnToDepot>
|
||||||
|
</vehicle>
|
||||||
<vehicle>
|
<vehicle>
|
||||||
<id>v1</id>
|
<id>v1</id>
|
||||||
<typeId>vehType</typeId>
|
<typeId>vehType</typeId>
|
||||||
|
|
@ -33,58 +48,16 @@
|
||||||
<time>0.0</time>
|
<time>0.0</time>
|
||||||
</costs>
|
</costs>
|
||||||
</type>
|
</type>
|
||||||
|
<type>
|
||||||
|
<id>vehType2</id>
|
||||||
|
<capacity-dimensions>
|
||||||
|
<dimension index="0">200</dimension>
|
||||||
|
</capacity-dimensions>
|
||||||
|
<costs>
|
||||||
|
<fixed>0.0</fixed>
|
||||||
|
<distance>1.0</distance>
|
||||||
|
<time>0.0</time>
|
||||||
|
</costs>
|
||||||
|
</type>
|
||||||
</vehicleTypes>
|
</vehicleTypes>
|
||||||
<services>
|
|
||||||
<service id="1" type="service">
|
|
||||||
<location>
|
|
||||||
<id>loc</id>
|
|
||||||
</location>
|
|
||||||
<capacity-dimensions>
|
|
||||||
<dimension index="0">1</dimension>
|
|
||||||
</capacity-dimensions>
|
|
||||||
<duration>2.0</duration>
|
|
||||||
<timeWindows>
|
|
||||||
<timeWindow>
|
|
||||||
<start>0.0</start>
|
|
||||||
<end>1.7976931348623157E308</end>
|
|
||||||
</timeWindow>
|
|
||||||
</timeWindows>
|
|
||||||
</service>
|
|
||||||
<service id="2" type="service">
|
|
||||||
<location>
|
|
||||||
<id>loc2</id>
|
|
||||||
</location>
|
|
||||||
<capacity-dimensions>
|
|
||||||
<dimension index="0">1</dimension>
|
|
||||||
</capacity-dimensions>
|
|
||||||
<duration>4.0</duration>
|
|
||||||
<timeWindows>
|
|
||||||
<timeWindow>
|
|
||||||
<start>0.0</start>
|
|
||||||
<end>1.7976931348623157E308</end>
|
|
||||||
</timeWindow>
|
|
||||||
</timeWindows>
|
|
||||||
</service>
|
|
||||||
</services>
|
|
||||||
<solutions>
|
|
||||||
<solution>
|
|
||||||
<cost>10.0</cost>
|
|
||||||
<routes>
|
|
||||||
<route>
|
|
||||||
<driverId>noDriver</driverId>
|
|
||||||
<vehicleId>v1</vehicleId>
|
|
||||||
<start>0.0</start>
|
|
||||||
<act type="service">
|
|
||||||
<serviceId>1</serviceId>
|
|
||||||
<arrTime>0.0</arrTime>
|
|
||||||
<endTime>0.0</endTime>
|
|
||||||
</act>
|
|
||||||
<end>0.0</end>
|
|
||||||
</route>
|
|
||||||
</routes>
|
|
||||||
<unassignedJobs>
|
|
||||||
<job id="2"/>
|
|
||||||
</unassignedJobs>
|
|
||||||
</solution>
|
|
||||||
</solutions>
|
|
||||||
</problem>
|
</problem>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue