mirror of
https://github.com/graphhopper/jsprit.git
synced 2020-01-24 07:45:05 +01:00
add some default hard constraints
This commit is contained in:
parent
91f2fa5cbd
commit
9d40d76a2b
1 changed files with 173 additions and 2 deletions
|
|
@ -1,7 +1,17 @@
|
||||||
package algorithms;
|
package algorithms;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
import basics.Delivery;
|
||||||
|
import basics.Pickup;
|
||||||
import basics.Service;
|
import basics.Service;
|
||||||
import basics.costs.VehicleRoutingTransportCosts;
|
import basics.costs.VehicleRoutingTransportCosts;
|
||||||
|
import basics.route.DeliveryActivity;
|
||||||
|
import basics.route.PickupActivity;
|
||||||
|
import basics.route.Start;
|
||||||
import basics.route.TourActivity;
|
import basics.route.TourActivity;
|
||||||
|
|
||||||
class HardConstraints {
|
class HardConstraints {
|
||||||
|
|
@ -18,6 +28,48 @@ class HardConstraints {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class HardRouteLevelConstraintAccumulator implements HardRouteLevelConstraint {
|
||||||
|
|
||||||
|
private Collection<HardRouteLevelConstraint> hardConstraints = new ArrayList<HardRouteLevelConstraint>();
|
||||||
|
|
||||||
|
public void addConstraint(HardRouteLevelConstraint constraint){
|
||||||
|
hardConstraints.add(constraint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean fulfilled(InsertionContext insertionContext) {
|
||||||
|
for(HardRouteLevelConstraint constraint : hardConstraints){
|
||||||
|
if(!constraint.fulfilled(insertionContext)){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static class HardActivityLevelConstraintAccumulator implements HardActivityLevelConstraint {
|
||||||
|
|
||||||
|
private Collection<HardActivityLevelConstraint> hardConstraints = new ArrayList<HardActivityLevelConstraint>();
|
||||||
|
|
||||||
|
public void addConstraint(HardActivityLevelConstraint constraint){
|
||||||
|
hardConstraints.add(constraint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean fulfilled(InsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
|
||||||
|
for(HardActivityLevelConstraint constraint : hardConstraints){
|
||||||
|
if(!constraint.fulfilled(iFacts, prevAct, newAct, nextAct, prevActDepTime)){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static class HardLoadConstraint implements HardRouteLevelConstraint{
|
static class HardLoadConstraint implements HardRouteLevelConstraint{
|
||||||
|
|
||||||
private StateManager states;
|
private StateManager states;
|
||||||
|
|
@ -38,8 +90,38 @@ class HardConstraints {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class HardPickupAndDeliveryLoadConstraint implements HardRouteLevelConstraint {
|
||||||
|
|
||||||
|
private StateManager stateManager;
|
||||||
|
|
||||||
|
public HardPickupAndDeliveryLoadConstraint(StateManager stateManager) {
|
||||||
|
super();
|
||||||
|
this.stateManager = stateManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean fulfilled(InsertionContext insertionContext) {
|
||||||
|
if(insertionContext.getJob() instanceof Delivery){
|
||||||
|
int loadAtDepot = (int) stateManager.getRouteState(insertionContext.getRoute(), StateTypes.LOAD_AT_DEPOT).toDouble();
|
||||||
|
if(loadAtDepot + insertionContext.getJob().getCapacityDemand() > insertionContext.getNewVehicle().getCapacity()){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(insertionContext.getJob() instanceof Pickup){
|
||||||
|
int loadAtEnd = (int) stateManager.getRouteState(insertionContext.getRoute(), StateTypes.LOAD).toDouble();
|
||||||
|
if(loadAtEnd + insertionContext.getJob().getCapacityDemand() > insertionContext.getNewVehicle().getCapacity()){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static class HardTimeWindowConstraint implements HardActivityLevelConstraint {
|
static class HardTimeWindowConstraint implements HardActivityLevelConstraint {
|
||||||
|
|
||||||
|
private static Logger log = Logger.getLogger(HardTimeWindowConstraint.class);
|
||||||
|
|
||||||
private StateManager states;
|
private StateManager states;
|
||||||
|
|
||||||
private VehicleRoutingTransportCosts routingCosts;
|
private VehicleRoutingTransportCosts routingCosts;
|
||||||
|
|
@ -52,17 +134,106 @@ class HardConstraints {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean fulfilled(InsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
|
public boolean fulfilled(InsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
|
||||||
|
// 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 arrTimeAtNewAct = prevActDepTime + routingCosts.getTransportTime(prevAct.getLocationId(), newAct.getLocationId(), prevActDepTime, iFacts.getNewDriver(), iFacts.getNewVehicle());
|
||||||
if(arrTimeAtNewAct > states.getActivityState(newAct, StateTypes.LATEST_OPERATION_START_TIME).toDouble()){
|
double latestArrTimeAtNewAct = states.getActivityState(newAct, StateTypes.LATEST_OPERATION_START_TIME).toDouble();
|
||||||
|
if(arrTimeAtNewAct > latestArrTimeAtNewAct){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
// log.info(newAct + " arrTime=" + arrTimeAtNewAct);
|
||||||
double endTimeAtNewAct = CalcUtils.getActivityEndTime(arrTimeAtNewAct, newAct);
|
double endTimeAtNewAct = CalcUtils.getActivityEndTime(arrTimeAtNewAct, newAct);
|
||||||
double arrTimeAtNextAct = endTimeAtNewAct + routingCosts.getTransportTime(newAct.getLocationId(), nextAct.getLocationId(), endTimeAtNewAct, iFacts.getNewDriver(), iFacts.getNewVehicle());
|
double arrTimeAtNextAct = endTimeAtNewAct + routingCosts.getTransportTime(newAct.getLocationId(), nextAct.getLocationId(), endTimeAtNewAct, iFacts.getNewDriver(), iFacts.getNewVehicle());
|
||||||
if(arrTimeAtNextAct > states.getActivityState(nextAct, StateTypes.LATEST_OPERATION_START_TIME).toDouble()){
|
double latestArrTimeAtNextAct = states.getActivityState(nextAct, StateTypes.LATEST_OPERATION_START_TIME).toDouble();
|
||||||
|
if(arrTimeAtNextAct > latestArrTimeAtNextAct){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
// log.info(nextAct + " arrTime=" + arrTimeAtNextAct);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class HardPickupAndDeliveryConstraint implements HardActivityLevelConstraint {
|
||||||
|
|
||||||
|
private StateManager stateManager;
|
||||||
|
|
||||||
|
public HardPickupAndDeliveryConstraint(StateManager stateManager) {
|
||||||
|
super();
|
||||||
|
this.stateManager = stateManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean fulfilled(InsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
|
||||||
|
int loadAtPrevAct;
|
||||||
|
int futurePicks;
|
||||||
|
int pastDeliveries;
|
||||||
|
if(prevAct instanceof Start){
|
||||||
|
loadAtPrevAct = (int)stateManager.getRouteState(iFacts.getRoute(), StateTypes.LOAD_AT_DEPOT).toDouble();
|
||||||
|
futurePicks = (int)stateManager.getRouteState(iFacts.getRoute(), StateTypes.LOAD).toDouble();
|
||||||
|
pastDeliveries = 0;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
loadAtPrevAct = (int) stateManager.getActivityState(prevAct, StateTypes.LOAD).toDouble();
|
||||||
|
futurePicks = (int) stateManager.getActivityState(prevAct, StateTypes.FUTURE_PICKS).toDouble();
|
||||||
|
pastDeliveries = (int) stateManager.getActivityState(prevAct, StateTypes.PAST_DELIVERIES).toDouble();
|
||||||
|
}
|
||||||
|
if(newAct instanceof PickupActivity){
|
||||||
|
if(loadAtPrevAct + newAct.getCapacityDemand() + futurePicks > iFacts.getNewVehicle().getCapacity()){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(newAct instanceof DeliveryActivity){
|
||||||
|
if(loadAtPrevAct + Math.abs(newAct.getCapacityDemand()) + pastDeliveries > iFacts.getNewVehicle().getCapacity()){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static class HardPickupAndDeliveryBackhaulConstraint implements HardActivityLevelConstraint {
|
||||||
|
|
||||||
|
private StateManager stateManager;
|
||||||
|
|
||||||
|
public HardPickupAndDeliveryBackhaulConstraint(StateManager stateManager) {
|
||||||
|
super();
|
||||||
|
this.stateManager = stateManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean fulfilled(InsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
|
||||||
|
if(newAct instanceof PickupActivity && nextAct instanceof DeliveryActivity){ return false; }
|
||||||
|
if(newAct instanceof DeliveryActivity && prevAct instanceof PickupActivity){ return false; }
|
||||||
|
int loadAtPrevAct;
|
||||||
|
int futurePicks;
|
||||||
|
int pastDeliveries;
|
||||||
|
if(prevAct instanceof Start){
|
||||||
|
loadAtPrevAct = (int)stateManager.getRouteState(iFacts.getRoute(), StateTypes.LOAD_AT_DEPOT).toDouble();
|
||||||
|
futurePicks = (int)stateManager.getRouteState(iFacts.getRoute(), StateTypes.LOAD).toDouble();
|
||||||
|
pastDeliveries = 0;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
loadAtPrevAct = (int) stateManager.getActivityState(prevAct, StateTypes.LOAD).toDouble();
|
||||||
|
futurePicks = (int) stateManager.getActivityState(prevAct, StateTypes.FUTURE_PICKS).toDouble();
|
||||||
|
pastDeliveries = (int) stateManager.getActivityState(prevAct, StateTypes.PAST_DELIVERIES).toDouble();
|
||||||
|
}
|
||||||
|
if(newAct instanceof PickupActivity){
|
||||||
|
if(loadAtPrevAct + newAct.getCapacityDemand() + futurePicks > iFacts.getNewVehicle().getCapacity()){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(newAct instanceof DeliveryActivity){
|
||||||
|
if(loadAtPrevAct + Math.abs(newAct.getCapacityDemand()) + pastDeliveries > iFacts.getNewVehicle().getCapacity()){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue