mirror of
https://github.com/graphhopper/jsprit.git
synced 2020-01-24 07:45:05 +01:00
Switch to Activity- and RouteVisitor
This commit is contained in:
parent
8c8f041933
commit
a32d8c1c6a
14 changed files with 447 additions and 226 deletions
|
|
@ -0,0 +1,82 @@
|
|||
package algorithms;
|
||||
|
||||
import basics.costs.ForwardTransportTime;
|
||||
import basics.route.Driver;
|
||||
import basics.route.TourActivity;
|
||||
import basics.route.Vehicle;
|
||||
import basics.route.VehicleRoute;
|
||||
|
||||
class ActivityTimeTracker implements ActivityVisitor{
|
||||
|
||||
private ForwardTransportTime transportTime;
|
||||
|
||||
private TourActivity prevAct = null;
|
||||
|
||||
private double startAtPrevAct;
|
||||
|
||||
private VehicleRoute route;
|
||||
|
||||
private boolean beginFirst = false;
|
||||
|
||||
private double actArrTime;
|
||||
|
||||
private double actEndTime;
|
||||
|
||||
public ActivityTimeTracker(ForwardTransportTime transportTime) {
|
||||
super();
|
||||
this.transportTime = transportTime;
|
||||
}
|
||||
|
||||
public double getActArrTime(){
|
||||
return actArrTime;
|
||||
}
|
||||
|
||||
public double getActEndTime(){
|
||||
return actEndTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void begin(VehicleRoute route) {
|
||||
prevAct = route.getStart();
|
||||
startAtPrevAct = prevAct.getEndTime();
|
||||
|
||||
actEndTime = startAtPrevAct;
|
||||
|
||||
this.route = route;
|
||||
|
||||
beginFirst = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(TourActivity activity) {
|
||||
if(!beginFirst) throw new IllegalStateException("never called begin. this however is essential here");
|
||||
double transportTime = this.transportTime.getTransportTime(prevAct.getLocationId(), activity.getLocationId(), startAtPrevAct, route.getDriver(), route.getVehicle());
|
||||
double arrivalTimeAtCurrAct = startAtPrevAct + transportTime;
|
||||
|
||||
actArrTime = arrivalTimeAtCurrAct;
|
||||
|
||||
double operationStartTime = Math.max(activity.getTheoreticalEarliestOperationStartTime(), arrivalTimeAtCurrAct);
|
||||
double operationEndTime = operationStartTime + activity.getOperationTime();
|
||||
|
||||
actEndTime = operationEndTime;
|
||||
|
||||
prevAct = activity;
|
||||
startAtPrevAct = operationEndTime;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish() {
|
||||
double transportTime = this.transportTime.getTransportTime(prevAct.getLocationId(), route.getEnd().getLocationId(), startAtPrevAct, route.getDriver(), route.getVehicle());
|
||||
double arrivalTimeAtCurrAct = startAtPrevAct + transportTime;
|
||||
|
||||
actArrTime = arrivalTimeAtCurrAct;
|
||||
actEndTime = arrivalTimeAtCurrAct;
|
||||
|
||||
beginFirst = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
14
jsprit-core/src/main/java/algorithms/ActivityVisitor.java
Normal file
14
jsprit-core/src/main/java/algorithms/ActivityVisitor.java
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
package algorithms;
|
||||
|
||||
import basics.route.TourActivity;
|
||||
import basics.route.VehicleRoute;
|
||||
|
||||
interface ActivityVisitor {
|
||||
|
||||
public void begin(VehicleRoute route);
|
||||
|
||||
public void visit(TourActivity activity);
|
||||
|
||||
public void finish();
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
package algorithms;
|
||||
|
||||
import basics.route.TourActivity;
|
||||
import basics.route.VehicleRoute;
|
||||
|
||||
interface ReverseActivityVisitor {
|
||||
|
||||
public void begin(VehicleRoute route);
|
||||
|
||||
public void visit(TourActivity activity);
|
||||
|
||||
public void finish();
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
package algorithms;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
import basics.route.TourActivity;
|
||||
import basics.route.VehicleRoute;
|
||||
|
||||
class ReverseRouteActivityVisitor implements RouteVisitor{
|
||||
|
||||
private Collection<ReverseActivityVisitor> visitors = new ArrayList<ReverseActivityVisitor>();
|
||||
|
||||
@Override
|
||||
public void visit(VehicleRoute route) {
|
||||
if(visitors.isEmpty()) return;
|
||||
begin(route);
|
||||
Iterator<TourActivity> revIterator = route.getTourActivities().reverseActivityIterator();
|
||||
while(revIterator.hasNext()){
|
||||
TourActivity act = revIterator.next();
|
||||
visit(act);
|
||||
}
|
||||
finish(route);
|
||||
}
|
||||
|
||||
private void finish(VehicleRoute route) {
|
||||
for(ReverseActivityVisitor visitor : visitors){
|
||||
visitor.finish();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void visit(TourActivity act) {
|
||||
for(ReverseActivityVisitor visitor : visitors){
|
||||
visitor.visit(act);
|
||||
}
|
||||
}
|
||||
|
||||
private void begin(VehicleRoute route) {
|
||||
for(ReverseActivityVisitor visitor : visitors){
|
||||
visitor.begin(route);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void addActivityVisitor(ReverseActivityVisitor activityVisitor){
|
||||
visitors.add(activityVisitor);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
package algorithms;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
import basics.route.TourActivity;
|
||||
import basics.route.VehicleRoute;
|
||||
|
||||
class RouteActivityVisitor implements RouteVisitor{
|
||||
|
||||
private Collection<ActivityVisitor> visitors = new ArrayList<ActivityVisitor>();
|
||||
|
||||
@Override
|
||||
public void visit(VehicleRoute route) {
|
||||
if(visitors.isEmpty()) return;
|
||||
begin(route);
|
||||
for(TourActivity act : route.getTourActivities().getActivities()){
|
||||
visit(act);
|
||||
}
|
||||
end(route);
|
||||
}
|
||||
|
||||
private void end(VehicleRoute route) {
|
||||
for(ActivityVisitor visitor : visitors){
|
||||
visitor.finish();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void visit(TourActivity act) {
|
||||
for(ActivityVisitor visitor : visitors){
|
||||
visitor.visit(act);
|
||||
}
|
||||
}
|
||||
|
||||
private void begin(VehicleRoute route) {
|
||||
for(ActivityVisitor visitor : visitors){
|
||||
visitor.begin(route);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void addActivityVisitor(ActivityVisitor activityVisitor){
|
||||
visitors.add(activityVisitor);
|
||||
}
|
||||
}
|
||||
9
jsprit-core/src/main/java/algorithms/RouteVisitor.java
Normal file
9
jsprit-core/src/main/java/algorithms/RouteVisitor.java
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
package algorithms;
|
||||
|
||||
import basics.route.VehicleRoute;
|
||||
|
||||
interface RouteVisitor {
|
||||
|
||||
public void visit(VehicleRoute route);
|
||||
|
||||
}
|
||||
|
|
@ -20,13 +20,18 @@
|
|||
******************************************************************************/
|
||||
package algorithms;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import basics.Job;
|
||||
import basics.algo.InsertionStartsListener;
|
||||
import basics.algo.JobInsertedListener;
|
||||
import basics.route.TourActivity;
|
||||
import basics.route.VehicleRoute;
|
||||
|
||||
class StateManagerImpl implements StateManager{
|
||||
class StateManagerImpl implements StateManager, InsertionStartsListener, JobInsertedListener {
|
||||
|
||||
static class StatesImpl implements States{
|
||||
|
||||
|
|
@ -47,6 +52,12 @@ class StateManagerImpl implements StateManager{
|
|||
|
||||
private Map<TourActivity,States> activityStates = new HashMap<TourActivity, StateManager.States>();
|
||||
|
||||
private RouteActivityVisitor routeActivityVisitor = new RouteActivityVisitor();
|
||||
|
||||
private ReverseRouteActivityVisitor revRouteActivityVisitor = new ReverseRouteActivityVisitor();
|
||||
|
||||
private Collection<RouteVisitor> routeVisitors = new ArrayList<RouteVisitor>();
|
||||
|
||||
public void clear(){
|
||||
vehicleRouteStates.clear();
|
||||
activityStates.clear();
|
||||
|
|
@ -113,7 +124,32 @@ class StateManagerImpl implements StateManager{
|
|||
StatesImpl routeStates = (StatesImpl) vehicleRouteStates.get(route);
|
||||
routeStates.putState(stateType, state);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) {
|
||||
for(RouteVisitor v : routeVisitors){ v.visit(inRoute); }
|
||||
routeActivityVisitor.visit(inRoute);
|
||||
revRouteActivityVisitor.visit(inRoute);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void informInsertionStarts(Collection<VehicleRoute> vehicleRoutes,Collection<Job> unassignedJobs) {
|
||||
for(VehicleRoute route : vehicleRoutes){
|
||||
for(RouteVisitor v : routeVisitors){ v.visit(route); }
|
||||
routeActivityVisitor.visit(route);
|
||||
revRouteActivityVisitor.visit(route);
|
||||
}
|
||||
}
|
||||
|
||||
public void addActivityVisitor(ActivityVisitor activityVistor){
|
||||
routeActivityVisitor.addActivityVisitor(activityVistor);
|
||||
}
|
||||
|
||||
public void addActivityVisitor(ReverseActivityVisitor activityVistor){
|
||||
revRouteActivityVisitor.addActivityVisitor(activityVistor);
|
||||
}
|
||||
|
||||
public void addRouteVisitor(RouteVisitor routeVisitor){
|
||||
routeVisitors.add(routeVisitor);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,95 +44,21 @@ import basics.algo.IterationStartsListener;
|
|||
import basics.algo.JobInsertedListener;
|
||||
import basics.algo.VehicleRoutingAlgorithmListener;
|
||||
import basics.costs.ForwardTransportCost;
|
||||
import basics.costs.ForwardTransportTime;
|
||||
import basics.costs.VehicleRoutingActivityCosts;
|
||||
import basics.costs.VehicleRoutingTransportCosts;
|
||||
import basics.route.DeliveryActivity;
|
||||
import basics.route.Driver;
|
||||
import basics.route.End;
|
||||
import basics.route.PickupActivity;
|
||||
import basics.route.ServiceActivity;
|
||||
import basics.route.Start;
|
||||
import basics.route.TourActivity;
|
||||
import basics.route.Vehicle;
|
||||
import basics.route.VehicleRoute;
|
||||
|
||||
class StateUpdates {
|
||||
|
||||
static class VRAListenersManager implements IterationStartsListener, IterationEndsListener, InsertionStartsListener, InsertionEndsListener, JobInsertedListener, RuinListener{
|
||||
|
||||
private Map<Class<? extends VehicleRoutingAlgorithmListener>,Collection<VehicleRoutingAlgorithmListener>> listeners = new HashMap<Class<? extends VehicleRoutingAlgorithmListener>,Collection<VehicleRoutingAlgorithmListener>>();
|
||||
|
||||
public void addListener(VehicleRoutingAlgorithmListener vraListener){
|
||||
if(!listeners.containsKey(vraListener.getClass())){
|
||||
listeners.put(vraListener.getClass(), new ArrayList<VehicleRoutingAlgorithmListener>());
|
||||
}
|
||||
listeners.get(vraListener.getClass()).add(vraListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ruinStarts(Collection<VehicleRoute> routes) {
|
||||
if(listeners.containsKey(RuinListener.class)){
|
||||
for(VehicleRoutingAlgorithmListener l : listeners.get(RuinListener.class)){
|
||||
((RuinListener)l).ruinStarts(routes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ruinEnds(Collection<VehicleRoute> routes,Collection<Job> unassignedJobs) {
|
||||
if(listeners.containsKey(RuinListener.class)){
|
||||
for(VehicleRoutingAlgorithmListener l : listeners.get(RuinListener.class)){
|
||||
((RuinListener)l).ruinEnds(routes,unassignedJobs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removed(Job job, VehicleRoute fromRoute) {
|
||||
if(listeners.containsKey(RuinListener.class)){
|
||||
for(VehicleRoutingAlgorithmListener l : listeners.get(RuinListener.class)){
|
||||
((RuinListener)l).removed(job, fromRoute);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) {
|
||||
if(listeners.containsKey(JobInsertedListener.class)){
|
||||
for(VehicleRoutingAlgorithmListener l : listeners.get(RuinListener.class)){
|
||||
((JobInsertedListener)l).informJobInserted(job2insert, inRoute, additionalCosts, additionalTime);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void informInsertionEnds(Collection<VehicleRoute> vehicleRoutes) {
|
||||
// if(listeners.containsKey(JobInsertedListener.class)){
|
||||
// for(VehicleRoutingAlgorithmListener l : listeners.get(RuinListener.class)){
|
||||
// ((JobInsertedListener)l).informJobInserted(job2insert, inRoute, additionalCosts, additionalTime);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
@Override
|
||||
public void informInsertionStarts(Collection<VehicleRoute> vehicleRoutes,Collection<Job> unassignedJobs) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void informIterationEnds(int i, VehicleRoutingProblem problem,Collection<VehicleRoutingProblemSolution> solutions) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void informIterationStarts(int i, VehicleRoutingProblem problem,Collection<VehicleRoutingProblemSolution> solutions) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class UpdateCostsAtRouteLevel implements JobInsertedListener, InsertionStartsListener, InsertionEndsListener{
|
||||
|
||||
private StateManagerImpl states;
|
||||
|
|
@ -158,10 +84,10 @@ class StateUpdates {
|
|||
|
||||
@Override
|
||||
public void informInsertionStarts(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs) {
|
||||
IterateRouteForwardInTime forwardInTime = new IterateRouteForwardInTime(tpCosts);
|
||||
forwardInTime.addListener(new UpdateCostsAtAllLevels(actCosts, tpCosts, states));
|
||||
RouteActivityVisitor forwardInTime = new RouteActivityVisitor();
|
||||
forwardInTime.addActivityVisitor(new UpdateCostsAtAllLevels(actCosts, tpCosts, states));
|
||||
for(VehicleRoute route : vehicleRoutes){
|
||||
forwardInTime.iterate(route);
|
||||
forwardInTime.visit(route);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -183,29 +109,42 @@ class StateUpdates {
|
|||
|
||||
}
|
||||
|
||||
static class UpdateActivityTimes implements ForwardInTimeListener{
|
||||
static class UpdateActivityTimes implements ActivityVisitor{
|
||||
|
||||
private Logger log = Logger.getLogger(UpdateActivityTimes.class);
|
||||
|
||||
@Override
|
||||
public void start(VehicleRoute route, Start start, double departureTime) {
|
||||
start.setEndTime(departureTime);
|
||||
private ActivityTimeTracker timeTracker;
|
||||
|
||||
private VehicleRoute route;
|
||||
|
||||
public UpdateActivityTimes(ForwardTransportTime transportTime) {
|
||||
super();
|
||||
timeTracker = new ActivityTimeTracker(transportTime);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nextActivity(TourActivity act, double arrTime, double endTime) {
|
||||
act.setArrTime(arrTime);
|
||||
act.setEndTime(endTime);
|
||||
public void begin(VehicleRoute route) {
|
||||
timeTracker.begin(route);
|
||||
this.route = route;
|
||||
route.getStart().setEndTime(timeTracker.getActEndTime());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void end(End end, double arrivalTime) {
|
||||
end.setArrTime(arrivalTime);
|
||||
public void visit(TourActivity activity) {
|
||||
timeTracker.visit(activity);
|
||||
activity.setArrTime(timeTracker.getActArrTime());
|
||||
activity.setEndTime(timeTracker.getActEndTime());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish() {
|
||||
timeTracker.finish();
|
||||
route.getEnd().setArrTime(timeTracker.getActArrTime());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class UpdateCostsAtAllLevels implements ForwardInTimeListener{
|
||||
static class UpdateCostsAtAllLevels implements ActivityVisitor{
|
||||
|
||||
private static Logger log = Logger.getLogger(UpdateCostsAtAllLevels.class);
|
||||
|
||||
|
|
@ -223,27 +162,31 @@ class StateUpdates {
|
|||
|
||||
private double startTimeAtPrevAct = 0.0;
|
||||
|
||||
public UpdateCostsAtAllLevels(VehicleRoutingActivityCosts activityCost, ForwardTransportCost transportCost, StateManagerImpl states) {
|
||||
private ActivityTimeTracker timeTracker;
|
||||
|
||||
public UpdateCostsAtAllLevels(VehicleRoutingActivityCosts activityCost, VehicleRoutingTransportCosts transportCost, StateManagerImpl states) {
|
||||
super();
|
||||
this.activityCost = activityCost;
|
||||
this.transportCost = transportCost;
|
||||
this.states = states;
|
||||
timeTracker = new ActivityTimeTracker(transportCost);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(VehicleRoute route, Start start, double departureTime) {
|
||||
public void begin(VehicleRoute route) {
|
||||
vehicleRoute = route;
|
||||
vehicleRoute.getVehicleRouteCostCalculator().reset();
|
||||
prevAct = start;
|
||||
startTimeAtPrevAct = departureTime;
|
||||
// log.info(start + " depTime=" + departureTime);
|
||||
timeTracker.begin(route);
|
||||
prevAct = route.getStart();
|
||||
startTimeAtPrevAct = timeTracker.getActEndTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nextActivity(TourActivity act, double arrTime, double endTime) {
|
||||
// log.info(act + " job " + ((JobActivity)act).getJob().getId() + " arrTime=" + arrTime + " endTime=" + endTime);
|
||||
public void visit(TourActivity act) {
|
||||
timeTracker.visit(act);
|
||||
|
||||
double transportCost = this.transportCost.getTransportCost(prevAct.getLocationId(), act.getLocationId(), startTimeAtPrevAct, vehicleRoute.getDriver(), vehicleRoute.getVehicle());
|
||||
double actCost = activityCost.getActivityCost(act, arrTime, vehicleRoute.getDriver(), vehicleRoute.getVehicle());
|
||||
double actCost = activityCost.getActivityCost(act, timeTracker.getActArrTime(), vehicleRoute.getDriver(), vehicleRoute.getVehicle());
|
||||
|
||||
vehicleRoute.getVehicleRouteCostCalculator().addTransportCost(transportCost);
|
||||
vehicleRoute.getVehicleRouteCostCalculator().addActivityCost(actCost);
|
||||
|
|
@ -254,14 +197,14 @@ class StateUpdates {
|
|||
states.putActivityState(act, StateTypes.COSTS, new StateImpl(totalOperationCost));
|
||||
|
||||
prevAct = act;
|
||||
startTimeAtPrevAct = endTime;
|
||||
startTimeAtPrevAct = timeTracker.getActEndTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void end(End end, double arrivalTime) {
|
||||
// log.info(end + " arrTime=" + arrivalTime);
|
||||
double transportCost = this.transportCost.getTransportCost(prevAct.getLocationId(), end.getLocationId(), startTimeAtPrevAct, vehicleRoute.getDriver(), vehicleRoute.getVehicle());
|
||||
double actCost = activityCost.getActivityCost(end, arrivalTime, vehicleRoute.getDriver(), vehicleRoute.getVehicle());
|
||||
public void finish() {
|
||||
timeTracker.finish();
|
||||
double transportCost = this.transportCost.getTransportCost(prevAct.getLocationId(), vehicleRoute.getEnd().getLocationId(), startTimeAtPrevAct, vehicleRoute.getDriver(), vehicleRoute.getVehicle());
|
||||
double actCost = activityCost.getActivityCost(vehicleRoute.getEnd(), timeTracker.getActEndTime(), vehicleRoute.getDriver(), vehicleRoute.getVehicle());
|
||||
|
||||
vehicleRoute.getVehicleRouteCostCalculator().addTransportCost(transportCost);
|
||||
vehicleRoute.getVehicleRouteCostCalculator().addActivityCost(actCost);
|
||||
|
|
@ -284,56 +227,78 @@ class StateUpdates {
|
|||
|
||||
}
|
||||
|
||||
static class UpdateEarliestStartTimeWindowAtActLocations implements ForwardInTimeListener{
|
||||
static class UpdateEarliestStartTimeWindowAtActLocations implements ActivityVisitor{
|
||||
|
||||
private StateManagerImpl states;
|
||||
|
||||
public UpdateEarliestStartTimeWindowAtActLocations(StateManagerImpl states) {
|
||||
private ActivityTimeTracker timeTracker;
|
||||
|
||||
public UpdateEarliestStartTimeWindowAtActLocations(StateManagerImpl states, VehicleRoutingTransportCosts transportCosts) {
|
||||
super();
|
||||
this.states = states;
|
||||
timeTracker = new ActivityTimeTracker(transportCosts);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(VehicleRoute route, Start start, double departureTime) {}
|
||||
|
||||
@Override
|
||||
public void nextActivity(TourActivity act, double arrTime, double endTime) {
|
||||
states.putActivityState(act, StateTypes.EARLIEST_OPERATION_START_TIME, new StateImpl(Math.max(arrTime, act.getTheoreticalEarliestOperationStartTime())));
|
||||
public void begin(VehicleRoute route) {
|
||||
timeTracker.begin(route);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void end(End end, double arrivalTime) {}
|
||||
public void visit(TourActivity activity) {
|
||||
timeTracker.visit(activity);
|
||||
states.putActivityState(activity, StateTypes.EARLIEST_OPERATION_START_TIME, new StateImpl(Math.max(timeTracker.getActArrTime(), activity.getTheoreticalEarliestOperationStartTime())));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish() {}
|
||||
|
||||
}
|
||||
|
||||
static class UpdateLatestOperationStartTimeAtActLocations implements BackwardInTimeListener{
|
||||
static class UpdateLatestOperationStartTimeAtActLocations implements ReverseActivityVisitor{
|
||||
|
||||
private static Logger log = Logger.getLogger(UpdateLatestOperationStartTimeAtActLocations.class);
|
||||
|
||||
private StateManagerImpl states;
|
||||
|
||||
public UpdateLatestOperationStartTimeAtActLocations(StateManagerImpl states) {
|
||||
private VehicleRoute route;
|
||||
|
||||
private VehicleRoutingTransportCosts transportCosts;
|
||||
|
||||
private double latestArrTimeAtPrevAct;
|
||||
|
||||
private TourActivity prevAct;
|
||||
|
||||
public UpdateLatestOperationStartTimeAtActLocations(StateManagerImpl states, VehicleRoutingTransportCosts tpCosts) {
|
||||
super();
|
||||
this.states = states;
|
||||
this.transportCosts = tpCosts;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(VehicleRoute route, End end, double latestArrivalTime) {}
|
||||
|
||||
@Override
|
||||
public void prevActivity(TourActivity act,double latestDepartureTime, double latestOperationStartTime) {
|
||||
// log.info(act + " jobId=" + ((JobActivity)act).getJob().getId() + " " + latestOperationStartTime);
|
||||
states.putActivityState(act, StateTypes.LATEST_OPERATION_START_TIME, new StateImpl(latestOperationStartTime));
|
||||
public void begin(VehicleRoute route) {
|
||||
this.route = route;
|
||||
latestArrTimeAtPrevAct = route.getEnd().getTheoreticalLatestOperationStartTime();
|
||||
prevAct = route.getEnd();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void end(Start start, double latestDepartureTime) {}
|
||||
|
||||
|
||||
public void visit(TourActivity activity) {
|
||||
double potentialLatestArrivalTimeAtCurrAct = latestArrTimeAtPrevAct - transportCosts.getBackwardTransportTime(activity.getLocationId(), prevAct.getLocationId(), latestArrTimeAtPrevAct, route.getDriver(),route.getVehicle()) - activity.getOperationTime();
|
||||
double latestArrivalTime = Math.min(activity.getTheoreticalLatestOperationStartTime(), potentialLatestArrivalTimeAtCurrAct);
|
||||
|
||||
states.putActivityState(activity, StateTypes.LATEST_OPERATION_START_TIME, new StateImpl(latestArrivalTime));
|
||||
|
||||
latestArrTimeAtPrevAct = latestArrivalTime;
|
||||
prevAct = activity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish() {}
|
||||
}
|
||||
|
||||
static class UpdateLoadAtAllLevels implements ForwardInTimeListener{
|
||||
static class UpdateLoadAtAllLevels implements ActivityVisitor{
|
||||
|
||||
private double load = 0.0;
|
||||
|
||||
|
|
@ -347,16 +312,18 @@ class StateUpdates {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void start(VehicleRoute route, Start start, double departureTime) { vehicleRoute = route; }
|
||||
|
||||
@Override
|
||||
public void nextActivity(TourActivity act, double arrTime, double endTime) {
|
||||
load += (double)act.getCapacityDemand();
|
||||
states.putActivityState(act, StateTypes.LOAD, new StateImpl(load));
|
||||
public void begin(VehicleRoute route) {
|
||||
vehicleRoute = route;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void end(End end, double arrivalTime) {
|
||||
public void visit(TourActivity activity) {
|
||||
load += (double)activity.getCapacityDemand();
|
||||
states.putActivityState(activity, StateTypes.LOAD, new StateImpl(load));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish() {
|
||||
states.putRouteState(vehicleRoute, StateTypes.LOAD, new StateImpl(load));
|
||||
load=0;
|
||||
vehicleRoute = null;
|
||||
|
|
@ -398,31 +365,30 @@ class StateUpdates {
|
|||
|
||||
static class UpdateStates implements JobInsertedListener, RuinListener{
|
||||
|
||||
private IterateRouteForwardInTime iterateForward;
|
||||
private RouteActivityVisitor routeActivityVisitor;
|
||||
|
||||
private IterateRouteBackwardInTime iterateBackward;
|
||||
private ReverseRouteActivityVisitor revRouteActivityVisitor;
|
||||
|
||||
public UpdateStates(StateManagerImpl states, VehicleRoutingTransportCosts routingCosts, VehicleRoutingActivityCosts activityCosts) {
|
||||
routeActivityVisitor = new RouteActivityVisitor();
|
||||
routeActivityVisitor.addActivityVisitor(new UpdateActivityTimes(routingCosts));
|
||||
routeActivityVisitor.addActivityVisitor(new UpdateCostsAtAllLevels(activityCosts, routingCosts, states));
|
||||
routeActivityVisitor.addActivityVisitor(new UpdateLoadAtAllLevels(states));
|
||||
|
||||
iterateForward = new IterateRouteForwardInTime(routingCosts);
|
||||
iterateForward.addListener(new UpdateActivityTimes());
|
||||
iterateForward.addListener(new UpdateCostsAtAllLevels(activityCosts, routingCosts, states));
|
||||
iterateForward.addListener(new UpdateLoadAtAllLevels(states));
|
||||
// iterateForward.addListener(new UpdateEarliestStartTimeWindowAtActLocations(states));
|
||||
|
||||
iterateBackward = new IterateRouteBackwardInTime(routingCosts);
|
||||
iterateBackward.addListener(new UpdateLatestOperationStartTimeAtActLocations(states));
|
||||
revRouteActivityVisitor = new ReverseRouteActivityVisitor();
|
||||
revRouteActivityVisitor.addActivityVisitor(new UpdateLatestOperationStartTimeAtActLocations(states, routingCosts));
|
||||
|
||||
}
|
||||
|
||||
public void update(VehicleRoute route){
|
||||
iterateForward.iterate(route);
|
||||
iterateBackward.iterate(route);
|
||||
routeActivityVisitor.visit(route);
|
||||
revRouteActivityVisitor.visit(route);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) {
|
||||
iterateForward.iterate(inRoute);
|
||||
iterateBackward.iterate(inRoute);
|
||||
routeActivityVisitor.visit(inRoute);
|
||||
revRouteActivityVisitor.visit(inRoute);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -431,8 +397,8 @@ class StateUpdates {
|
|||
@Override
|
||||
public void ruinEnds(Collection<VehicleRoute> routes,Collection<Job> unassignedJobs) {
|
||||
for(VehicleRoute route : routes) {
|
||||
iterateForward.iterate(route);
|
||||
iterateBackward.iterate(route);
|
||||
routeActivityVisitor.visit(route);
|
||||
revRouteActivityVisitor.visit(route);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -441,7 +407,7 @@ class StateUpdates {
|
|||
|
||||
}
|
||||
|
||||
static class UpdateFuturePickupsAtActivityLevel implements BackwardInTimeListener {
|
||||
static class UpdateFuturePickupsAtActivityLevel implements ReverseActivityVisitor {
|
||||
private StateManagerImpl stateManager;
|
||||
private int futurePicks = 0;
|
||||
private VehicleRoute route;
|
||||
|
|
@ -452,12 +418,12 @@ class StateUpdates {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void start(VehicleRoute route, End end, double latestArrivalTime) {
|
||||
public void begin(VehicleRoute route) {
|
||||
this.route = route;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void prevActivity(TourActivity act, double latestDepartureTime, double latestOperationStartTime) {
|
||||
public void visit(TourActivity act) {
|
||||
stateManager.putActivityState(act, StateTypes.FUTURE_PICKS, new StateImpl(futurePicks));
|
||||
if(act instanceof PickupActivity || act instanceof ServiceActivity){
|
||||
futurePicks += act.getCapacityDemand();
|
||||
|
|
@ -465,15 +431,15 @@ class StateUpdates {
|
|||
assert futurePicks <= route.getVehicle().getCapacity() : "sum of pickups must not be > vehicleCap";
|
||||
assert futurePicks >= 0 : "sum of pickups must not < 0";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void end(Start start, double latestDepartureTime) {
|
||||
public void finish() {
|
||||
futurePicks = 0;
|
||||
route = null;
|
||||
}
|
||||
}
|
||||
|
||||
static class UpdateOccuredDeliveriesAtActivityLevel implements ForwardInTimeListener {
|
||||
static class UpdateOccuredDeliveriesAtActivityLevel implements ActivityVisitor {
|
||||
private StateManagerImpl stateManager;
|
||||
private int deliveries = 0;
|
||||
private VehicleRoute route;
|
||||
|
|
@ -484,12 +450,12 @@ class StateUpdates {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void start(VehicleRoute route, Start start, double departureTime) {
|
||||
public void begin(VehicleRoute route) {
|
||||
this.route = route;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void nextActivity(TourActivity act, double arrTime, double endTime) {
|
||||
public void visit(TourActivity act) {
|
||||
if(act instanceof DeliveryActivity){
|
||||
deliveries += Math.abs(act.getCapacityDemand());
|
||||
}
|
||||
|
|
@ -497,9 +463,9 @@ class StateUpdates {
|
|||
assert deliveries >= 0 : "deliveries < 0";
|
||||
assert deliveries <= route.getVehicle().getCapacity() : "deliveries > vehicleCap";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void end(End end, double arrivalTime) {
|
||||
public void finish() {
|
||||
deliveries = 0;
|
||||
route = null;
|
||||
}
|
||||
|
|
@ -512,7 +478,7 @@ class StateUpdates {
|
|||
* @author stefan
|
||||
*
|
||||
*/
|
||||
static class UpdateLoadAtActivityLevel implements ForwardInTimeListener {
|
||||
static class UpdateLoadAtActivityLevel implements ActivityVisitor {
|
||||
private StateManagerImpl stateManager;
|
||||
private int currentLoad = 0;
|
||||
private VehicleRoute route;
|
||||
|
|
@ -521,23 +487,23 @@ class StateUpdates {
|
|||
super();
|
||||
this.stateManager = stateManager;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void start(VehicleRoute route, Start start, double departureTime) {
|
||||
public void begin(VehicleRoute route) {
|
||||
currentLoad = (int) stateManager.getRouteState(route, StateTypes.LOAD_AT_DEPOT).toDouble();
|
||||
this.route = route;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void nextActivity(TourActivity act, double arrTime, double endTime) {
|
||||
public void visit(TourActivity act) {
|
||||
currentLoad += act.getCapacityDemand();
|
||||
stateManager.putActivityState(act, StateTypes.LOAD, new StateImpl(currentLoad));
|
||||
assert currentLoad <= route.getVehicle().getCapacity() : "currentLoad at activity must not be > vehicleCapacity";
|
||||
assert currentLoad >= 0 : "currentLoad at act must not be < 0";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void end(End end, double arrivalTime) {
|
||||
public void finish() {
|
||||
currentLoad = 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -617,27 +583,27 @@ class StateUpdates {
|
|||
|
||||
static class UpdateRouteStatesOnceTheRouteHasBeenChanged implements InsertionStartsListener, JobInsertedListener {
|
||||
|
||||
private IterateRouteForwardInTime forwardInTimeIterator;
|
||||
private RouteActivityVisitor forwardInTimeIterator;
|
||||
|
||||
private IterateRouteBackwardInTime backwardInTimeIterator;
|
||||
private ReverseRouteActivityVisitor backwardInTimeIterator;
|
||||
|
||||
private Collection<InsertionStarts> insertionStartsListeners;
|
||||
|
||||
private Collection<JobInsertedListener> jobInsertionListeners;
|
||||
|
||||
public UpdateRouteStatesOnceTheRouteHasBeenChanged(VehicleRoutingTransportCosts routingCosts) {
|
||||
forwardInTimeIterator = new IterateRouteForwardInTime(routingCosts);
|
||||
backwardInTimeIterator = new IterateRouteBackwardInTime(routingCosts);
|
||||
forwardInTimeIterator = new RouteActivityVisitor();
|
||||
backwardInTimeIterator = new ReverseRouteActivityVisitor();
|
||||
insertionStartsListeners = new ArrayList<InsertionStarts>();
|
||||
jobInsertionListeners = new ArrayList<JobInsertedListener>();
|
||||
}
|
||||
|
||||
void addListener(ForwardInTimeListener l){
|
||||
forwardInTimeIterator.addListener(l);
|
||||
void addVisitor(ActivityVisitor vis){
|
||||
forwardInTimeIterator.addActivityVisitor(vis);
|
||||
}
|
||||
|
||||
void addListener(BackwardInTimeListener l){
|
||||
backwardInTimeIterator.addListener(l);
|
||||
void addVisitor(ReverseActivityVisitor revVis){
|
||||
backwardInTimeIterator.addActivityVisitor(revVis);
|
||||
}
|
||||
|
||||
void addInsertionStartsListener(InsertionStarts insertionStartListener){
|
||||
|
|
@ -651,8 +617,8 @@ class StateUpdates {
|
|||
@Override
|
||||
public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) {
|
||||
for(JobInsertedListener l : jobInsertionListeners){ l.informJobInserted(job2insert, inRoute, additionalCosts, additionalTime); }
|
||||
forwardInTimeIterator.iterate(inRoute);
|
||||
backwardInTimeIterator.iterate(inRoute);
|
||||
forwardInTimeIterator.visit(inRoute);
|
||||
backwardInTimeIterator.visit(inRoute);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -661,8 +627,8 @@ class StateUpdates {
|
|||
for(InsertionStarts insertionsStartsHandler : insertionStartsListeners){
|
||||
insertionsStartsHandler.insertionStarts(route);
|
||||
}
|
||||
forwardInTimeIterator.iterate(route);
|
||||
backwardInTimeIterator.iterate(route);
|
||||
forwardInTimeIterator.visit(route);
|
||||
backwardInTimeIterator.visit(route);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -506,13 +506,13 @@ public class VehicleRoutingAlgorithms {
|
|||
routeChangedListener.addInsertionStartsListener(new StateUpdates.UpdateLoadsAtStartAndEndOfRouteWhenInsertionStarts(stateManager));
|
||||
routeChangedListener.addJobInsertedListener(new StateUpdates.UpdateLoadsAtStartAndEndOfRouteWhenJobHasBeenInserted(stateManager));
|
||||
|
||||
routeChangedListener.addListener(new StateUpdates.UpdateActivityTimes());
|
||||
routeChangedListener.addListener(new StateUpdates.UpdateLoadAtActivityLevel(stateManager));
|
||||
routeChangedListener.addListener(new StateUpdates.UpdateCostsAtAllLevels(vrp.getActivityCosts(), vrp.getTransportCosts(), stateManager));
|
||||
routeChangedListener.addVisitor(new StateUpdates.UpdateActivityTimes(vrp.getTransportCosts()));
|
||||
routeChangedListener.addVisitor(new StateUpdates.UpdateLoadAtActivityLevel(stateManager));
|
||||
routeChangedListener.addVisitor(new StateUpdates.UpdateCostsAtAllLevels(vrp.getActivityCosts(), vrp.getTransportCosts(), stateManager));
|
||||
|
||||
routeChangedListener.addListener(new StateUpdates.UpdateOccuredDeliveriesAtActivityLevel(stateManager));
|
||||
routeChangedListener.addListener(new StateUpdates.UpdateLatestOperationStartTimeAtActLocations(stateManager));
|
||||
routeChangedListener.addListener(new StateUpdates.UpdateFuturePickupsAtActivityLevel(stateManager));
|
||||
routeChangedListener.addVisitor(new StateUpdates.UpdateOccuredDeliveriesAtActivityLevel(stateManager));
|
||||
routeChangedListener.addVisitor(new StateUpdates.UpdateLatestOperationStartTimeAtActLocations(stateManager, vrp.getTransportCosts()));
|
||||
routeChangedListener.addVisitor(new StateUpdates.UpdateFuturePickupsAtActivityLevel(stateManager));
|
||||
|
||||
metaAlgorithm.getSearchStrategyManager().addSearchStrategyModuleListener(routeChangedListener);
|
||||
metaAlgorithm.getSearchStrategyManager().addSearchStrategyModuleListener(new RemoveEmptyVehicles(vehicleFleetManager));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue