mirror of
https://github.com/graphhopper/jsprit.git
synced 2020-01-24 07:45:05 +01:00
pd-contraints stuff and tests
This commit is contained in:
parent
8010e0f2c2
commit
a853ad5672
13 changed files with 683 additions and 650 deletions
|
|
@ -3,24 +3,65 @@ package algorithms;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
import algorithms.ConstraintManager.Priority;
|
||||
import basics.route.TourActivity;
|
||||
|
||||
class HardActivityLevelConstraintManager implements HardActivityStateLevelConstraint {
|
||||
|
||||
private Collection<HardActivityStateLevelConstraint> hardConstraints = new ArrayList<HardActivityStateLevelConstraint>();
|
||||
private Collection<HardActivityStateLevelConstraint> criticalConstraints = new ArrayList<HardActivityStateLevelConstraint>();
|
||||
|
||||
public void addConstraint(HardActivityStateLevelConstraint constraint){
|
||||
hardConstraints.add(constraint);
|
||||
private Collection<HardActivityStateLevelConstraint> highPrioConstraints = new ArrayList<HardActivityStateLevelConstraint>();
|
||||
|
||||
private Collection<HardActivityStateLevelConstraint> lowPrioConstraints = new ArrayList<HardActivityStateLevelConstraint>();
|
||||
|
||||
public void addConstraint(HardActivityStateLevelConstraint constraint, Priority priority){
|
||||
if(priority.equals(Priority.CRITICAL)){
|
||||
criticalConstraints.add(constraint);
|
||||
}
|
||||
else if(priority.equals(Priority.HIGH)){
|
||||
highPrioConstraints.add(constraint);
|
||||
}
|
||||
else{
|
||||
lowPrioConstraints.add(constraint);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConstraintsStatus fulfilled(InsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
|
||||
for(HardActivityStateLevelConstraint constraint : hardConstraints){
|
||||
ConstraintsStatus notFulfilled = null;
|
||||
for(HardActivityStateLevelConstraint c : criticalConstraints){
|
||||
ConstraintsStatus status = c.fulfilled(iFacts, prevAct, newAct, nextAct, prevActDepTime);
|
||||
if(status.equals(ConstraintsStatus.NOT_FULFILLED_BREAK)){
|
||||
return status;
|
||||
}
|
||||
else{
|
||||
if(status.equals(ConstraintsStatus.NOT_FULFILLED)){
|
||||
notFulfilled = status;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(notFulfilled != null) return notFulfilled;
|
||||
|
||||
for(HardActivityStateLevelConstraint c : highPrioConstraints){
|
||||
ConstraintsStatus status = c.fulfilled(iFacts, prevAct, newAct, nextAct, prevActDepTime);
|
||||
if(status.equals(ConstraintsStatus.NOT_FULFILLED_BREAK)){
|
||||
return status;
|
||||
}
|
||||
else{
|
||||
if(status.equals(ConstraintsStatus.NOT_FULFILLED)){
|
||||
notFulfilled = status;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(notFulfilled != null) return notFulfilled;
|
||||
|
||||
for(HardActivityStateLevelConstraint constraint : lowPrioConstraints){
|
||||
ConstraintsStatus status = constraint.fulfilled(iFacts, prevAct, newAct, nextAct, prevActDepTime);
|
||||
if(status.equals(ConstraintsStatus.NOT_FULFILLED_BREAK) || status.equals(ConstraintsStatus.NOT_FULFILLED)){
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
return ConstraintsStatus.FULFILLED;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,76 +0,0 @@
|
|||
package algorithms;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import algorithms.HardActivityStateLevelConstraint.ConstraintsStatus;
|
||||
import basics.route.DeliverShipment;
|
||||
import basics.route.PickupShipment;
|
||||
import basics.route.Start;
|
||||
import basics.route.TourActivity;
|
||||
|
||||
public class HardPickupAndDeliveryShipmentActivityLevelConstraint implements HardActivityStateLevelConstraint {
|
||||
|
||||
private static Logger logger = Logger.getLogger(HardPickupAndDeliveryShipmentActivityLevelConstraint.class);
|
||||
|
||||
private StateManager stateManager;
|
||||
|
||||
private boolean backhaul = false;
|
||||
|
||||
public HardPickupAndDeliveryShipmentActivityLevelConstraint(StateManager stateManager) {
|
||||
super();
|
||||
this.stateManager = stateManager;
|
||||
}
|
||||
|
||||
public HardPickupAndDeliveryShipmentActivityLevelConstraint(StateManager stateManager, boolean backhaul) {
|
||||
super();
|
||||
this.stateManager = stateManager;
|
||||
this.backhaul = backhaul;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConstraintsStatus fulfilled(InsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
|
||||
// logger.info(prevAct + " - " + newAct + " - " + nextAct);
|
||||
if(!(newAct instanceof PickupShipment) && !(newAct instanceof DeliverShipment)){
|
||||
return ConstraintsStatus.FULFILLED;
|
||||
}
|
||||
if(backhaul){
|
||||
if(newAct instanceof PickupShipment && prevAct instanceof DeliverShipment){
|
||||
// logger.info("NOT_FULFILLED_BREAK");
|
||||
return ConstraintsStatus.NOT_FULFILLED_BREAK; }
|
||||
if(newAct instanceof DeliverShipment && nextAct instanceof PickupShipment){
|
||||
// logger.info("NOT_FULFILLED");
|
||||
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(), StateTypes.LOAD).toDouble();
|
||||
// pastDeliveries = 0;
|
||||
}
|
||||
else{
|
||||
loadAtPrevAct = (int) stateManager.getActivityState(prevAct, StateFactory.LOAD).toDouble();
|
||||
// futurePicks = (int) stateManager.getActivityState(prevAct, StateTypes.FUTURE_PICKS).toDouble();
|
||||
// pastDeliveries = (int) stateManager.getActivityState(prevAct, StateTypes.PAST_DELIVERIES).toDouble();
|
||||
}
|
||||
if(newAct instanceof PickupShipment){
|
||||
if(loadAtPrevAct + newAct.getCapacityDemand() > iFacts.getNewVehicle().getCapacity()){
|
||||
// logger.info("NOT_FULFILLED");
|
||||
return ConstraintsStatus.NOT_FULFILLED;
|
||||
}
|
||||
}
|
||||
if(newAct instanceof DeliverShipment){
|
||||
if(loadAtPrevAct + Math.abs(newAct.getCapacityDemand()) > iFacts.getNewVehicle().getCapacity()){
|
||||
// logger.info("NOT_FULFILLED_BREAK");
|
||||
return ConstraintsStatus.NOT_FULFILLED_BREAK;
|
||||
}
|
||||
|
||||
}
|
||||
// logger.info("FULFILLED");
|
||||
return ConstraintsStatus.FULFILLED;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
package algorithms;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import algorithms.HardActivityStateLevelConstraint.ConstraintsStatus;
|
||||
import basics.route.DeliverShipment;
|
||||
import basics.route.PickupShipment;
|
||||
import basics.route.Start;
|
||||
import basics.route.TourActivity;
|
||||
|
||||
/**
|
||||
* Constraint that ensures capacity constraint at each activity.
|
||||
*
|
||||
* <p>This is critical to consistently calculate pd-problems with capacity constraints. Critical means
|
||||
* that is MUST be visited. It also assumes that pd-activities are visited in the order they occur in a tour.
|
||||
*
|
||||
* @author schroeder
|
||||
*
|
||||
*/
|
||||
public class PickupAndDeliverShipmentLoadActivityLevelConstraint implements HardActivityStateLevelConstraint {
|
||||
|
||||
private static Logger logger = Logger.getLogger(PickupAndDeliverShipmentLoadActivityLevelConstraint.class);
|
||||
|
||||
private StateManager stateManager;
|
||||
|
||||
/**
|
||||
* Constructs the constraint ensuring capacity constraint at each activity.
|
||||
*
|
||||
* <p>This is critical to consistently calculate pd-problems with capacity constraints. Critical means
|
||||
* that is MUST be visited. It also assumes that pd-activities are visited in the order they occur in a tour.
|
||||
*
|
||||
*
|
||||
* @param stateManager
|
||||
*/
|
||||
public PickupAndDeliverShipmentLoadActivityLevelConstraint(StateManager stateManager) {
|
||||
super();
|
||||
this.stateManager = stateManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConstraintsStatus fulfilled(InsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
|
||||
if(!(newAct instanceof PickupShipment) && !(newAct instanceof DeliverShipment)){
|
||||
return ConstraintsStatus.FULFILLED;
|
||||
}
|
||||
int loadAtPrevAct;
|
||||
if(prevAct instanceof Start){
|
||||
loadAtPrevAct = (int)stateManager.getRouteState(iFacts.getRoute(), StateFactory.LOAD_AT_BEGINNING).toDouble();
|
||||
}
|
||||
else{
|
||||
loadAtPrevAct = (int) stateManager.getActivityState(prevAct, StateFactory.LOAD).toDouble();
|
||||
}
|
||||
if(newAct instanceof PickupShipment){
|
||||
if(loadAtPrevAct + newAct.getCapacityDemand() > iFacts.getNewVehicle().getCapacity()){
|
||||
return ConstraintsStatus.NOT_FULFILLED;
|
||||
}
|
||||
}
|
||||
if(newAct instanceof DeliverShipment){
|
||||
if(loadAtPrevAct + Math.abs(newAct.getCapacityDemand()) > iFacts.getNewVehicle().getCapacity()){
|
||||
return ConstraintsStatus.NOT_FULFILLED_BREAK;
|
||||
}
|
||||
}
|
||||
return ConstraintsStatus.FULFILLED;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
package algorithms;
|
||||
|
||||
import basics.route.DeliveryActivity;
|
||||
import basics.route.PickupActivity;
|
||||
import basics.route.DeliverService;
|
||||
import basics.route.PickupService;
|
||||
import basics.route.ServiceActivity;
|
||||
import basics.route.Start;
|
||||
import basics.route.TourActivity;
|
||||
|
|
@ -39,12 +39,12 @@ class ServiceLoadActivityLevelConstraint implements HardActivityStateLevelConstr
|
|||
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(newAct instanceof PickupService || newAct instanceof ServiceActivity){
|
||||
if(loadAtPrevAct + newAct.getCapacityDemand() + futurePicks > iFacts.getNewVehicle().getCapacity()){
|
||||
return ConstraintsStatus.NOT_FULFILLED;
|
||||
}
|
||||
}
|
||||
if(newAct instanceof DeliveryActivity){
|
||||
if(newAct instanceof DeliverService){
|
||||
if(loadAtPrevAct + Math.abs(newAct.getCapacityDemand()) + pastDeliveries > iFacts.getNewVehicle().getCapacity()){
|
||||
return ConstraintsStatus.NOT_FULFILLED;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
package algorithms;
|
||||
|
||||
import basics.route.DeliverShipment;
|
||||
import basics.route.PickupShipment;
|
||||
import basics.route.TourActivity;
|
||||
|
||||
public class ShipmentPickupsFirstConstraint implements HardActivityStateLevelConstraint {
|
||||
|
||||
@Override
|
||||
public ConstraintsStatus fulfilled(InsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) {
|
||||
if(newAct instanceof DeliverShipment && nextAct instanceof PickupShipment){ return ConstraintsStatus.NOT_FULFILLED; }
|
||||
if(newAct instanceof PickupShipment && prevAct instanceof DeliverShipment){ return ConstraintsStatus.NOT_FULFILLED_BREAK; }
|
||||
return ConstraintsStatus.FULFILLED;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
package algorithms;
|
||||
|
||||
import basics.route.PickupActivity;
|
||||
import basics.route.PickupService;
|
||||
import basics.route.ReverseActivityVisitor;
|
||||
import basics.route.ServiceActivity;
|
||||
import basics.route.TourActivity;
|
||||
|
|
@ -24,7 +24,7 @@ class UpdateFuturePickups implements ReverseActivityVisitor, StateUpdater {
|
|||
@Override
|
||||
public void visit(TourActivity act) {
|
||||
stateManager.putActivityState(act, StateFactory.FUTURE_PICKS, StateFactory.createState(futurePicks));
|
||||
if(act instanceof PickupActivity || act instanceof ServiceActivity){
|
||||
if(act instanceof PickupService || act instanceof ServiceActivity){
|
||||
futurePicks += act.getCapacityDemand();
|
||||
}
|
||||
assert futurePicks <= route.getVehicle().getCapacity() : "sum of pickups must not be > vehicleCap";
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package algorithms;
|
||||
|
||||
import basics.route.ActivityVisitor;
|
||||
import basics.route.DeliveryActivity;
|
||||
import basics.route.DeliverService;
|
||||
import basics.route.TourActivity;
|
||||
import basics.route.VehicleRoute;
|
||||
|
||||
|
|
@ -22,7 +22,7 @@ class UpdateOccuredDeliveries implements ActivityVisitor, StateUpdater {
|
|||
|
||||
@Override
|
||||
public void visit(TourActivity act) {
|
||||
if(act instanceof DeliveryActivity){
|
||||
if(act instanceof DeliverService){
|
||||
deliveries += Math.abs(act.getCapacityDemand());
|
||||
}
|
||||
stateManager.putActivityState(act, StateFactory.PAST_DELIVERIES, StateFactory.createState(deliveries));
|
||||
|
|
|
|||
|
|
@ -446,16 +446,8 @@ public class VehicleRoutingAlgorithms {
|
|||
*/
|
||||
//constraint manager
|
||||
ConstraintManager constraintManager = new ConstraintManager(vrp,stateManager);
|
||||
constraintManager.addConstraint(new TimeWindowConstraint(stateManager, vrp.getTransportCosts()));
|
||||
|
||||
if(vrp.getProblemConstraints().contains(Constraint.DELIVERIES_FIRST)){
|
||||
constraintManager.addConstraint(new ServiceBackhaulConstraint());
|
||||
}
|
||||
else{
|
||||
constraintManager.addConstraint(new ServiceLoadActivityLevelConstraint(stateManager));
|
||||
}
|
||||
|
||||
constraintManager.addConstraint(new ServiceLoadRouteLevelConstraint(stateManager));
|
||||
constraintManager.addTimeWindowConstraint();
|
||||
constraintManager.addLoadConstraint();
|
||||
|
||||
//construct initial solution creator
|
||||
AlgorithmStartsListener createInitialSolution = createInitialSolution(config,vrp,vehicleFleetManager,stateManager,algorithmListeners,definedClasses,executorService,nuOfThreads,constraintManager);
|
||||
|
|
@ -492,24 +484,15 @@ public class VehicleRoutingAlgorithms {
|
|||
/*
|
||||
* define stateUpdates
|
||||
*/
|
||||
|
||||
// stateManager.addListener(new UpdateLoadsAtStartAndEndOfRouteWhenInsertionStarts(stateManager));
|
||||
// stateManager.addListener(new UpdateLoadsAtStartAndEndOfRouteWhenJobHasBeenInserted(stateManager));
|
||||
//
|
||||
|
||||
UpdateLoads loadUpdater = new UpdateLoads(stateManager);
|
||||
stateManager.addListener(loadUpdater);
|
||||
stateManager.addActivityVisitor(loadUpdater);
|
||||
|
||||
// UpdateLoads loadUpdater = new UpdateLoads(stateManager);
|
||||
// stateManager.addListener(loadUpdater);
|
||||
// stateManager.addActivityVisitor(loadUpdater);
|
||||
stateManager.addActivityVisitor(new UpdateActivityTimes(vrp.getTransportCosts()));
|
||||
|
||||
|
||||
stateManager.addActivityVisitor(new UpdateVariableCosts(vrp.getActivityCosts(), vrp.getTransportCosts(), stateManager));
|
||||
|
||||
stateManager.addActivityVisitor(new UpdateOccuredDeliveries(stateManager));
|
||||
stateManager.addActivityVisitor(new TimeWindowUpdater(stateManager, vrp.getTransportCosts()));
|
||||
stateManager.addActivityVisitor(new UpdateFuturePickups(stateManager));
|
||||
|
||||
// stateManager.addActivityVisitor(new UpdateOccuredDeliveries(stateManager));
|
||||
// stateManager.addActivityVisitor(new TimeWindowUpdater(stateManager, vrp.getTransportCosts()));
|
||||
// stateManager.addActivityVisitor(new UpdateFuturePickups(stateManager));
|
||||
|
||||
metaAlgorithm.getSearchStrategyManager().addSearchStrategyModuleListener(stateManager);
|
||||
metaAlgorithm.getAlgorithmListeners().addListener(stateManager);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue