diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/VehicleRoutingAlgorithmBuilder.java b/jsprit-core/src/main/java/jsprit/core/algorithm/VehicleRoutingAlgorithmBuilder.java index de3f0e56..9b60d5ec 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/VehicleRoutingAlgorithmBuilder.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/VehicleRoutingAlgorithmBuilder.java @@ -1,20 +1,18 @@ /******************************************************************************* - * Copyright (c) 2014 Stefan Schroeder. - * + * Copyright (C) 2014 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 + * 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 + * 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 . - * - * Contributors: - * Stefan Schroeder - initial API and implementation ******************************************************************************/ package jsprit.core.algorithm; @@ -22,9 +20,7 @@ import jsprit.core.algorithm.io.AlgorithmConfig; import jsprit.core.algorithm.io.AlgorithmConfigXmlReader; import jsprit.core.algorithm.io.VehicleRoutingAlgorithms; import jsprit.core.algorithm.state.StateManager; -import jsprit.core.algorithm.state.UpdateActivityTimes; import jsprit.core.algorithm.state.UpdateEndLocationIfRouteIsOpen; -import jsprit.core.algorithm.state.UpdateVariableCosts; import jsprit.core.problem.VehicleRoutingProblem; import jsprit.core.problem.constraint.ConstraintManager; import jsprit.core.problem.solution.SolutionCostCalculator; @@ -162,8 +158,7 @@ public class VehicleRoutingAlgorithmBuilder { //add core updater stateManager.addStateUpdater(new UpdateEndLocationIfRouteIsOpen()); // stateManager.addStateUpdater(new OpenRouteStateVerifier()); - stateManager.addStateUpdater(new UpdateActivityTimes(vrp.getTransportCosts())); - stateManager.addStateUpdater(new UpdateVariableCosts(vrp.getActivityCosts(), vrp.getTransportCosts(), stateManager)); + if(addCoreConstraints){ constraintManager.addLoadConstraint(); constraintManager.addTimeWindowConstraint(); diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/io/VehicleRoutingAlgorithms.java b/jsprit-core/src/main/java/jsprit/core/algorithm/io/VehicleRoutingAlgorithms.java index 8827a82b..326e3090 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/io/VehicleRoutingAlgorithms.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/io/VehicleRoutingAlgorithms.java @@ -54,6 +54,7 @@ import jsprit.core.problem.vehicle.FiniteFleetManagerFactory; import jsprit.core.problem.vehicle.InfiniteFleetManagerFactory; import jsprit.core.problem.vehicle.Vehicle; import jsprit.core.problem.vehicle.VehicleFleetManager; +import jsprit.core.util.ActivityTimeTracker; import org.apache.commons.configuration.HierarchicalConfiguration; import org.apache.commons.configuration.XMLConfiguration; import org.apache.logging.log4j.LogManager; @@ -546,6 +547,7 @@ public class VehicleRoutingAlgorithms { switchAllowed = Boolean.parseBoolean(switchString); } else switchAllowed = true; + ActivityTimeTracker.ActivityPolicy activityPolicy; if(stateManager.timeWindowUpdateIsActivated()){ UpdateVehicleDependentPracticalTimeWindows timeWindowUpdater = new UpdateVehicleDependentPracticalTimeWindows(stateManager,vrp.getTransportCosts()); timeWindowUpdater.setVehiclesToUpdate(new UpdateVehicleDependentPracticalTimeWindows.VehiclesToUpdate() { @@ -562,7 +564,13 @@ public class VehicleRoutingAlgorithms { }); stateManager.addStateUpdater(timeWindowUpdater); + activityPolicy = ActivityTimeTracker.ActivityPolicy.AS_SOON_AS_TIME_WINDOW_OPENS; } + else{ + activityPolicy = ActivityTimeTracker.ActivityPolicy.AS_SOON_AS_ARRIVED; + } + stateManager.addStateUpdater(new UpdateActivityTimes(vrp.getTransportCosts(),activityPolicy)); + stateManager.addStateUpdater(new UpdateVariableCosts(vrp.getActivityCosts(), vrp.getTransportCosts(), stateManager, activityPolicy)); SolutionCostCalculator costCalculator; if(solutionCostCalculator==null) costCalculator = getDefaultCostCalculator(stateManager); diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/state/UpdateActivityTimes.java b/jsprit-core/src/main/java/jsprit/core/algorithm/state/UpdateActivityTimes.java index ca748eab..2264aaa0 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/state/UpdateActivityTimes.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/state/UpdateActivityTimes.java @@ -1,20 +1,18 @@ /******************************************************************************* - * Copyright (c) 2014 Stefan Schroeder. - * + * Copyright (C) 2014 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 + * 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 + * 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 . - * - * Contributors: - * Stefan Schroeder - initial API and implementation ******************************************************************************/ package jsprit.core.algorithm.state; @@ -35,10 +33,12 @@ import jsprit.core.util.ActivityTimeTracker; */ public class UpdateActivityTimes implements ActivityVisitor, StateUpdater{ - private ActivityTimeTracker timeTracker; + + + private ActivityTimeTracker timeTracker; private VehicleRoute route; - + /** * Updates arrival and end times of activities. * @@ -48,7 +48,7 @@ public class UpdateActivityTimes implements ActivityVisitor, StateUpdater{ * activity.getArrTime() and * activity.getEndTime() * - * @author stefan + * * */ public UpdateActivityTimes(ForwardTransportTime transportTime) { @@ -56,6 +56,10 @@ public class UpdateActivityTimes implements ActivityVisitor, StateUpdater{ timeTracker = new ActivityTimeTracker(transportTime); } + public UpdateActivityTimes(ForwardTransportTime transportTime, ActivityTimeTracker.ActivityPolicy activityPolicy){ + timeTracker = new ActivityTimeTracker(transportTime,activityPolicy); + } + @Override public void begin(VehicleRoute route) { timeTracker.begin(route); diff --git a/jsprit-core/src/main/java/jsprit/core/algorithm/state/UpdateVariableCosts.java b/jsprit-core/src/main/java/jsprit/core/algorithm/state/UpdateVariableCosts.java index 279f4580..4251053e 100644 --- a/jsprit-core/src/main/java/jsprit/core/algorithm/state/UpdateVariableCosts.java +++ b/jsprit-core/src/main/java/jsprit/core/algorithm/state/UpdateVariableCosts.java @@ -1,20 +1,18 @@ /******************************************************************************* - * Copyright (c) 2014 Stefan Schroeder. - * + * Copyright (C) 2014 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 + * 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 + * 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 . - * - * Contributors: - * Stefan Schroeder - initial API and implementation ******************************************************************************/ package jsprit.core.algorithm.state; @@ -71,7 +69,14 @@ public class UpdateVariableCosts implements ActivityVisitor,StateUpdater{ timeTracker = new ActivityTimeTracker(transportCost); } - @Override + public UpdateVariableCosts(VehicleRoutingActivityCosts activityCosts, VehicleRoutingTransportCosts transportCosts, StateManager stateManager, ActivityTimeTracker.ActivityPolicy activityPolicy) { + this.activityCost = activityCosts; + this.transportCost = transportCosts; + this.states = stateManager; + timeTracker = new ActivityTimeTracker(transportCosts, activityPolicy); + } + + @Override public void begin(VehicleRoute route) { vehicleRoute = route; timeTracker.begin(route); diff --git a/jsprit-core/src/main/java/jsprit/core/problem/constraint/ConstraintManager.java b/jsprit-core/src/main/java/jsprit/core/problem/constraint/ConstraintManager.java index 2f5e07a9..13a13edf 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/constraint/ConstraintManager.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/constraint/ConstraintManager.java @@ -167,5 +167,6 @@ public class ConstraintManager implements HardActivityConstraint, HardRouteConst public double getCosts(JobInsertionContext iFacts, TourActivity prevAct,TourActivity newAct, TourActivity nextAct, double prevActDepTime) { return softActivityConstraintManager.getCosts(iFacts, prevAct, newAct, nextAct, prevActDepTime); } + } diff --git a/jsprit-core/src/main/java/jsprit/core/util/ActivityTimeTracker.java b/jsprit-core/src/main/java/jsprit/core/util/ActivityTimeTracker.java index 6c349300..39934a09 100644 --- a/jsprit-core/src/main/java/jsprit/core/util/ActivityTimeTracker.java +++ b/jsprit-core/src/main/java/jsprit/core/util/ActivityTimeTracker.java @@ -1,16 +1,16 @@ /******************************************************************************* - * Copyright (C) 2013 Stefan Schroeder - * + * Copyright (C) 2014 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 + * 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 . ******************************************************************************/ @@ -23,6 +23,12 @@ import jsprit.core.problem.solution.route.activity.TourActivity; public class ActivityTimeTracker implements ActivityVisitor{ + public static enum ActivityPolicy { + + AS_SOON_AS_TIME_WINDOW_OPENS, AS_SOON_AS_ARRIVED + + } + private ForwardTransportTime transportTime; private TourActivity prevAct = null; @@ -36,12 +42,20 @@ public class ActivityTimeTracker implements ActivityVisitor{ private double actArrTime; private double actEndTime; + + private ActivityPolicy activityPolicy = ActivityPolicy.AS_SOON_AS_TIME_WINDOW_OPENS; public ActivityTimeTracker(ForwardTransportTime transportTime) { super(); this.transportTime = transportTime; } + public ActivityTimeTracker(ForwardTransportTime transportTime, ActivityPolicy activityPolicy) { + super(); + this.transportTime = transportTime; + this.activityPolicy = activityPolicy; + } + public double getActArrTime(){ return actArrTime; } @@ -54,12 +68,9 @@ public class ActivityTimeTracker implements ActivityVisitor{ public void begin(VehicleRoute route) { prevAct = route.getStart(); startAtPrevAct = prevAct.getEndTime(); - - actEndTime = startAtPrevAct; - - this.route = route; - - beginFirst = true; + actEndTime = startAtPrevAct; + this.route = route; + beginFirst = true; } @Override @@ -69,8 +80,16 @@ public class ActivityTimeTracker implements ActivityVisitor{ double arrivalTimeAtCurrAct = startAtPrevAct + transportTime; actArrTime = arrivalTimeAtCurrAct; - - double operationStartTime = Math.max(activity.getTheoreticalEarliestOperationStartTime(), arrivalTimeAtCurrAct); + double operationStartTime; + + if(activityPolicy.equals(ActivityPolicy.AS_SOON_AS_TIME_WINDOW_OPENS)){ + operationStartTime = Math.max(activity.getTheoreticalEarliestOperationStartTime(), arrivalTimeAtCurrAct); + } + else if(activityPolicy.equals(ActivityPolicy.AS_SOON_AS_ARRIVED)){ + operationStartTime = actArrTime; + } + else operationStartTime = actArrTime; + double operationEndTime = operationStartTime + activity.getOperationTime(); actEndTime = operationEndTime; diff --git a/jsprit-core/src/test/java/jsprit/core/algorithm/DeactivateTimeWindowsTest.java b/jsprit-core/src/test/java/jsprit/core/algorithm/DeactivateTimeWindowsTest.java index fca624d7..b8bcf1c3 100644 --- a/jsprit-core/src/test/java/jsprit/core/algorithm/DeactivateTimeWindowsTest.java +++ b/jsprit-core/src/test/java/jsprit/core/algorithm/DeactivateTimeWindowsTest.java @@ -18,7 +18,9 @@ package jsprit.core.algorithm; +import jsprit.core.algorithm.state.StateManager; import jsprit.core.problem.VehicleRoutingProblem; +import jsprit.core.problem.constraint.ConstraintManager; import jsprit.core.problem.job.Service; import jsprit.core.problem.solution.VehicleRoutingProblemSolution; import jsprit.core.problem.solution.route.VehicleRoute; @@ -48,4 +50,61 @@ public class DeactivateTimeWindowsTest { VehicleRoute route = Solutions.bestOf(solutions).getRoutes().iterator().next(); Assert.assertEquals(20., route.getActivities().get(0).getEndTime(), 0.01); } + + @Test + public void whenNotActivatingViaStateManager_activityTimesShouldConsiderTimeWindows(){ + Service service = Service.Builder.newInstance("s").setCoord(Coordinate.newInstance(20, 0)) + .setTimeWindow(TimeWindow.newInstance(40,50)).build(); + VehicleImpl vehicle = VehicleImpl.Builder.newInstance("v").setStartLocationCoordinate(Coordinate.newInstance(0,0)).build(); + VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance().addJob(service).addVehicle(vehicle).build(); + VehicleRoutingAlgorithmBuilder vraBuilder = new VehicleRoutingAlgorithmBuilder(vrp,"src/test/resources/algorithmConfig.xml"); + vraBuilder.addDefaultCostCalculators(); + StateManager stateManager = new StateManager(vrp); + ConstraintManager constraintManager = new ConstraintManager(vrp,stateManager); + vraBuilder.setStateAndConstraintManager(stateManager,constraintManager); + VehicleRoutingAlgorithm vra = vraBuilder.build(); //this should ignore any constraints + vra.setMaxIterations(10); + Collection solutions = vra.searchSolutions(); + + VehicleRoute route = Solutions.bestOf(solutions).getRoutes().iterator().next(); + Assert.assertEquals(20., route.getActivities().get(0).getEndTime(), 0.01); + } + + @Test + public void activityTimesShouldConsiderTimeWindows(){ + Service service = Service.Builder.newInstance("s").setCoord(Coordinate.newInstance(20, 0)) + .setTimeWindow(TimeWindow.newInstance(40,50)).build(); + VehicleImpl vehicle = VehicleImpl.Builder.newInstance("v").setStartLocationCoordinate(Coordinate.newInstance(0,0)).build(); + VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance().addJob(service).addVehicle(vehicle).build(); + VehicleRoutingAlgorithmBuilder vraBuilder = new VehicleRoutingAlgorithmBuilder(vrp,"src/test/resources/algorithmConfig.xml"); + vraBuilder.addCoreConstraints(); + vraBuilder.addDefaultCostCalculators(); + VehicleRoutingAlgorithm vra = vraBuilder.build(); //this should ignore any constraints + vra.setMaxIterations(10); + Collection solutions = vra.searchSolutions(); + + VehicleRoute route = Solutions.bestOf(solutions).getRoutes().iterator().next(); + Assert.assertEquals(40., route.getActivities().get(0).getEndTime(), 0.01); + } + + @Test + public void whenActivatingViaStateManager_activityTimesShouldConsiderTimeWindows(){ + Service service = Service.Builder.newInstance("s").setCoord(Coordinate.newInstance(20, 0)) + .setTimeWindow(TimeWindow.newInstance(40,50)).build(); + VehicleImpl vehicle = VehicleImpl.Builder.newInstance("v").setStartLocationCoordinate(Coordinate.newInstance(0,0)).build(); + VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance().addJob(service).addVehicle(vehicle).build(); + VehicleRoutingAlgorithmBuilder vraBuilder = new VehicleRoutingAlgorithmBuilder(vrp,"src/test/resources/algorithmConfig.xml"); + vraBuilder.addDefaultCostCalculators(); + StateManager stateManager = new StateManager(vrp); + stateManager.updateTimeWindowStates(); + ConstraintManager constraintManager = new ConstraintManager(vrp,stateManager); + constraintManager.addTimeWindowConstraint(); + vraBuilder.setStateAndConstraintManager(stateManager,constraintManager); + VehicleRoutingAlgorithm vra = vraBuilder.build(); //this should ignore any constraints + vra.setMaxIterations(10); + Collection solutions = vra.searchSolutions(); + + VehicleRoute route = Solutions.bestOf(solutions).getRoutes().iterator().next(); + Assert.assertEquals(40., route.getActivities().get(0).getEndTime(), 0.01); + } }