1
0
Fork 0
mirror of https://github.com/graphhopper/jsprit.git synced 2020-01-24 07:45:05 +01:00

relax api - move constraints of serviceCalc

This commit is contained in:
Stefan Schroeder 2013-10-18 15:25:41 +02:00
parent 5437d384db
commit 202c22ecd2
11 changed files with 82 additions and 66 deletions

View file

@ -22,6 +22,8 @@ public class BestInsertionBuilder implements InsertionStrategyBuilder{
private double weightOfFixedCosts;
private boolean considerFixedCosts = false;
private ActivityInsertionCostsCalculator actInsertionCostsCalculator = null;
public BestInsertionBuilder(VehicleRoutingProblem vrp, StateManager stateManager) {
super();
@ -58,7 +60,9 @@ public class BestInsertionBuilder implements InsertionStrategyBuilder{
return this;
}
//public void setActivityInsertionCostCalculator(ActivityInsertionCostCalculator costCalc){};
public void setActivityInsertionCostCalculator(ActivityInsertionCostsCalculator activityInsertionCostsCalculator){
this.actInsertionCostsCalculator = activityInsertionCostsCalculator;
};
@Override
public InsertionStrategy build() {
@ -72,6 +76,7 @@ public class BestInsertionBuilder implements InsertionStrategyBuilder{
calcBuilder.setStates(stateManager);
calcBuilder.setVehicleRoutingProblem(vrp);
calcBuilder.setVehicleFleetManager(fleetManager);
calcBuilder.setActivityInsertionCostsCalculator(actInsertionCostsCalculator);
if(considerFixedCosts) calcBuilder.considerFixedCosts(weightOfFixedCosts);
JobInsertionCalculator jobInsertions = calcBuilder.build();
BestInsertion bestInsertion = new BestInsertion(jobInsertions);

View file

@ -79,6 +79,8 @@ class CalculatorBuilder {
private int neighbors;
private ConstraintManager constraintManager;
private ActivityInsertionCostsCalculator activityInsertionCostCalculator = null;
/**
* Constructs the builder.
@ -136,6 +138,10 @@ class CalculatorBuilder {
public void setLocalLevel(){
local = true;
}
public void setActivityInsertionCostsCalculator(ActivityInsertionCostsCalculator activityInsertionCostsCalculator){
this.activityInsertionCostCalculator = activityInsertionCostsCalculator;
}
/**
* Sets a flag to build a calculator that evaluates job insertion on route-level.
@ -214,11 +220,16 @@ class CalculatorBuilder {
private CalculatorPlusListeners createStandardLocal(VehicleRoutingProblem vrp, StateManager statesManager){
if(constraintManager == null) throw new IllegalStateException("constraint-manager is null");
ActivityInsertionCostsCalculator defaultCalc = new LocalActivityInsertionCostsCalculator(vrp.getTransportCosts(), vrp.getActivityCosts(), constraintManager);
ActivityInsertionCostsCalculator actInsertionCalc;
if(activityInsertionCostCalculator == null){
actInsertionCalc = new LocalActivityInsertionCostsCalculator(vrp.getTransportCosts(), vrp.getActivityCosts());
}
else{
actInsertionCalc = activityInsertionCostCalculator;
}
JobInsertionCalculator standardServiceInsertion = new CalculatesServiceInsertion(vrp.getTransportCosts(), defaultCalc, constraintManager);
((CalculatesServiceInsertion) standardServiceInsertion).setNeighborhood(vrp.getNeighborhood());
JobInsertionCalculator standardServiceInsertion = new ServiceInsertionCalculator(vrp.getTransportCosts(), actInsertionCalc, constraintManager, constraintManager);
((ServiceInsertionCalculator) standardServiceInsertion).setNeighborhood(vrp.getNeighborhood());
CalculatorPlusListeners calcPlusListeners = new CalculatorPlusListeners(standardServiceInsertion);
return calcPlusListeners;
@ -234,12 +245,18 @@ class CalculatorBuilder {
private CalculatorPlusListeners createStandardRoute(VehicleRoutingProblem vrp, StateManager activityStates2, int forwardLooking, int solutionMemory){
int after = forwardLooking;
ActivityInsertionCostsCalculator routeLevelCostEstimator = new RouteLevelActivityInsertionCostsEstimator(vrp.getTransportCosts(), vrp.getActivityCosts(), constraintManager, activityStates2);
JobInsertionCalculator jobInsertionCalculator = new CalculatesServiceInsertionOnRouteLevel(vrp.getTransportCosts(), vrp.getActivityCosts(), constraintManager, routeLevelCostEstimator);
((CalculatesServiceInsertionOnRouteLevel)jobInsertionCalculator).setNuOfActsForwardLooking(after);
((CalculatesServiceInsertionOnRouteLevel)jobInsertionCalculator).setMemorySize(solutionMemory);
((CalculatesServiceInsertionOnRouteLevel)jobInsertionCalculator).setNeighborhood(vrp.getNeighborhood());
((CalculatesServiceInsertionOnRouteLevel) jobInsertionCalculator).setStates(activityStates2);
ActivityInsertionCostsCalculator routeLevelCostEstimator;
if(activityInsertionCostCalculator == null){
routeLevelCostEstimator = new RouteLevelActivityInsertionCostsEstimator(vrp.getTransportCosts(), vrp.getActivityCosts(), activityStates2);
}
else{
routeLevelCostEstimator = activityInsertionCostCalculator;
}
JobInsertionCalculator jobInsertionCalculator = new ServiceInsertionOnRouteLevelCalculator(vrp.getTransportCosts(), vrp.getActivityCosts(), routeLevelCostEstimator, constraintManager, constraintManager);
((ServiceInsertionOnRouteLevelCalculator)jobInsertionCalculator).setNuOfActsForwardLooking(after);
((ServiceInsertionOnRouteLevelCalculator)jobInsertionCalculator).setMemorySize(solutionMemory);
((ServiceInsertionOnRouteLevelCalculator)jobInsertionCalculator).setNeighborhood(vrp.getNeighborhood());
((ServiceInsertionOnRouteLevelCalculator) jobInsertionCalculator).setStates(activityStates2);
CalculatorPlusListeners calcPlusListener = new CalculatorPlusListeners(jobInsertionCalculator);
return calcPlusListener;
}

View file

@ -26,23 +26,17 @@ import basics.route.TourActivity;
class LocalActivityInsertionCostsCalculator implements ActivityInsertionCostsCalculator{
private HardActivityLevelConstraint hardConstraint;
private VehicleRoutingTransportCosts routingCosts;
private VehicleRoutingActivityCosts activityCosts;
public LocalActivityInsertionCostsCalculator(VehicleRoutingTransportCosts routingCosts, VehicleRoutingActivityCosts actCosts, HardActivityLevelConstraint hardActivityLevelConstraint) {
public LocalActivityInsertionCostsCalculator(VehicleRoutingTransportCosts routingCosts, VehicleRoutingActivityCosts actCosts) {
super();
this.routingCosts = routingCosts;
this.activityCosts = actCosts;
this.hardConstraint = hardActivityLevelConstraint;
}
@Override
public ActivityInsertionCosts calculate(InsertionContext iFacts, TourActivity prevAct, TourActivity nextAct, TourActivity newAct, double depTimeAtPrevAct) {
if(!hardConstraint.fulfilled(iFacts, prevAct, newAct, nextAct, depTimeAtPrevAct)){
return null;
}
double tp_costs_prevAct_newAct = routingCosts.getTransportCost(prevAct.getLocationId(), newAct.getLocationId(), depTimeAtPrevAct, iFacts.getNewDriver(), iFacts.getNewVehicle());
double tp_time_prevAct_newAct = routingCosts.getTransportTime(prevAct.getLocationId(), newAct.getLocationId(), depTimeAtPrevAct, iFacts.getNewDriver(), iFacts.getNewVehicle());

View file

@ -32,8 +32,6 @@ import basics.route.VehicleRoute;
class RouteLevelActivityInsertionCostsEstimator implements ActivityInsertionCostsCalculator{
private HardActivityLevelConstraint hardConstraint;
private VehicleRoutingActivityCosts activityCosts;
private AuxilliaryCostCalculator auxilliaryPathCostCalculator;
@ -42,20 +40,15 @@ class RouteLevelActivityInsertionCostsEstimator implements ActivityInsertionCost
private int nuOfActivities2LookForward = 0;
public RouteLevelActivityInsertionCostsEstimator(VehicleRoutingTransportCosts routingCosts, VehicleRoutingActivityCosts actCosts, HardActivityLevelConstraint hardActivityLevelConstraint, StateManager stateManager) {
public RouteLevelActivityInsertionCostsEstimator(VehicleRoutingTransportCosts routingCosts, VehicleRoutingActivityCosts actCosts, StateManager stateManager) {
super();
this.activityCosts = actCosts;
this.hardConstraint = hardActivityLevelConstraint;
this.stateManager = stateManager;
auxilliaryPathCostCalculator = new AuxilliaryCostCalculator(routingCosts, activityCosts);
}
@Override
public ActivityInsertionCosts calculate(InsertionContext iFacts, TourActivity prevAct, TourActivity nextAct, TourActivity newAct, double depTimeAtPrevAct) {
if(!hardConstraint.fulfilled(iFacts, prevAct, newAct, nextAct, depTimeAtPrevAct)){
return null;
}
List<TourActivity> path = new ArrayList<TourActivity>();
path.add(prevAct); path.add(newAct); path.add(nextAct);
int actIndex;

View file

@ -35,12 +35,14 @@ import basics.route.VehicleRoute;
final class CalculatesServiceInsertion implements JobInsertionCalculator{
final class ServiceInsertionCalculator implements JobInsertionCalculator{
private static final Logger logger = Logger.getLogger(CalculatesServiceInsertion.class);
private static final Logger logger = Logger.getLogger(ServiceInsertionCalculator.class);
private HardRouteLevelConstraint hardRouteLevelConstraint;
private HardActivityLevelConstraint hardActivityLevelConstraint;
private Neighborhood neighborhood = new Neighborhood() {
@Override
@ -61,10 +63,11 @@ final class CalculatesServiceInsertion implements JobInsertionCalculator{
}
public CalculatesServiceInsertion(VehicleRoutingTransportCosts routingCosts, ActivityInsertionCostsCalculator activityInsertionCostsCalculator, HardRouteLevelConstraint hardRouteLevelConstraint) {
public ServiceInsertionCalculator(VehicleRoutingTransportCosts routingCosts, ActivityInsertionCostsCalculator activityInsertionCostsCalculator, HardRouteLevelConstraint hardRouteLevelConstraint, HardActivityLevelConstraint hardActivityLevelConstraint) {
super();
this.activityInsertionCostsCalculator = activityInsertionCostsCalculator;
this.hardRouteLevelConstraint = hardRouteLevelConstraint;
this.hardActivityLevelConstraint = hardActivityLevelConstraint;
this.transportCosts = routingCosts;
activityFactory = new DefaultTourActivityFactory();
logger.info("initialise " + this);
@ -108,8 +111,8 @@ final class CalculatesServiceInsertion implements JobInsertionCalculator{
for(TourActivity nextAct : currentRoute.getTourActivities().getActivities()){
if(neighborhood.areNeighbors(deliveryAct2Insert.getLocationId(), prevAct.getLocationId()) && neighborhood.areNeighbors(deliveryAct2Insert.getLocationId(), nextAct.getLocationId())){
ActivityInsertionCosts mc = calculate(insertionContext, prevAct, nextAct, deliveryAct2Insert, prevActStartTime);
if(mc != null){
if(hardActivityLevelConstraint.fulfilled(insertionContext, prevAct, deliveryAct2Insert, nextAct, prevActStartTime)){
ActivityInsertionCosts mc = calculate(insertionContext, prevAct, nextAct, deliveryAct2Insert, prevActStartTime);
if(mc.getAdditionalCosts() < bestCost){
bestCost = mc.getAdditionalCosts();
bestMarginals = mc;
@ -127,8 +130,8 @@ final class CalculatesServiceInsertion implements JobInsertionCalculator{
}
End nextAct = end;
if(neighborhood.areNeighbors(deliveryAct2Insert.getLocationId(), prevAct.getLocationId()) && neighborhood.areNeighbors(deliveryAct2Insert.getLocationId(), nextAct.getLocationId())){
ActivityInsertionCosts mc = calculate(insertionContext, prevAct, nextAct, deliveryAct2Insert, prevActStartTime);
if(mc != null) {
if(hardActivityLevelConstraint.fulfilled(insertionContext, prevAct, deliveryAct2Insert, nextAct, prevActStartTime)){
ActivityInsertionCosts mc = calculate(insertionContext, prevAct, nextAct, deliveryAct2Insert, prevActStartTime);
if(mc.getAdditionalCosts() < bestCost){
bestCost = mc.getAdditionalCosts();
bestMarginals = mc;

View file

@ -44,9 +44,9 @@ import basics.route.VehicleRoute;
final class CalculatesServiceInsertionOnRouteLevel implements JobInsertionCalculator{
final class ServiceInsertionOnRouteLevelCalculator implements JobInsertionCalculator{
private static final Logger logger = Logger.getLogger(CalculatesServiceInsertionOnRouteLevel.class);
private static final Logger logger = Logger.getLogger(ServiceInsertionOnRouteLevelCalculator.class);
private final VehicleRoutingTransportCosts transportCosts;
@ -60,6 +60,8 @@ final class CalculatesServiceInsertionOnRouteLevel implements JobInsertionCalcul
private HardRouteLevelConstraint hardRouteLevelConstraint;
private HardActivityLevelConstraint hardActivityLevelConstraint;
private ActivityInsertionCostsCalculator activityInsertionCostsCalculator;
private int nuOfActsForwardLooking = 0;
@ -93,12 +95,13 @@ final class CalculatesServiceInsertionOnRouteLevel implements JobInsertionCalcul
logger.info("set [solutionMemory="+memorySize+"]");
}
public CalculatesServiceInsertionOnRouteLevel(VehicleRoutingTransportCosts vehicleRoutingCosts, VehicleRoutingActivityCosts costFunc, HardRouteLevelConstraint hardRouteLevelConstraint, ActivityInsertionCostsCalculator activityInsertionCostsCalculator) {
public ServiceInsertionOnRouteLevelCalculator(VehicleRoutingTransportCosts vehicleRoutingCosts, VehicleRoutingActivityCosts costFunc, ActivityInsertionCostsCalculator activityInsertionCostsCalculator, HardRouteLevelConstraint hardRouteLevelConstraint, HardActivityLevelConstraint hardActivityLevelConstraint) {
super();
this.transportCosts = vehicleRoutingCosts;
this.activityCosts = costFunc;
this.hardRouteLevelConstraint = hardRouteLevelConstraint;
this.activityInsertionCostsCalculator = activityInsertionCostsCalculator;
this.hardRouteLevelConstraint = hardRouteLevelConstraint;
this.hardActivityLevelConstraint = hardActivityLevelConstraint;
auxilliaryPathCostCalculator = new AuxilliaryCostCalculator(transportCosts, activityCosts);
logger.info("initialise " + this);
}
@ -172,12 +175,12 @@ final class CalculatesServiceInsertionOnRouteLevel implements JobInsertionCalcul
*/
for(TourActivity nextAct : tour.getActivities()){
if(neighborhood.areNeighbors(serviceAct2Insert.getLocationId(), prevAct.getLocationId()) && neighborhood.areNeighbors(serviceAct2Insert.getLocationId(), nextAct.getLocationId())){
/**
* builds a path on this route forwardPath={i,k,j,j+1,j+2,...,j+nuOfActsForwardLooking}
*/
InsertionContext iContext = new InsertionContext(currentRoute, jobToInsert, newVehicle, newDriver, prevActDepTime_newVehicle);
ActivityInsertionCosts actInsertionCosts = activityInsertionCostsCalculator.calculate(iContext, prevAct, nextAct, serviceAct2Insert, prevActDepTime_newVehicle);
if(actInsertionCosts != null){
if(hardActivityLevelConstraint.fulfilled(insertionContext, prevAct, serviceAct2Insert, nextAct, prevActDepTime_newVehicle)){
/**
* builds a path on this route forwardPath={i,k,j,j+1,j+2,...,j+nuOfActsForwardLooking}
*/
ActivityInsertionCosts actInsertionCosts = activityInsertionCostsCalculator.calculate(insertionContext, prevAct, nextAct, serviceAct2Insert, prevActDepTime_newVehicle);
/**
* insertion_cost_approximation = c({0,1,...,i},newVehicle) + c({i,k,j,j+1,j+2,...,j+nuOfActsForwardLooking},newVehicle) - c({0,1,...,i,j,j+1,...,j+nuOfActsForwardLooking},oldVehicle)
*/
@ -190,6 +193,7 @@ final class CalculatesServiceInsertionOnRouteLevel implements JobInsertionCalcul
bestInsertionsQueue.add(new InsertionData(insertion_cost_approximation, InsertionData.NO_INDEX, actIndex, newVehicle, newDriver));
}
}
}
/**
@ -221,20 +225,20 @@ final class CalculatesServiceInsertionOnRouteLevel implements JobInsertionCalcul
}
End nextAct = end;
if(neighborhood.areNeighbors(serviceAct2Insert.getLocationId(), prevAct.getLocationId()) && neighborhood.areNeighbors(serviceAct2Insert.getLocationId(), nextAct.getLocationId())){
if(hardActivityLevelConstraint.fulfilled(insertionContext, prevAct, serviceAct2Insert, nextAct, prevActDepTime_newVehicle)){
ActivityInsertionCosts actInsertionCosts = activityInsertionCostsCalculator.calculate(insertionContext, prevAct, nextAct, serviceAct2Insert, prevActDepTime_newVehicle);
if(actInsertionCosts != null){
/**
* insertion_cost_approximation = c({0,1,...,i},newVehicle) + c({i,k,j,j+1,j+2,...,j+nuOfActsForwardLooking},newVehicle) - c({0,1,...,i,j,j+1,...,j+nuOfActsForwardLooking},oldVehicle)
*/
double insertion_cost_approximation = sumOf_prevCosts_newVehicle - sumOf_prevCosts_oldVehicle(currentRoute,prevAct) + actInsertionCosts.getAdditionalCosts();
InsertionContext iContext = new InsertionContext(currentRoute, jobToInsert, newVehicle, newDriver, prevActDepTime_newVehicle);
ActivityInsertionCosts actInsertionCosts = activityInsertionCostsCalculator.calculate(iContext, prevAct, nextAct, serviceAct2Insert, prevActDepTime_newVehicle);
if(actInsertionCosts != null){
/**
* insertion_cost_approximation = c({0,1,...,i},newVehicle) + c({i,k,j,j+1,j+2,...,j+nuOfActsForwardLooking},newVehicle) - c({0,1,...,i,j,j+1,...,j+nuOfActsForwardLooking},oldVehicle)
*/
double insertion_cost_approximation = sumOf_prevCosts_newVehicle - sumOf_prevCosts_oldVehicle(currentRoute,prevAct) + actInsertionCosts.getAdditionalCosts();
/**
* memorize it in insertion-queue
*/
if(insertion_cost_approximation < best_known_insertion_costs){
bestInsertionsQueue.add(new InsertionData(insertion_cost_approximation, InsertionData.NO_INDEX, actIndex, newVehicle, newDriver));
/**
* memorize it in insertion-queue
*/
if(insertion_cost_approximation < best_known_insertion_costs){
bestInsertionsQueue.add(new InsertionData(insertion_cost_approximation, InsertionData.NO_INDEX, actIndex, newVehicle, newDriver));
}
}
}
}