mirror of
https://github.com/graphhopper/jsprit.git
synced 2020-01-24 07:45:05 +01:00
Merge branch 'master' into relaxAPI
This commit is contained in:
commit
cba6a759e0
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;
|
package algorithms;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import basics.Job;
|
||||||
|
import basics.algo.InsertionStartsListener;
|
||||||
|
import basics.algo.JobInsertedListener;
|
||||||
import basics.route.TourActivity;
|
import basics.route.TourActivity;
|
||||||
import basics.route.VehicleRoute;
|
import basics.route.VehicleRoute;
|
||||||
|
|
||||||
class StateManagerImpl implements StateManager{
|
class StateManagerImpl implements StateManager, InsertionStartsListener, JobInsertedListener {
|
||||||
|
|
||||||
static class StatesImpl implements States{
|
static class StatesImpl implements States{
|
||||||
|
|
||||||
|
|
@ -47,6 +52,12 @@ class StateManagerImpl implements StateManager{
|
||||||
|
|
||||||
private Map<TourActivity,States> activityStates = new HashMap<TourActivity, StateManager.States>();
|
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(){
|
public void clear(){
|
||||||
vehicleRouteStates.clear();
|
vehicleRouteStates.clear();
|
||||||
activityStates.clear();
|
activityStates.clear();
|
||||||
|
|
@ -114,6 +125,31 @@ class StateManagerImpl implements StateManager{
|
||||||
routeStates.putState(stateType, state);
|
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.JobInsertedListener;
|
||||||
import basics.algo.VehicleRoutingAlgorithmListener;
|
import basics.algo.VehicleRoutingAlgorithmListener;
|
||||||
import basics.costs.ForwardTransportCost;
|
import basics.costs.ForwardTransportCost;
|
||||||
|
import basics.costs.ForwardTransportTime;
|
||||||
import basics.costs.VehicleRoutingActivityCosts;
|
import basics.costs.VehicleRoutingActivityCosts;
|
||||||
import basics.costs.VehicleRoutingTransportCosts;
|
import basics.costs.VehicleRoutingTransportCosts;
|
||||||
import basics.route.DeliveryActivity;
|
import basics.route.DeliveryActivity;
|
||||||
|
import basics.route.Driver;
|
||||||
import basics.route.End;
|
import basics.route.End;
|
||||||
import basics.route.PickupActivity;
|
import basics.route.PickupActivity;
|
||||||
import basics.route.ServiceActivity;
|
import basics.route.ServiceActivity;
|
||||||
import basics.route.Start;
|
import basics.route.Start;
|
||||||
import basics.route.TourActivity;
|
import basics.route.TourActivity;
|
||||||
|
import basics.route.Vehicle;
|
||||||
import basics.route.VehicleRoute;
|
import basics.route.VehicleRoute;
|
||||||
|
|
||||||
class StateUpdates {
|
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{
|
static class UpdateCostsAtRouteLevel implements JobInsertedListener, InsertionStartsListener, InsertionEndsListener{
|
||||||
|
|
||||||
private StateManagerImpl states;
|
private StateManagerImpl states;
|
||||||
|
|
@ -158,10 +84,10 @@ class StateUpdates {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void informInsertionStarts(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs) {
|
public void informInsertionStarts(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs) {
|
||||||
IterateRouteForwardInTime forwardInTime = new IterateRouteForwardInTime(tpCosts);
|
RouteActivityVisitor forwardInTime = new RouteActivityVisitor();
|
||||||
forwardInTime.addListener(new UpdateCostsAtAllLevels(actCosts, tpCosts, states));
|
forwardInTime.addActivityVisitor(new UpdateCostsAtAllLevels(actCosts, tpCosts, states));
|
||||||
for(VehicleRoute route : vehicleRoutes){
|
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);
|
private Logger log = Logger.getLogger(UpdateActivityTimes.class);
|
||||||
|
|
||||||
@Override
|
private ActivityTimeTracker timeTracker;
|
||||||
public void start(VehicleRoute route, Start start, double departureTime) {
|
|
||||||
start.setEndTime(departureTime);
|
private VehicleRoute route;
|
||||||
|
|
||||||
|
public UpdateActivityTimes(ForwardTransportTime transportTime) {
|
||||||
|
super();
|
||||||
|
timeTracker = new ActivityTimeTracker(transportTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void nextActivity(TourActivity act, double arrTime, double endTime) {
|
public void begin(VehicleRoute route) {
|
||||||
act.setArrTime(arrTime);
|
timeTracker.begin(route);
|
||||||
act.setEndTime(endTime);
|
this.route = route;
|
||||||
|
route.getStart().setEndTime(timeTracker.getActEndTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void end(End end, double arrivalTime) {
|
public void visit(TourActivity activity) {
|
||||||
end.setArrTime(arrivalTime);
|
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);
|
private static Logger log = Logger.getLogger(UpdateCostsAtAllLevels.class);
|
||||||
|
|
||||||
|
|
@ -223,27 +162,31 @@ class StateUpdates {
|
||||||
|
|
||||||
private double startTimeAtPrevAct = 0.0;
|
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();
|
super();
|
||||||
this.activityCost = activityCost;
|
this.activityCost = activityCost;
|
||||||
this.transportCost = transportCost;
|
this.transportCost = transportCost;
|
||||||
this.states = states;
|
this.states = states;
|
||||||
|
timeTracker = new ActivityTimeTracker(transportCost);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start(VehicleRoute route, Start start, double departureTime) {
|
public void begin(VehicleRoute route) {
|
||||||
vehicleRoute = route;
|
vehicleRoute = route;
|
||||||
vehicleRoute.getVehicleRouteCostCalculator().reset();
|
vehicleRoute.getVehicleRouteCostCalculator().reset();
|
||||||
prevAct = start;
|
timeTracker.begin(route);
|
||||||
startTimeAtPrevAct = departureTime;
|
prevAct = route.getStart();
|
||||||
// log.info(start + " depTime=" + departureTime);
|
startTimeAtPrevAct = timeTracker.getActEndTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void nextActivity(TourActivity act, double arrTime, double endTime) {
|
public void visit(TourActivity act) {
|
||||||
// log.info(act + " job " + ((JobActivity)act).getJob().getId() + " arrTime=" + arrTime + " endTime=" + endTime);
|
timeTracker.visit(act);
|
||||||
|
|
||||||
double transportCost = this.transportCost.getTransportCost(prevAct.getLocationId(), act.getLocationId(), startTimeAtPrevAct, vehicleRoute.getDriver(), vehicleRoute.getVehicle());
|
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().addTransportCost(transportCost);
|
||||||
vehicleRoute.getVehicleRouteCostCalculator().addActivityCost(actCost);
|
vehicleRoute.getVehicleRouteCostCalculator().addActivityCost(actCost);
|
||||||
|
|
@ -254,14 +197,14 @@ class StateUpdates {
|
||||||
states.putActivityState(act, StateTypes.COSTS, new StateImpl(totalOperationCost));
|
states.putActivityState(act, StateTypes.COSTS, new StateImpl(totalOperationCost));
|
||||||
|
|
||||||
prevAct = act;
|
prevAct = act;
|
||||||
startTimeAtPrevAct = endTime;
|
startTimeAtPrevAct = timeTracker.getActEndTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void end(End end, double arrivalTime) {
|
public void finish() {
|
||||||
// log.info(end + " arrTime=" + arrivalTime);
|
timeTracker.finish();
|
||||||
double transportCost = this.transportCost.getTransportCost(prevAct.getLocationId(), end.getLocationId(), startTimeAtPrevAct, vehicleRoute.getDriver(), vehicleRoute.getVehicle());
|
double transportCost = this.transportCost.getTransportCost(prevAct.getLocationId(), vehicleRoute.getEnd().getLocationId(), startTimeAtPrevAct, vehicleRoute.getDriver(), vehicleRoute.getVehicle());
|
||||||
double actCost = activityCost.getActivityCost(end, arrivalTime, vehicleRoute.getDriver(), vehicleRoute.getVehicle());
|
double actCost = activityCost.getActivityCost(vehicleRoute.getEnd(), timeTracker.getActEndTime(), vehicleRoute.getDriver(), vehicleRoute.getVehicle());
|
||||||
|
|
||||||
vehicleRoute.getVehicleRouteCostCalculator().addTransportCost(transportCost);
|
vehicleRoute.getVehicleRouteCostCalculator().addTransportCost(transportCost);
|
||||||
vehicleRoute.getVehicleRouteCostCalculator().addActivityCost(actCost);
|
vehicleRoute.getVehicleRouteCostCalculator().addActivityCost(actCost);
|
||||||
|
|
@ -284,56 +227,78 @@ class StateUpdates {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static class UpdateEarliestStartTimeWindowAtActLocations implements ForwardInTimeListener{
|
static class UpdateEarliestStartTimeWindowAtActLocations implements ActivityVisitor{
|
||||||
|
|
||||||
private StateManagerImpl states;
|
private StateManagerImpl states;
|
||||||
|
|
||||||
public UpdateEarliestStartTimeWindowAtActLocations(StateManagerImpl states) {
|
private ActivityTimeTracker timeTracker;
|
||||||
|
|
||||||
|
public UpdateEarliestStartTimeWindowAtActLocations(StateManagerImpl states, VehicleRoutingTransportCosts transportCosts) {
|
||||||
super();
|
super();
|
||||||
this.states = states;
|
this.states = states;
|
||||||
|
timeTracker = new ActivityTimeTracker(transportCosts);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start(VehicleRoute route, Start start, double departureTime) {}
|
public void begin(VehicleRoute route) {
|
||||||
|
timeTracker.begin(route);
|
||||||
@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())));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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())));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static class UpdateLatestOperationStartTimeAtActLocations implements BackwardInTimeListener{
|
@Override
|
||||||
|
public void finish() {}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static class UpdateLatestOperationStartTimeAtActLocations implements ReverseActivityVisitor{
|
||||||
|
|
||||||
private static Logger log = Logger.getLogger(UpdateLatestOperationStartTimeAtActLocations.class);
|
private static Logger log = Logger.getLogger(UpdateLatestOperationStartTimeAtActLocations.class);
|
||||||
|
|
||||||
private StateManagerImpl states;
|
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();
|
super();
|
||||||
this.states = states;
|
this.states = states;
|
||||||
|
this.transportCosts = tpCosts;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start(VehicleRoute route, End end, double latestArrivalTime) {}
|
public void begin(VehicleRoute route) {
|
||||||
|
this.route = route;
|
||||||
@Override
|
latestArrTimeAtPrevAct = route.getEnd().getTheoreticalLatestOperationStartTime();
|
||||||
public void prevActivity(TourActivity act,double latestDepartureTime, double latestOperationStartTime) {
|
prevAct = route.getEnd();
|
||||||
// log.info(act + " jobId=" + ((JobActivity)act).getJob().getId() + " " + latestOperationStartTime);
|
|
||||||
states.putActivityState(act, StateTypes.LATEST_OPERATION_START_TIME, new StateImpl(latestOperationStartTime));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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;
|
||||||
}
|
}
|
||||||
|
|
||||||
static class UpdateLoadAtAllLevels implements ForwardInTimeListener{
|
@Override
|
||||||
|
public void finish() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class UpdateLoadAtAllLevels implements ActivityVisitor{
|
||||||
|
|
||||||
private double load = 0.0;
|
private double load = 0.0;
|
||||||
|
|
||||||
|
|
@ -347,16 +312,18 @@ class StateUpdates {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start(VehicleRoute route, Start start, double departureTime) { vehicleRoute = route; }
|
public void begin(VehicleRoute route) {
|
||||||
|
vehicleRoute = route;
|
||||||
@Override
|
|
||||||
public void nextActivity(TourActivity act, double arrTime, double endTime) {
|
|
||||||
load += (double)act.getCapacityDemand();
|
|
||||||
states.putActivityState(act, StateTypes.LOAD, new StateImpl(load));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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));
|
states.putRouteState(vehicleRoute, StateTypes.LOAD, new StateImpl(load));
|
||||||
load=0;
|
load=0;
|
||||||
vehicleRoute = null;
|
vehicleRoute = null;
|
||||||
|
|
@ -398,31 +365,30 @@ class StateUpdates {
|
||||||
|
|
||||||
static class UpdateStates implements JobInsertedListener, RuinListener{
|
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) {
|
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);
|
revRouteActivityVisitor = new ReverseRouteActivityVisitor();
|
||||||
iterateForward.addListener(new UpdateActivityTimes());
|
revRouteActivityVisitor.addActivityVisitor(new UpdateLatestOperationStartTimeAtActLocations(states, routingCosts));
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void update(VehicleRoute route){
|
public void update(VehicleRoute route){
|
||||||
iterateForward.iterate(route);
|
routeActivityVisitor.visit(route);
|
||||||
iterateBackward.iterate(route);
|
revRouteActivityVisitor.visit(route);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) {
|
public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) {
|
||||||
iterateForward.iterate(inRoute);
|
routeActivityVisitor.visit(inRoute);
|
||||||
iterateBackward.iterate(inRoute);
|
revRouteActivityVisitor.visit(inRoute);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -431,8 +397,8 @@ class StateUpdates {
|
||||||
@Override
|
@Override
|
||||||
public void ruinEnds(Collection<VehicleRoute> routes,Collection<Job> unassignedJobs) {
|
public void ruinEnds(Collection<VehicleRoute> routes,Collection<Job> unassignedJobs) {
|
||||||
for(VehicleRoute route : routes) {
|
for(VehicleRoute route : routes) {
|
||||||
iterateForward.iterate(route);
|
routeActivityVisitor.visit(route);
|
||||||
iterateBackward.iterate(route);
|
revRouteActivityVisitor.visit(route);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -441,7 +407,7 @@ class StateUpdates {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static class UpdateFuturePickupsAtActivityLevel implements BackwardInTimeListener {
|
static class UpdateFuturePickupsAtActivityLevel implements ReverseActivityVisitor {
|
||||||
private StateManagerImpl stateManager;
|
private StateManagerImpl stateManager;
|
||||||
private int futurePicks = 0;
|
private int futurePicks = 0;
|
||||||
private VehicleRoute route;
|
private VehicleRoute route;
|
||||||
|
|
@ -452,12 +418,12 @@ class StateUpdates {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start(VehicleRoute route, End end, double latestArrivalTime) {
|
public void begin(VehicleRoute route) {
|
||||||
this.route = route;
|
this.route = route;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void prevActivity(TourActivity act, double latestDepartureTime, double latestOperationStartTime) {
|
public void visit(TourActivity act) {
|
||||||
stateManager.putActivityState(act, StateTypes.FUTURE_PICKS, new StateImpl(futurePicks));
|
stateManager.putActivityState(act, StateTypes.FUTURE_PICKS, new StateImpl(futurePicks));
|
||||||
if(act instanceof PickupActivity || act instanceof ServiceActivity){
|
if(act instanceof PickupActivity || act instanceof ServiceActivity){
|
||||||
futurePicks += act.getCapacityDemand();
|
futurePicks += act.getCapacityDemand();
|
||||||
|
|
@ -467,13 +433,13 @@ class StateUpdates {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void end(Start start, double latestDepartureTime) {
|
public void finish() {
|
||||||
futurePicks = 0;
|
futurePicks = 0;
|
||||||
route = null;
|
route = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static class UpdateOccuredDeliveriesAtActivityLevel implements ForwardInTimeListener {
|
static class UpdateOccuredDeliveriesAtActivityLevel implements ActivityVisitor {
|
||||||
private StateManagerImpl stateManager;
|
private StateManagerImpl stateManager;
|
||||||
private int deliveries = 0;
|
private int deliveries = 0;
|
||||||
private VehicleRoute route;
|
private VehicleRoute route;
|
||||||
|
|
@ -484,12 +450,12 @@ class StateUpdates {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start(VehicleRoute route, Start start, double departureTime) {
|
public void begin(VehicleRoute route) {
|
||||||
this.route = route;
|
this.route = route;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void nextActivity(TourActivity act, double arrTime, double endTime) {
|
public void visit(TourActivity act) {
|
||||||
if(act instanceof DeliveryActivity){
|
if(act instanceof DeliveryActivity){
|
||||||
deliveries += Math.abs(act.getCapacityDemand());
|
deliveries += Math.abs(act.getCapacityDemand());
|
||||||
}
|
}
|
||||||
|
|
@ -499,7 +465,7 @@ class StateUpdates {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void end(End end, double arrivalTime) {
|
public void finish() {
|
||||||
deliveries = 0;
|
deliveries = 0;
|
||||||
route = null;
|
route = null;
|
||||||
}
|
}
|
||||||
|
|
@ -512,7 +478,7 @@ class StateUpdates {
|
||||||
* @author stefan
|
* @author stefan
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static class UpdateLoadAtActivityLevel implements ForwardInTimeListener {
|
static class UpdateLoadAtActivityLevel implements ActivityVisitor {
|
||||||
private StateManagerImpl stateManager;
|
private StateManagerImpl stateManager;
|
||||||
private int currentLoad = 0;
|
private int currentLoad = 0;
|
||||||
private VehicleRoute route;
|
private VehicleRoute route;
|
||||||
|
|
@ -523,13 +489,13 @@ class StateUpdates {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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();
|
currentLoad = (int) stateManager.getRouteState(route, StateTypes.LOAD_AT_DEPOT).toDouble();
|
||||||
this.route = route;
|
this.route = route;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void nextActivity(TourActivity act, double arrTime, double endTime) {
|
public void visit(TourActivity act) {
|
||||||
currentLoad += act.getCapacityDemand();
|
currentLoad += act.getCapacityDemand();
|
||||||
stateManager.putActivityState(act, StateTypes.LOAD, new StateImpl(currentLoad));
|
stateManager.putActivityState(act, StateTypes.LOAD, new StateImpl(currentLoad));
|
||||||
assert currentLoad <= route.getVehicle().getCapacity() : "currentLoad at activity must not be > vehicleCapacity";
|
assert currentLoad <= route.getVehicle().getCapacity() : "currentLoad at activity must not be > vehicleCapacity";
|
||||||
|
|
@ -537,7 +503,7 @@ class StateUpdates {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void end(End end, double arrivalTime) {
|
public void finish() {
|
||||||
currentLoad = 0;
|
currentLoad = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -617,27 +583,27 @@ class StateUpdates {
|
||||||
|
|
||||||
static class UpdateRouteStatesOnceTheRouteHasBeenChanged implements InsertionStartsListener, JobInsertedListener {
|
static class UpdateRouteStatesOnceTheRouteHasBeenChanged implements InsertionStartsListener, JobInsertedListener {
|
||||||
|
|
||||||
private IterateRouteForwardInTime forwardInTimeIterator;
|
private RouteActivityVisitor forwardInTimeIterator;
|
||||||
|
|
||||||
private IterateRouteBackwardInTime backwardInTimeIterator;
|
private ReverseRouteActivityVisitor backwardInTimeIterator;
|
||||||
|
|
||||||
private Collection<InsertionStarts> insertionStartsListeners;
|
private Collection<InsertionStarts> insertionStartsListeners;
|
||||||
|
|
||||||
private Collection<JobInsertedListener> jobInsertionListeners;
|
private Collection<JobInsertedListener> jobInsertionListeners;
|
||||||
|
|
||||||
public UpdateRouteStatesOnceTheRouteHasBeenChanged(VehicleRoutingTransportCosts routingCosts) {
|
public UpdateRouteStatesOnceTheRouteHasBeenChanged(VehicleRoutingTransportCosts routingCosts) {
|
||||||
forwardInTimeIterator = new IterateRouteForwardInTime(routingCosts);
|
forwardInTimeIterator = new RouteActivityVisitor();
|
||||||
backwardInTimeIterator = new IterateRouteBackwardInTime(routingCosts);
|
backwardInTimeIterator = new ReverseRouteActivityVisitor();
|
||||||
insertionStartsListeners = new ArrayList<InsertionStarts>();
|
insertionStartsListeners = new ArrayList<InsertionStarts>();
|
||||||
jobInsertionListeners = new ArrayList<JobInsertedListener>();
|
jobInsertionListeners = new ArrayList<JobInsertedListener>();
|
||||||
}
|
}
|
||||||
|
|
||||||
void addListener(ForwardInTimeListener l){
|
void addVisitor(ActivityVisitor vis){
|
||||||
forwardInTimeIterator.addListener(l);
|
forwardInTimeIterator.addActivityVisitor(vis);
|
||||||
}
|
}
|
||||||
|
|
||||||
void addListener(BackwardInTimeListener l){
|
void addVisitor(ReverseActivityVisitor revVis){
|
||||||
backwardInTimeIterator.addListener(l);
|
backwardInTimeIterator.addActivityVisitor(revVis);
|
||||||
}
|
}
|
||||||
|
|
||||||
void addInsertionStartsListener(InsertionStarts insertionStartListener){
|
void addInsertionStartsListener(InsertionStarts insertionStartListener){
|
||||||
|
|
@ -651,8 +617,8 @@ class StateUpdates {
|
||||||
@Override
|
@Override
|
||||||
public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) {
|
public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) {
|
||||||
for(JobInsertedListener l : jobInsertionListeners){ l.informJobInserted(job2insert, inRoute, additionalCosts, additionalTime); }
|
for(JobInsertedListener l : jobInsertionListeners){ l.informJobInserted(job2insert, inRoute, additionalCosts, additionalTime); }
|
||||||
forwardInTimeIterator.iterate(inRoute);
|
forwardInTimeIterator.visit(inRoute);
|
||||||
backwardInTimeIterator.iterate(inRoute);
|
backwardInTimeIterator.visit(inRoute);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -661,8 +627,8 @@ class StateUpdates {
|
||||||
for(InsertionStarts insertionsStartsHandler : insertionStartsListeners){
|
for(InsertionStarts insertionsStartsHandler : insertionStartsListeners){
|
||||||
insertionsStartsHandler.insertionStarts(route);
|
insertionsStartsHandler.insertionStarts(route);
|
||||||
}
|
}
|
||||||
forwardInTimeIterator.iterate(route);
|
forwardInTimeIterator.visit(route);
|
||||||
backwardInTimeIterator.iterate(route);
|
backwardInTimeIterator.visit(route);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -506,13 +506,13 @@ public class VehicleRoutingAlgorithms {
|
||||||
routeChangedListener.addInsertionStartsListener(new StateUpdates.UpdateLoadsAtStartAndEndOfRouteWhenInsertionStarts(stateManager));
|
routeChangedListener.addInsertionStartsListener(new StateUpdates.UpdateLoadsAtStartAndEndOfRouteWhenInsertionStarts(stateManager));
|
||||||
routeChangedListener.addJobInsertedListener(new StateUpdates.UpdateLoadsAtStartAndEndOfRouteWhenJobHasBeenInserted(stateManager));
|
routeChangedListener.addJobInsertedListener(new StateUpdates.UpdateLoadsAtStartAndEndOfRouteWhenJobHasBeenInserted(stateManager));
|
||||||
|
|
||||||
routeChangedListener.addListener(new StateUpdates.UpdateActivityTimes());
|
routeChangedListener.addVisitor(new StateUpdates.UpdateActivityTimes(vrp.getTransportCosts()));
|
||||||
routeChangedListener.addListener(new StateUpdates.UpdateLoadAtActivityLevel(stateManager));
|
routeChangedListener.addVisitor(new StateUpdates.UpdateLoadAtActivityLevel(stateManager));
|
||||||
routeChangedListener.addListener(new StateUpdates.UpdateCostsAtAllLevels(vrp.getActivityCosts(), vrp.getTransportCosts(), stateManager));
|
routeChangedListener.addVisitor(new StateUpdates.UpdateCostsAtAllLevels(vrp.getActivityCosts(), vrp.getTransportCosts(), stateManager));
|
||||||
|
|
||||||
routeChangedListener.addListener(new StateUpdates.UpdateOccuredDeliveriesAtActivityLevel(stateManager));
|
routeChangedListener.addVisitor(new StateUpdates.UpdateOccuredDeliveriesAtActivityLevel(stateManager));
|
||||||
routeChangedListener.addListener(new StateUpdates.UpdateLatestOperationStartTimeAtActLocations(stateManager));
|
routeChangedListener.addVisitor(new StateUpdates.UpdateLatestOperationStartTimeAtActLocations(stateManager, vrp.getTransportCosts()));
|
||||||
routeChangedListener.addListener(new StateUpdates.UpdateFuturePickupsAtActivityLevel(stateManager));
|
routeChangedListener.addVisitor(new StateUpdates.UpdateFuturePickupsAtActivityLevel(stateManager));
|
||||||
|
|
||||||
metaAlgorithm.getSearchStrategyManager().addSearchStrategyModuleListener(routeChangedListener);
|
metaAlgorithm.getSearchStrategyManager().addSearchStrategyModuleListener(routeChangedListener);
|
||||||
metaAlgorithm.getSearchStrategyManager().addSearchStrategyModuleListener(new RemoveEmptyVehicles(vehicleFleetManager));
|
metaAlgorithm.getSearchStrategyManager().addSearchStrategyModuleListener(new RemoveEmptyVehicles(vehicleFleetManager));
|
||||||
|
|
|
||||||
|
|
@ -107,18 +107,18 @@ public class BuildPDVRPAlgoFromScratchTest {
|
||||||
|
|
||||||
vra.getAlgorithmListeners().addListener(new StateUpdates.ResetStateManager(stateManager));
|
vra.getAlgorithmListeners().addListener(new StateUpdates.ResetStateManager(stateManager));
|
||||||
|
|
||||||
final IterateRouteForwardInTime iterateForward = new IterateRouteForwardInTime(vrp.getTransportCosts());
|
final RouteActivityVisitor iterateForward = new RouteActivityVisitor();
|
||||||
|
|
||||||
iterateForward.addListener(new UpdateActivityTimes());
|
iterateForward.addActivityVisitor(new UpdateActivityTimes(vrp.getTransportCosts()));
|
||||||
iterateForward.addListener(new UpdateEarliestStartTimeWindowAtActLocations(stateManager));
|
iterateForward.addActivityVisitor(new UpdateEarliestStartTimeWindowAtActLocations(stateManager, vrp.getTransportCosts()));
|
||||||
iterateForward.addListener(new UpdateCostsAtAllLevels(vrp.getActivityCosts(), vrp.getTransportCosts(), stateManager));
|
iterateForward.addActivityVisitor(new UpdateCostsAtAllLevels(vrp.getActivityCosts(), vrp.getTransportCosts(), stateManager));
|
||||||
|
|
||||||
iterateForward.addListener(new StateUpdates.UpdateOccuredDeliveriesAtActivityLevel(stateManager));
|
iterateForward.addActivityVisitor(new StateUpdates.UpdateOccuredDeliveriesAtActivityLevel(stateManager));
|
||||||
iterateForward.addListener(new StateUpdates.UpdateLoadAtActivityLevel(stateManager));
|
iterateForward.addActivityVisitor(new StateUpdates.UpdateLoadAtActivityLevel(stateManager));
|
||||||
|
|
||||||
final IterateRouteBackwardInTime iterateBackward = new IterateRouteBackwardInTime(vrp.getTransportCosts());
|
final ReverseRouteActivityVisitor iterateBackward = new ReverseRouteActivityVisitor();
|
||||||
iterateBackward.addListener(new UpdateLatestOperationStartTimeAtActLocations(stateManager));
|
iterateBackward.addActivityVisitor(new UpdateLatestOperationStartTimeAtActLocations(stateManager, vrp.getTransportCosts()));
|
||||||
iterateBackward.addListener(new StateUpdates.UpdateFuturePickupsAtActivityLevel(stateManager));
|
iterateBackward.addActivityVisitor(new StateUpdates.UpdateFuturePickupsAtActivityLevel(stateManager));
|
||||||
|
|
||||||
|
|
||||||
InsertionStartsListener loadVehicleInDepot = new InsertionStartsListener() {
|
InsertionStartsListener loadVehicleInDepot = new InsertionStartsListener() {
|
||||||
|
|
@ -138,8 +138,8 @@ public class BuildPDVRPAlgoFromScratchTest {
|
||||||
}
|
}
|
||||||
stateManager.putRouteState(route, StateTypes.LOAD_AT_DEPOT, new StateImpl(loadAtDepot));
|
stateManager.putRouteState(route, StateTypes.LOAD_AT_DEPOT, new StateImpl(loadAtDepot));
|
||||||
stateManager.putRouteState(route, StateTypes.LOAD, new StateImpl(loadAtEnd));
|
stateManager.putRouteState(route, StateTypes.LOAD, new StateImpl(loadAtEnd));
|
||||||
iterateForward.iterate(route);
|
iterateForward.visit(route);
|
||||||
iterateBackward.iterate(route);
|
iterateBackward.visit(route);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -163,8 +163,8 @@ public class BuildPDVRPAlgoFromScratchTest {
|
||||||
// log.info("loadAtEnd="+loadAtEnd);
|
// log.info("loadAtEnd="+loadAtEnd);
|
||||||
stateManager.putRouteState(inRoute, StateTypes.LOAD, new StateImpl(loadAtEnd + job2insert.getCapacityDemand()));
|
stateManager.putRouteState(inRoute, StateTypes.LOAD, new StateImpl(loadAtEnd + job2insert.getCapacityDemand()));
|
||||||
}
|
}
|
||||||
iterateForward.iterate(inRoute);
|
iterateForward.visit(inRoute);
|
||||||
iterateBackward.iterate(inRoute);
|
iterateBackward.visit(inRoute);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -139,9 +139,9 @@ public class TestIterateRouteForwardInTime {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenIteratingWithActivityTimeUpdater_itShouldUpdateActivityTimes() {
|
public void whenIteratingWithActivityTimeUpdater_itShouldUpdateActivityTimes() {
|
||||||
IterateRouteForwardInTime forwardInTime = new IterateRouteForwardInTime(cost);
|
RouteActivityVisitor forwardInTime = new RouteActivityVisitor();
|
||||||
forwardInTime.addListener(new UpdateActivityTimes());
|
forwardInTime.addActivityVisitor(new UpdateActivityTimes(cost));
|
||||||
forwardInTime.iterate(vehicleRoute);
|
forwardInTime.visit(vehicleRoute);
|
||||||
|
|
||||||
assertEquals(10.0,firstAct.getArrTime(),0.1);
|
assertEquals(10.0,firstAct.getArrTime(),0.1);
|
||||||
assertEquals(10.0,firstAct.getEndTime(),0.1);
|
assertEquals(10.0,firstAct.getEndTime(),0.1);
|
||||||
|
|
@ -152,9 +152,9 @@ public class TestIterateRouteForwardInTime {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenIteratingWithLoadUpdateAtActLocations_itShouldUpdateLoad() {
|
public void whenIteratingWithLoadUpdateAtActLocations_itShouldUpdateLoad() {
|
||||||
IterateRouteForwardInTime forwardInTime = new IterateRouteForwardInTime(cost);
|
RouteActivityVisitor forwardInTime = new RouteActivityVisitor();
|
||||||
forwardInTime.addListener(new UpdateLoadAtAllLevels(stateManager));
|
forwardInTime.addActivityVisitor(new UpdateLoadAtAllLevels(stateManager));
|
||||||
forwardInTime.iterate(vehicleRoute);
|
forwardInTime.visit(vehicleRoute);
|
||||||
|
|
||||||
assertEquals(5.0, stateManager.getActivityState(firstAct,StateTypes.LOAD).toDouble(), 0.01);
|
assertEquals(5.0, stateManager.getActivityState(firstAct,StateTypes.LOAD).toDouble(), 0.01);
|
||||||
assertEquals(10.0, stateManager.getActivityState(secondAct,StateTypes.LOAD).toDouble(), 0.01);
|
assertEquals(10.0, stateManager.getActivityState(secondAct,StateTypes.LOAD).toDouble(), 0.01);
|
||||||
|
|
@ -163,8 +163,8 @@ public class TestIterateRouteForwardInTime {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStatesOfAct0(){
|
public void testStatesOfAct0(){
|
||||||
IterateRouteForwardInTime forwardInTime = new IterateRouteForwardInTime(cost);
|
RouteActivityVisitor forwardInTime = new RouteActivityVisitor();
|
||||||
forwardInTime.iterate(vehicleRoute);
|
forwardInTime.visit(vehicleRoute);
|
||||||
|
|
||||||
assertEquals(0.0, vehicleRoute.getStart().getEndTime(),0.05);
|
assertEquals(0.0, vehicleRoute.getStart().getEndTime(),0.05);
|
||||||
assertEquals(vehicleRoute.getVehicle().getLocationId(), vehicleRoute.getStart().getLocationId());
|
assertEquals(vehicleRoute.getVehicle().getLocationId(), vehicleRoute.getStart().getLocationId());
|
||||||
|
|
@ -175,11 +175,11 @@ public class TestIterateRouteForwardInTime {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStatesOfAct1(){
|
public void testStatesOfAct1(){
|
||||||
IterateRouteForwardInTime forwardInTime = new IterateRouteForwardInTime(cost);
|
RouteActivityVisitor forwardInTime = new RouteActivityVisitor();
|
||||||
forwardInTime.addListener(new UpdateLoadAtAllLevels(stateManager));
|
forwardInTime.addActivityVisitor(new UpdateLoadAtAllLevels(stateManager));
|
||||||
forwardInTime.addListener(new UpdateEarliestStartTimeWindowAtActLocations(stateManager));
|
forwardInTime.addActivityVisitor(new UpdateEarliestStartTimeWindowAtActLocations(stateManager, cost));
|
||||||
forwardInTime.addListener(new UpdateCostsAtAllLevels(new DefaultVehicleRoutingActivityCosts(), cost, stateManager));
|
forwardInTime.addActivityVisitor(new UpdateCostsAtAllLevels(new DefaultVehicleRoutingActivityCosts(), cost, stateManager));
|
||||||
forwardInTime.iterate(vehicleRoute);
|
forwardInTime.visit(vehicleRoute);
|
||||||
|
|
||||||
assertEquals(10.0, stateManager.getActivityState(firstAct, StateTypes.COSTS).toDouble(),0.05);
|
assertEquals(10.0, stateManager.getActivityState(firstAct, StateTypes.COSTS).toDouble(),0.05);
|
||||||
assertEquals(5.0, stateManager.getActivityState(firstAct, StateTypes.LOAD).toDouble(),0.05);
|
assertEquals(5.0, stateManager.getActivityState(firstAct, StateTypes.LOAD).toDouble(),0.05);
|
||||||
|
|
@ -189,12 +189,12 @@ public class TestIterateRouteForwardInTime {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStatesOfAct2(){
|
public void testStatesOfAct2(){
|
||||||
IterateRouteForwardInTime forwardInTime = new IterateRouteForwardInTime(cost);
|
RouteActivityVisitor forwardInTime = new RouteActivityVisitor();
|
||||||
|
|
||||||
forwardInTime.addListener(new UpdateLoadAtAllLevels(stateManager));
|
forwardInTime.addActivityVisitor(new UpdateLoadAtAllLevels(stateManager));
|
||||||
forwardInTime.addListener(new UpdateEarliestStartTimeWindowAtActLocations(stateManager));
|
forwardInTime.addActivityVisitor(new UpdateEarliestStartTimeWindowAtActLocations(stateManager, cost));
|
||||||
forwardInTime.addListener(new UpdateCostsAtAllLevels(new DefaultVehicleRoutingActivityCosts(), cost, stateManager));
|
forwardInTime.addActivityVisitor(new UpdateCostsAtAllLevels(new DefaultVehicleRoutingActivityCosts(), cost, stateManager));
|
||||||
forwardInTime.iterate(vehicleRoute);
|
forwardInTime.visit(vehicleRoute);
|
||||||
|
|
||||||
assertEquals(30.0, stateManager.getActivityState(secondAct, StateTypes.COSTS).toDouble(),0.05);
|
assertEquals(30.0, stateManager.getActivityState(secondAct, StateTypes.COSTS).toDouble(),0.05);
|
||||||
assertEquals(10.0, stateManager.getActivityState(secondAct, StateTypes.LOAD).toDouble(),0.05);
|
assertEquals(10.0, stateManager.getActivityState(secondAct, StateTypes.LOAD).toDouble(),0.05);
|
||||||
|
|
@ -204,11 +204,11 @@ public class TestIterateRouteForwardInTime {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStatesOfAct3(){
|
public void testStatesOfAct3(){
|
||||||
IterateRouteForwardInTime forwardInTime = new IterateRouteForwardInTime(cost);
|
RouteActivityVisitor forwardInTime = new RouteActivityVisitor();
|
||||||
|
|
||||||
forwardInTime.addListener(new UpdateActivityTimes());
|
forwardInTime.addActivityVisitor(new UpdateActivityTimes(cost));
|
||||||
forwardInTime.addListener(new UpdateCostsAtAllLevels(new DefaultVehicleRoutingActivityCosts(), cost, stateManager));
|
forwardInTime.addActivityVisitor(new UpdateCostsAtAllLevels(new DefaultVehicleRoutingActivityCosts(), cost, stateManager));
|
||||||
forwardInTime.iterate(vehicleRoute);
|
forwardInTime.visit(vehicleRoute);
|
||||||
|
|
||||||
assertEquals(40.0, stateManager.getRouteState(vehicleRoute,StateTypes.COSTS).toDouble(), 0.05);
|
assertEquals(40.0, stateManager.getRouteState(vehicleRoute,StateTypes.COSTS).toDouble(), 0.05);
|
||||||
assertEquals(40.0, vehicleRoute.getEnd().getArrTime(),0.05);
|
assertEquals(40.0, vehicleRoute.getEnd().getArrTime(),0.05);
|
||||||
|
|
|
||||||
|
|
@ -104,7 +104,7 @@ public class PickupAndDeliveryExample2 {
|
||||||
Plotter plotter = new Plotter(vrp, solution);
|
Plotter plotter = new Plotter(vrp, solution);
|
||||||
plotter.setLabel(Label.SIZE);
|
plotter.setLabel(Label.SIZE);
|
||||||
plotter.setShowFirstActivity(true);
|
plotter.setShowFirstActivity(true);
|
||||||
plotter.plot("output/pd_christophides_vrpnc1.png","pd_vrpnc1");
|
plotter.plot("output/pd_christophides_vrpnc1_solution.png","pd_vrpnc1");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,11 @@ import basics.VehicleRoutingAlgorithm;
|
||||||
import basics.VehicleRoutingProblem;
|
import basics.VehicleRoutingProblem;
|
||||||
import basics.VehicleRoutingProblemSolution;
|
import basics.VehicleRoutingProblemSolution;
|
||||||
import basics.VehicleRoutingProblem.Constraint;
|
import basics.VehicleRoutingProblem.Constraint;
|
||||||
|
import basics.costs.VehicleRoutingActivityCosts;
|
||||||
import basics.io.VrpXMLReader;
|
import basics.io.VrpXMLReader;
|
||||||
|
import basics.route.Driver;
|
||||||
|
import basics.route.TourActivity;
|
||||||
|
import basics.route.Vehicle;
|
||||||
|
|
||||||
public class VRPWithBackhaulsExample {
|
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).
|
* Finally, the problem can be built. By default, transportCosts are crowFlyDistances (as usually used for vrp-instances).
|
||||||
*/
|
*/
|
||||||
vrpBuilder.addProblemConstraint(Constraint.DELIVERIES_FIRST);
|
vrpBuilder.addProblemConstraint(Constraint.DELIVERIES_FIRST);
|
||||||
|
|
||||||
VehicleRoutingProblem vrp = vrpBuilder.build();
|
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.
|
* 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 plotter = new Plotter(vrp, solution);
|
||||||
plotter.setLabel(Label.SIZE);
|
plotter.setLabel(Label.SIZE);
|
||||||
plotter.setShowFirstActivity(true);
|
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");
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ public class VRPWithBackhaulsExample2 {
|
||||||
*/
|
*/
|
||||||
VehicleRoutingProblem vrp = vrpBuilder.build();
|
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.
|
* 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 plotter = new Plotter(vrp, solution);
|
||||||
plotter.setLabel(Label.SIZE);
|
plotter.setLabel(Label.SIZE);
|
||||||
plotter.setShowFirstActivity(true);
|
plotter.setShowFirstActivity(true);
|
||||||
plotter.plot("output/vrpwbh_christophides_vrpnc1.png","vrpwbh_vrpnc1");
|
plotter.plot("output/vrpwbh_christophides_vrpnc1_solution.png","vrpwbh_vrpnc1");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue