1
0
Fork 0
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:
oblonski 2013-11-14 10:01:32 +01:00
parent 8010e0f2c2
commit a853ad5672
13 changed files with 683 additions and 650 deletions

View file

@ -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;
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}

View file

@ -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;
}
}

View file

@ -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";

View file

@ -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));

View file

@ -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);

View file

@ -23,6 +23,7 @@ import org.junit.Before;
import org.junit.Test;
import util.Solutions;
import algorithms.ConstraintManager.Priority;
import algorithms.StateManager.StateImpl;
import algorithms.acceptors.AcceptNewIfBetterThanWorst;
import algorithms.selectors.SelectBest;
@ -62,8 +63,8 @@ public class BuildPDVRPAlgoFromScratchTest {
final StateManager stateManager = new StateManager();
ConstraintManager actLevelConstraintAccumulator = new ConstraintManager(vrp,stateManager);
actLevelConstraintAccumulator.addConstraint(new ServiceLoadActivityLevelConstraint(stateManager));
actLevelConstraintAccumulator.addConstraint(new TimeWindowConstraint(stateManager, vrp.getTransportCosts()));
actLevelConstraintAccumulator.addConstraint(new ServiceLoadActivityLevelConstraint(stateManager),Priority.LOW);
actLevelConstraintAccumulator.addConstraint(new TimeWindowConstraint(stateManager, vrp.getTransportCosts()),Priority.HIGH);
ActivityInsertionCostsCalculator marginalCalculus = new LocalActivityInsertionCostsCalculator(vrp.getTransportCosts(), vrp.getActivityCosts());

View file

@ -80,7 +80,7 @@ public class BuildPDVRPWithShipmentsAlgoFromScratchTest {
ConstraintManager constraintManager = new ConstraintManager(vrp,stateManager);
constraintManager.addTimeWindowConstraint();
constraintManager.addLoadConstraint();
constraintManager.addConstraint(new HardPickupAndDeliveryShipmentActivityLevelConstraint(stateManager,true));
// constraintManager.addConstraint(new HardPickupAndDeliveryShipmentActivityLevelConstraint(stateManager));
ActivityInsertionCostsCalculator marginalCalculus = new LocalActivityInsertionCostsCalculator(vrp.getTransportCosts(), vrp.getActivityCosts());
@ -176,7 +176,7 @@ public class BuildPDVRPWithShipmentsAlgoFromScratchTest {
// System.out.println("ini: costs="+iniSolution.getCost()+";#routes="+iniSolution.getRoutes().size());
vra.addInitialSolution(iniSolution);
vra.setNuOfIterations(1000);
vra.setNuOfIterations(100);
// vra.setPrematureBreak(500);
}

View file

@ -23,7 +23,7 @@ public class HardPickupAndDeliveryShipmentActivityConstraintTest {
Shipment shipment;
HardPickupAndDeliveryShipmentActivityLevelConstraint constraint;
PickupAndDeliverShipmentLoadActivityLevelConstraint constraint;
InsertionContext iFacts;
@ -35,7 +35,7 @@ public class HardPickupAndDeliveryShipmentActivityConstraintTest {
shipment = mock(Shipment.class);
when(shipment.getCapacityDemand()).thenReturn(1);
iFacts = new InsertionContext(null, null, vehicle, null, 0.0);
constraint = new HardPickupAndDeliveryShipmentActivityLevelConstraint(stateManager);
constraint = new PickupAndDeliverShipmentLoadActivityLevelConstraint(stateManager);
}
@Test

View file

@ -12,6 +12,7 @@ import org.junit.Test;
import util.Coordinate;
import util.Locations;
import util.ManhattanCosts;
import algorithms.ConstraintManager.Priority;
import algorithms.HardActivityStateLevelConstraint.ConstraintsStatus;
import basics.Shipment;
import basics.VehicleRoutingProblem;
@ -188,8 +189,9 @@ public class ShipmentInsertionCalculatorTest {
VehicleRoutingProblem vrp = mock(VehicleRoutingProblem.class);
ConstraintManager constraintManager = new ConstraintManager(vrp,stateManager);
constraintManager.addConstraint(new PickupAndDeliverShipmentLoadActivityLevelConstraint(stateManager),Priority.CRITICAL);
constraintManager.addConstraint(new ShipmentPickupsFirstConstraint(),Priority.CRITICAL);
constraintManager.addConstraint(new HardPickupAndDeliveryShipmentActivityLevelConstraint(stateManager,true));
ShipmentInsertionCalculator insertionCalculator = new ShipmentInsertionCalculator(routingCosts, activityInsertionCostsCalculator,
hardRouteLevelConstraint, constraintManager);

File diff suppressed because it is too large Load diff