1
0
Fork 0
mirror of https://github.com/graphhopper/jsprit.git synced 2020-01-24 07:45:05 +01:00
This commit is contained in:
oblonski 2015-12-17 08:57:46 +01:00
parent 1075e38504
commit d28471fbda
50 changed files with 753 additions and 796 deletions

View file

@ -34,7 +34,6 @@ import jsprit.core.util.CalculationUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.Collection;
import java.util.Iterator;
/**
@ -131,17 +130,12 @@ final class ServiceInsertionCalculator implements JobInsertionCostsCalculator {
nextAct = end;
tourEnd = true;
}
double actArrTime = prevActStartTime + transportCosts.getTransportTime(prevAct.getLocation(),deliveryAct2Insert.getLocation(),prevActStartTime,newDriver,newVehicle);
Collection<TimeWindow> timeWindows = service.getTimeWindows(actArrTime);
// TimeWindow timeWindow = getNextTimeWindow(actArrTime,timeWindows);
// if(timeWindow == null) break;
boolean not_fulfilled_break = true;
for(TimeWindow timeWindow : timeWindows) {
for(TimeWindow timeWindow : service.getTimeWindows()) {
deliveryAct2Insert.setTheoreticalEarliestOperationStartTime(timeWindow.getStart());
deliveryAct2Insert.setTheoreticalLatestOperationStartTime(timeWindow.getEnd());
ConstraintsStatus status = hardActivityLevelConstraint.fulfilled(insertionContext, prevAct, deliveryAct2Insert, nextAct, prevActStartTime);
if (status.equals(ConstraintsStatus.FULFILLED)) {
//from job2insert induced costs at activity level
double additionalICostsAtActLevel = softActivityConstraint.getCosts(insertionContext, prevAct, deliveryAct2Insert, nextAct, prevActStartTime);
double additionalTransportationCosts = additionalTransportCostsCalculator.getCosts(insertionContext, prevAct, nextAct, deliveryAct2Insert, prevActStartTime);
if (additionalICostsAtRouteLevel + additionalICostsAtActLevel + additionalTransportationCosts < bestCost) {
@ -171,15 +165,4 @@ final class ServiceInsertionCalculator implements JobInsertionCostsCalculator {
insertionData.setVehicleDepartureTime(newVehicleDepartureTime);
return insertionData;
}
private TimeWindow getNextTimeWindow(double actArrTime, Collection<TimeWindow> timeWindows) {
for(TimeWindow tw : timeWindows){
if(actArrTime >= tw.getStart() && actArrTime <= tw.getEnd()) return tw;
else if(actArrTime < tw.getStart()){
return tw;
}
}
return null;
}
}

View file

@ -28,6 +28,7 @@ import jsprit.core.problem.misc.JobInsertionContext;
import jsprit.core.problem.solution.route.VehicleRoute;
import jsprit.core.problem.solution.route.activity.End;
import jsprit.core.problem.solution.route.activity.Start;
import jsprit.core.problem.solution.route.activity.TimeWindow;
import jsprit.core.problem.solution.route.activity.TourActivity;
import jsprit.core.problem.vehicle.Vehicle;
import jsprit.core.util.CalculationUtils;
@ -108,6 +109,9 @@ final class ShipmentInsertionCalculator implements JobInsertionCostsCalculator {
int pickupInsertionIndex = InsertionData.NO_INDEX;
int deliveryInsertionIndex = InsertionData.NO_INDEX;
TimeWindow bestPickupTimeWindow = null;
TimeWindow bestDeliveryTimeWindow = null;
Start start = new Start(newVehicle.getStartLocation(), newVehicle.getEarliestDeparture(), newVehicle.getLatestArrival());
start.setEndTime(newVehicleDepartureTime);
@ -132,67 +136,83 @@ final class ShipmentInsertionCalculator implements JobInsertionCostsCalculator {
nextAct = end;
tourEnd = true;
}
// logger.info("activity: {}, act-size: {}", i, activities.size());
ConstraintsStatus pickupShipmentConstraintStatus = hardActivityLevelConstraint.fulfilled(insertionContext, prevAct, pickupShipment, nextAct, prevActEndTime);
if (pickupShipmentConstraintStatus.equals(ConstraintsStatus.NOT_FULFILLED)) {
double nextActArrTime = prevActEndTime + transportCosts.getTransportTime(prevAct.getLocation(), nextAct.getLocation(), prevActEndTime, newDriver, newVehicle);
prevActEndTime = CalculationUtils.getActivityEndTime(nextActArrTime, nextAct);
prevAct = nextAct;
i++;
continue;
} else if (pickupShipmentConstraintStatus.equals(ConstraintsStatus.NOT_FULFILLED_BREAK)) {
break;
}
double additionalPickupICosts = softActivityConstraint.getCosts(insertionContext, prevAct, pickupShipment, nextAct, prevActEndTime);
double pickupAIC = calculate(insertionContext, prevAct, pickupShipment, nextAct, prevActEndTime);
TourActivity prevAct_deliveryLoop = pickupShipment;
double shipmentPickupArrTime = prevActEndTime + transportCosts.getTransportTime(prevAct.getLocation(), pickupShipment.getLocation(), prevActEndTime, newDriver, newVehicle);
double shipmentPickupEndTime = CalculationUtils.getActivityEndTime(shipmentPickupArrTime, pickupShipment);
boolean pickupInsertionNotFulfilledBreak = true;
for(TimeWindow pickupTimeWindow : shipment.getPickupTimeWindows()) {
pickupShipment.setTheoreticalEarliestOperationStartTime(pickupTimeWindow.getStart());
pickupShipment.setTheoreticalLatestOperationStartTime(pickupTimeWindow.getEnd());
ConstraintsStatus pickupShipmentConstraintStatus = hardActivityLevelConstraint.fulfilled(insertionContext, prevAct, pickupShipment, nextAct, prevActEndTime);
if (pickupShipmentConstraintStatus.equals(ConstraintsStatus.NOT_FULFILLED)) {
pickupInsertionNotFulfilledBreak = false;
continue;
} else if(pickupShipmentConstraintStatus.equals(ConstraintsStatus.NOT_FULFILLED_BREAK)) {
continue;
}
else if (pickupShipmentConstraintStatus.equals(ConstraintsStatus.FULFILLED)) {
pickupInsertionNotFulfilledBreak = false;
}
double additionalPickupICosts = softActivityConstraint.getCosts(insertionContext, prevAct, pickupShipment, nextAct, prevActEndTime);
double pickupAIC = calculate(insertionContext, prevAct, pickupShipment, nextAct, prevActEndTime);
pickupContext.setArrivalTime(shipmentPickupArrTime);
pickupContext.setEndTime(shipmentPickupEndTime);
pickupContext.setInsertionIndex(i);
insertionContext.setRelatedActivityContext(pickupContext);
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(i);
insertionContext.setRelatedActivityContext(pickupContext);
double prevActEndTime_deliveryLoop = shipmentPickupEndTime;
/*
--------------------------------
*/
//deliverShipmentLoop
int j = i;
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)) {
double additionalDeliveryICosts = softActivityConstraint.getCosts(insertionContext, prevAct_deliveryLoop, deliverShipment, nextAct_deliveryLoop, prevActEndTime_deliveryLoop);
double deliveryAIC = calculate(insertionContext, prevAct_deliveryLoop, deliverShipment, nextAct_deliveryLoop, prevActEndTime_deliveryLoop);
double totalActivityInsertionCosts = pickupAIC + deliveryAIC
+ additionalICostsAtRouteLevel + additionalPickupICosts + additionalDeliveryICosts;
if (totalActivityInsertionCosts < bestCost) {
bestCost = totalActivityInsertionCosts;
pickupInsertionIndex = i;
deliveryInsertionIndex = j;
//deliverShipmentLoop
int j = i;
boolean tourEnd_deliveryLoop = false;
while (!tourEnd_deliveryLoop) {
TourActivity nextAct_deliveryLoop;
if (j < activities.size()) {
nextAct_deliveryLoop = activities.get(j);
} else {
nextAct_deliveryLoop = end;
tourEnd_deliveryLoop = true;
}
} else if (deliverShipmentConstraintStatus.equals(ConstraintsStatus.NOT_FULFILLED_BREAK)) {
break;
boolean deliveryInsertionNotFulfilledBreak = true;
for (TimeWindow deliveryTimeWindow : shipment.getDeliveryTimeWindows()) {
deliverShipment.setTheoreticalEarliestOperationStartTime(deliveryTimeWindow.getStart());
deliverShipment.setTheoreticalLatestOperationStartTime(deliveryTimeWindow.getEnd());
ConstraintsStatus deliverShipmentConstraintStatus = hardActivityLevelConstraint.fulfilled(insertionContext, prevAct_deliveryLoop, deliverShipment, nextAct_deliveryLoop, prevActEndTime_deliveryLoop);
if (deliverShipmentConstraintStatus.equals(ConstraintsStatus.FULFILLED)) {
double additionalDeliveryICosts = softActivityConstraint.getCosts(insertionContext, prevAct_deliveryLoop, deliverShipment, nextAct_deliveryLoop, prevActEndTime_deliveryLoop);
double deliveryAIC = calculate(insertionContext, prevAct_deliveryLoop, deliverShipment, nextAct_deliveryLoop, prevActEndTime_deliveryLoop);
double totalActivityInsertionCosts = pickupAIC + deliveryAIC
+ additionalICostsAtRouteLevel + additionalPickupICosts + additionalDeliveryICosts;
if (totalActivityInsertionCosts < bestCost) {
bestCost = totalActivityInsertionCosts;
pickupInsertionIndex = i;
deliveryInsertionIndex = j;
bestPickupTimeWindow = pickupTimeWindow;
bestDeliveryTimeWindow = deliveryTimeWindow;
}
deliveryInsertionNotFulfilledBreak = false;
} else if (deliverShipmentConstraintStatus.equals(ConstraintsStatus.NOT_FULFILLED)) {
deliveryInsertionNotFulfilledBreak = false;
}
}
if (deliveryInsertionNotFulfilledBreak) break;
//update prevAct and endTime
double nextActArrTime = prevActEndTime_deliveryLoop + transportCosts.getTransportTime(prevAct_deliveryLoop.getLocation(), nextAct_deliveryLoop.getLocation(), prevActEndTime_deliveryLoop, newDriver, newVehicle);
prevActEndTime_deliveryLoop = CalculationUtils.getActivityEndTime(nextActArrTime, nextAct_deliveryLoop);
prevAct_deliveryLoop = nextAct_deliveryLoop;
j++;
}
//update prevAct and endTime
double nextActArrTime = prevActEndTime_deliveryLoop + transportCosts.getTransportTime(prevAct_deliveryLoop.getLocation(), nextAct_deliveryLoop.getLocation(), prevActEndTime_deliveryLoop, newDriver, newVehicle);
prevActEndTime_deliveryLoop = CalculationUtils.getActivityEndTime(nextActArrTime, nextAct_deliveryLoop);
prevAct_deliveryLoop = nextAct_deliveryLoop;
j++;
}
if(pickupInsertionNotFulfilledBreak){
break;
}
//update prevAct and endTime
double nextActArrTime = prevActEndTime + transportCosts.getTransportTime(prevAct.getLocation(), nextAct.getLocation(), prevActEndTime, newDriver, newVehicle);
@ -204,6 +224,10 @@ final class ShipmentInsertionCalculator implements JobInsertionCostsCalculator {
return InsertionData.createEmptyInsertionData();
}
InsertionData insertionData = new InsertionData(bestCost, pickupInsertionIndex, deliveryInsertionIndex, newVehicle, newDriver);
pickupShipment.setTheoreticalEarliestOperationStartTime(bestPickupTimeWindow.getStart());
pickupShipment.setTheoreticalLatestOperationStartTime(bestPickupTimeWindow.getEnd());
deliverShipment.setTheoreticalEarliestOperationStartTime(bestDeliveryTimeWindow.getStart());
deliverShipment.setTheoreticalLatestOperationStartTime(bestDeliveryTimeWindow.getEnd());
insertionData.setVehicleDepartureTime(newVehicleDepartureTime);
insertionData.getEvents().add(new InsertActivity(currentRoute, newVehicle, deliverShipment, deliveryInsertionIndex));
insertionData.getEvents().add(new InsertActivity(currentRoute, newVehicle, pickupShipment, pickupInsertionIndex));

View file

@ -1,28 +0,0 @@
package jsprit.core.algorithm.state;
import jsprit.core.problem.solution.route.activity.TourActivity;
/**
* Created by schroeder on 08/07/15.
*/
public class ActivityStartsAsSoonAsNextTimeWindowOpens implements ActivityStartStrategy {
@Override
public double getActivityStartTime(TourActivity activity, double arrivalTime) {
return Math.max(arrivalTime,activity.getTheoreticalEarliestOperationStartTime());
// TimeWindow last = null;
// for(int i=activity.getTimeWindows().size()-1; i >= 0; i--){
// TimeWindow tw = activity.getTimeWindows().get(i);
// if(tw.getStart() <= arrivalTime && tw.getEnd() >= arrivalTime){
// return arrivalTime;
// }
// else if(arrivalTime > tw.getEnd()){
// if(last != null) return last.getStart();
// else return arrivalTime;
// }
// last = tw;
// }
// return Math.max(arrivalTime,last.getStart());
}
}

View file

@ -66,10 +66,10 @@ public class UpdateActivityTimes implements ActivityVisitor, StateUpdater {
timeTracker.visit(activity);
activity.setArrTime(timeTracker.getActArrTime());
activity.setEndTime(timeTracker.getActEndTime());
double theoreticalLatestOperationStartTime = activity.getTheoreticalLatestOperationStartTime();
if(activity.getArrTime() > theoreticalLatestOperationStartTime){
throw new IllegalStateException("arrTime > latestArrTime");
}
// double theoreticalLatestOperationStartTime = activity.getTheoreticalLatestOperationStartTime();
// if(activity.getArrTime() > theoreticalLatestOperationStartTime){
// throw new IllegalStateException("arrTime > latestArrTime");
// }
}
@Override

View file

@ -1,88 +0,0 @@
/*******************************************************************************
* Copyright (C) 2014 Stefan Schroeder
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
package jsprit.core.algorithm.state;
import jsprit.core.problem.cost.VehicleRoutingTransportCosts;
import jsprit.core.problem.solution.route.VehicleRoute;
import jsprit.core.problem.solution.route.activity.ReverseActivityVisitor;
import jsprit.core.problem.solution.route.activity.TimeWindow;
import jsprit.core.problem.solution.route.activity.TourActivity;
import java.util.Collection;
/**
* Updates and memorizes latest operation start times at activities.
*
* @author schroeder
*/
class UpdatePracticalTimeWindows implements ReverseActivityVisitor, StateUpdater {
private StateManager states;
private VehicleRoute route;
private VehicleRoutingTransportCosts transportCosts;
private double latestArrTimeAtPrevAct;
private TourActivity prevAct;
public UpdatePracticalTimeWindows(StateManager states, VehicleRoutingTransportCosts tpCosts) {
super();
this.states = states;
this.transportCosts = tpCosts;
}
@Override
public void begin(VehicleRoute route) {
this.route = route;
latestArrTimeAtPrevAct = route.getEnd().getTheoreticalLatestOperationStartTime();
prevAct = route.getEnd();
}
@Override
public void visit(TourActivity activity) {
double potentialLatestArrivalTimeAtCurrAct = latestArrTimeAtPrevAct - transportCosts.getBackwardTransportTime(activity.getLocation(), prevAct.getLocation(), latestArrTimeAtPrevAct, route.getDriver(),route.getVehicle()) - activity.getOperationTime();
Collection<TimeWindow> timeWindows = activity.getTimeWindows();
double latestArrivalTime = getLatestArrivalTime(timeWindows,potentialLatestArrivalTimeAtCurrAct);
states.putInternalTypedActivityState(activity, InternalStates.LATEST_OPERATION_START_TIME, latestArrivalTime);
latestArrTimeAtPrevAct = latestArrivalTime;
prevAct = activity;
}
private double getLatestArrivalTime(Collection<TimeWindow> timeWindows, double potentialLatestArrivalTimeAtCurrAct) {
TimeWindow last = null;
for(TimeWindow tw : timeWindows){
if(tw.getStart() <= potentialLatestArrivalTimeAtCurrAct && tw.getEnd() >= potentialLatestArrivalTimeAtCurrAct){
return potentialLatestArrivalTimeAtCurrAct;
}
else if(tw.getStart() > potentialLatestArrivalTimeAtCurrAct){
if(last == null){
return potentialLatestArrivalTimeAtCurrAct;
}
else return last.getEnd();
}
last = tw;
}
return last.getEnd();
}
@Override
public void finish() {
}
}

View file

@ -97,7 +97,8 @@ public class UpdateVehicleDependentPracticalTimeWindows implements RouteVisitor,
Location prevLocation = location_of_prevAct[vehicle.getVehicleTypeIdentifier().getIndex()];
double potentialLatestArrivalTimeAtCurrAct = latestArrTimeAtPrevAct - transportCosts.getBackwardTransportTime(activity.getLocation(), prevLocation,
latestArrTimeAtPrevAct, route.getDriver(), vehicle) - activity.getOperationTime();
double latestArrivalTime = getLatestArrivalTime(activity.getTimeWindows(), potentialLatestArrivalTimeAtCurrAct);
double latestArrivalTime = Math.min(activity.getTheoreticalLatestOperationStartTime(), potentialLatestArrivalTimeAtCurrAct);
// getLatestArrivalTime(activity.getTimeWindows(), potentialLatestArrivalTimeAtCurrAct);
if (latestArrivalTime < activity.getTheoreticalEarliestOperationStartTime()) {
stateManager.putTypedInternalRouteState(route, vehicle, InternalStates.SWITCH_NOT_FEASIBLE, true);
}

View file

@ -42,21 +42,11 @@ public class VehicleDependentTimeWindowConstraints implements HardActivityConstr
this.routingCosts = routingCosts;
}
public double getLatestOperationStartTime(TourActivity act){
return act.getTimeWindows().get(act.getTimeWindows().size()-1).getEnd();
}
public double getEarliestOperationStartTime(TourActivity act){
return act.getTimeWindows().get(0).getStart();
}
@Override
public ConstraintsStatus fulfilled(JobInsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
double latestVehicleArrival = iFacts.getNewVehicle().getLatestArrival();
Double latestArrTimeAtNextAct;
Location nextActLocation;
// double nextAct_theoreticalLatestOperationStartTime = getLatestOperationStartTime(nextAct);
if (nextAct instanceof End) {
latestArrTimeAtNextAct = latestVehicleArrival;
nextActLocation = iFacts.getNewVehicle().getEndLocation();
@ -64,15 +54,9 @@ public class VehicleDependentTimeWindowConstraints implements HardActivityConstr
nextActLocation = newAct.getLocation();
}
} else {
//try to get latest_operation_start_time of newVehicle
latestArrTimeAtNextAct = states.getActivityState(nextAct, iFacts.getNewVehicle(), InternalStates.LATEST_OPERATION_START_TIME, Double.class);
// if(latestArrTimeAtNextAct == null) //try to get latest_operation_start_time of currVehicle
// latestArrTimeAtNextAct = states.getActivityState(nextAct, iFacts.getRoute().getVehicle(), StateFactory.LATEST_OPERATION_START_TIME ,Double.class);
if (latestArrTimeAtNextAct == null) {//otherwise set it to theoretical_latest_operation_startTime
latestArrTimeAtNextAct = nextAct.getTheoreticalLatestOperationStartTime();
// latestArrTimeAtNextAct = nextAct_theoreticalLatestOperationStartTime;
// throw new IllegalStateException("this is strange and should not be");
//ToDo here, there should be another solution
}
nextActLocation = nextAct.getLocation();
}
@ -84,11 +68,7 @@ public class VehicleDependentTimeWindowConstraints implements HardActivityConstr
* |--- vehicle's operation time ---|
* |--- prevAct or newAct or nextAct ---|
*/
// double prevAct_theoreticalEarliestOperationStartTime = getEarliestOperationStartTime(prevAct);
double newAct_theoreticalEarliestOperationStartTime = newAct.getTheoreticalEarliestOperationStartTime();
// newAct.getTheoreticalEarliestOperationStartTime();
// double nextAct_theoreticalEarliestOperationStartTime = getEarliestOperationStartTime(nextAct);
// nextAct.getTheoreticalEarliestOperationStartTime();
if (latestVehicleArrival < prevAct.getTheoreticalEarliestOperationStartTime() ||
latestVehicleArrival < newAct_theoreticalEarliestOperationStartTime ||

View file

@ -82,14 +82,14 @@ public class Service extends AbstractJob {
protected Location location;
protected TimeWindows timeWindows = new TimeWindowsImpl();
protected TimeWindowsImpl timeWindows;
private boolean twAdded = false;
Builder(String id){
this.id = id;
timeWindows = new TimeWindowsImpl();
((TimeWindowsImpl)timeWindows).add(timeWindow);
timeWindows.add(timeWindow);
}
/**
@ -133,11 +133,6 @@ public class Service extends AbstractJob {
return this;
}
public Builder<T> setTimeWindows(TimeWindows timeWindows){
this.timeWindows = timeWindows;
return this;
}
/**
* Adds capacity dimension.
*
@ -156,7 +151,7 @@ public class Service extends AbstractJob {
if(tw == null) throw new IllegalArgumentException("time-window arg must not be null");
this.timeWindow = tw;
this.timeWindows = new TimeWindowsImpl();
((TimeWindowsImpl) timeWindows).add(tw);
timeWindows.add(tw);
return this;
}
@ -166,15 +161,7 @@ public class Service extends AbstractJob {
timeWindows = new TimeWindowsImpl();
twAdded = true;
}
for(TimeWindow tw : ((TimeWindowsImpl)timeWindows).getTimeWindows()){
if(timeWindow.getStart() > tw.getStart() && timeWindow.getStart() < tw.getEnd()){
throw new IllegalStateException("time-windows cannot overlap each other. overlap: " + tw + ", " + timeWindow);
}
if(timeWindow.getEnd() > tw.getStart() && timeWindow.getEnd() < tw.getEnd()){
throw new IllegalStateException("time-windows cannot overlap each other. overlap: " + tw + ", " + timeWindow);
}
}
((TimeWindowsImpl) timeWindows).add(timeWindow);
timeWindows.add(timeWindow);
return this;
}
@ -251,8 +238,8 @@ public class Service extends AbstractJob {
timeWindowManager = builder.timeWindows;
}
public Collection<TimeWindow> getTimeWindows(double arrTime){
return timeWindowManager.getTimeWindows(arrTime);
public Collection<TimeWindow> getTimeWindows(){
return timeWindowManager.getTimeWindows();
}
@Override
@ -281,11 +268,13 @@ public class Service extends AbstractJob {
/**
* Returns the time-window a service(-operation) is allowed to start.
* It is recommended to use getTimeWindows() instead. If you still use this, it returns the first time window of getTimeWindows() collection.
*
* @return time window
*
*/
public TimeWindow getTimeWindow() {
return timeWindow;
return timeWindowManager.getTimeWindows().iterator().next();
}
/**

View file

@ -21,6 +21,9 @@ import jsprit.core.problem.Capacity;
import jsprit.core.problem.Location;
import jsprit.core.problem.Skills;
import jsprit.core.problem.solution.route.activity.TimeWindow;
import jsprit.core.problem.solution.route.activity.TimeWindowsImpl;
import java.util.Collection;
/**
@ -42,6 +45,7 @@ import jsprit.core.problem.solution.route.activity.TimeWindow;
public class Shipment extends AbstractJob {
/**
* Builder that builds the shipment.
*
@ -73,6 +77,14 @@ public class Shipment extends AbstractJob {
private Location deliveryLocation_;
protected TimeWindowsImpl deliveryTimeWindows;
private boolean deliveryTimeWindowAdded = false;
private boolean pickupTimeWindowAdded = false;
private TimeWindowsImpl pickupTimeWindows;
/**
* Returns new instance of this builder.
*
@ -86,6 +98,10 @@ public class Shipment extends AbstractJob {
Builder(String id) {
if (id == null) throw new IllegalArgumentException("id must not be null");
this.id = id;
pickupTimeWindows = new TimeWindowsImpl();
pickupTimeWindows.add(pickupTimeWindow);
deliveryTimeWindows = new TimeWindowsImpl();
deliveryTimeWindows.add(deliveryTimeWindow);
}
/**
@ -125,11 +141,15 @@ public class Shipment extends AbstractJob {
* @throws IllegalArgumentException if timeWindow is null
*/
public Builder setPickupTimeWindow(TimeWindow timeWindow) {
if (timeWindow == null) throw new IllegalArgumentException("timeWindow cannot be null");
if (timeWindow == null) throw new IllegalArgumentException("delivery time-window must not be null");
this.pickupTimeWindow = timeWindow;
this.pickupTimeWindows = new TimeWindowsImpl();
this.pickupTimeWindows.add(timeWindow);
return this;
}
/**
* Sets delivery location.
*
@ -169,6 +189,8 @@ public class Shipment extends AbstractJob {
public Builder setDeliveryTimeWindow(TimeWindow timeWindow) {
if (timeWindow == null) throw new IllegalArgumentException("delivery time-window must not be null");
this.deliveryTimeWindow = timeWindow;
this.deliveryTimeWindows = new TimeWindowsImpl();
this.deliveryTimeWindows.add(timeWindow);
return this;
}
@ -212,6 +234,35 @@ public class Shipment extends AbstractJob {
this.name = name;
return this;
}
public Builder addDeliveryTimeWindow(TimeWindow timeWindow) {
if(timeWindow == null) throw new IllegalArgumentException("time-window arg must not be null");
if(!deliveryTimeWindowAdded){
deliveryTimeWindows = new TimeWindowsImpl();
deliveryTimeWindowAdded = true;
}
deliveryTimeWindows.add(timeWindow);
return this;
}
public Builder addDeliveryTimeWindow(double earliest, double latest) {
addDeliveryTimeWindow(TimeWindow.newInstance(earliest, latest));
return this;
}
public Builder addPickupTimeWindow(TimeWindow timeWindow) {
if(timeWindow == null) throw new IllegalArgumentException("time-window arg must not be null");
if(!pickupTimeWindowAdded){
pickupTimeWindows = new TimeWindowsImpl();
pickupTimeWindowAdded = true;
}
pickupTimeWindows.add(timeWindow);
return this;
}
public Builder addPickupTimeWindow(double earliest, double latest) {
return addPickupTimeWindow(TimeWindow.newInstance(earliest, latest));
}
}
private final String id;
@ -234,6 +285,10 @@ public class Shipment extends AbstractJob {
private final Location deliveryLocation_;
private final TimeWindowsImpl deliveryTimeWindows;
private final TimeWindowsImpl pickupTimeWindows;
Shipment(Builder builder) {
this.id = builder.id;
this.pickupServiceTime = builder.pickupServiceTime;
@ -245,6 +300,8 @@ public class Shipment extends AbstractJob {
this.name = builder.name;
this.pickupLocation_ = builder.pickupLocation_;
this.deliveryLocation_ = builder.deliveryLocation_;
this.deliveryTimeWindows = builder.deliveryTimeWindows;
this.pickupTimeWindows = builder.pickupTimeWindows;
}
@Override
@ -286,7 +343,11 @@ public class Shipment extends AbstractJob {
* @return time-window of delivery
*/
public TimeWindow getDeliveryTimeWindow() {
return deliveryTimeWindow;
return deliveryTimeWindows.getTimeWindows().iterator().next();
}
public Collection<TimeWindow> getDeliveryTimeWindows() {
return deliveryTimeWindows.getTimeWindows();
}
/**
@ -295,9 +356,14 @@ public class Shipment extends AbstractJob {
* @return time-window of pickup
*/
public TimeWindow getPickupTimeWindow() {
return pickupTimeWindow;
return pickupTimeWindows.getTimeWindows().iterator().next();
}
public Collection<TimeWindow> getPickupTimeWindows() {
return pickupTimeWindows.getTimeWindows();
}
@Override
public int hashCode() {
final int prime = 31;

View file

@ -212,7 +212,8 @@ public class VehicleRoute {
}
/**
* Adds a service to this route.
* Adds a service to this route. Activity is initialized with .getTimeWindow(). If you want to explicitly set another time window
* use .addService(Service service, TimeWindow timeWindow)
* <p/>
* <p>This implies that for this service a serviceActivity is created with {@link TourActivityFactory} and added to the sequence of tourActivities.
* <p/>
@ -223,9 +224,15 @@ public class VehicleRoute {
* @throws IllegalArgumentException if service is null
*/
public Builder addService(Service service) {
return addService(service,service.getTimeWindow());
}
public Builder addService(Service service, TimeWindow timeWindow) {
if (service == null) throw new IllegalArgumentException("service must not be null");
List<AbstractActivity> acts = jobActivityFactory.createActivities(service);
TourActivity act = acts.get(0);
act.setTheoreticalEarliestOperationStartTime(timeWindow.getStart());
act.setTheoreticalLatestOperationStartTime(timeWindow.getEnd());
tourActivities.addActivity(act);
return this;
}
@ -238,8 +245,12 @@ public class VehicleRoute {
*/
public Builder addPickup(Pickup pickup) {
if (pickup == null) throw new IllegalArgumentException("pickup must not be null");
addService(pickup);
return this;
return addService(pickup);
}
public Builder addPickup(Pickup pickup, TimeWindow timeWindow) {
if (pickup == null) throw new IllegalArgumentException("pickup must not be null");
return addService(pickup,timeWindow);
}
/**
@ -250,8 +261,12 @@ public class VehicleRoute {
*/
public Builder addDelivery(Delivery delivery) {
if (delivery == null) throw new IllegalArgumentException("delivery must not be null");
addService(delivery);
return this;
return addService(delivery);
}
public Builder addDelivery(Delivery delivery, TimeWindow timeWindow) {
if (delivery == null) throw new IllegalArgumentException("delivery must not be null");
return addService(delivery,timeWindow);
}
/**
@ -262,10 +277,16 @@ public class VehicleRoute {
* @throws IllegalStateException if method has already been called with the specified shipment.
*/
public Builder addPickup(Shipment shipment) {
return addPickup(shipment, shipment.getPickupTimeWindow());
}
public Builder addPickup(Shipment shipment, TimeWindow pickupTimeWindow) {
if (openShipments.contains(shipment))
throw new IllegalStateException("shipment has already been added. cannot add it twice.");
List<AbstractActivity> acts = jobActivityFactory.createActivities(shipment);
TourActivity act = acts.get(0);
act.setTheoreticalEarliestOperationStartTime(pickupTimeWindow.getStart());
act.setTheoreticalLatestOperationStartTime(pickupTimeWindow.getEnd());
tourActivities.addActivity(act);
openShipments.add(shipment);
openActivities.put(shipment, acts.get(1));
@ -280,8 +301,14 @@ public class VehicleRoute {
* @throws IllegalStateException if specified shipment has not been picked up yet (i.e. method addPickup(shipment) has not been called yet).
*/
public Builder addDelivery(Shipment shipment) {
return addDelivery(shipment,shipment.getDeliveryTimeWindow());
}
public Builder addDelivery(Shipment shipment, TimeWindow deliveryTimeWindow) {
if (openShipments.contains(shipment)) {
TourActivity act = openActivities.get(shipment);
act.setTheoreticalEarliestOperationStartTime(deliveryTimeWindow.getStart());
act.setTheoreticalLatestOperationStartTime(deliveryTimeWindow.getEnd());
tourActivities.addActivity(act);
openShipments.remove(shipment);
} else {

View file

@ -1,6 +1,4 @@
package jsprit.core.algorithm.state;
import jsprit.core.problem.solution.route.activity.TourActivity;
package jsprit.core.problem.solution.route.activity;
/**
* Created by schroeder on 08/07/15.

View file

@ -1,6 +1,4 @@
package jsprit.core.algorithm.state;
import jsprit.core.problem.solution.route.activity.TourActivity;
package jsprit.core.problem.solution.route.activity;
/**
* Created by schroeder on 08/07/15.

View file

@ -1,6 +1,4 @@
package jsprit.core.algorithm.state;
import jsprit.core.problem.solution.route.activity.TourActivity;
package jsprit.core.problem.solution.route.activity;
/**
* Created by schroeder on 08/07/15.

View file

@ -23,8 +23,6 @@ import jsprit.core.problem.job.Break;
import jsprit.core.problem.job.Service;
import jsprit.core.problem.solution.route.activity.TourActivity.JobActivity;
import java.util.List;
public class BreakActivity extends AbstractActivity implements JobActivity {
public static int counter = 0;
@ -73,9 +71,9 @@ public class BreakActivity extends AbstractActivity implements JobActivity {
private final Break aBreak;
private double earliest;
private double earliest = 0;
private double latest;
private double latest = Double.MAX_VALUE;
protected BreakActivity(Break aBreak) {
counter++;
@ -89,6 +87,8 @@ public class BreakActivity extends AbstractActivity implements JobActivity {
this.endTime = breakActivity.getEndTime();
this.location = breakActivity.getLocation();
setIndex(breakActivity.getIndex());
this.earliest = breakActivity.getTheoreticalEarliestOperationStartTime();
this.latest = breakActivity.getTheoreticalLatestOperationStartTime();
}
@ -174,11 +174,6 @@ public class BreakActivity extends AbstractActivity implements JobActivity {
this.latest = latest;
}
@Override
public List<TimeWindow> getTimeWindows() {
return null;
}
@Override
public String getName() {
return aBreak.getType();

View file

@ -21,9 +21,6 @@ import jsprit.core.problem.Capacity;
import jsprit.core.problem.Location;
import jsprit.core.problem.job.Delivery;
import java.util.ArrayList;
import java.util.List;
public final class DeliverService extends AbstractActivity implements DeliveryActivity {
private Delivery delivery;
@ -34,17 +31,14 @@ public final class DeliverService extends AbstractActivity implements DeliveryAc
private double endTime;
private double theoreticalEarliest;
private double theoreticalEarliest = 0;
private double theoreticalLatest;
private List<TimeWindow> timeWindows;
private double theoreticalLatest = Double.MAX_VALUE;
public DeliverService(Delivery delivery) {
super();
this.delivery = delivery;
capacity = Capacity.invert(delivery.getSize());
timeWindows = new ArrayList<TimeWindow>(delivery.getTimeWindows(0.));
}
private DeliverService(DeliverService deliveryActivity) {
@ -53,7 +47,6 @@ public final class DeliverService extends AbstractActivity implements DeliveryAc
this.endTime = deliveryActivity.getEndTime();
capacity = deliveryActivity.getSize();
setIndex(deliveryActivity.getIndex());
timeWindows = new ArrayList<TimeWindow>(delivery.getTimeWindows(0.));
this.theoreticalEarliest = deliveryActivity.getTheoreticalEarliestOperationStartTime();
this.theoreticalLatest = deliveryActivity.getTheoreticalLatestOperationStartTime();
}
@ -83,10 +76,6 @@ public final class DeliverService extends AbstractActivity implements DeliveryAc
theoreticalLatest = latest;
}
@Override
public List<TimeWindow> getTimeWindows() {
return timeWindows;
}
@Override
public double getTheoreticalEarliestOperationStartTime() {

View file

@ -22,8 +22,6 @@ import jsprit.core.problem.Location;
import jsprit.core.problem.job.Job;
import jsprit.core.problem.job.Shipment;
import java.util.List;
public final class DeliverShipment extends AbstractActivity implements DeliveryActivity {
private Shipment shipment;
@ -34,6 +32,10 @@ public final class DeliverShipment extends AbstractActivity implements DeliveryA
private Capacity capacity;
private double earliest = 0;
private double latest = Double.MAX_VALUE;
public DeliverShipment(Shipment shipment) {
super();
this.shipment = shipment;
@ -47,6 +49,8 @@ public final class DeliverShipment extends AbstractActivity implements DeliveryA
this.endTime = deliveryShipmentActivity.getEndTime();
this.capacity = deliveryShipmentActivity.getSize();
setIndex(deliveryShipmentActivity.getIndex());
this.earliest = deliveryShipmentActivity.getTheoreticalEarliestOperationStartTime();
this.latest = deliveryShipmentActivity.getTheoreticalLatestOperationStartTime();
}
@Override
@ -56,18 +60,12 @@ public final class DeliverShipment extends AbstractActivity implements DeliveryA
@Override
public void setTheoreticalEarliestOperationStartTime(double earliest) {
this.earliest = earliest;
}
@Override
public void setTheoreticalLatestOperationStartTime(double latest) {
}
@Override
public List<TimeWindow> getTimeWindows() {
// return shipment.getDeliveryTimeWindow();
return null;
this.latest = latest;
}
@Override
@ -87,12 +85,12 @@ public final class DeliverShipment extends AbstractActivity implements DeliveryA
@Override
public double getTheoreticalEarliestOperationStartTime() {
return shipment.getDeliveryTimeWindow().getStart();
return earliest;
}
@Override
public double getTheoreticalLatestOperationStartTime() {
return shipment.getDeliveryTimeWindow().getEnd();
return latest;
}
@Override

View file

@ -21,9 +21,6 @@ import jsprit.core.problem.Capacity;
import jsprit.core.problem.Location;
import jsprit.core.util.Coordinate;
import java.util.Arrays;
import java.util.List;
public final class End extends AbstractActivity implements TourActivity {
@Deprecated
@ -71,11 +68,6 @@ public final class End extends AbstractActivity implements TourActivity {
theoretical_latestOperationStartTime = theoreticalLatestOperationStartTime;
}
@Override
public List<TimeWindow> getTimeWindows() {
return Arrays.asList(TimeWindow.newInstance(theoretical_earliestOperationStartTime,theoretical_latestOperationStartTime));
}
public End(Location location, double theoreticalStart, double theoreticalEnd) {
super();
this.location = location;

View file

@ -22,9 +22,6 @@ import jsprit.core.problem.Location;
import jsprit.core.problem.job.Pickup;
import jsprit.core.problem.job.Service;
import java.util.ArrayList;
import java.util.List;
public final class PickupService extends AbstractActivity implements PickupActivity {
private Service pickup;
@ -33,22 +30,17 @@ public final class PickupService extends AbstractActivity implements PickupActiv
private double depTime;
private double theoreticalEarliest;
private double theoreticalLatest;
private List<TimeWindow> timeWindows;
private double theoreticalEarliest = 0;
private double theoreticalLatest = Double.MAX_VALUE;
public PickupService(Pickup pickup) {
super();
this.pickup = pickup;
timeWindows = new ArrayList<TimeWindow>(pickup.getTimeWindows(0.));
}
public PickupService(Service service) {
this.pickup = service;
timeWindows = new ArrayList<TimeWindow>(service.getTimeWindows(0.));
}
private PickupService(PickupService pickupActivity) {
@ -56,7 +48,6 @@ public final class PickupService extends AbstractActivity implements PickupActiv
this.arrTime = pickupActivity.getArrTime();
this.depTime = pickupActivity.getEndTime();
setIndex(pickupActivity.getIndex());
timeWindows = new ArrayList<TimeWindow>(pickup.getTimeWindows(0.));
this.theoreticalEarliest = pickupActivity.getTheoreticalEarliestOperationStartTime();
this.theoreticalLatest = pickupActivity.getTheoreticalLatestOperationStartTime();
}
@ -96,11 +87,6 @@ public final class PickupService extends AbstractActivity implements PickupActiv
this.theoreticalLatest = latest;
}
@Override
public List<TimeWindow> getTimeWindows() {
return timeWindows;
}
@Override
public double getOperationTime() {
return pickup.getServiceDuration();

View file

@ -22,8 +22,6 @@ import jsprit.core.problem.Location;
import jsprit.core.problem.job.Job;
import jsprit.core.problem.job.Shipment;
import java.util.List;
public final class PickupShipment extends AbstractActivity implements PickupActivity{
private Shipment shipment;
@ -32,6 +30,10 @@ public final class PickupShipment extends AbstractActivity implements PickupActi
private double arrTime;
private double earliest = 0;
private double latest = Double.MAX_VALUE;
public PickupShipment(Shipment shipment) {
super();
this.shipment = shipment;
@ -43,6 +45,8 @@ public final class PickupShipment extends AbstractActivity implements PickupActi
this.arrTime = pickupShipmentActivity.getArrTime();
this.endTime = pickupShipmentActivity.getEndTime();
setIndex(pickupShipmentActivity.getIndex());
this.earliest = pickupShipmentActivity.getTheoreticalEarliestOperationStartTime();
this.latest = pickupShipmentActivity.getTheoreticalLatestOperationStartTime();
}
@Override
@ -52,17 +56,12 @@ public final class PickupShipment extends AbstractActivity implements PickupActi
@Override
public void setTheoreticalEarliestOperationStartTime(double earliest) {
this.earliest = earliest;
}
@Override
public void setTheoreticalLatestOperationStartTime(double latest) {
}
@Override
public List<TimeWindow> getTimeWindows() {
return null;
this.latest = latest;
}
@Override
@ -82,12 +81,12 @@ public final class PickupShipment extends AbstractActivity implements PickupActi
@Override
public double getTheoreticalEarliestOperationStartTime() {
return shipment.getPickupTimeWindow().getStart();
return earliest;
}
@Override
public double getTheoreticalLatestOperationStartTime() {
return shipment.getPickupTimeWindow().getEnd();
return latest;
}
@Override

View file

@ -82,7 +82,7 @@ public class ServiceActivity extends AbstractActivity implements JobActivity {
protected ServiceActivity(Service service) {
counter++;
this.service = service;
timeWindows = new ArrayList<TimeWindow>(service.getTimeWindows(0.));
timeWindows = new ArrayList<TimeWindow>(service.getTimeWindows());
}
protected ServiceActivity(ServiceActivity serviceActivity) {
@ -91,7 +91,6 @@ public class ServiceActivity extends AbstractActivity implements JobActivity {
this.arrTime = serviceActivity.getArrTime();
this.endTime = serviceActivity.getEndTime();
setIndex(serviceActivity.getIndex());
timeWindows = new ArrayList<TimeWindow>(serviceActivity.getTimeWindows());
this.theoreticalEarliest = serviceActivity.getTheoreticalEarliestOperationStartTime();
this.theoreticalLatest = serviceActivity.getTheoreticalLatestOperationStartTime();
}
@ -146,11 +145,6 @@ public class ServiceActivity extends AbstractActivity implements JobActivity {
theoreticalLatest = latest;
}
@Override
public List<TimeWindow> getTimeWindows() {
return timeWindows;
}
@Override
public double getOperationTime() {
return service.getServiceDuration();

View file

@ -20,9 +20,6 @@ import jsprit.core.problem.AbstractActivity;
import jsprit.core.problem.Capacity;
import jsprit.core.problem.Location;
import java.util.Arrays;
import java.util.List;
public final class Start extends AbstractActivity implements TourActivity {
public final static String ACTIVITY_NAME = "start";
@ -110,12 +107,6 @@ public final class Start extends AbstractActivity implements TourActivity {
this.theoretical_latestOperationStartTime = time;
}
@Override
public List<TimeWindow> getTimeWindows() {
return Arrays.asList(TimeWindow.newInstance(theoretical_earliestOperationStartTime,theoretical_latestOperationStartTime));
}
@Deprecated
@Override
public String getLocationId() {

View file

@ -7,6 +7,6 @@ import java.util.Collection;
*/
public interface TimeWindows {
public Collection<TimeWindow> getTimeWindows(double time);
public Collection<TimeWindow> getTimeWindows();
}

View file

@ -12,6 +12,14 @@ public class TimeWindowsImpl implements TimeWindows {
private Collection<TimeWindow> timeWindows = new ArrayList<TimeWindow>();
public void add(TimeWindow timeWindow){
for(TimeWindow tw : timeWindows){
if(timeWindow.getStart() > tw.getStart() && timeWindow.getStart() < tw.getEnd()){
throw new IllegalStateException("time-windows cannot overlap each other. overlap: " + tw + ", " + timeWindow);
}
if(timeWindow.getEnd() > tw.getStart() && timeWindow.getEnd() < tw.getEnd()){
throw new IllegalStateException("time-windows cannot overlap each other. overlap: " + tw + ", " + timeWindow);
}
}
timeWindows.add(timeWindow);
}
@ -19,9 +27,4 @@ public class TimeWindowsImpl implements TimeWindows {
return Collections.unmodifiableCollection(timeWindows);
}
@Override
public Collection<TimeWindow> getTimeWindows(double time) {
return Collections.unmodifiableCollection(timeWindows);
}
}

View file

@ -21,8 +21,6 @@ import jsprit.core.problem.HasIndex;
import jsprit.core.problem.Location;
import jsprit.core.problem.job.Job;
import java.util.List;
/**
* Basic interface for tour-activities.
* <p/>
@ -36,8 +34,6 @@ public interface TourActivity extends HasIndex {
public void setTheoreticalLatestOperationStartTime(double latest);
public List<TimeWindow> getTimeWindows();
/**
* Basic interface of job-activies.
* <p/>

View file

@ -16,13 +16,9 @@
******************************************************************************/
package jsprit.core.util;
import jsprit.core.algorithm.state.ActivityStartAsSoonAsArrived;
import jsprit.core.algorithm.state.ActivityStartStrategy;
import jsprit.core.algorithm.state.ActivityStartsAsSoonAsNextTimeWindowOpens;
import jsprit.core.problem.cost.ForwardTransportTime;
import jsprit.core.problem.solution.route.VehicleRoute;
import jsprit.core.problem.solution.route.activity.ActivityVisitor;
import jsprit.core.problem.solution.route.activity.TourActivity;
import jsprit.core.problem.solution.route.activity.*;
public class ActivityTimeTracker implements ActivityVisitor {
@ -51,7 +47,7 @@ public class ActivityTimeTracker implements ActivityVisitor {
public ActivityTimeTracker(ForwardTransportTime transportTime) {
super();
this.transportTime = transportTime;
this.startStrategy = new ActivityStartsAsSoonAsNextTimeWindowOpens();
this.startStrategy = new ActivityStartsAsSoonAsTimeWindowOpens();
}
public ActivityTimeTracker(ForwardTransportTime transportTime, ActivityPolicy activityPolicy) {
@ -60,7 +56,7 @@ public class ActivityTimeTracker implements ActivityVisitor {
if(activityPolicy.equals(ActivityPolicy.AS_SOON_AS_ARRIVED)){
this.startStrategy = new ActivityStartAsSoonAsArrived();
}
else this.startStrategy = new ActivityStartsAsSoonAsNextTimeWindowOpens();
else this.startStrategy = new ActivityStartsAsSoonAsTimeWindowOpens();
}
public ActivityTimeTracker(ForwardTransportTime transportTime, ActivityStartStrategy startStrategy) {
@ -92,7 +88,6 @@ public class ActivityTimeTracker implements ActivityVisitor {
double transportTime = this.transportTime.getTransportTime(prevAct.getLocation(), activity.getLocation(), startAtPrevAct, route.getDriver(), route.getVehicle());
double arrivalTimeAtCurrAct = startAtPrevAct + transportTime;
actArrTime = arrivalTimeAtCurrAct;
assert actArrTime <= activity.getTimeWindows().get(activity.getTimeWindows().size()-1).getEnd() : "that should not be";
double operationEndTime = startStrategy.getActivityStartTime(activity,arrivalTimeAtCurrAct) + activity.getOperationTime();
actEndTime = operationEndTime;
prevAct = activity;
@ -104,7 +99,6 @@ public class ActivityTimeTracker implements ActivityVisitor {
double transportTime = this.transportTime.getTransportTime(prevAct.getLocation(), route.getEnd().getLocation(), startAtPrevAct, route.getDriver(), route.getVehicle());
double arrivalTimeAtCurrAct = startAtPrevAct + transportTime;
actArrTime = arrivalTimeAtCurrAct;
assert actArrTime <= route.getVehicle().getLatestArrival() : "oohh. this should not be";
actEndTime = arrivalTimeAtCurrAct;
beginFirst = false;
}

View file

@ -18,7 +18,6 @@
package jsprit.core.util;
import jsprit.core.algorithm.state.ActivityStartsAsSoonAsNextTimeWindowOpens;
import jsprit.core.problem.solution.route.activity.TourActivity;
public class CalculationUtils {
@ -32,7 +31,6 @@ public class CalculationUtils {
* @return
*/
public static double getActivityEndTime(double actArrTime, TourActivity act){
return new ActivityStartsAsSoonAsNextTimeWindowOpens().getActivityStartTime(act, actArrTime) + act.getOperationTime();
// return Math.max(actArrTime, act.getTheoreticalEarliestOperationStartTime()) + act.getOperationTime();
return Math.max(actArrTime, act.getTheoreticalEarliestOperationStartTime()) + act.getOperationTime();
}
}