mirror of
https://github.com/graphhopper/jsprit.git
synced 2020-01-24 07:45:05 +01:00
tested and modified according to multiple capacities
This commit is contained in:
parent
217c824506
commit
09486fadec
49 changed files with 878 additions and 490 deletions
|
|
@ -22,7 +22,7 @@ public class VariablePlusFixedSolutionCostCalculatorFactory {
|
|||
public double getCosts(VehicleRoutingProblemSolution solution) {
|
||||
double c = 0.0;
|
||||
for(VehicleRoute r : solution.getRoutes()){
|
||||
c += stateManager.getRouteState(r, StateFactory.COSTS).toDouble();
|
||||
c += stateManager.getRouteState(r, StateFactory.COSTS,Double.class);
|
||||
c += r.getVehicle().getType().getVehicleCostParams().fix;
|
||||
}
|
||||
return c;
|
||||
|
|
|
|||
|
|
@ -540,7 +540,7 @@ public class VehicleRoutingAlgorithms {
|
|||
stateManager = stateMan;
|
||||
}
|
||||
else{
|
||||
stateManager = new StateManager(vrp);
|
||||
stateManager = new StateManager(vrp.getTransportCosts());
|
||||
}
|
||||
stateManager.updateLoadStates();
|
||||
stateManager.updateTimeWindowStates();
|
||||
|
|
@ -621,7 +621,7 @@ public class VehicleRoutingAlgorithms {
|
|||
public double getCosts(VehicleRoutingProblemSolution solution) {
|
||||
double costs = 0.0;
|
||||
for(VehicleRoute route : solution.getRoutes()){
|
||||
costs += stateManager.getRouteState(route, StateFactory.COSTS).toDouble() + getFixedCosts(route.getVehicle());
|
||||
costs += stateManager.getRouteState(route, StateFactory.COSTS, Double.class) + getFixedCosts(route.getVehicle());
|
||||
}
|
||||
return costs;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,9 +73,9 @@ class RouteLevelActivityInsertionCostsEstimator implements ActivityInsertionCost
|
|||
|
||||
private double actCostsOld(VehicleRoute vehicleRoute, TourActivity act) {
|
||||
if(act instanceof End){
|
||||
return stateManager.getRouteState(vehicleRoute,StateFactory.COSTS).toDouble();
|
||||
return stateManager.getRouteState(vehicleRoute,StateFactory.COSTS,Double.class);
|
||||
}
|
||||
return stateManager.getActivityState(act,StateFactory.COSTS).toDouble();
|
||||
return stateManager.getActivityState(act,StateFactory.COSTS,Double.class);
|
||||
}
|
||||
|
||||
private List<TourActivity> getForwardLookingPath(VehicleRoute route, int actIndex) {
|
||||
|
|
|
|||
|
|
@ -291,7 +291,7 @@ final class ServiceInsertionOnRouteLevelCalculator implements JobInsertionCostsC
|
|||
/**
|
||||
* compute cost-diff of tour with and without new activity --> insertion_costs
|
||||
*/
|
||||
double insertion_costs = auxilliaryPathCostCalculator.costOfPath(wholeTour, start.getEndTime(), newDriver, newVehicle) - stateManager.getRouteState(currentRoute,StateFactory.COSTS).toDouble();
|
||||
double insertion_costs = auxilliaryPathCostCalculator.costOfPath(wholeTour, start.getEndTime(), newDriver, newVehicle) - stateManager.getRouteState(currentRoute,StateFactory.COSTS,Double.class);
|
||||
|
||||
/**
|
||||
* if better than best known, make it the best known
|
||||
|
|
@ -336,9 +336,9 @@ final class ServiceInsertionOnRouteLevelCalculator implements JobInsertionCostsC
|
|||
|
||||
private double sumOf_prevCosts_oldVehicle(VehicleRoute vehicleRoute, TourActivity act) {
|
||||
if(act instanceof End){
|
||||
return stateManager.getRouteState(vehicleRoute,StateFactory.COSTS).toDouble();
|
||||
return stateManager.getRouteState(vehicleRoute,StateFactory.COSTS,Double.class);
|
||||
}
|
||||
return stateManager.getActivityState(act,StateFactory.COSTS).toDouble();
|
||||
return stateManager.getActivityState(act,StateFactory.COSTS,Double.class);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -117,19 +117,19 @@ public class StateManager implements RouteAndActivityStateGetter, IterationStart
|
|||
defaultActivityStates_.put(StateFactory.LOAD, Capacity.Builder.newInstance().build());
|
||||
|
||||
|
||||
defaultActivityStates_.put(StateFactory.COSTS, StateFactory.createState(0));
|
||||
defaultActivityStates_.put(StateFactory.DURATION, StateFactory.createState(0));
|
||||
defaultActivityStates_.put(StateFactory.FUTURE_MAXLOAD, StateFactory.createState(0));
|
||||
defaultActivityStates_.put(StateFactory.PAST_MAXLOAD, StateFactory.createState(0));
|
||||
defaultActivityStates_.put(StateFactory.COSTS, 0.);
|
||||
defaultActivityStates_.put(StateFactory.DURATION, 0.);
|
||||
defaultActivityStates_.put(StateFactory.FUTURE_MAXLOAD, Capacity.Builder.newInstance().build());
|
||||
defaultActivityStates_.put(StateFactory.PAST_MAXLOAD, Capacity.Builder.newInstance().build());
|
||||
|
||||
defaultRouteStates_.put(StateFactory.LOAD, Capacity.Builder.newInstance().build());
|
||||
|
||||
defaultRouteStates_.put(StateFactory.COSTS, StateFactory.createState(0));
|
||||
defaultRouteStates_.put(StateFactory.DURATION, StateFactory.createState(0));
|
||||
defaultRouteStates_.put(StateFactory.FUTURE_MAXLOAD, StateFactory.createState(0));
|
||||
defaultRouteStates_.put(StateFactory.PAST_MAXLOAD, StateFactory.createState(0));
|
||||
defaultRouteStates_.put(StateFactory.COSTS, 0.);
|
||||
defaultRouteStates_.put(StateFactory.DURATION, 0.);
|
||||
defaultRouteStates_.put(StateFactory.FUTURE_MAXLOAD, Capacity.Builder.newInstance().build());
|
||||
defaultRouteStates_.put(StateFactory.PAST_MAXLOAD, Capacity.Builder.newInstance().build());
|
||||
|
||||
defaultRouteStates_.put(StateFactory.MAXLOAD, StateFactory.createState(0));
|
||||
defaultRouteStates_.put(StateFactory.MAXLOAD, Capacity.Builder.newInstance().build());
|
||||
|
||||
defaultRouteStates_.put(StateFactory.LOAD_AT_END, Capacity.Builder.newInstance().build());
|
||||
defaultRouteStates_.put(StateFactory.LOAD_AT_BEGINNING, Capacity.Builder.newInstance().build());
|
||||
|
|
@ -223,10 +223,10 @@ public class StateManager implements RouteAndActivityStateGetter, IterationStart
|
|||
return type.cast(defaultActivityStates_.get(stateId));
|
||||
}
|
||||
if(stateId.equals(StateFactory.EARLIEST_OPERATION_START_TIME)){
|
||||
return type.cast(StateFactory.createState(act.getTheoreticalEarliestOperationStartTime()));
|
||||
return type.cast(act.getTheoreticalEarliestOperationStartTime());
|
||||
}
|
||||
if(stateId.equals(StateFactory.LATEST_OPERATION_START_TIME)){
|
||||
return type.cast(StateFactory.createState(act.getTheoreticalLatestOperationStartTime()));
|
||||
return type.cast(act.getTheoreticalLatestOperationStartTime());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
@ -437,7 +437,7 @@ public class StateManager implements RouteAndActivityStateGetter, IterationStart
|
|||
public void updateTimeWindowStates() {
|
||||
if(!updateTWs){
|
||||
updateTWs=true;
|
||||
addActivityVisitor(new UpdateTimeWindow(this, routingCosts));
|
||||
addActivityVisitor(new UpdatePracticalTimeWindows(this, routingCosts));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,37 +0,0 @@
|
|||
package jsprit.core.algorithm.state;
|
||||
|
||||
import jsprit.core.problem.cost.VehicleRoutingTransportCosts;
|
||||
import jsprit.core.problem.solution.route.VehicleRoute;
|
||||
import jsprit.core.problem.solution.route.activity.ActivityVisitor;
|
||||
import jsprit.core.problem.solution.route.activity.TourActivity;
|
||||
import jsprit.core.problem.solution.route.state.StateFactory;
|
||||
import jsprit.core.util.ActivityTimeTracker;
|
||||
|
||||
class UpdateEarliestStartTime implements ActivityVisitor,StateUpdater{
|
||||
|
||||
private StateManager states;
|
||||
|
||||
private ActivityTimeTracker timeTracker;
|
||||
|
||||
public UpdateEarliestStartTime(StateManager states, VehicleRoutingTransportCosts transportCosts) {
|
||||
super();
|
||||
this.states = states;
|
||||
timeTracker = new ActivityTimeTracker(transportCosts);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void begin(VehicleRoute route) {
|
||||
timeTracker.begin(route);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(TourActivity activity) {
|
||||
timeTracker.visit(activity);
|
||||
states.putInternalActivityState(activity, StateFactory.EARLIEST_OPERATION_START_TIME, StateFactory.createState(Math.max(timeTracker.getActArrTime(), activity.getTheoreticalEarliestOperationStartTime())));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish() {}
|
||||
|
||||
}
|
||||
|
|
@ -6,8 +6,13 @@ import jsprit.core.problem.solution.route.activity.ReverseActivityVisitor;
|
|||
import jsprit.core.problem.solution.route.activity.TourActivity;
|
||||
import jsprit.core.problem.solution.route.state.StateFactory;
|
||||
|
||||
|
||||
class UpdateTimeWindow implements ReverseActivityVisitor, StateUpdater{
|
||||
/**
|
||||
* Updates and memorizes latest operation start times at activities.
|
||||
*
|
||||
* @author schroeder
|
||||
*
|
||||
*/
|
||||
class UpdatePracticalTimeWindows implements ReverseActivityVisitor, StateUpdater{
|
||||
|
||||
private StateManager states;
|
||||
|
||||
|
|
@ -19,7 +24,7 @@ class UpdateTimeWindow implements ReverseActivityVisitor, StateUpdater{
|
|||
|
||||
private TourActivity prevAct;
|
||||
|
||||
public UpdateTimeWindow(StateManager states, VehicleRoutingTransportCosts tpCosts) {
|
||||
public UpdatePracticalTimeWindows(StateManager states, VehicleRoutingTransportCosts tpCosts) {
|
||||
super();
|
||||
this.states = states;
|
||||
this.transportCosts = tpCosts;
|
||||
|
|
@ -37,7 +42,7 @@ class UpdateTimeWindow implements ReverseActivityVisitor, StateUpdater{
|
|||
double potentialLatestArrivalTimeAtCurrAct = latestArrTimeAtPrevAct - transportCosts.getBackwardTransportTime(activity.getLocationId(), prevAct.getLocationId(), latestArrTimeAtPrevAct, route.getDriver(),route.getVehicle()) - activity.getOperationTime();
|
||||
double latestArrivalTime = Math.min(activity.getTheoreticalLatestOperationStartTime(), potentialLatestArrivalTimeAtCurrAct);
|
||||
|
||||
states.putInternalActivityState(activity, StateFactory.LATEST_OPERATION_START_TIME, StateFactory.createState(latestArrivalTime));
|
||||
states.putInternalActivityState_(activity, StateFactory.LATEST_OPERATION_START_TIME, Double.class, latestArrivalTime);
|
||||
|
||||
latestArrTimeAtPrevAct = latestArrivalTime;
|
||||
prevAct = activity;
|
||||
|
|
@ -61,7 +61,6 @@ public class UpdateVariableCosts implements ActivityVisitor,StateUpdater{
|
|||
@Override
|
||||
public void begin(VehicleRoute route) {
|
||||
vehicleRoute = route;
|
||||
// vehicleRoute.getVehicleRouteCostCalculator().reset();
|
||||
timeTracker.begin(route);
|
||||
prevAct = route.getStart();
|
||||
startTimeAtPrevAct = timeTracker.getActEndTime();
|
||||
|
|
@ -74,13 +73,10 @@ public class UpdateVariableCosts implements ActivityVisitor,StateUpdater{
|
|||
double transportCost = this.transportCost.getTransportCost(prevAct.getLocationId(), act.getLocationId(), startTimeAtPrevAct, vehicleRoute.getDriver(), vehicleRoute.getVehicle());
|
||||
double actCost = activityCost.getActivityCost(act, timeTracker.getActArrTime(), vehicleRoute.getDriver(), vehicleRoute.getVehicle());
|
||||
|
||||
// vehicleRoute.getVehicleRouteCostCalculator().addTransportCost(transportCost);
|
||||
// vehicleRoute.getVehicleRouteCostCalculator().addActivityCost(actCost);
|
||||
//
|
||||
totalOperationCost += transportCost;
|
||||
totalOperationCost += actCost;
|
||||
|
||||
states.putInternalActivityState(act, StateFactory.COSTS, StateFactory.createState(totalOperationCost));
|
||||
states.putInternalActivityState_(act, StateFactory.COSTS, Double.class, totalOperationCost);
|
||||
|
||||
prevAct = act;
|
||||
startTimeAtPrevAct = timeTracker.getActEndTime();
|
||||
|
|
@ -91,20 +87,11 @@ public class UpdateVariableCosts implements ActivityVisitor,StateUpdater{
|
|||
timeTracker.finish();
|
||||
double transportCost = this.transportCost.getTransportCost(prevAct.getLocationId(), vehicleRoute.getEnd().getLocationId(), startTimeAtPrevAct, vehicleRoute.getDriver(), vehicleRoute.getVehicle());
|
||||
double actCost = activityCost.getActivityCost(vehicleRoute.getEnd(), timeTracker.getActEndTime(), vehicleRoute.getDriver(), vehicleRoute.getVehicle());
|
||||
|
||||
// vehicleRoute.getVehicleRouteCostCalculator().addTransportCost(transportCost);
|
||||
// vehicleRoute.getVehicleRouteCostCalculator().addActivityCost(actCost);
|
||||
//
|
||||
|
||||
totalOperationCost += transportCost;
|
||||
totalOperationCost += actCost;
|
||||
// totalOperationCost += getFixCosts(vehicleRoute.getVehicle());
|
||||
|
||||
states.putInternalRouteState(vehicleRoute, StateFactory.COSTS, StateFactory.createState(totalOperationCost));
|
||||
|
||||
// //this is rather strange and likely to change
|
||||
// vehicleRoute.getVehicleRouteCostCalculator().price(vehicleRoute.getDriver());
|
||||
// vehicleRoute.getVehicleRouteCostCalculator().price(vehicleRoute.getVehicle());
|
||||
// vehicleRoute.getVehicleRouteCostCalculator().finish();
|
||||
states.putInternalRouteState_(vehicleRoute, StateFactory.COSTS, Double.class, totalOperationCost);
|
||||
|
||||
startTimeAtPrevAct = 0.0;
|
||||
prevAct = null;
|
||||
|
|
|
|||
|
|
@ -190,12 +190,9 @@ public class Capacity {
|
|||
* @param toCompare
|
||||
* @return
|
||||
* @throws NullPointerException if one of the args is null
|
||||
* @throws IllegalStateException if number of capacityDimensions of this capacity and toCompare are different.
|
||||
*/
|
||||
public boolean isLessOrEqual(Capacity toCompare){
|
||||
if(toCompare == null) throw new NullPointerException();
|
||||
if(this.getNuOfDimensions() != toCompare.getNuOfDimensions()) throw new IllegalStateException("cap1.getNuOfDimension()="+this.getNuOfDimensions()+
|
||||
"!= cap2.getNuOfDimension()="+toCompare.getNuOfDimensions()+ ". cannot add up capacities with different dimension.");
|
||||
for(int i=0;i<this.getNuOfDimensions();i++){
|
||||
if(this.get(i) > toCompare.get(i)) return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -388,10 +388,11 @@ public class VehicleRoutingProblem {
|
|||
if(penaltyFixedCosts!=null){
|
||||
fixed = penaltyFixedCosts;
|
||||
}
|
||||
VehicleTypeImpl t = VehicleTypeImpl.Builder.newInstance(v.getType().getTypeId(), v.getCapacity())
|
||||
VehicleTypeImpl t = VehicleTypeImpl.Builder.newInstance(v.getType().getTypeId())
|
||||
.setCostPerDistance(penaltyFactor*v.getType().getVehicleCostParams().perDistanceUnit)
|
||||
.setCostPerTime(penaltyFactor*v.getType().getVehicleCostParams().perTimeUnit)
|
||||
.setFixedCost(fixed)
|
||||
.setCapacityDimensions(v.getType().getCapacityDimensions())
|
||||
.build();
|
||||
PenaltyVehicleType penType = new PenaltyVehicleType(t,penaltyFactor);
|
||||
String vehicleId = "penaltyVehicle_" + v.getStartLocationId() + "_" + t.getTypeId();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package jsprit.core.problem.constraint;
|
||||
|
||||
import jsprit.core.problem.Capacity;
|
||||
import jsprit.core.problem.misc.JobInsertionContext;
|
||||
import jsprit.core.problem.solution.route.activity.DeliverShipment;
|
||||
import jsprit.core.problem.solution.route.activity.PickupShipment;
|
||||
|
|
@ -45,22 +46,29 @@ public class PickupAndDeliverShipmentLoadActivityLevelConstraint implements Hard
|
|||
if(!(newAct instanceof PickupShipment) && !(newAct instanceof DeliverShipment)){
|
||||
return ConstraintsStatus.FULFILLED;
|
||||
}
|
||||
int loadAtPrevAct;
|
||||
Capacity loadAtPrevAct;
|
||||
// int loadAtPrevAct;
|
||||
if(prevAct instanceof Start){
|
||||
loadAtPrevAct = (int)stateManager.getRouteState(iFacts.getRoute(), StateFactory.LOAD_AT_BEGINNING).toDouble();
|
||||
loadAtPrevAct = stateManager.getRouteState(iFacts.getRoute(), StateFactory.LOAD_AT_BEGINNING, Capacity.class);
|
||||
}
|
||||
else{
|
||||
loadAtPrevAct = (int) stateManager.getActivityState(prevAct, StateFactory.LOAD).toDouble();
|
||||
loadAtPrevAct = stateManager.getActivityState(prevAct, StateFactory.LOAD, Capacity.class);
|
||||
}
|
||||
if(newAct instanceof PickupShipment){
|
||||
if(loadAtPrevAct + newAct.getCapacityDemand() > iFacts.getNewVehicle().getCapacity()){
|
||||
if(!Capacity.addup(loadAtPrevAct, newAct.getSize()).isLessOrEqual(iFacts.getNewVehicle().getType().getCapacityDimensions())){
|
||||
return ConstraintsStatus.NOT_FULFILLED;
|
||||
}
|
||||
// if(loadAtPrevAct + newAct.getCapacityDemand() > iFacts.getNewVehicle().getCapacity()){
|
||||
// return ConstraintsStatus.NOT_FULFILLED;
|
||||
// }
|
||||
}
|
||||
if(newAct instanceof DeliverShipment){
|
||||
if(loadAtPrevAct + Math.abs(newAct.getCapacityDemand()) > iFacts.getNewVehicle().getCapacity()){
|
||||
if(!Capacity.addup(loadAtPrevAct, Capacity.invert(newAct.getSize())).isLessOrEqual(iFacts.getNewVehicle().getType().getCapacityDimensions())){
|
||||
return ConstraintsStatus.NOT_FULFILLED_BREAK;
|
||||
}
|
||||
// if(loadAtPrevAct + Math.abs(newAct.getCapacityDemand()) > iFacts.getNewVehicle().getCapacity()){
|
||||
// return ConstraintsStatus.NOT_FULFILLED_BREAK;
|
||||
// }
|
||||
}
|
||||
return ConstraintsStatus.FULFILLED;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package jsprit.core.problem.constraint;
|
||||
|
||||
import jsprit.core.problem.Capacity;
|
||||
import jsprit.core.problem.misc.JobInsertionContext;
|
||||
import jsprit.core.problem.solution.route.activity.DeliverService;
|
||||
import jsprit.core.problem.solution.route.activity.PickupService;
|
||||
|
|
@ -30,28 +31,38 @@ class ServiceLoadActivityLevelConstraint implements HardActivityStateLevelConstr
|
|||
|
||||
@Override
|
||||
public ConstraintsStatus fulfilled(JobInsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
|
||||
int futureMaxLoad;
|
||||
int prevMaxLoad;
|
||||
Capacity futureMaxLoad;
|
||||
Capacity prevMaxLoad;
|
||||
if(prevAct instanceof Start){
|
||||
futureMaxLoad = (int)stateManager.getRouteState(iFacts.getRoute(), StateFactory.MAXLOAD).toDouble();
|
||||
prevMaxLoad = (int)stateManager.getRouteState(iFacts.getRoute(), StateFactory.LOAD_AT_BEGINNING).toDouble();
|
||||
futureMaxLoad = stateManager.getRouteState(iFacts.getRoute(), StateFactory.MAXLOAD, Capacity.class);
|
||||
// futureMaxLoad = (int)stateManager.getRouteState(iFacts.getRoute(), StateFactory.MAXLOAD).toDouble();
|
||||
prevMaxLoad = stateManager.getRouteState(iFacts.getRoute(), StateFactory.LOAD_AT_BEGINNING, Capacity.class);
|
||||
// prevMaxLoad = (int)stateManager.getRouteState(iFacts.getRoute(), StateFactory.LOAD_AT_BEGINNING).toDouble();
|
||||
}
|
||||
else{
|
||||
futureMaxLoad = (int) stateManager.getActivityState(prevAct, StateFactory.FUTURE_MAXLOAD).toDouble();
|
||||
prevMaxLoad = (int) stateManager.getActivityState(prevAct, StateFactory.PAST_MAXLOAD).toDouble();
|
||||
futureMaxLoad = stateManager.getActivityState(prevAct, StateFactory.FUTURE_MAXLOAD, Capacity.class);
|
||||
// futureMaxLoad = (int) stateManager.getActivityState(prevAct, StateFactory.FUTURE_MAXLOAD).toDouble();
|
||||
prevMaxLoad = stateManager.getActivityState(prevAct, StateFactory.PAST_MAXLOAD, Capacity.class);
|
||||
// prevMaxLoad = (int) stateManager.getActivityState(prevAct, StateFactory.PAST_MAXLOAD).toDouble();
|
||||
|
||||
}
|
||||
if(newAct instanceof PickupService || newAct instanceof ServiceActivity){
|
||||
if(newAct.getCapacityDemand() + futureMaxLoad > iFacts.getNewVehicle().getCapacity()){
|
||||
// log.debug("insertionOf("+newAct+").BETWEEN("+prevAct+").AND("+nextAct+")=NOT_POSSIBLE");
|
||||
if(!Capacity.addup(newAct.getSize(), futureMaxLoad).isLessOrEqual(iFacts.getNewVehicle().getType().getCapacityDimensions())){
|
||||
return ConstraintsStatus.NOT_FULFILLED;
|
||||
}
|
||||
// if(newAct.getCapacityDemand() + futureMaxLoad > iFacts.getNewVehicle().getCapacity()){
|
||||
//// log.debug("insertionOf("+newAct+").BETWEEN("+prevAct+").AND("+nextAct+")=NOT_POSSIBLE");
|
||||
// return ConstraintsStatus.NOT_FULFILLED;
|
||||
// }
|
||||
}
|
||||
if(newAct instanceof DeliverService){
|
||||
if(Math.abs(newAct.getCapacityDemand()) + prevMaxLoad > iFacts.getNewVehicle().getCapacity()){
|
||||
// log.debug("insertionOf("+newAct+").BETWEEN("+prevAct+").AND("+nextAct+")=NOT_POSSIBLE[break=neverBePossibleAnymore]");
|
||||
if(!Capacity.addup(Capacity.invert(newAct.getSize()), prevMaxLoad).isLessOrEqual(iFacts.getNewVehicle().getType().getCapacityDimensions())){
|
||||
return ConstraintsStatus.NOT_FULFILLED_BREAK;
|
||||
}
|
||||
// if(Math.abs(newAct.getCapacityDemand()) + prevMaxLoad > iFacts.getNewVehicle().getCapacity()){
|
||||
//// log.debug("insertionOf("+newAct+").BETWEEN("+prevAct+").AND("+nextAct+")=NOT_POSSIBLE[break=neverBePossibleAnymore]");
|
||||
// return ConstraintsStatus.NOT_FULFILLED_BREAK;
|
||||
// }
|
||||
|
||||
}
|
||||
// log.debug("insertionOf("+newAct+").BETWEEN("+prevAct+").AND("+nextAct+")=POSSIBLE");
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package jsprit.core.problem.constraint;
|
||||
|
||||
import jsprit.core.problem.Capacity;
|
||||
import jsprit.core.problem.job.Delivery;
|
||||
import jsprit.core.problem.job.Pickup;
|
||||
import jsprit.core.problem.job.Service;
|
||||
|
|
@ -25,16 +26,25 @@ class ServiceLoadRouteLevelConstraint implements HardRouteStateLevelConstraint {
|
|||
@Override
|
||||
public boolean fulfilled(JobInsertionContext insertionContext) {
|
||||
if(insertionContext.getJob() instanceof Delivery){
|
||||
int loadAtDepot = (int) stateManager.getRouteState(insertionContext.getRoute(), StateFactory.LOAD_AT_BEGINNING).toDouble();
|
||||
if(loadAtDepot + insertionContext.getJob().getCapacityDemand() > insertionContext.getNewVehicle().getCapacity()){
|
||||
Capacity loadAtDepot = stateManager.getRouteState(insertionContext.getRoute(), StateFactory.LOAD_AT_BEGINNING, Capacity.class);
|
||||
// int loadAtDepot = (int) stateManager.getRouteState(insertionContext.getRoute(), StateFactory.LOAD_AT_BEGINNING).toDouble();
|
||||
if(!Capacity.addup(loadAtDepot, insertionContext.getJob().getSize()).isLessOrEqual(insertionContext.getNewVehicle().getType().getCapacityDimensions())){
|
||||
return false;
|
||||
}
|
||||
// if(loadAtDepot + insertionContext.getJob().getCapacityDemand() > insertionContext.getNewVehicle().getCapacity()){
|
||||
// return false;
|
||||
// }
|
||||
}
|
||||
else if(insertionContext.getJob() instanceof Pickup || insertionContext.getJob() instanceof Service){
|
||||
int loadAtEnd = (int) stateManager.getRouteState(insertionContext.getRoute(), StateFactory.LOAD_AT_END).toDouble();
|
||||
if(loadAtEnd + insertionContext.getJob().getCapacityDemand() > insertionContext.getNewVehicle().getCapacity()){
|
||||
Capacity loadAtEnd = stateManager.getRouteState(insertionContext.getRoute(), StateFactory.LOAD_AT_END, Capacity.class);
|
||||
// int loadAtEnd = (int) stateManager.getRouteState(insertionContext.getRoute(), StateFactory.LOAD_AT_END).toDouble();
|
||||
if(!Capacity.addup(loadAtEnd, insertionContext.getJob().getSize()).isLessOrEqual(insertionContext.getNewVehicle().getType().getCapacityDimensions())){
|
||||
return false;
|
||||
}
|
||||
//
|
||||
// if(loadAtEnd + insertionContext.getJob().getCapacityDemand() > insertionContext.getNewVehicle().getCapacity()){
|
||||
// return false;
|
||||
// }
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ import jsprit.core.util.CalculationUtils;
|
|||
}
|
||||
// log.info("check insertion of " + newAct + " between " + prevAct + " and " + nextAct + ". prevActDepTime=" + prevActDepTime);
|
||||
double arrTimeAtNewAct = prevActDepTime + routingCosts.getTransportTime(prevAct.getLocationId(), newAct.getLocationId(), prevActDepTime, iFacts.getNewDriver(), iFacts.getNewVehicle());
|
||||
double latestArrTimeAtNewAct = states.getActivityState(newAct, StateFactory.LATEST_OPERATION_START_TIME).toDouble();
|
||||
double latestArrTimeAtNewAct = states.getActivityState(newAct, StateFactory.LATEST_OPERATION_START_TIME, Double.class);
|
||||
|
||||
if(arrTimeAtNewAct > latestArrTimeAtNewAct){
|
||||
return ConstraintsStatus.NOT_FULFILLED;
|
||||
|
|
@ -43,7 +43,7 @@ import jsprit.core.util.CalculationUtils;
|
|||
// log.info(newAct + " arrTime=" + arrTimeAtNewAct);
|
||||
double endTimeAtNewAct = CalculationUtils.getActivityEndTime(arrTimeAtNewAct, newAct);
|
||||
double arrTimeAtNextAct = endTimeAtNewAct + routingCosts.getTransportTime(newAct.getLocationId(), nextAct.getLocationId(), endTimeAtNewAct, iFacts.getNewDriver(), iFacts.getNewVehicle());
|
||||
double latestArrTimeAtNextAct = states.getActivityState(nextAct, StateFactory.LATEST_OPERATION_START_TIME).toDouble();
|
||||
double latestArrTimeAtNextAct = states.getActivityState(nextAct, StateFactory.LATEST_OPERATION_START_TIME, Double.class);
|
||||
if(arrTimeAtNextAct > latestArrTimeAtNextAct){
|
||||
return ConstraintsStatus.NOT_FULFILLED;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@
|
|||
******************************************************************************/
|
||||
package jsprit.core.problem.job;
|
||||
|
||||
import jsprit.core.problem.job.Pickup.Builder;
|
||||
|
||||
/**
|
||||
* Delivery extends Service and is intended to model a Service where smth is UNLOADED (i.e. delivered) from a transport unit.
|
||||
|
|
|
|||
|
|
@ -45,6 +45,10 @@ public class PenaltyVehicleType implements VehicleType{
|
|||
return type.getTypeId();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use <code>getCapacityDimensions()</code> instead
|
||||
*/
|
||||
@Deprecated
|
||||
@Override
|
||||
public int getCapacity() {
|
||||
return type.getCapacity();
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ public class VehicleImpl implements Vehicle {
|
|||
|
||||
private boolean returnToDepot = true;
|
||||
|
||||
private VehicleType type = VehicleTypeImpl.Builder.newInstance("default", 0).build();
|
||||
private VehicleType type = VehicleTypeImpl.Builder.newInstance("default").build();
|
||||
|
||||
/**
|
||||
* Constructs the builder with the vehicleId.
|
||||
|
|
|
|||
|
|
@ -76,7 +76,9 @@ public class VehicleTypeImpl implements VehicleType {
|
|||
* @param capacity
|
||||
* @return the vehicleType builder
|
||||
* @throws IllegalStateException if capacity is smaller than zero or id is null
|
||||
* @deprecated use <code>newInstance(String id)</code> instead
|
||||
*/
|
||||
@Deprecated
|
||||
public static VehicleTypeImpl.Builder newInstance(String id, int capacity){
|
||||
if(capacity < 0) throw new IllegalStateException("capacity cannot be smaller than zero");
|
||||
if(id == null) throw new IllegalStateException("typeId must be null");
|
||||
|
|
@ -102,7 +104,9 @@ public class VehicleTypeImpl implements VehicleType {
|
|||
|
||||
private Capacity.Builder capacityBuilder = Capacity.Builder.newInstance();
|
||||
|
||||
private Capacity capacityDimensions;
|
||||
private Capacity capacityDimensions = null;
|
||||
|
||||
private boolean dimensionAdded = false;
|
||||
|
||||
/**
|
||||
* Constructs the builder.
|
||||
|
|
@ -110,6 +114,7 @@ public class VehicleTypeImpl implements VehicleType {
|
|||
* @param id
|
||||
* @param capacity
|
||||
*/
|
||||
@Deprecated
|
||||
private Builder(String id, int capacity) {
|
||||
super();
|
||||
this.id = id;
|
||||
|
|
@ -183,7 +188,9 @@ public class VehicleTypeImpl implements VehicleType {
|
|||
* @return VehicleTypeImpl
|
||||
*/
|
||||
public VehicleTypeImpl build(){
|
||||
capacityDimensions = capacityBuilder.build();
|
||||
if(capacityDimensions == null){
|
||||
capacityDimensions = capacityBuilder.build();
|
||||
}
|
||||
return new VehicleTypeImpl(this);
|
||||
}
|
||||
|
||||
|
|
@ -194,14 +201,36 @@ public class VehicleTypeImpl implements VehicleType {
|
|||
* @param dimVal
|
||||
* @return the builder
|
||||
* @throws IllegalArgumentException if dimVal < 0
|
||||
* @throws IllegalStateException if capacity dimension is already set
|
||||
*/
|
||||
public Builder addCapacityDimension(int dimIndex, int dimVal) {
|
||||
if(dimVal<0) throw new IllegalArgumentException("capacity value cannot be negative");
|
||||
if(capacityDimensions != null) throw new IllegalStateException("either build your dimension with build your dimensions with " +
|
||||
"addCapacityDimension(int dimIndex, int dimVal) or set the already built dimensions with .setCapacityDimensions(Capacity capacity)." +
|
||||
"You used both methods.");
|
||||
dimensionAdded = true;
|
||||
capacityBuilder.addDimension(dimIndex,dimVal);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets capacity dimensions.
|
||||
*
|
||||
* <p>Note if you use this you cannot use <code>addCapacityDimension(int dimIndex, int dimVal)</code> anymore. Thus either build
|
||||
* your dimensions with <code>addCapacityDimension(int dimIndex, int dimVal)</code> or set the already built dimensions with
|
||||
* this method.
|
||||
*
|
||||
* @param capacity
|
||||
* @return this builder
|
||||
* @throws IllegalStateException if capacityDimension has already been added
|
||||
*/
|
||||
public Builder setCapacityDimensions(Capacity capacity){
|
||||
if(dimensionAdded) throw new IllegalStateException("either build your dimension with build your dimensions with " +
|
||||
"addCapacityDimension(int dimIndex, int dimVal) or set the already built dimensions with .setCapacityDimensions(Capacity capacity)." +
|
||||
"You used both methods.");
|
||||
this.capacityDimensions = capacity;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -1,97 +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 jsprit.core.util;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import jsprit.core.algorithm.VehicleRoutingAlgorithm;
|
||||
import jsprit.core.algorithm.listener.AlgorithmStartsListener;
|
||||
import jsprit.core.problem.VehicleRoutingProblem;
|
||||
import jsprit.core.problem.job.Job;
|
||||
import jsprit.core.problem.solution.VehicleRoutingProblemSolution;
|
||||
import jsprit.core.problem.vehicle.Vehicle;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
/**
|
||||
* Verifies whether vrp can be solved.
|
||||
*
|
||||
* <p>Checks<br>
|
||||
* - capacities, i.e. whether all job at least fit into the biggest vehicle
|
||||
*
|
||||
* @author stefan
|
||||
*
|
||||
*/
|
||||
public class VrpVerifier implements AlgorithmStartsListener{
|
||||
|
||||
private static Logger log = Logger.getLogger(VrpVerifier.class);
|
||||
|
||||
@Override
|
||||
public void informAlgorithmStarts(VehicleRoutingProblem problem, VehicleRoutingAlgorithm algorithm, Collection<VehicleRoutingProblemSolution> solutions) {
|
||||
//check capacity
|
||||
log.info("verifying vehicle-routing-problem ...");
|
||||
log.info("check vehicle capacities ...");
|
||||
Vehicle vehicleWithMaxCapacity = getMaxVehicle(problem);
|
||||
if(vehicleWithMaxCapacity == null) throw new IllegalStateException("vehicles are missing.");
|
||||
for(Job j : problem.getJobs().values()){
|
||||
if(vehicleWithMaxCapacity.getCapacity() < Math.abs(j.getCapacityDemand())){
|
||||
throw new IllegalStateException("maximal vehicle-capacity is "+vehicleWithMaxCapacity.getCapacity() + ", but there is a job bigger than this. [job=" + j + "]");
|
||||
}
|
||||
}
|
||||
log.info("ok");
|
||||
// log.info("check vehicles can manage shuttle tours ...");
|
||||
// for(Job j : problem.getJobs().values()){
|
||||
// Service s = (Service)j;
|
||||
// boolean jobCanBeRoutedWithinTimeWindow = false;
|
||||
// for(Vehicle v : problem.getVehicles()){
|
||||
// double transportTime = problem.getTransportCosts().getTransportTime(v.getStartLocationId(), s.getLocationId(), v.getEarliestDeparture(), DriverImpl.noDriver(), v);
|
||||
// if(transportTime+v.getEarliestDeparture() < s.getTimeWindow().getEnd()){
|
||||
// jobCanBeRoutedWithinTimeWindow = true;
|
||||
// break;
|
||||
// }
|
||||
// else{
|
||||
// log.warn("vehicle " + v + " needs " + transportTime + " time-units to get to " + s.getLocationId() + ". latestOperationStartTime however is " + s.getTimeWindow().getEnd());
|
||||
// }
|
||||
//
|
||||
// }
|
||||
// if(!jobCanBeRoutedWithinTimeWindow){
|
||||
// throw new IllegalStateException("no vehicle is able to cover the distance from depot to " + s.getLocationId() + " to meet the time-window " + s.getTimeWindow() + ".");
|
||||
// }
|
||||
// }
|
||||
// log.info("ok");
|
||||
log.info("verifying done");
|
||||
}
|
||||
|
||||
public void verify(VehicleRoutingProblem pblm, VehicleRoutingAlgorithm vra){
|
||||
informAlgorithmStarts(pblm, vra, null);
|
||||
}
|
||||
|
||||
private Vehicle getMaxVehicle(VehicleRoutingProblem problem) {
|
||||
Vehicle maxVehicle = null;
|
||||
for(Vehicle v : problem.getVehicles()){
|
||||
if(maxVehicle == null) {
|
||||
maxVehicle = v;
|
||||
continue;
|
||||
}
|
||||
else if(v.getCapacity() > maxVehicle.getCapacity()){
|
||||
maxVehicle = v;
|
||||
}
|
||||
}
|
||||
return maxVehicle;
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue