mirror of
https://github.com/graphhopper/jsprit.git
synced 2020-01-24 07:45:05 +01:00
Merge remote-tracking branch 'choose_remote_name/relaxAPI' into relaxAPI
This commit is contained in:
commit
0cd8101e89
47 changed files with 288 additions and 596 deletions
|
|
@ -1,72 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
* Copyright (C) 2013 Stefan Schroeder
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 3.0 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
******************************************************************************/
|
|
||||||
package algorithms;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
import basics.route.End;
|
|
||||||
import basics.route.Start;
|
|
||||||
import basics.route.TourActivity;
|
|
||||||
import basics.route.VehicleRoute;
|
|
||||||
|
|
||||||
class BackwardInTimeListeners {
|
|
||||||
|
|
||||||
interface BackwardInTimeListener{
|
|
||||||
|
|
||||||
public void start(VehicleRoute route, End end, double latestArrivalTime);
|
|
||||||
|
|
||||||
public void prevActivity(TourActivity act, double latestDepartureTime, double latestOperationStartTime);
|
|
||||||
|
|
||||||
public void end(Start start, double latestDepartureTime);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private Collection<BackwardInTimeListener> listeners = new ArrayList<BackwardInTimeListener>();
|
|
||||||
|
|
||||||
public void addListener(BackwardInTimeListener l){
|
|
||||||
listeners.add(l);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void start(VehicleRoute route, End end, double latestArrivalTime){
|
|
||||||
for(BackwardInTimeListener l : listeners){ l.start(route, end, latestArrivalTime); }
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Informs listener about nextActivity.
|
|
||||||
*
|
|
||||||
* <p>LatestDepartureTime is the theoretical latest departureTime to meet the latestOperationStartTimeWindow at the nextActivity (forward in time), i.e.
|
|
||||||
* assume act_i and act_j are two successive activities and the latestDepTime of act_j is 10pm. With a travelTime from act_i to act_j of 1h the latestDepartureTime at act_i is 9pm.
|
|
||||||
* However, the latestOperationStartTime of act_i is 8pm, then (with a serviceTime of 0) the latestOperationStartTime at act_i amounts to 8pm.
|
|
||||||
*
|
|
||||||
* @param act
|
|
||||||
* @param latestDepartureTime
|
|
||||||
* @param latestArrivalTime
|
|
||||||
*/
|
|
||||||
public void prevActivity(TourActivity act, double latestDepartureTime, double latestArrivalTime){
|
|
||||||
for(BackwardInTimeListener l : listeners){ l.prevActivity(act,latestDepartureTime,latestArrivalTime); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public void end(Start start, double latestDepartureTime){
|
|
||||||
for(BackwardInTimeListener l : listeners){ l.end(start, latestDepartureTime); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isEmpty() {
|
|
||||||
return listeners.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -4,7 +4,6 @@ import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import basics.VehicleRoutingProblem;
|
import basics.VehicleRoutingProblem;
|
||||||
import basics.VehicleRoutingProblem.Constraint;
|
|
||||||
import basics.algo.InsertionListener;
|
import basics.algo.InsertionListener;
|
||||||
import basics.algo.VehicleRoutingAlgorithmListeners.PrioritizedVRAListener;
|
import basics.algo.VehicleRoutingAlgorithmListeners.PrioritizedVRAListener;
|
||||||
import basics.route.VehicleFleetManager;
|
import basics.route.VehicleFleetManager;
|
||||||
|
|
@ -35,55 +34,15 @@ public class BestInsertionBuilder {
|
||||||
super();
|
super();
|
||||||
this.vrp = vrp;
|
this.vrp = vrp;
|
||||||
this.stateManager = stateManager;
|
this.stateManager = stateManager;
|
||||||
this.constraintManager = new ConstraintManager();
|
this.constraintManager = new ConstraintManager(vrp,stateManager);
|
||||||
this.fleetManager = vehicleFleetManager;
|
this.fleetManager = vehicleFleetManager;
|
||||||
addCoreStateUpdaters();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addCoreStateUpdaters(){
|
public BestInsertionBuilder setRouteLevel(int forwardLooking, int memory){
|
||||||
stateManager.addListener(new UpdateLoadsAtStartAndEndOfRouteWhenInsertionStarts(stateManager));
|
|
||||||
stateManager.addListener(new UpdateLoadsAtStartAndEndOfRouteWhenJobHasBeenInserted(stateManager));
|
|
||||||
|
|
||||||
stateManager.addActivityVisitor(new UpdateMaxLoad(stateManager));
|
|
||||||
stateManager.addActivityVisitor(new UpdateActivityTimes(vrp.getTransportCosts()));
|
|
||||||
stateManager.addActivityVisitor(new UpdateCostsAtAllLevels(vrp.getActivityCosts(), vrp.getTransportCosts(), stateManager));
|
|
||||||
}
|
|
||||||
|
|
||||||
public BestInsertionBuilder addHardLoadConstraints(){
|
|
||||||
constraintManager.addConstraint(new HardPickupAndDeliveryLoadRouteLevelConstraint(stateManager));
|
|
||||||
if(vrp.getProblemConstraints().contains(Constraint.DELIVERIES_FIRST)){
|
|
||||||
constraintManager.addConstraint(new HardPickupAndDeliveryBackhaulActivityLevelConstraint(stateManager));
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
constraintManager.addConstraint(new HardPickupAndDeliveryActivityLevelConstraint(stateManager));
|
|
||||||
}
|
|
||||||
stateManager.addActivityVisitor(new UpdateOccuredDeliveriesAtActivityLevel(stateManager));
|
|
||||||
stateManager.addActivityVisitor(new UpdateFuturePickupsAtActivityLevel(stateManager));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BestInsertionBuilder addHardTimeWindowConstraint(){
|
|
||||||
constraintManager.addConstraint(new HardTimeWindowActivityLevelConstraint(stateManager, vrp.getTransportCosts()));
|
|
||||||
// stateManager.addActivityVisitor(new UpdateEarliestStartTimeWindowAtActLocations(stateManager, vrp.getTransportCosts()));
|
|
||||||
stateManager.addActivityVisitor(new UpdateLatestOperationStartTimeAtActLocations(stateManager, vrp.getTransportCosts()));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public BestInsertionBuilder addConstraint(HardActivityLevelConstraint hardActvitiyLevelConstraint){
|
|
||||||
constraintManager.addConstraint(hardActvitiyLevelConstraint);
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
public BestInsertionBuilder addConstraint(HardRouteLevelConstraint hardRouteLevelConstraint){
|
|
||||||
constraintManager.addConstraint(hardRouteLevelConstraint);
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
public void setRouteLevel(int forwardLooking, int memory){
|
|
||||||
local = false;
|
local = false;
|
||||||
this.forwaredLooking = forwardLooking;
|
this.forwaredLooking = forwardLooking;
|
||||||
this.memory = memory;
|
this.memory = memory;
|
||||||
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
public BestInsertionBuilder setLocalLevel(){
|
public BestInsertionBuilder setLocalLevel(){
|
||||||
|
|
@ -126,4 +85,8 @@ public class BestInsertionBuilder {
|
||||||
return bestInsertion;
|
return bestInsertion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setConstraintManager(ConstraintManager constraintManager) {
|
||||||
|
this.constraintManager = constraintManager;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,53 @@
|
||||||
package algorithms;
|
package algorithms;
|
||||||
|
|
||||||
|
import basics.VehicleRoutingProblem;
|
||||||
import basics.route.TourActivity;
|
import basics.route.TourActivity;
|
||||||
|
|
||||||
class ConstraintManager implements HardActivityLevelConstraint, HardRouteLevelConstraint{
|
public class ConstraintManager implements HardActivityStateLevelConstraint, HardRouteStateLevelConstraint{
|
||||||
|
|
||||||
private HardActivityLevelConstraintManager actLevelConstraintManager = new HardActivityLevelConstraintManager();
|
private HardActivityLevelConstraintManager actLevelConstraintManager = new HardActivityLevelConstraintManager();
|
||||||
|
|
||||||
private HardRouteLevelConstraintManager routeLevelConstraintManager = new HardRouteLevelConstraintManager();
|
private HardRouteLevelConstraintManager routeLevelConstraintManager = new HardRouteLevelConstraintManager();
|
||||||
|
|
||||||
public void addConstraint(HardActivityLevelConstraint actLevelConstraint){
|
private VehicleRoutingProblem vrp;
|
||||||
|
|
||||||
|
private StateManager stateManager;
|
||||||
|
|
||||||
|
private boolean loadConstraintsSet = false;
|
||||||
|
|
||||||
|
private boolean timeWindowConstraintsSet = false;
|
||||||
|
|
||||||
|
public ConstraintManager(VehicleRoutingProblem vrp, StateManager stateManager) {
|
||||||
|
this.vrp = vrp;
|
||||||
|
this.stateManager = stateManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addTimeWindowConstraint(){
|
||||||
|
if(!timeWindowConstraintsSet){
|
||||||
|
addConstraint(new TimeWindowConstraint(stateManager, vrp.getTransportCosts()));
|
||||||
|
stateManager.addActivityVisitor(new TimeWindowUpdater(stateManager, vrp.getTransportCosts()));
|
||||||
|
timeWindowConstraintsSet = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addLoadConstraint(){
|
||||||
|
if(!loadConstraintsSet){
|
||||||
|
addConstraint(new ServiceLoadRouteLevelConstraint(stateManager));
|
||||||
|
addConstraint(new ServiceLoadActivityLevelConstraint(stateManager));
|
||||||
|
UpdateLoads updateLoads = new UpdateLoads(stateManager);
|
||||||
|
stateManager.addActivityVisitor(updateLoads);
|
||||||
|
stateManager.addListener(updateLoads);
|
||||||
|
stateManager.addActivityVisitor(new UpdateFuturePickups(stateManager));
|
||||||
|
stateManager.addActivityVisitor(new UpdateOccuredDeliveries(stateManager));
|
||||||
|
loadConstraintsSet=true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addConstraint(HardActivityStateLevelConstraint actLevelConstraint){
|
||||||
actLevelConstraintManager.addConstraint(actLevelConstraint);
|
actLevelConstraintManager.addConstraint(actLevelConstraint);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addConstraint(HardRouteLevelConstraint routeLevelConstraint){
|
public void addConstraint(HardRouteStateLevelConstraint routeLevelConstraint){
|
||||||
routeLevelConstraintManager.addConstraint(routeLevelConstraint);
|
routeLevelConstraintManager.addConstraint(routeLevelConstraint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,61 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
* Copyright (C) 2013 Stefan Schroeder
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 3.0 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
******************************************************************************/
|
|
||||||
package algorithms;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
import basics.route.End;
|
|
||||||
import basics.route.Start;
|
|
||||||
import basics.route.TourActivity;
|
|
||||||
import basics.route.VehicleRoute;
|
|
||||||
|
|
||||||
class ForwardInTimeListeners {
|
|
||||||
|
|
||||||
interface ForwardInTimeListener{
|
|
||||||
|
|
||||||
public void start(VehicleRoute route, Start start, double departureTime);
|
|
||||||
|
|
||||||
public void nextActivity(TourActivity act, double arrTime,double endTime);
|
|
||||||
|
|
||||||
public void end(End end, double arrivalTime);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private Collection<ForwardInTimeListener> listeners = new ArrayList<ForwardInTimeListeners.ForwardInTimeListener>();
|
|
||||||
|
|
||||||
public void addListener(ForwardInTimeListener l){
|
|
||||||
listeners.add(l);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void start(VehicleRoute route, Start start, double departureTime){
|
|
||||||
for(ForwardInTimeListener l : listeners){ l.start(route, start, departureTime); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public void nextActivity(TourActivity act, double arrTime, double endTime){
|
|
||||||
for(ForwardInTimeListener l : listeners){ l.nextActivity(act,arrTime,endTime); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public void end(End end, double arrivalTime){
|
|
||||||
for(ForwardInTimeListener l : listeners){ l.end(end, arrivalTime); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isEmpty() {
|
|
||||||
return listeners.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -5,17 +5,17 @@ import java.util.Collection;
|
||||||
|
|
||||||
import basics.route.TourActivity;
|
import basics.route.TourActivity;
|
||||||
|
|
||||||
class HardActivityLevelConstraintManager implements HardActivityLevelConstraint {
|
class HardActivityLevelConstraintManager implements HardActivityStateLevelConstraint {
|
||||||
|
|
||||||
private Collection<HardActivityLevelConstraint> hardConstraints = new ArrayList<HardActivityLevelConstraint>();
|
private Collection<HardActivityStateLevelConstraint> hardConstraints = new ArrayList<HardActivityStateLevelConstraint>();
|
||||||
|
|
||||||
public void addConstraint(HardActivityLevelConstraint constraint){
|
public void addConstraint(HardActivityStateLevelConstraint constraint){
|
||||||
hardConstraints.add(constraint);
|
hardConstraints.add(constraint);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ConstraintsStatus fulfilled(InsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
|
public ConstraintsStatus fulfilled(InsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
|
||||||
for(HardActivityLevelConstraint constraint : hardConstraints){
|
for(HardActivityStateLevelConstraint constraint : hardConstraints){
|
||||||
ConstraintsStatus status = constraint.fulfilled(iFacts, prevAct, newAct, nextAct, prevActDepTime);
|
ConstraintsStatus status = constraint.fulfilled(iFacts, prevAct, newAct, nextAct, prevActDepTime);
|
||||||
if(status.equals(ConstraintsStatus.NOT_FULFILLED_BREAK) || status.equals(ConstraintsStatus.NOT_FULFILLED)){
|
if(status.equals(ConstraintsStatus.NOT_FULFILLED_BREAK) || status.equals(ConstraintsStatus.NOT_FULFILLED)){
|
||||||
return status;
|
return status;
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ package algorithms;
|
||||||
|
|
||||||
import basics.route.TourActivity;
|
import basics.route.TourActivity;
|
||||||
|
|
||||||
public interface HardActivityLevelConstraint {
|
public interface HardActivityStateLevelConstraint {
|
||||||
|
|
||||||
static enum ConstraintsStatus {
|
static enum ConstraintsStatus {
|
||||||
|
|
||||||
|
|
@ -1,51 +0,0 @@
|
||||||
package algorithms;
|
|
||||||
|
|
||||||
import basics.route.DeliveryActivity;
|
|
||||||
import basics.route.PickupActivity;
|
|
||||||
import basics.route.ServiceActivity;
|
|
||||||
import basics.route.Start;
|
|
||||||
import basics.route.TourActivity;
|
|
||||||
|
|
||||||
class HardPickupAndDeliveryBackhaulActivityLevelConstraint implements HardActivityLevelConstraint {
|
|
||||||
|
|
||||||
private StateGetter stateManager;
|
|
||||||
|
|
||||||
public HardPickupAndDeliveryBackhaulActivityLevelConstraint(StateGetter stateManager) {
|
|
||||||
super();
|
|
||||||
this.stateManager = stateManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ConstraintsStatus fulfilled(InsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
|
|
||||||
if(newAct instanceof PickupActivity && nextAct instanceof DeliveryActivity){ return ConstraintsStatus.NOT_FULFILLED; }
|
|
||||||
if(newAct instanceof ServiceActivity && nextAct instanceof DeliveryActivity){ return ConstraintsStatus.NOT_FULFILLED; }
|
|
||||||
if(newAct instanceof DeliveryActivity && prevAct instanceof PickupActivity){ return ConstraintsStatus.NOT_FULFILLED; }
|
|
||||||
if(newAct instanceof DeliveryActivity && prevAct instanceof ServiceActivity){ return ConstraintsStatus.NOT_FULFILLED; }
|
|
||||||
int loadAtPrevAct;
|
|
||||||
int futurePicks;
|
|
||||||
int pastDeliveries;
|
|
||||||
if(prevAct instanceof Start){
|
|
||||||
loadAtPrevAct = (int)stateManager.getRouteState(iFacts.getRoute(), StateFactory.LOAD_AT_BEGINNING).toDouble();
|
|
||||||
futurePicks = (int)stateManager.getRouteState(iFacts.getRoute(), StateFactory.LOAD_AT_END).toDouble();
|
|
||||||
pastDeliveries = 0;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
loadAtPrevAct = (int) stateManager.getActivityState(prevAct, StateFactory.LOAD).toDouble();
|
|
||||||
futurePicks = (int) stateManager.getActivityState(prevAct, StateFactory.FUTURE_PICKS).toDouble();
|
|
||||||
pastDeliveries = (int) stateManager.getActivityState(prevAct, StateFactory.PAST_DELIVERIES).toDouble();
|
|
||||||
}
|
|
||||||
if(newAct instanceof PickupActivity || newAct instanceof ServiceActivity){
|
|
||||||
if(loadAtPrevAct + newAct.getCapacityDemand() + futurePicks > iFacts.getNewVehicle().getCapacity()){
|
|
||||||
return ConstraintsStatus.NOT_FULFILLED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(newAct instanceof DeliveryActivity){
|
|
||||||
if(loadAtPrevAct + Math.abs(newAct.getCapacityDemand()) + pastDeliveries > iFacts.getNewVehicle().getCapacity()){
|
|
||||||
return ConstraintsStatus.NOT_FULFILLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return ConstraintsStatus.FULFILLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -4,17 +4,17 @@ import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
|
|
||||||
class HardRouteLevelConstraintManager implements HardRouteLevelConstraint {
|
class HardRouteLevelConstraintManager implements HardRouteStateLevelConstraint {
|
||||||
|
|
||||||
private Collection<HardRouteLevelConstraint> hardConstraints = new ArrayList<HardRouteLevelConstraint>();
|
private Collection<HardRouteStateLevelConstraint> hardConstraints = new ArrayList<HardRouteStateLevelConstraint>();
|
||||||
|
|
||||||
public void addConstraint(HardRouteLevelConstraint constraint){
|
public void addConstraint(HardRouteStateLevelConstraint constraint){
|
||||||
hardConstraints.add(constraint);
|
hardConstraints.add(constraint);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean fulfilled(InsertionContext insertionContext) {
|
public boolean fulfilled(InsertionContext insertionContext) {
|
||||||
for(HardRouteLevelConstraint constraint : hardConstraints){
|
for(HardRouteStateLevelConstraint constraint : hardConstraints){
|
||||||
if(!constraint.fulfilled(insertionContext)){
|
if(!constraint.fulfilled(insertionContext)){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
package algorithms;
|
package algorithms;
|
||||||
|
|
||||||
|
|
||||||
public interface HardRouteLevelConstraint {
|
public interface HardRouteStateLevelConstraint {
|
||||||
|
|
||||||
public boolean fulfilled(InsertionContext insertionContext);
|
public boolean fulfilled(InsertionContext insertionContext);
|
||||||
|
|
||||||
|
|
@ -31,7 +31,7 @@ import basics.costs.VehicleRoutingTransportCosts;
|
||||||
* @author stefan schroeder
|
* @author stefan schroeder
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class JobDistanceAvgCosts implements JobDistance {
|
public class JobDistanceAvgCosts implements JobDistance {
|
||||||
|
|
||||||
private static Logger log = Logger.getLogger(JobDistanceAvgCosts.class);
|
private static Logger log = Logger.getLogger(JobDistanceAvgCosts.class);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ import basics.route.TourActivity;
|
||||||
* @author stefan
|
* @author stefan
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class LocalActivityInsertionCostsCalculator implements ActivityInsertionCostsCalculator{
|
public class LocalActivityInsertionCostsCalculator implements ActivityInsertionCostsCalculator{
|
||||||
|
|
||||||
private VehicleRoutingTransportCosts routingCosts;
|
private VehicleRoutingTransportCosts routingCosts;
|
||||||
private VehicleRoutingActivityCosts activityCosts;
|
private VehicleRoutingActivityCosts activityCosts;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
package algorithms;
|
||||||
|
|
||||||
|
import basics.route.DeliveryActivity;
|
||||||
|
import basics.route.PickupActivity;
|
||||||
|
import basics.route.ServiceActivity;
|
||||||
|
import basics.route.Start;
|
||||||
|
import basics.route.TourActivity;
|
||||||
|
|
||||||
|
public class ServiceBackhaulConstraint implements HardActivityStateLevelConstraint {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConstraintsStatus fulfilled(InsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
|
||||||
|
if(newAct instanceof PickupActivity && nextAct instanceof DeliveryActivity){ return ConstraintsStatus.NOT_FULFILLED; }
|
||||||
|
if(newAct instanceof ServiceActivity && nextAct instanceof DeliveryActivity){ return ConstraintsStatus.NOT_FULFILLED; }
|
||||||
|
if(newAct instanceof DeliveryActivity && prevAct instanceof PickupActivity){ return ConstraintsStatus.NOT_FULFILLED; }
|
||||||
|
if(newAct instanceof DeliveryActivity && prevAct instanceof ServiceActivity){ return ConstraintsStatus.NOT_FULFILLED; }
|
||||||
|
return ConstraintsStatus.FULFILLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -20,7 +20,7 @@ import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import util.Neighborhood;
|
import util.Neighborhood;
|
||||||
import algorithms.ActivityInsertionCostsCalculator.ActivityInsertionCosts;
|
import algorithms.ActivityInsertionCostsCalculator.ActivityInsertionCosts;
|
||||||
import algorithms.HardActivityLevelConstraint.ConstraintsStatus;
|
import algorithms.HardActivityStateLevelConstraint.ConstraintsStatus;
|
||||||
import basics.Job;
|
import basics.Job;
|
||||||
import basics.Service;
|
import basics.Service;
|
||||||
import basics.costs.VehicleRoutingTransportCosts;
|
import basics.costs.VehicleRoutingTransportCosts;
|
||||||
|
|
@ -40,9 +40,9 @@ final class ServiceInsertionCalculator implements JobInsertionCostsCalculator{
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(ServiceInsertionCalculator.class);
|
private static final Logger logger = Logger.getLogger(ServiceInsertionCalculator.class);
|
||||||
|
|
||||||
private HardRouteLevelConstraint hardRouteLevelConstraint;
|
private HardRouteStateLevelConstraint hardRouteLevelConstraint;
|
||||||
|
|
||||||
private HardActivityLevelConstraint hardActivityLevelConstraint;
|
private HardActivityStateLevelConstraint hardActivityLevelConstraint;
|
||||||
|
|
||||||
private Neighborhood neighborhood = new Neighborhood() {
|
private Neighborhood neighborhood = new Neighborhood() {
|
||||||
|
|
||||||
|
|
@ -64,7 +64,7 @@ final class ServiceInsertionCalculator implements JobInsertionCostsCalculator{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public ServiceInsertionCalculator(VehicleRoutingTransportCosts routingCosts, ActivityInsertionCostsCalculator activityInsertionCostsCalculator, HardRouteLevelConstraint hardRouteLevelConstraint, HardActivityLevelConstraint hardActivityLevelConstraint) {
|
public ServiceInsertionCalculator(VehicleRoutingTransportCosts routingCosts, ActivityInsertionCostsCalculator activityInsertionCostsCalculator, HardRouteStateLevelConstraint hardRouteLevelConstraint, HardActivityStateLevelConstraint hardActivityLevelConstraint) {
|
||||||
super();
|
super();
|
||||||
this.activityInsertionCostsCalculator = activityInsertionCostsCalculator;
|
this.activityInsertionCostsCalculator = activityInsertionCostsCalculator;
|
||||||
this.hardRouteLevelConstraint = hardRouteLevelConstraint;
|
this.hardRouteLevelConstraint = hardRouteLevelConstraint;
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import util.Neighborhood;
|
import util.Neighborhood;
|
||||||
import algorithms.ActivityInsertionCostsCalculator.ActivityInsertionCosts;
|
import algorithms.ActivityInsertionCostsCalculator.ActivityInsertionCosts;
|
||||||
import algorithms.HardActivityLevelConstraint.ConstraintsStatus;
|
import algorithms.HardActivityStateLevelConstraint.ConstraintsStatus;
|
||||||
import basics.Job;
|
import basics.Job;
|
||||||
import basics.Service;
|
import basics.Service;
|
||||||
import basics.costs.VehicleRoutingActivityCosts;
|
import basics.costs.VehicleRoutingActivityCosts;
|
||||||
|
|
@ -59,9 +59,9 @@ final class ServiceInsertionOnRouteLevelCalculator implements JobInsertionCostsC
|
||||||
|
|
||||||
private StateGetter stateManager;
|
private StateGetter stateManager;
|
||||||
|
|
||||||
private HardRouteLevelConstraint hardRouteLevelConstraint;
|
private HardRouteStateLevelConstraint hardRouteLevelConstraint;
|
||||||
|
|
||||||
private HardActivityLevelConstraint hardActivityLevelConstraint;
|
private HardActivityStateLevelConstraint hardActivityLevelConstraint;
|
||||||
|
|
||||||
private ActivityInsertionCostsCalculator activityInsertionCostsCalculator;
|
private ActivityInsertionCostsCalculator activityInsertionCostsCalculator;
|
||||||
|
|
||||||
|
|
@ -96,7 +96,7 @@ final class ServiceInsertionOnRouteLevelCalculator implements JobInsertionCostsC
|
||||||
logger.info("set [solutionMemory="+memorySize+"]");
|
logger.info("set [solutionMemory="+memorySize+"]");
|
||||||
}
|
}
|
||||||
|
|
||||||
public ServiceInsertionOnRouteLevelCalculator(VehicleRoutingTransportCosts vehicleRoutingCosts, VehicleRoutingActivityCosts costFunc, ActivityInsertionCostsCalculator activityInsertionCostsCalculator, HardRouteLevelConstraint hardRouteLevelConstraint, HardActivityLevelConstraint hardActivityLevelConstraint) {
|
public ServiceInsertionOnRouteLevelCalculator(VehicleRoutingTransportCosts vehicleRoutingCosts, VehicleRoutingActivityCosts costFunc, ActivityInsertionCostsCalculator activityInsertionCostsCalculator, HardRouteStateLevelConstraint hardRouteLevelConstraint, HardActivityStateLevelConstraint hardActivityLevelConstraint) {
|
||||||
super();
|
super();
|
||||||
this.transportCosts = vehicleRoutingCosts;
|
this.transportCosts = vehicleRoutingCosts;
|
||||||
this.activityCosts = costFunc;
|
this.activityCosts = costFunc;
|
||||||
|
|
|
||||||
|
|
@ -6,11 +6,20 @@ import basics.route.ServiceActivity;
|
||||||
import basics.route.Start;
|
import basics.route.Start;
|
||||||
import basics.route.TourActivity;
|
import basics.route.TourActivity;
|
||||||
|
|
||||||
class HardPickupAndDeliveryActivityLevelConstraint implements HardActivityLevelConstraint {
|
/**
|
||||||
|
* Ensures load constraint for inserting ServiceActivity.
|
||||||
|
*
|
||||||
|
* <p>When using this, you need to use<br>
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @author schroeder
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class ServiceLoadActivityLevelConstraint implements HardActivityStateLevelConstraint {
|
||||||
|
|
||||||
private StateGetter stateManager;
|
private StateGetter stateManager;
|
||||||
|
|
||||||
public HardPickupAndDeliveryActivityLevelConstraint(StateGetter stateManager) {
|
public ServiceLoadActivityLevelConstraint(StateGetter stateManager) {
|
||||||
super();
|
super();
|
||||||
this.stateManager = stateManager;
|
this.stateManager = stateManager;
|
||||||
}
|
}
|
||||||
|
|
@ -10,11 +10,11 @@ import basics.Service;
|
||||||
* @author stefan
|
* @author stefan
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class HardPickupAndDeliveryLoadRouteLevelConstraint implements HardRouteLevelConstraint {
|
class ServiceLoadRouteLevelConstraint implements HardRouteStateLevelConstraint {
|
||||||
|
|
||||||
private StateGetter stateManager;
|
private StateGetter stateManager;
|
||||||
|
|
||||||
public HardPickupAndDeliveryLoadRouteLevelConstraint(StateGetter stateManager) {
|
public ServiceLoadRouteLevelConstraint(StateGetter stateManager) {
|
||||||
super();
|
super();
|
||||||
this.stateManager = stateManager;
|
this.stateManager = stateManager;
|
||||||
}
|
}
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
package algorithms;
|
|
||||||
|
|
||||||
import basics.VehicleRoutingProblem;
|
|
||||||
|
|
||||||
class StateUtils {
|
|
||||||
|
|
||||||
public static void addCoreStateUpdaters(VehicleRoutingProblem vrp, StateManager stateManager){
|
|
||||||
stateManager.addListener(new UpdateLoadsAtStartAndEndOfRouteWhenInsertionStarts(stateManager));
|
|
||||||
stateManager.addListener(new UpdateLoadsAtStartAndEndOfRouteWhenJobHasBeenInserted(stateManager));
|
|
||||||
|
|
||||||
stateManager.addActivityVisitor(new UpdateActivityTimes(vrp.getTransportCosts()));
|
|
||||||
stateManager.addActivityVisitor(new UpdateLoadAtActivityLevel(stateManager));
|
|
||||||
|
|
||||||
stateManager.addActivityVisitor(new UpdateCostsAtAllLevels(vrp.getActivityCosts(), vrp.getTransportCosts(), stateManager));
|
|
||||||
|
|
||||||
stateManager.addActivityVisitor(new UpdateOccuredDeliveriesAtActivityLevel(stateManager));
|
|
||||||
|
|
||||||
stateManager.addActivityVisitor(new UpdateLatestOperationStartTimeAtActLocations(stateManager, vrp.getTransportCosts()));
|
|
||||||
|
|
||||||
stateManager.addActivityVisitor(new UpdateFuturePickupsAtActivityLevel(stateManager));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -10,15 +10,15 @@ import basics.route.TourActivity;
|
||||||
* @author stefan
|
* @author stefan
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class HardTimeWindowActivityLevelConstraint implements HardActivityLevelConstraint {
|
class TimeWindowConstraint implements HardActivityStateLevelConstraint {
|
||||||
|
|
||||||
private static Logger log = Logger.getLogger(HardTimeWindowActivityLevelConstraint.class);
|
private static Logger log = Logger.getLogger(TimeWindowConstraint.class);
|
||||||
|
|
||||||
private StateGetter states;
|
private StateGetter states;
|
||||||
|
|
||||||
private VehicleRoutingTransportCosts routingCosts;
|
private VehicleRoutingTransportCosts routingCosts;
|
||||||
|
|
||||||
public HardTimeWindowActivityLevelConstraint(StateGetter states, VehicleRoutingTransportCosts routingCosts) {
|
public TimeWindowConstraint(StateGetter states, VehicleRoutingTransportCosts routingCosts) {
|
||||||
super();
|
super();
|
||||||
this.states = states;
|
this.states = states;
|
||||||
this.routingCosts = routingCosts;
|
this.routingCosts = routingCosts;
|
||||||
|
|
@ -8,9 +8,9 @@ import basics.route.ReverseActivityVisitor;
|
||||||
import basics.route.TourActivity;
|
import basics.route.TourActivity;
|
||||||
import basics.route.VehicleRoute;
|
import basics.route.VehicleRoute;
|
||||||
|
|
||||||
class UpdateLatestOperationStartTimeAtActLocations implements ReverseActivityVisitor, StateUpdater{
|
class TimeWindowUpdater implements ReverseActivityVisitor, StateUpdater{
|
||||||
|
|
||||||
private static Logger log = Logger.getLogger(UpdateLatestOperationStartTimeAtActLocations.class);
|
private static Logger log = Logger.getLogger(TimeWindowUpdater.class);
|
||||||
|
|
||||||
private StateManager states;
|
private StateManager states;
|
||||||
|
|
||||||
|
|
@ -22,7 +22,7 @@ class UpdateLatestOperationStartTimeAtActLocations implements ReverseActivityVis
|
||||||
|
|
||||||
private TourActivity prevAct;
|
private TourActivity prevAct;
|
||||||
|
|
||||||
public UpdateLatestOperationStartTimeAtActLocations(StateManager states, VehicleRoutingTransportCosts tpCosts) {
|
public TimeWindowUpdater(StateManager states, VehicleRoutingTransportCosts tpCosts) {
|
||||||
super();
|
super();
|
||||||
this.states = states;
|
this.states = states;
|
||||||
this.transportCosts = tpCosts;
|
this.transportCosts = tpCosts;
|
||||||
|
|
@ -7,13 +7,13 @@ import basics.route.ActivityVisitor;
|
||||||
import basics.route.TourActivity;
|
import basics.route.TourActivity;
|
||||||
import basics.route.VehicleRoute;
|
import basics.route.VehicleRoute;
|
||||||
|
|
||||||
class UpdateEarliestStartTimeWindowAtActLocations implements ActivityVisitor,StateUpdater{
|
class UpdateEarliestStartTime implements ActivityVisitor,StateUpdater{
|
||||||
|
|
||||||
private StateManager states;
|
private StateManager states;
|
||||||
|
|
||||||
private ActivityTimeTracker timeTracker;
|
private ActivityTimeTracker timeTracker;
|
||||||
|
|
||||||
public UpdateEarliestStartTimeWindowAtActLocations(StateManager states, VehicleRoutingTransportCosts transportCosts) {
|
public UpdateEarliestStartTime(StateManager states, VehicleRoutingTransportCosts transportCosts) {
|
||||||
super();
|
super();
|
||||||
this.states = states;
|
this.states = states;
|
||||||
timeTracker = new ActivityTimeTracker(transportCosts);
|
timeTracker = new ActivityTimeTracker(transportCosts);
|
||||||
|
|
@ -6,12 +6,12 @@ import basics.route.ServiceActivity;
|
||||||
import basics.route.TourActivity;
|
import basics.route.TourActivity;
|
||||||
import basics.route.VehicleRoute;
|
import basics.route.VehicleRoute;
|
||||||
|
|
||||||
class UpdateFuturePickupsAtActivityLevel implements ReverseActivityVisitor, StateUpdater {
|
class UpdateFuturePickups implements ReverseActivityVisitor, StateUpdater {
|
||||||
private StateManager stateManager;
|
private StateManager stateManager;
|
||||||
private int futurePicks = 0;
|
private int futurePicks = 0;
|
||||||
private VehicleRoute route;
|
private VehicleRoute route;
|
||||||
|
|
||||||
public UpdateFuturePickupsAtActivityLevel(StateManager stateManager) {
|
public UpdateFuturePickups(StateManager stateManager) {
|
||||||
super();
|
super();
|
||||||
this.stateManager = stateManager;
|
this.stateManager = stateManager;
|
||||||
}
|
}
|
||||||
|
|
@ -1,67 +0,0 @@
|
||||||
package algorithms;
|
|
||||||
|
|
||||||
import algorithms.StateManager.StateImpl;
|
|
||||||
import basics.route.ActivityVisitor;
|
|
||||||
import basics.route.TourActivity;
|
|
||||||
import basics.route.VehicleRoute;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates load at activity level.
|
|
||||||
*
|
|
||||||
* <p>Note that this assumes that StateTypes.LOAD_AT_DEPOT is already updated, i.e. it starts by setting loadAtDepot to StateTypes.LOAD_AT_DEPOT.
|
|
||||||
* If StateTypes.LOAD_AT_DEPOT is not set, it starts with 0 load at depot.
|
|
||||||
*
|
|
||||||
* <p>Thus it DEPENDS on StateTypes.LOAD_AT_DEPOT
|
|
||||||
*
|
|
||||||
* @author stefan
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
class UpdateLoadAtActivityLevel implements ActivityVisitor, StateUpdater {
|
|
||||||
private StateManager stateManager;
|
|
||||||
private int currentLoad = 0;
|
|
||||||
private VehicleRoute route;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates load at activity level.
|
|
||||||
*
|
|
||||||
* <p>Note that this assumes that StateTypes.LOAD_AT_DEPOT is already updated, i.e. it starts by setting loadAtDepot to StateTypes.LOAD_AT_DEPOT.
|
|
||||||
* If StateTypes.LOAD_AT_DEPOT is not set, it starts with 0 load at depot.
|
|
||||||
*
|
|
||||||
* <p>Thus it DEPENDS on StateTypes.LOAD_AT_DEPOT
|
|
||||||
*
|
|
||||||
* <p>If you want to update StateTypes.LOAD_AT_DEPOT see {@link UpdateLoadsAtStartAndEndOfRouteWhenInsertionStarts}, {@link UpdateLoadsAtStartAndEndOfRouteWhenJobHasBeenInserted}
|
|
||||||
*
|
|
||||||
* <p>The loads can be retrieved by <br>
|
|
||||||
* <code>stateManager.getActivityState(activity,StateTypes.LOAD);</code>
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @see {@link UpdateLoadsAtStartAndEndOfRouteWhenInsertionStarts}, {@link UpdateLoadsAtStartAndEndOfRouteWhenJobHasBeenInserted}
|
|
||||||
* @author stefan
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public UpdateLoadAtActivityLevel(StateManager stateManager) {
|
|
||||||
super();
|
|
||||||
this.stateManager = stateManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void begin(VehicleRoute route) {
|
|
||||||
currentLoad = (int) stateManager.getRouteState(route, StateFactory.LOAD_AT_BEGINNING).toDouble();
|
|
||||||
this.route = route;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(TourActivity act) {
|
|
||||||
currentLoad += act.getCapacityDemand();
|
|
||||||
stateManager.putActivityState(act, StateFactory.LOAD, StateFactory.createState(currentLoad));
|
|
||||||
assert currentLoad <= route.getVehicle().getCapacity() : "currentLoad at activity must not be > vehicleCapacity";
|
|
||||||
assert currentLoad >= 0 : "currentLoad at act must not be < 0";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void finish() {
|
|
||||||
// stateManager.putRouteState(route, StateFactory., state)
|
|
||||||
currentLoad = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
||||||
package algorithms;
|
|
||||||
|
|
||||||
import algorithms.StateManager.StateImpl;
|
|
||||||
import basics.route.ActivityVisitor;
|
|
||||||
import basics.route.TourActivity;
|
|
||||||
import basics.route.VehicleRoute;
|
|
||||||
|
|
||||||
class UpdateLoadAtAllLevels implements ActivityVisitor,StateUpdater{
|
|
||||||
|
|
||||||
private double load = 0.0;
|
|
||||||
|
|
||||||
private StateManager states;
|
|
||||||
|
|
||||||
private VehicleRoute vehicleRoute;
|
|
||||||
|
|
||||||
public UpdateLoadAtAllLevels(StateManager states) {
|
|
||||||
super();
|
|
||||||
this.states = states;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void begin(VehicleRoute route) {
|
|
||||||
vehicleRoute = route;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(TourActivity activity) {
|
|
||||||
load += (double)activity.getCapacityDemand();
|
|
||||||
states.putActivityState(activity, StateFactory.LOAD, new StateImpl(load));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void finish() {
|
|
||||||
states.putRouteState(vehicleRoute, StateFactory.LOAD, new StateImpl(load));
|
|
||||||
load=0;
|
|
||||||
vehicleRoute = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
104
jsprit-core/src/main/java/algorithms/UpdateLoads.java
Normal file
104
jsprit-core/src/main/java/algorithms/UpdateLoads.java
Normal file
|
|
@ -0,0 +1,104 @@
|
||||||
|
package algorithms;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import basics.Delivery;
|
||||||
|
import basics.Job;
|
||||||
|
import basics.Pickup;
|
||||||
|
import basics.Service;
|
||||||
|
import basics.algo.InsertionStartsListener;
|
||||||
|
import basics.algo.JobInsertedListener;
|
||||||
|
import basics.route.ActivityVisitor;
|
||||||
|
import basics.route.TourActivity;
|
||||||
|
import basics.route.VehicleRoute;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates load at activity level.
|
||||||
|
*
|
||||||
|
* <p>Note that this assumes that StateTypes.LOAD_AT_DEPOT is already updated, i.e. it starts by setting loadAtDepot to StateTypes.LOAD_AT_DEPOT.
|
||||||
|
* If StateTypes.LOAD_AT_DEPOT is not set, it starts with 0 load at depot.
|
||||||
|
*
|
||||||
|
* <p>Thus it DEPENDS on StateTypes.LOAD_AT_DEPOT
|
||||||
|
*
|
||||||
|
* @author stefan
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class UpdateLoads implements ActivityVisitor, StateUpdater, InsertionStartsListener, JobInsertedListener {
|
||||||
|
private StateManager stateManager;
|
||||||
|
private int currentLoad = 0;
|
||||||
|
private VehicleRoute route;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates load at activity level.
|
||||||
|
*
|
||||||
|
* <p>Note that this assumes that StateTypes.LOAD_AT_DEPOT is already updated, i.e. it starts by setting loadAtDepot to StateTypes.LOAD_AT_DEPOT.
|
||||||
|
* If StateTypes.LOAD_AT_DEPOT is not set, it starts with 0 load at depot.
|
||||||
|
*
|
||||||
|
* <p>Thus it DEPENDS on StateTypes.LOAD_AT_DEPOT
|
||||||
|
*
|
||||||
|
* <p>The loads can be retrieved by <br>
|
||||||
|
* <code>stateManager.getActivityState(activity,StateTypes.LOAD);</code>
|
||||||
|
*
|
||||||
|
* @author stefan
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public UpdateLoads(StateManager stateManager) {
|
||||||
|
super();
|
||||||
|
this.stateManager = stateManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void begin(VehicleRoute route) {
|
||||||
|
currentLoad = (int) stateManager.getRouteState(route, StateFactory.LOAD_AT_BEGINNING).toDouble();
|
||||||
|
this.route = route;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(TourActivity act) {
|
||||||
|
currentLoad += act.getCapacityDemand();
|
||||||
|
stateManager.putActivityState(act, StateFactory.LOAD, StateFactory.createState(currentLoad));
|
||||||
|
assert currentLoad <= route.getVehicle().getCapacity() : "currentLoad at activity must not be > vehicleCapacity";
|
||||||
|
assert currentLoad >= 0 : "currentLoad at act must not be < 0";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void finish() {
|
||||||
|
// stateManager.putRouteState(route, StateFactory., state)
|
||||||
|
currentLoad = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void insertionStarts(VehicleRoute route) {
|
||||||
|
int loadAtDepot = 0;
|
||||||
|
int loadAtEnd = 0;
|
||||||
|
for(Job j : route.getTourActivities().getJobs()){
|
||||||
|
if(j instanceof Delivery){
|
||||||
|
loadAtDepot += j.getCapacityDemand();
|
||||||
|
}
|
||||||
|
else if(j instanceof Pickup || j instanceof Service){
|
||||||
|
loadAtEnd += j.getCapacityDemand();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stateManager.putRouteState(route, StateFactory.LOAD_AT_BEGINNING, StateFactory.createState(loadAtDepot));
|
||||||
|
stateManager.putRouteState(route, StateFactory.LOAD_AT_END, StateFactory.createState(loadAtEnd));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void informInsertionStarts(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs) {
|
||||||
|
for(VehicleRoute route : vehicleRoutes){ insertionStarts(route); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) {
|
||||||
|
if(job2insert instanceof Delivery){
|
||||||
|
int loadAtDepot = (int) stateManager.getRouteState(inRoute, StateFactory.LOAD_AT_BEGINNING).toDouble();
|
||||||
|
// log.info("loadAtDepot="+loadAtDepot);
|
||||||
|
stateManager.putRouteState(inRoute, StateFactory.LOAD_AT_BEGINNING, StateFactory.createState(loadAtDepot + job2insert.getCapacityDemand()));
|
||||||
|
}
|
||||||
|
else if(job2insert instanceof Pickup || job2insert instanceof Service){
|
||||||
|
int loadAtEnd = (int) stateManager.getRouteState(inRoute, StateFactory.LOAD_AT_END).toDouble();
|
||||||
|
// log.info("loadAtEnd="+loadAtEnd);
|
||||||
|
stateManager.putRouteState(inRoute, StateFactory.LOAD_AT_END, StateFactory.createState(loadAtEnd + job2insert.getCapacityDemand()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,62 +0,0 @@
|
||||||
package algorithms;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
import algorithms.StateManager.StateImpl;
|
|
||||||
import basics.Delivery;
|
|
||||||
import basics.Job;
|
|
||||||
import basics.Pickup;
|
|
||||||
import basics.Service;
|
|
||||||
import basics.algo.InsertionStartsListener;
|
|
||||||
import basics.route.VehicleRoute;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes the load of each route/vehicle at start- and end-location before insertion starts.
|
|
||||||
*
|
|
||||||
* <p>StateTypes.LOAD_AT_DEPOT and StateTypes.LOAD are modified for each route
|
|
||||||
* <p>These states can be retrieved by <br>
|
|
||||||
* stateManager.getRouteState(route, StateTypes.LOAD_AT_DEPOT) for LOAD_AT_DEPOT and <br>
|
|
||||||
* stateManager.getRouteState(route, StateTypes.LOAD) for LOAD (i.e. load at end)
|
|
||||||
*
|
|
||||||
* @param stateManager
|
|
||||||
*/
|
|
||||||
class UpdateLoadsAtStartAndEndOfRouteWhenInsertionStarts implements InsertionStartsListener {
|
|
||||||
|
|
||||||
private StateManager stateManager;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes the load of each route/vehicle at start- and end-location before insertion starts.
|
|
||||||
*
|
|
||||||
* <p>StateTypes.LOAD_AT_DEPOT and StateTypes.LOAD are modified for each route
|
|
||||||
* <p>These states can be retrieved by <br>
|
|
||||||
* stateManager.getRouteState(route, StateTypes.LOAD_AT_DEPOT) for LOAD_AT_DEPOT and <br>
|
|
||||||
* stateManager.getRouteState(route, StateTypes.LOAD) for LOAD (i.e. load at end)
|
|
||||||
*
|
|
||||||
* @param stateManager
|
|
||||||
*/
|
|
||||||
public UpdateLoadsAtStartAndEndOfRouteWhenInsertionStarts(StateManager stateManager) {
|
|
||||||
super();
|
|
||||||
this.stateManager = stateManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
void insertionStarts(VehicleRoute route) {
|
|
||||||
int loadAtDepot = 0;
|
|
||||||
int loadAtEnd = 0;
|
|
||||||
for(Job j : route.getTourActivities().getJobs()){
|
|
||||||
if(j instanceof Delivery){
|
|
||||||
loadAtDepot += j.getCapacityDemand();
|
|
||||||
}
|
|
||||||
else if(j instanceof Pickup || j instanceof Service){
|
|
||||||
loadAtEnd += j.getCapacityDemand();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stateManager.putRouteState(route, StateFactory.LOAD_AT_BEGINNING, StateFactory.createState(loadAtDepot));
|
|
||||||
stateManager.putRouteState(route, StateFactory.LOAD_AT_END, StateFactory.createState(loadAtEnd));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void informInsertionStarts(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs) {
|
|
||||||
for(VehicleRoute route : vehicleRoutes){ insertionStarts(route); }
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,52 +0,0 @@
|
||||||
package algorithms;
|
|
||||||
|
|
||||||
import algorithms.StateManager.StateImpl;
|
|
||||||
import basics.Delivery;
|
|
||||||
import basics.Job;
|
|
||||||
import basics.Pickup;
|
|
||||||
import basics.Service;
|
|
||||||
import basics.algo.JobInsertedListener;
|
|
||||||
import basics.route.VehicleRoute;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates loads at start and end of a route if a job has been inserted in that route.
|
|
||||||
*
|
|
||||||
* <p>These states can be retrieved by <br>
|
|
||||||
* stateManager.getRouteState(route, StateTypes.LOAD_AT_DEPOT) for LOAD_AT_DEPOT and <br>
|
|
||||||
* stateManager.getRouteState(route, StateTypes.LOAD) for LOAD (i.e. load at end)
|
|
||||||
*
|
|
||||||
* @param stateManager
|
|
||||||
*/
|
|
||||||
class UpdateLoadsAtStartAndEndOfRouteWhenJobHasBeenInserted implements JobInsertedListener, StateUpdater {
|
|
||||||
|
|
||||||
private StateManager stateManager;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates loads at start and end of a route if a job has been inserted in that route.
|
|
||||||
*
|
|
||||||
* <p>These states can be retrieved by <br>
|
|
||||||
* stateManager.getRouteState(route, StateTypes.LOAD_AT_DEPOT) for LOAD_AT_DEPOT and <br>
|
|
||||||
* stateManager.getRouteState(route, StateTypes.LOAD) for LOAD (i.e. load at end)
|
|
||||||
*
|
|
||||||
* @param stateManager
|
|
||||||
*/
|
|
||||||
public UpdateLoadsAtStartAndEndOfRouteWhenJobHasBeenInserted(StateManager stateManager) {
|
|
||||||
super();
|
|
||||||
this.stateManager = stateManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) {
|
|
||||||
if(job2insert instanceof Delivery){
|
|
||||||
int loadAtDepot = (int) stateManager.getRouteState(inRoute, StateFactory.LOAD_AT_BEGINNING).toDouble();
|
|
||||||
// log.info("loadAtDepot="+loadAtDepot);
|
|
||||||
stateManager.putRouteState(inRoute, StateFactory.LOAD_AT_BEGINNING, StateFactory.createState(loadAtDepot + job2insert.getCapacityDemand()));
|
|
||||||
}
|
|
||||||
else if(job2insert instanceof Pickup || job2insert instanceof Service){
|
|
||||||
int loadAtEnd = (int) stateManager.getRouteState(inRoute, StateFactory.LOAD_AT_END).toDouble();
|
|
||||||
// log.info("loadAtEnd="+loadAtEnd);
|
|
||||||
stateManager.putRouteState(inRoute, StateFactory.LOAD_AT_END, StateFactory.createState(loadAtEnd + job2insert.getCapacityDemand()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -29,14 +29,12 @@ class UpdateMaxLoad implements ActivityVisitor, StateUpdater {
|
||||||
*
|
*
|
||||||
* <p>Thus it DEPENDS on StateTypes.LOAD_AT_DEPOT
|
* <p>Thus it DEPENDS on StateTypes.LOAD_AT_DEPOT
|
||||||
*
|
*
|
||||||
* <p>If you want to update StateTypes.LOAD_AT_DEPOT see {@link UpdateLoadsAtStartAndEndOfRouteWhenInsertionStarts}, {@link UpdateLoadsAtStartAndEndOfRouteWhenJobHasBeenInserted}
|
*
|
||||||
*
|
*
|
||||||
* <p>The loads can be retrieved by <br>
|
* <p>The loads can be retrieved by <br>
|
||||||
* <code>stateManager.getActivityState(activity,StateTypes.LOAD);</code>
|
* <code>stateManager.getActivityState(activity,StateTypes.LOAD);</code>
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*
|
|
||||||
* @see {@link UpdateLoadsAtStartAndEndOfRouteWhenInsertionStarts}, {@link UpdateLoadsAtStartAndEndOfRouteWhenJobHasBeenInserted}
|
|
||||||
* @author stefan
|
* @author stefan
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,16 @@
|
||||||
package algorithms;
|
package algorithms;
|
||||||
|
|
||||||
import algorithms.StateManager.StateImpl;
|
|
||||||
import basics.route.ActivityVisitor;
|
import basics.route.ActivityVisitor;
|
||||||
import basics.route.DeliveryActivity;
|
import basics.route.DeliveryActivity;
|
||||||
import basics.route.TourActivity;
|
import basics.route.TourActivity;
|
||||||
import basics.route.VehicleRoute;
|
import basics.route.VehicleRoute;
|
||||||
|
|
||||||
class UpdateOccuredDeliveriesAtActivityLevel implements ActivityVisitor, StateUpdater {
|
class UpdateOccuredDeliveries implements ActivityVisitor, StateUpdater {
|
||||||
private StateManager stateManager;
|
private StateManager stateManager;
|
||||||
private int deliveries = 0;
|
private int deliveries = 0;
|
||||||
private VehicleRoute route;
|
private VehicleRoute route;
|
||||||
|
|
||||||
public UpdateOccuredDeliveriesAtActivityLevel(StateManager stateManager) {
|
public UpdateOccuredDeliveries(StateManager stateManager) {
|
||||||
super();
|
super();
|
||||||
this.stateManager = stateManager;
|
this.stateManager = stateManager;
|
||||||
}
|
}
|
||||||
|
|
@ -24,9 +24,9 @@ import basics.route.VehicleRoute;
|
||||||
* @param transportCost
|
* @param transportCost
|
||||||
* @param states
|
* @param states
|
||||||
*/
|
*/
|
||||||
class UpdateCostsAtAllLevels implements ActivityVisitor,StateUpdater{
|
class UpdateVariableCosts implements ActivityVisitor,StateUpdater{
|
||||||
|
|
||||||
private static Logger log = Logger.getLogger(UpdateCostsAtAllLevels.class);
|
private static Logger log = Logger.getLogger(UpdateVariableCosts.class);
|
||||||
|
|
||||||
private VehicleRoutingActivityCosts activityCost;
|
private VehicleRoutingActivityCosts activityCost;
|
||||||
|
|
||||||
|
|
@ -55,7 +55,7 @@ class UpdateCostsAtAllLevels implements ActivityVisitor,StateUpdater{
|
||||||
* @param transportCost
|
* @param transportCost
|
||||||
* @param states
|
* @param states
|
||||||
*/
|
*/
|
||||||
public UpdateCostsAtAllLevels(VehicleRoutingActivityCosts activityCost, VehicleRoutingTransportCosts transportCost, StateManager states) {
|
public UpdateVariableCosts(VehicleRoutingActivityCosts activityCost, VehicleRoutingTransportCosts transportCost, StateManager states) {
|
||||||
super();
|
super();
|
||||||
this.activityCost = activityCost;
|
this.activityCost = activityCost;
|
||||||
this.transportCost = transportCost;
|
this.transportCost = transportCost;
|
||||||
|
|
@ -117,10 +117,4 @@ class UpdateCostsAtAllLevels implements ActivityVisitor,StateUpdater{
|
||||||
totalOperationCost = 0.0;
|
totalOperationCost = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private double getFixCosts(Vehicle vehicle) {
|
|
||||||
if(vehicle == null) return 0.0;
|
|
||||||
if(vehicle.getType() == null) return 0.0;
|
|
||||||
return vehicle.getType().getVehicleCostParams().fix;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,39 +1,31 @@
|
||||||
package algorithms;
|
package algorithms;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
import basics.VehicleRoutingAlgorithm;
|
import basics.VehicleRoutingAlgorithm;
|
||||||
import basics.VehicleRoutingProblem;
|
import basics.VehicleRoutingProblem;
|
||||||
import basics.algo.SearchStrategyManager;
|
import basics.algo.SearchStrategyManager;
|
||||||
import basics.algo.VehicleRoutingAlgorithmListener;
|
import basics.algo.VehicleRoutingAlgorithmFactory;
|
||||||
import basics.route.VehicleFleetManager;
|
import basics.route.VehicleFleetManager;
|
||||||
|
|
||||||
public class VehicleRoutingAlgorithmBuilder {
|
public class VehicleRoutingAlgorithmFactoryImpl implements VehicleRoutingAlgorithmFactory{
|
||||||
|
|
||||||
private VehicleRoutingProblem vrp;
|
|
||||||
|
|
||||||
private SearchStrategyManager searchStrategyManager;
|
private SearchStrategyManager searchStrategyManager;
|
||||||
|
|
||||||
private StateManager stateManager;
|
private StateManager stateManager;
|
||||||
|
|
||||||
private Collection<VehicleRoutingAlgorithmListener> listeners = new ArrayList<VehicleRoutingAlgorithmListener>();
|
|
||||||
|
|
||||||
private VehicleFleetManager fleetManager;
|
private VehicleFleetManager fleetManager;
|
||||||
|
|
||||||
public VehicleRoutingAlgorithmBuilder(VehicleRoutingProblem vrp, SearchStrategyManager searchStrategyManager, StateManager stateManager, VehicleFleetManager vehicleFleetManager) {
|
public VehicleRoutingAlgorithmFactoryImpl(SearchStrategyManager searchStrategyManager,
|
||||||
|
StateManager stateManager, VehicleFleetManager fleetManager) {
|
||||||
super();
|
super();
|
||||||
this.vrp = vrp;
|
|
||||||
this.searchStrategyManager = searchStrategyManager;
|
this.searchStrategyManager = searchStrategyManager;
|
||||||
this.stateManager = stateManager;
|
this.stateManager = stateManager;
|
||||||
this.fleetManager = vehicleFleetManager;
|
this.fleetManager = fleetManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addListener(VehicleRoutingAlgorithmListener listener){
|
@Override
|
||||||
listeners.add(listener);
|
public VehicleRoutingAlgorithm createAlgorithm(VehicleRoutingProblem vrp) {
|
||||||
}
|
this.stateManager.addActivityVisitor(new UpdateVariableCosts(vrp.getActivityCosts(), vrp.getTransportCosts(), this.stateManager));
|
||||||
|
this.stateManager.addActivityVisitor(new UpdateMaxLoad(this.stateManager));
|
||||||
public VehicleRoutingAlgorithm build(){
|
|
||||||
VehicleRoutingAlgorithm algorithm = new VehicleRoutingAlgorithm(vrp, searchStrategyManager);
|
VehicleRoutingAlgorithm algorithm = new VehicleRoutingAlgorithm(vrp, searchStrategyManager);
|
||||||
algorithm.getAlgorithmListeners().addListener(stateManager);
|
algorithm.getAlgorithmListeners().addListener(stateManager);
|
||||||
algorithm.getSearchStrategyManager().addSearchStrategyModuleListener(stateManager);
|
algorithm.getSearchStrategyManager().addSearchStrategyModuleListener(stateManager);
|
||||||
|
|
@ -445,17 +445,17 @@ public class VehicleRoutingAlgorithms {
|
||||||
* define constraints
|
* define constraints
|
||||||
*/
|
*/
|
||||||
//constraint manager
|
//constraint manager
|
||||||
ConstraintManager constraintManager = new ConstraintManager();
|
ConstraintManager constraintManager = new ConstraintManager(vrp,stateManager);
|
||||||
constraintManager.addConstraint(new HardTimeWindowActivityLevelConstraint(stateManager, vrp.getTransportCosts()));
|
constraintManager.addConstraint(new TimeWindowConstraint(stateManager, vrp.getTransportCosts()));
|
||||||
|
|
||||||
if(vrp.getProblemConstraints().contains(Constraint.DELIVERIES_FIRST)){
|
if(vrp.getProblemConstraints().contains(Constraint.DELIVERIES_FIRST)){
|
||||||
constraintManager.addConstraint(new HardPickupAndDeliveryBackhaulActivityLevelConstraint(stateManager));
|
constraintManager.addConstraint(new ServiceBackhaulConstraint());
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
constraintManager.addConstraint(new HardPickupAndDeliveryActivityLevelConstraint(stateManager));
|
constraintManager.addConstraint(new ServiceLoadActivityLevelConstraint(stateManager));
|
||||||
}
|
}
|
||||||
|
|
||||||
constraintManager.addConstraint(new HardPickupAndDeliveryLoadRouteLevelConstraint(stateManager));
|
constraintManager.addConstraint(new ServiceLoadRouteLevelConstraint(stateManager));
|
||||||
|
|
||||||
//construct initial solution creator
|
//construct initial solution creator
|
||||||
AlgorithmStartsListener createInitialSolution = createInitialSolution(config,vrp,vehicleFleetManager,stateManager,algorithmListeners,definedClasses,executorService,nuOfThreads,constraintManager);
|
AlgorithmStartsListener createInitialSolution = createInitialSolution(config,vrp,vehicleFleetManager,stateManager,algorithmListeners,definedClasses,executorService,nuOfThreads,constraintManager);
|
||||||
|
|
@ -493,17 +493,22 @@ public class VehicleRoutingAlgorithms {
|
||||||
* define stateUpdates
|
* define stateUpdates
|
||||||
*/
|
*/
|
||||||
|
|
||||||
stateManager.addListener(new UpdateLoadsAtStartAndEndOfRouteWhenInsertionStarts(stateManager));
|
// stateManager.addListener(new UpdateLoadsAtStartAndEndOfRouteWhenInsertionStarts(stateManager));
|
||||||
stateManager.addListener(new UpdateLoadsAtStartAndEndOfRouteWhenJobHasBeenInserted(stateManager));
|
// stateManager.addListener(new UpdateLoadsAtStartAndEndOfRouteWhenJobHasBeenInserted(stateManager));
|
||||||
|
//
|
||||||
|
|
||||||
|
UpdateLoads loadUpdater = new UpdateLoads(stateManager);
|
||||||
|
stateManager.addListener(loadUpdater);
|
||||||
|
stateManager.addActivityVisitor(loadUpdater);
|
||||||
|
|
||||||
stateManager.addActivityVisitor(new UpdateActivityTimes(vrp.getTransportCosts()));
|
stateManager.addActivityVisitor(new UpdateActivityTimes(vrp.getTransportCosts()));
|
||||||
stateManager.addActivityVisitor(new UpdateLoadAtActivityLevel(stateManager));
|
|
||||||
|
|
||||||
stateManager.addActivityVisitor(new UpdateCostsAtAllLevels(vrp.getActivityCosts(), vrp.getTransportCosts(), stateManager));
|
|
||||||
|
|
||||||
stateManager.addActivityVisitor(new UpdateOccuredDeliveriesAtActivityLevel(stateManager));
|
stateManager.addActivityVisitor(new UpdateVariableCosts(vrp.getActivityCosts(), vrp.getTransportCosts(), stateManager));
|
||||||
stateManager.addActivityVisitor(new UpdateLatestOperationStartTimeAtActLocations(stateManager, vrp.getTransportCosts()));
|
|
||||||
stateManager.addActivityVisitor(new UpdateFuturePickupsAtActivityLevel(stateManager));
|
stateManager.addActivityVisitor(new UpdateOccuredDeliveries(stateManager));
|
||||||
|
stateManager.addActivityVisitor(new TimeWindowUpdater(stateManager, vrp.getTransportCosts()));
|
||||||
|
stateManager.addActivityVisitor(new UpdateFuturePickups(stateManager));
|
||||||
|
|
||||||
|
|
||||||
metaAlgorithm.getSearchStrategyManager().addSearchStrategyModuleListener(stateManager);
|
metaAlgorithm.getSearchStrategyManager().addSearchStrategyModuleListener(stateManager);
|
||||||
|
|
|
||||||
|
|
@ -260,9 +260,11 @@ public class VehicleRoutingProblem {
|
||||||
/**
|
/**
|
||||||
* Adds a vehicleType.
|
* Adds a vehicleType.
|
||||||
*
|
*
|
||||||
|
* @deprecated use add vehicle instead
|
||||||
* @param type
|
* @param type
|
||||||
* @return builder
|
* @return builder
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public Builder addVehicleType(VehicleType type){
|
public Builder addVehicleType(VehicleType type){
|
||||||
vehicleTypes.add(type);
|
vehicleTypes.add(type);
|
||||||
return this;
|
return this;
|
||||||
|
|
|
||||||
|
|
@ -16,16 +16,16 @@ public class InsertionListeners {
|
||||||
|
|
||||||
public void addListener(InsertionListener insertionListener){
|
public void addListener(InsertionListener insertionListener){
|
||||||
if(insertionListener instanceof InsertionStartsListener) startListeners.add((InsertionStartsListener) insertionListener);
|
if(insertionListener instanceof InsertionStartsListener) startListeners.add((InsertionStartsListener) insertionListener);
|
||||||
else if(insertionListener instanceof JobInsertedListener) jobInsertedListeners.add((JobInsertedListener) insertionListener);
|
if(insertionListener instanceof JobInsertedListener) jobInsertedListeners.add((JobInsertedListener) insertionListener);
|
||||||
else if(insertionListener instanceof InsertionEndsListener) endListeners.add((InsertionEndsListener) insertionListener);
|
if(insertionListener instanceof InsertionEndsListener) endListeners.add((InsertionEndsListener) insertionListener);
|
||||||
else throw new IllegalStateException("cannot add this type of insertionListener");
|
// else throw new IllegalStateException("cannot add this type of insertionListener");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeListener(InsertionListener insertionListener){
|
public void removeListener(InsertionListener insertionListener){
|
||||||
if(insertionListener instanceof InsertionStartsListener) startListeners.remove((InsertionStartsListener) insertionListener);
|
if(insertionListener instanceof InsertionStartsListener) startListeners.remove((InsertionStartsListener) insertionListener);
|
||||||
else if(insertionListener instanceof JobInsertedListener) jobInsertedListeners.remove((JobInsertedListener) insertionListener);
|
if(insertionListener instanceof JobInsertedListener) jobInsertedListeners.remove((JobInsertedListener) insertionListener);
|
||||||
else if(insertionListener instanceof InsertionEndsListener) endListeners.remove((InsertionEndsListener) insertionListener);
|
if(insertionListener instanceof InsertionEndsListener) endListeners.remove((InsertionEndsListener) insertionListener);
|
||||||
else throw new IllegalStateException("cannot remove this type of insertionListener");
|
// else throw new IllegalStateException("cannot remove this type of insertionListener");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void insertionStarts(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs){
|
public void insertionStarts(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs){
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ import basics.route.Vehicle;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function that basically does not allow soft time-windows. Actually, it is allowed but it is penalized with Double.MaxValue().
|
* DefaultActivityCosts = 0.0, i.e. activities do not induce costs at all.
|
||||||
*
|
*
|
||||||
* @author schroeder
|
* @author schroeder
|
||||||
*
|
*
|
||||||
|
|
@ -31,15 +31,12 @@ public class DefaultVehicleRoutingActivityCosts implements VehicleRoutingActivit
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double getActivityCost(TourActivity tourAct, double arrivalTime, Driver driver, Vehicle vehicle) {
|
public double getActivityCost(TourActivity tourAct, double arrivalTime, Driver driver, Vehicle vehicle) {
|
||||||
if(arrivalTime > tourAct.getTheoreticalLatestOperationStartTime()){
|
|
||||||
return Double.MAX_VALUE;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "[name=hardTimeWindowActCosts]";
|
return "[name=defaultActivityCosts]";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -301,7 +301,7 @@ public class VrpXMLReader{
|
||||||
if(distC != null) typeBuilder.setCostPerDistance(distC);
|
if(distC != null) typeBuilder.setCostPerDistance(distC);
|
||||||
VehicleTypeImpl type = typeBuilder.build();
|
VehicleTypeImpl type = typeBuilder.build();
|
||||||
types.put(type.getTypeId(), type);
|
types.put(type.getTypeId(), type);
|
||||||
vrpBuilder.addVehicleType(type);
|
// vrpBuilder.addVehicleType(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
//read vehicles
|
//read vehicles
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,8 @@ public class ReverseRouteActivityVisitor implements RouteVisitor{
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addActivityVisitor(ReverseActivityVisitor activityVisitor){
|
public void addActivityVisitor(ReverseActivityVisitor activityVisitor){
|
||||||
|
if(!visitors.contains(activityVisitor)){
|
||||||
visitors.add(activityVisitor);
|
visitors.add(activityVisitor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,8 @@ public class RouteActivityVisitor implements RouteVisitor{
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addActivityVisitor(ActivityVisitor activityVisitor){
|
public void addActivityVisitor(ActivityVisitor activityVisitor){
|
||||||
|
if(!visitors.contains(activityVisitor)){
|
||||||
visitors.add(activityVisitor);
|
visitors.add(activityVisitor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ public class BuildCVRPAlgoFromScratchTest {
|
||||||
vrp = builder.build();
|
vrp = builder.build();
|
||||||
|
|
||||||
final StateManager stateManager = new StateManager();
|
final StateManager stateManager = new StateManager();
|
||||||
HardActivityLevelConstraint hardActLevelConstraint = new HardActivityLevelConstraint() {
|
HardActivityStateLevelConstraint hardActLevelConstraint = new HardActivityStateLevelConstraint() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ConstraintsStatus fulfilled(InsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
|
public ConstraintsStatus fulfilled(InsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
|
||||||
|
|
@ -61,7 +61,7 @@ public class BuildCVRPAlgoFromScratchTest {
|
||||||
};
|
};
|
||||||
|
|
||||||
ActivityInsertionCostsCalculator marginalCalculus = new LocalActivityInsertionCostsCalculator(vrp.getTransportCosts(), vrp.getActivityCosts());
|
ActivityInsertionCostsCalculator marginalCalculus = new LocalActivityInsertionCostsCalculator(vrp.getTransportCosts(), vrp.getActivityCosts());
|
||||||
ServiceInsertionCalculator serviceInsertion = new ServiceInsertionCalculator(vrp.getTransportCosts(), marginalCalculus, new HardLoadConstraint(stateManager), hardActLevelConstraint);
|
ServiceInsertionCalculator serviceInsertion = new ServiceInsertionCalculator(vrp.getTransportCosts(), marginalCalculus, new LoadConstraint(stateManager), hardActLevelConstraint);
|
||||||
|
|
||||||
|
|
||||||
VehicleFleetManager fleetManager = new InfiniteFleetManagerFactory(vrp.getVehicles()).createFleetManager();
|
VehicleFleetManager fleetManager = new InfiniteFleetManagerFactory(vrp.getVehicles()).createFleetManager();
|
||||||
|
|
|
||||||
|
|
@ -61,14 +61,13 @@ public class BuildPDVRPAlgoFromScratchTest {
|
||||||
|
|
||||||
final StateManager stateManager = new StateManager();
|
final StateManager stateManager = new StateManager();
|
||||||
|
|
||||||
ConstraintManager actLevelConstraintAccumulator = new ConstraintManager();
|
ConstraintManager actLevelConstraintAccumulator = new ConstraintManager(vrp,stateManager);
|
||||||
actLevelConstraintAccumulator.addConstraint(new HardPickupAndDeliveryActivityLevelConstraint(stateManager));
|
actLevelConstraintAccumulator.addConstraint(new ServiceLoadActivityLevelConstraint(stateManager));
|
||||||
actLevelConstraintAccumulator.addConstraint(new HardTimeWindowActivityLevelConstraint(stateManager, vrp.getTransportCosts()));
|
actLevelConstraintAccumulator.addConstraint(new TimeWindowConstraint(stateManager, vrp.getTransportCosts()));
|
||||||
|
|
||||||
ActivityInsertionCostsCalculator marginalCalculus = new LocalActivityInsertionCostsCalculator(vrp.getTransportCosts(), vrp.getActivityCosts());
|
ActivityInsertionCostsCalculator marginalCalculus = new LocalActivityInsertionCostsCalculator(vrp.getTransportCosts(), vrp.getActivityCosts());
|
||||||
|
|
||||||
|
ServiceInsertionCalculator serviceInsertion = new ServiceInsertionCalculator(vrp.getTransportCosts(), marginalCalculus, new ServiceLoadRouteLevelConstraint(stateManager), actLevelConstraintAccumulator);
|
||||||
ServiceInsertionCalculator serviceInsertion = new ServiceInsertionCalculator(vrp.getTransportCosts(), marginalCalculus, new HardPickupAndDeliveryLoadRouteLevelConstraint(stateManager), actLevelConstraintAccumulator);
|
|
||||||
// CalculatesServiceInsertion serviceInsertion = new CalculatesServiceInsertion(vrp.getTransportCosts(), marginalCalculus, new HardConstraints.HardLoadConstraint(stateManager));
|
// CalculatesServiceInsertion serviceInsertion = new CalculatesServiceInsertion(vrp.getTransportCosts(), marginalCalculus, new HardConstraints.HardLoadConstraint(stateManager));
|
||||||
|
|
||||||
VehicleFleetManager fleetManager = new InfiniteFleetManagerFactory(vrp.getVehicles()).createFleetManager();
|
VehicleFleetManager fleetManager = new InfiniteFleetManagerFactory(vrp.getVehicles()).createFleetManager();
|
||||||
|
|
@ -110,15 +109,15 @@ public class BuildPDVRPAlgoFromScratchTest {
|
||||||
final RouteActivityVisitor iterateForward = new RouteActivityVisitor();
|
final RouteActivityVisitor iterateForward = new RouteActivityVisitor();
|
||||||
|
|
||||||
iterateForward.addActivityVisitor(new UpdateActivityTimes(vrp.getTransportCosts()));
|
iterateForward.addActivityVisitor(new UpdateActivityTimes(vrp.getTransportCosts()));
|
||||||
iterateForward.addActivityVisitor(new UpdateEarliestStartTimeWindowAtActLocations(stateManager, vrp.getTransportCosts()));
|
// iterateForward.addActivityVisitor(new UpdateEarliestStartTime(stateManager, vrp.getTransportCosts()));
|
||||||
iterateForward.addActivityVisitor(new UpdateCostsAtAllLevels(vrp.getActivityCosts(), vrp.getTransportCosts(), stateManager));
|
iterateForward.addActivityVisitor(new UpdateVariableCosts(vrp.getActivityCosts(), vrp.getTransportCosts(), stateManager));
|
||||||
|
|
||||||
iterateForward.addActivityVisitor(new UpdateOccuredDeliveriesAtActivityLevel(stateManager));
|
iterateForward.addActivityVisitor(new UpdateOccuredDeliveries(stateManager));
|
||||||
iterateForward.addActivityVisitor(new UpdateLoadAtActivityLevel(stateManager));
|
iterateForward.addActivityVisitor(new UpdateLoads(stateManager));
|
||||||
|
|
||||||
final ReverseRouteActivityVisitor iterateBackward = new ReverseRouteActivityVisitor();
|
final ReverseRouteActivityVisitor iterateBackward = new ReverseRouteActivityVisitor();
|
||||||
iterateBackward.addActivityVisitor(new UpdateLatestOperationStartTimeAtActLocations(stateManager, vrp.getTransportCosts()));
|
iterateBackward.addActivityVisitor(new TimeWindowUpdater(stateManager, vrp.getTransportCosts()));
|
||||||
iterateBackward.addActivityVisitor(new UpdateFuturePickupsAtActivityLevel(stateManager));
|
iterateBackward.addActivityVisitor(new UpdateFuturePickups(stateManager));
|
||||||
|
|
||||||
|
|
||||||
InsertionStartsListener loadVehicleInDepot = new InsertionStartsListener() {
|
InsertionStartsListener loadVehicleInDepot = new InsertionStartsListener() {
|
||||||
|
|
@ -175,7 +174,6 @@ public class BuildPDVRPAlgoFromScratchTest {
|
||||||
|
|
||||||
// System.out.println("ini: costs="+iniSolution.getCost()+";#routes="+iniSolution.getRoutes().size());
|
// System.out.println("ini: costs="+iniSolution.getCost()+";#routes="+iniSolution.getRoutes().size());
|
||||||
vra.addInitialSolution(iniSolution);
|
vra.addInitialSolution(iniSolution);
|
||||||
|
|
||||||
vra.setNuOfIterations(10000);
|
vra.setNuOfIterations(10000);
|
||||||
vra.setPrematureBreak(1000);
|
vra.setPrematureBreak(1000);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -149,7 +149,7 @@ public class GendreauPostOptTest {
|
||||||
|
|
||||||
activityCosts = new ExampleActivityCostFunction();
|
activityCosts = new ExampleActivityCostFunction();
|
||||||
|
|
||||||
ServiceInsertionCalculator standardServiceInsertion = new ServiceInsertionCalculator(cost, new LocalActivityInsertionCostsCalculator(cost, activityCosts), new HardLoadConstraint(states), new HardTimeWindowActivityLevelConstraint(states, cost));
|
ServiceInsertionCalculator standardServiceInsertion = new ServiceInsertionCalculator(cost, new LocalActivityInsertionCostsCalculator(cost, activityCosts), new LoadConstraint(states), new TimeWindowConstraint(states, cost));
|
||||||
|
|
||||||
|
|
||||||
JobInsertionConsideringFixCostsCalculator withFixCost = new JobInsertionConsideringFixCostsCalculator(standardServiceInsertion, states);
|
JobInsertionConsideringFixCostsCalculator withFixCost = new JobInsertionConsideringFixCostsCalculator(standardServiceInsertion, states);
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,11 @@ package algorithms;
|
||||||
|
|
||||||
import basics.Service;
|
import basics.Service;
|
||||||
|
|
||||||
class HardLoadConstraint implements HardRouteLevelConstraint{
|
class LoadConstraint implements HardRouteStateLevelConstraint{
|
||||||
|
|
||||||
private StateGetter states;
|
private StateGetter states;
|
||||||
|
|
||||||
public HardLoadConstraint(StateGetter states) {
|
public LoadConstraint(StateGetter states) {
|
||||||
super();
|
super();
|
||||||
this.states = states;
|
this.states = states;
|
||||||
}
|
}
|
||||||
|
|
@ -43,13 +43,13 @@ class UpdateStates implements JobInsertedListener, InsertionStartsListener{
|
||||||
public UpdateStates(StateManager states, VehicleRoutingTransportCosts routingCosts, VehicleRoutingActivityCosts activityCosts) {
|
public UpdateStates(StateManager states, VehicleRoutingTransportCosts routingCosts, VehicleRoutingActivityCosts activityCosts) {
|
||||||
routeActivityVisitor = new RouteActivityVisitor();
|
routeActivityVisitor = new RouteActivityVisitor();
|
||||||
routeActivityVisitor.addActivityVisitor(new UpdateActivityTimes(routingCosts));
|
routeActivityVisitor.addActivityVisitor(new UpdateActivityTimes(routingCosts));
|
||||||
routeActivityVisitor.addActivityVisitor(new UpdateCostsAtAllLevels(activityCosts, routingCosts, states));
|
routeActivityVisitor.addActivityVisitor(new UpdateVariableCosts(activityCosts, routingCosts, states));
|
||||||
routeActivityVisitor.addActivityVisitor(new UpdateLoadAtAllLevels(states));
|
routeActivityVisitor.addActivityVisitor(new UpdateLoads(states));
|
||||||
routeActivityVisitor.addActivityVisitor(new UpdateMaxLoad(states));
|
routeActivityVisitor.addActivityVisitor(new UpdateMaxLoad(states));
|
||||||
revRouteActivityVisitor = new ReverseRouteActivityVisitor();
|
revRouteActivityVisitor = new ReverseRouteActivityVisitor();
|
||||||
revRouteActivityVisitor.addActivityVisitor(new UpdateLatestOperationStartTimeAtActLocations(states, routingCosts));
|
revRouteActivityVisitor.addActivityVisitor(new TimeWindowUpdater(states, routingCosts));
|
||||||
insertionListeners.addListener(new UpdateLoadsAtStartAndEndOfRouteWhenInsertionStarts(states));
|
insertionListeners.addListener(new UpdateLoads(states));
|
||||||
insertionListeners.addListener(new UpdateLoadsAtStartAndEndOfRouteWhenJobHasBeenInserted(states));
|
// insertionListeners.addListener(new UpdateLoadsAtStartAndEndOfRouteWhenJobHasBeenInserted(states));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void update(VehicleRoute route){
|
public void update(VehicleRoute route){
|
||||||
|
|
|
||||||
|
|
@ -152,7 +152,7 @@ public class TestCalculatesServiceInsertion {
|
||||||
|
|
||||||
ExampleActivityCostFunction activityCosts = new ExampleActivityCostFunction();
|
ExampleActivityCostFunction activityCosts = new ExampleActivityCostFunction();
|
||||||
|
|
||||||
serviceInsertion = new ServiceInsertionCalculator(costs, new LocalActivityInsertionCostsCalculator(costs, activityCosts), new HardLoadConstraint(states), new HardTimeWindowActivityLevelConstraint(states, costs));
|
serviceInsertion = new ServiceInsertionCalculator(costs, new LocalActivityInsertionCostsCalculator(costs, activityCosts), new LoadConstraint(states), new TimeWindowConstraint(states, costs));
|
||||||
|
|
||||||
stateUpdater = new UpdateStates(states, costs, activityCosts);
|
stateUpdater = new UpdateStates(states, costs, activityCosts);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -143,7 +143,7 @@ public class TestCalculatesServiceInsertionOnRouteLevel {
|
||||||
|
|
||||||
ExampleActivityCostFunction activityCosts = new ExampleActivityCostFunction();
|
ExampleActivityCostFunction activityCosts = new ExampleActivityCostFunction();
|
||||||
ActivityInsertionCostsCalculator actInsertionCostCalculator = new RouteLevelActivityInsertionCostsEstimator(costs, activityCosts, states);
|
ActivityInsertionCostsCalculator actInsertionCostCalculator = new RouteLevelActivityInsertionCostsEstimator(costs, activityCosts, states);
|
||||||
serviceInsertion = new ServiceInsertionOnRouteLevelCalculator(costs,activityCosts, actInsertionCostCalculator, new HardLoadConstraint(states), new HardTimeWindowActivityLevelConstraint(states, costs));
|
serviceInsertion = new ServiceInsertionOnRouteLevelCalculator(costs,activityCosts, actInsertionCostCalculator, new LoadConstraint(states), new TimeWindowConstraint(states, costs));
|
||||||
serviceInsertion.setNuOfActsForwardLooking(4);
|
serviceInsertion.setNuOfActsForwardLooking(4);
|
||||||
serviceInsertion.setStates(states);
|
serviceInsertion.setStates(states);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -119,7 +119,7 @@ public class TestTourStateUpdaterWithService {
|
||||||
public void testCalculatedCost() {
|
public void testCalculatedCost() {
|
||||||
updateStates.update(vehicleRoute);
|
updateStates.update(vehicleRoute);
|
||||||
assertEquals(40.0, states.getRouteState(vehicleRoute,StateFactory.COSTS).toDouble(), 0.05);
|
assertEquals(40.0, states.getRouteState(vehicleRoute,StateFactory.COSTS).toDouble(), 0.05);
|
||||||
assertEquals(10, states.getRouteState(vehicleRoute, StateFactory.LOAD).toDouble(), 0.05);
|
assertEquals(10, states.getRouteState(vehicleRoute, StateFactory.LOAD_AT_END).toDouble(), 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ class UpdateCostsAtRouteLevel implements StateUpdater,JobInsertedListener, Inser
|
||||||
@Override
|
@Override
|
||||||
public void informInsertionStarts(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs) {
|
public void informInsertionStarts(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs) {
|
||||||
RouteActivityVisitor forwardInTime = new RouteActivityVisitor();
|
RouteActivityVisitor forwardInTime = new RouteActivityVisitor();
|
||||||
forwardInTime.addActivityVisitor(new UpdateCostsAtAllLevels(actCosts, tpCosts, states));
|
forwardInTime.addActivityVisitor(new UpdateVariableCosts(actCosts, tpCosts, states));
|
||||||
for(VehicleRoute route : vehicleRoutes){
|
for(VehicleRoute route : vehicleRoutes){
|
||||||
forwardInTime.visit(route);
|
forwardInTime.visit(route);
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue