1
0
Fork 0
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:
oblonski 2013-10-07 11:02:39 +02:00
parent 8c8f041933
commit a32d8c1c6a
14 changed files with 447 additions and 226 deletions

View file

@ -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;
}
}

View 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();
}

View file

@ -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();
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -0,0 +1,9 @@
package algorithms;
import basics.route.VehicleRoute;
interface RouteVisitor {
public void visit(VehicleRoute route);
}

View file

@ -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();
@ -114,6 +125,31 @@ class StateManagerImpl implements StateManager{
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);
}
}

View file

@ -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));
revRouteActivityVisitor = new ReverseRouteActivityVisitor();
revRouteActivityVisitor.addActivityVisitor(new UpdateLatestOperationStartTimeAtActLocations(states, routingCosts));
iterateBackward = new IterateRouteBackwardInTime(routingCosts);
iterateBackward.addListener(new UpdateLatestOperationStartTimeAtActLocations(states));
}
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();
@ -467,13 +433,13 @@ class StateUpdates {
}
@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());
}
@ -499,7 +465,7 @@ class StateUpdates {
}
@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;
@ -523,13 +489,13 @@ class StateUpdates {
}
@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";
@ -537,7 +503,7 @@ class StateUpdates {
}
@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);
}
}

View file

@ -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));

View file

@ -108,18 +108,18 @@ public class BuildPDVRPAlgoFromScratchTest {
vra.getAlgorithmListeners().addListener(new StateUpdates.ResetStateManager(stateManager));
final IterateRouteForwardInTime iterateForward = new IterateRouteForwardInTime(vrp.getTransportCosts());
final RouteActivityVisitor iterateForward = new RouteActivityVisitor();
iterateForward.addListener(new UpdateActivityTimes());
iterateForward.addListener(new UpdateEarliestStartTimeWindowAtActLocations(stateManager));
iterateForward.addListener(new UpdateCostsAtAllLevels(vrp.getActivityCosts(), vrp.getTransportCosts(), stateManager));
iterateForward.addActivityVisitor(new UpdateActivityTimes(vrp.getTransportCosts()));
iterateForward.addActivityVisitor(new UpdateEarliestStartTimeWindowAtActLocations(stateManager, vrp.getTransportCosts()));
iterateForward.addActivityVisitor(new UpdateCostsAtAllLevels(vrp.getActivityCosts(), vrp.getTransportCosts(), stateManager));
iterateForward.addListener(new StateUpdates.UpdateOccuredDeliveriesAtActivityLevel(stateManager));
iterateForward.addListener(new StateUpdates.UpdateLoadAtActivityLevel(stateManager));
iterateForward.addActivityVisitor(new StateUpdates.UpdateOccuredDeliveriesAtActivityLevel(stateManager));
iterateForward.addActivityVisitor(new StateUpdates.UpdateLoadAtActivityLevel(stateManager));
final IterateRouteBackwardInTime iterateBackward = new IterateRouteBackwardInTime(vrp.getTransportCosts());
iterateBackward.addListener(new UpdateLatestOperationStartTimeAtActLocations(stateManager));
iterateBackward.addListener(new StateUpdates.UpdateFuturePickupsAtActivityLevel(stateManager));
final ReverseRouteActivityVisitor iterateBackward = new ReverseRouteActivityVisitor();
iterateBackward.addActivityVisitor(new UpdateLatestOperationStartTimeAtActLocations(stateManager, vrp.getTransportCosts()));
iterateBackward.addActivityVisitor(new StateUpdates.UpdateFuturePickupsAtActivityLevel(stateManager));
InsertionStartsListener loadVehicleInDepot = new InsertionStartsListener() {
@ -139,8 +139,8 @@ public class BuildPDVRPAlgoFromScratchTest {
}
stateManager.putRouteState(route, StateTypes.LOAD_AT_DEPOT, new StateImpl(loadAtDepot));
stateManager.putRouteState(route, StateTypes.LOAD, new StateImpl(loadAtEnd));
iterateForward.iterate(route);
iterateBackward.iterate(route);
iterateForward.visit(route);
iterateBackward.visit(route);
}
}
@ -164,8 +164,8 @@ public class BuildPDVRPAlgoFromScratchTest {
// log.info("loadAtEnd="+loadAtEnd);
stateManager.putRouteState(inRoute, StateTypes.LOAD, new StateImpl(loadAtEnd + job2insert.getCapacityDemand()));
}
iterateForward.iterate(inRoute);
iterateBackward.iterate(inRoute);
iterateForward.visit(inRoute);
iterateBackward.visit(inRoute);
}
};

View file

@ -139,9 +139,9 @@ public class TestIterateRouteForwardInTime {
@Test
public void whenIteratingWithActivityTimeUpdater_itShouldUpdateActivityTimes() {
IterateRouteForwardInTime forwardInTime = new IterateRouteForwardInTime(cost);
forwardInTime.addListener(new UpdateActivityTimes());
forwardInTime.iterate(vehicleRoute);
RouteActivityVisitor forwardInTime = new RouteActivityVisitor();
forwardInTime.addActivityVisitor(new UpdateActivityTimes(cost));
forwardInTime.visit(vehicleRoute);
assertEquals(10.0,firstAct.getArrTime(),0.1);
assertEquals(10.0,firstAct.getEndTime(),0.1);
@ -152,9 +152,9 @@ public class TestIterateRouteForwardInTime {
@Test
public void whenIteratingWithLoadUpdateAtActLocations_itShouldUpdateLoad() {
IterateRouteForwardInTime forwardInTime = new IterateRouteForwardInTime(cost);
forwardInTime.addListener(new UpdateLoadAtAllLevels(stateManager));
forwardInTime.iterate(vehicleRoute);
RouteActivityVisitor forwardInTime = new RouteActivityVisitor();
forwardInTime.addActivityVisitor(new UpdateLoadAtAllLevels(stateManager));
forwardInTime.visit(vehicleRoute);
assertEquals(5.0, stateManager.getActivityState(firstAct,StateTypes.LOAD).toDouble(), 0.01);
assertEquals(10.0, stateManager.getActivityState(secondAct,StateTypes.LOAD).toDouble(), 0.01);
@ -163,8 +163,8 @@ public class TestIterateRouteForwardInTime {
@Test
public void testStatesOfAct0(){
IterateRouteForwardInTime forwardInTime = new IterateRouteForwardInTime(cost);
forwardInTime.iterate(vehicleRoute);
RouteActivityVisitor forwardInTime = new RouteActivityVisitor();
forwardInTime.visit(vehicleRoute);
assertEquals(0.0, vehicleRoute.getStart().getEndTime(),0.05);
assertEquals(vehicleRoute.getVehicle().getLocationId(), vehicleRoute.getStart().getLocationId());
@ -175,11 +175,11 @@ public class TestIterateRouteForwardInTime {
@Test
public void testStatesOfAct1(){
IterateRouteForwardInTime forwardInTime = new IterateRouteForwardInTime(cost);
forwardInTime.addListener(new UpdateLoadAtAllLevels(stateManager));
forwardInTime.addListener(new UpdateEarliestStartTimeWindowAtActLocations(stateManager));
forwardInTime.addListener(new UpdateCostsAtAllLevels(new DefaultVehicleRoutingActivityCosts(), cost, stateManager));
forwardInTime.iterate(vehicleRoute);
RouteActivityVisitor forwardInTime = new RouteActivityVisitor();
forwardInTime.addActivityVisitor(new UpdateLoadAtAllLevels(stateManager));
forwardInTime.addActivityVisitor(new UpdateEarliestStartTimeWindowAtActLocations(stateManager, cost));
forwardInTime.addActivityVisitor(new UpdateCostsAtAllLevels(new DefaultVehicleRoutingActivityCosts(), cost, stateManager));
forwardInTime.visit(vehicleRoute);
assertEquals(10.0, stateManager.getActivityState(firstAct, StateTypes.COSTS).toDouble(),0.05);
assertEquals(5.0, stateManager.getActivityState(firstAct, StateTypes.LOAD).toDouble(),0.05);
@ -189,12 +189,12 @@ public class TestIterateRouteForwardInTime {
@Test
public void testStatesOfAct2(){
IterateRouteForwardInTime forwardInTime = new IterateRouteForwardInTime(cost);
RouteActivityVisitor forwardInTime = new RouteActivityVisitor();
forwardInTime.addListener(new UpdateLoadAtAllLevels(stateManager));
forwardInTime.addListener(new UpdateEarliestStartTimeWindowAtActLocations(stateManager));
forwardInTime.addListener(new UpdateCostsAtAllLevels(new DefaultVehicleRoutingActivityCosts(), cost, stateManager));
forwardInTime.iterate(vehicleRoute);
forwardInTime.addActivityVisitor(new UpdateLoadAtAllLevels(stateManager));
forwardInTime.addActivityVisitor(new UpdateEarliestStartTimeWindowAtActLocations(stateManager, cost));
forwardInTime.addActivityVisitor(new UpdateCostsAtAllLevels(new DefaultVehicleRoutingActivityCosts(), cost, stateManager));
forwardInTime.visit(vehicleRoute);
assertEquals(30.0, stateManager.getActivityState(secondAct, StateTypes.COSTS).toDouble(),0.05);
assertEquals(10.0, stateManager.getActivityState(secondAct, StateTypes.LOAD).toDouble(),0.05);
@ -204,11 +204,11 @@ public class TestIterateRouteForwardInTime {
@Test
public void testStatesOfAct3(){
IterateRouteForwardInTime forwardInTime = new IterateRouteForwardInTime(cost);
RouteActivityVisitor forwardInTime = new RouteActivityVisitor();
forwardInTime.addListener(new UpdateActivityTimes());
forwardInTime.addListener(new UpdateCostsAtAllLevels(new DefaultVehicleRoutingActivityCosts(), cost, stateManager));
forwardInTime.iterate(vehicleRoute);
forwardInTime.addActivityVisitor(new UpdateActivityTimes(cost));
forwardInTime.addActivityVisitor(new UpdateCostsAtAllLevels(new DefaultVehicleRoutingActivityCosts(), cost, stateManager));
forwardInTime.visit(vehicleRoute);
assertEquals(40.0, stateManager.getRouteState(vehicleRoute,StateTypes.COSTS).toDouble(), 0.05);
assertEquals(40.0, vehicleRoute.getEnd().getArrTime(),0.05);

View file

@ -104,7 +104,7 @@ public class PickupAndDeliveryExample2 {
Plotter plotter = new Plotter(vrp, solution);
plotter.setLabel(Label.SIZE);
plotter.setShowFirstActivity(true);
plotter.plot("output/pd_christophides_vrpnc1.png","pd_vrpnc1");
plotter.plot("output/pd_christophides_vrpnc1_solution.png","pd_vrpnc1");

View file

@ -35,7 +35,11 @@ import basics.VehicleRoutingAlgorithm;
import basics.VehicleRoutingProblem;
import basics.VehicleRoutingProblemSolution;
import basics.VehicleRoutingProblem.Constraint;
import basics.costs.VehicleRoutingActivityCosts;
import basics.io.VrpXMLReader;
import basics.route.Driver;
import basics.route.TourActivity;
import basics.route.Vehicle;
public class VRPWithBackhaulsExample {
@ -68,9 +72,10 @@ public class VRPWithBackhaulsExample {
* Finally, the problem can be built. By default, transportCosts are crowFlyDistances (as usually used for vrp-instances).
*/
vrpBuilder.addProblemConstraint(Constraint.DELIVERIES_FIRST);
VehicleRoutingProblem vrp = vrpBuilder.build();
SolutionPlotter.plotVrpAsPNG(vrp, "output/pd_solomon_r101.png", "pd_r101");
// SolutionPlotter.plotVrpAsPNG(vrp, "output/vrpwbh_solomon_r101.png", "pd_r101");
/*
* Define the required vehicle-routing algorithms to solve the above problem.
@ -103,7 +108,7 @@ public class VRPWithBackhaulsExample {
Plotter plotter = new Plotter(vrp, solution);
plotter.setLabel(Label.SIZE);
plotter.setShowFirstActivity(true);
plotter.plot("output/pd_withBackhauls_solomon_r101_solution.png","pd_withBackhauls_r101");
plotter.plot("output/vrpwbh_solomon_r101_solution.png","vrpwbh_r101");
}

View file

@ -74,7 +74,7 @@ public class VRPWithBackhaulsExample2 {
*/
VehicleRoutingProblem vrp = vrpBuilder.build();
SolutionPlotter.plotVrpAsPNG(vrp, "output/pd_christophides_vrpnc1.png", "pd_vrpnc1");
SolutionPlotter.plotVrpAsPNG(vrp, "output/vrpwbh_christophides_vrpnc1.png", "pd_vrpnc1");
/*
* Define the required vehicle-routing algorithms to solve the above problem.
@ -107,7 +107,7 @@ public class VRPWithBackhaulsExample2 {
Plotter plotter = new Plotter(vrp, solution);
plotter.setLabel(Label.SIZE);
plotter.setShowFirstActivity(true);
plotter.plot("output/vrpwbh_christophides_vrpnc1.png","vrpwbh_vrpnc1");
plotter.plot("output/vrpwbh_christophides_vrpnc1_solution.png","vrpwbh_vrpnc1");