diff --git a/jsprit-core/src/test/java/algorithms/BuildCVRPAlgoFromScratchTest.java b/jsprit-core/src/test/java/algorithms/BuildCVRPAlgoFromScratchTest.java index b255891e..64928195 100644 --- a/jsprit-core/src/test/java/algorithms/BuildCVRPAlgoFromScratchTest.java +++ b/jsprit-core/src/test/java/algorithms/BuildCVRPAlgoFromScratchTest.java @@ -36,7 +36,7 @@ public class BuildCVRPAlgoFromScratchTest { HardActivityLevelConstraint hardActLevelConstraint = new HardActivityLevelConstraint() { @Override - public boolean fulfilled(InsertionContext iFacts, TourActivity act, double arrTime) { + public boolean fulfilled(InsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) { return true; } }; diff --git a/jsprit-core/src/test/java/algorithms/BuildPDVRPAlgoFromScratchTest.java b/jsprit-core/src/test/java/algorithms/BuildPDVRPAlgoFromScratchTest.java index 40079dc0..c998dfd5 100644 --- a/jsprit-core/src/test/java/algorithms/BuildPDVRPAlgoFromScratchTest.java +++ b/jsprit-core/src/test/java/algorithms/BuildPDVRPAlgoFromScratchTest.java @@ -2,19 +2,37 @@ package algorithms; import java.util.Collection; +import org.apache.log4j.Logger; import org.junit.Before; +import org.junit.Test; +import util.Solutions; +import algorithms.BackwardInTimeListeners.BackwardInTimeListener; +import algorithms.ForwardInTimeListeners.ForwardInTimeListener; import algorithms.HardConstraints.HardActivityLevelConstraint; +import algorithms.StateManager.State; +import algorithms.StateManager.StateImpl; import algorithms.acceptors.AcceptNewIfBetterThanWorst; import algorithms.selectors.SelectBest; +import basics.Delivery; +import basics.Job; +import basics.Pickup; import basics.VehicleRoutingAlgorithm; import basics.VehicleRoutingProblem; import basics.VehicleRoutingProblemSolution; +import basics.algo.InsertionStartsListener; import basics.algo.IterationStartsListener; +import basics.algo.JobInsertedListener; import basics.algo.SearchStrategy; import basics.algo.SearchStrategyManager; import basics.io.VrpXMLReader; +import basics.io.VrpXMLWriter; +import basics.route.DeliveryActivity; +import basics.route.End; +import basics.route.PickupActivity; +import basics.route.Start; import basics.route.TourActivity; +import basics.route.VehicleRoute; public class BuildPDVRPAlgoFromScratchTest { @@ -22,24 +40,86 @@ public class BuildPDVRPAlgoFromScratchTest { VehicleRoutingAlgorithm vra; + static Logger log = Logger.getLogger(BuildPDVRPAlgoFromScratchTest.class); @Before public void setup(){ VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance(); - new VrpXMLReader(builder).read("src/test/resources/vrpnc1-jsprit.xml"); + new VrpXMLReader(builder).read("src/test/resources/pdVRP_vrpnc1_jsprit.xml"); vrp = builder.build(); final StateManagerImpl stateManager = new StateManagerImpl(); + HardActivityLevelConstraint hardActLevelConstraint = new HardActivityLevelConstraint() { @Override - public boolean fulfilled(InsertionContext iFacts, TourActivity act, double arrTime) { + 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(); + State futurePickState = stateManager.getActivityState(prevAct, "futurePicks"); + if(futurePickState == null) { + futurePicks = 0; + } + else { + futurePicks = (int) futurePickState.toDouble(); + } + State pastDeliveryState = stateManager.getActivityState(prevAct, "pastDeliveries"); + if(pastDeliveryState == null){ + pastDeliveries = 0; + } + else { + pastDeliveries = (int) pastDeliveryState.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; } + }; + MarginalsCalculus marginalCalculus = new MarginalsCalculusTriangleInequality(vrp.getTransportCosts(), vrp.getActivityCosts(), hardActLevelConstraint); - CalculatesServiceInsertion serviceInsertion = new CalculatesServiceInsertion(vrp.getTransportCosts(), marginalCalculus, new HardConstraints.HardLoadConstraint(stateManager)); + CalculatesServiceInsertion serviceInsertion = new CalculatesServiceInsertion(vrp.getTransportCosts(), marginalCalculus, new HardConstraints.HardRouteLevelConstraint() { + + @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; + } + } + else throw new IllegalStateException("ähh"); + return true; + } + + }); VehicleFleetManager fleetManager = new InfiniteVehicles(vrp.getVehicles()); JobInsertionCalculator finalServiceInsertion = new CalculatesVehTypeDepServiceInsertion(fleetManager, serviceInsertion); @@ -70,12 +150,127 @@ public class BuildPDVRPAlgoFromScratchTest { public void informIterationStarts(int i, VehicleRoutingProblem problem, Collection solutions) { stateManager.clear(); } + }; vra.getAlgorithmListeners().addListener(clearStateManager); - vra.getSearchStrategyManager().addSearchStrategyModuleListener(new RemoveEmptyVehicles(fleetManager)); - vra.getSearchStrategyManager().addSearchStrategyModuleListener(new UdateCostsAtRouteLevel(stateManager, vrp.getTransportCosts(), vrp.getActivityCosts())); - vra.getSearchStrategyManager().addSearchStrategyModuleListener(new UpdateLoadAtRouteLevel(stateManager)); + final IterateRouteForwardInTime iterateForward = new IterateRouteForwardInTime(vrp.getTransportCosts()); + + iterateForward.addListener(new UpdateCostsAtAllLevels(vrp.getActivityCosts(), vrp.getTransportCosts(), stateManager)); + iterateForward.addListener(new ForwardInTimeListener() { + + private int currentLoad = 0; + private int deliveries = 0; + + @Override + public void start(VehicleRoute route, Start start, double departureTime) { +// log.info("iterate forward"); + currentLoad = (int) stateManager.getRouteState(route, StateTypes.LOAD_AT_DEPOT).toDouble(); +// log.info("currentLoad="+currentLoad); + } + + @Override + public void nextActivity(TourActivity act, double arrTime, double endTime) { +// log.info("nextAct="+act.getClass().toString()+ " capDemand=" + act.getCapacityDemand() + " currentLoad="+currentLoad); + currentLoad += act.getCapacityDemand(); + if(act instanceof DeliveryActivity){ + deliveries += Math.abs(act.getCapacityDemand()); + } + stateManager.putActivityState(act, StateTypes.LOAD, new StateImpl(currentLoad)); + stateManager.putActivityState(act, "pastDeliveries", new StateImpl(deliveries)); + if(currentLoad < 0) throw new IllegalStateException("currentload < 0"); + if(currentLoad > 50){ + throw new IllegalStateException("currentload="+currentLoad+" wich is > 50"); + } + } + + @Override + public void end(End end, double arrivalTime) { +// log.info("currentLoad="+currentLoad); +// stateManager.putRouteState(route, StateTypes.LOAD, new StateImpl(currentLoad)); + currentLoad = 0; + deliveries = 0; + } + }); + + final IterateRouteBackwardInTime iterateBackward = new IterateRouteBackwardInTime(vrp.getTransportCosts()); + iterateBackward.addListener(new BackwardInTimeListener() { + + int futurePicks = 0; + @Override + public void start(VehicleRoute route, End end, double latestArrivalTime) { + + + } + + @Override + public void prevActivity(TourActivity act, double latestDepartureTime, double latestOperationStartTime) { + stateManager.putActivityState(act, "futurePicks", new StateImpl(futurePicks)); + if(act.getCapacityDemand() > 0){ + futurePicks += act.getCapacityDemand(); + } + + } + + @Override + public void end(Start start, double latestDepartureTime) { + futurePicks = 0; + + } + }); + + + + InsertionStartsListener loadVehicleInDepot = new InsertionStartsListener() { + + @Override + public void informInsertionStarts(Collection vehicleRoutes, Collection unassignedJobs) { + for(VehicleRoute route : vehicleRoutes){ + int loadAtDepot = 0; + int loadAtEnd = 0; + for(Job j : route.getTourActivities().getJobs()){ + if(j instanceof Delivery){ + loadAtDepot += j.getCapacityDemand(); + } + if(j instanceof Pickup){ + loadAtEnd += j.getCapacityDemand(); + } + } + stateManager.putRouteState(route, StateTypes.LOAD_AT_DEPOT, new StateImpl(loadAtDepot)); + stateManager.putRouteState(route, StateTypes.LOAD, new StateImpl(loadAtEnd)); + iterateForward.iterate(route); + iterateBackward.iterate(route); + } + } + + }; + + vra.getSearchStrategyManager().addSearchStrategyModuleListener(new RemoveEmptyVehicles(fleetManager)); + vra.getSearchStrategyManager().addSearchStrategyModuleListener(loadVehicleInDepot); + + + JobInsertedListener updateLoadAfterJobHasBeenInserted = new JobInsertedListener() { + + @Override + public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) { +// log.info("insert job " + job2insert.getClass().toString() + " " + job2insert.getCapacityDemand() + " in route " + inRoute.getTourActivities()); + if(job2insert instanceof Delivery){ + int loadAtDepot = (int) stateManager.getRouteState(inRoute, StateTypes.LOAD_AT_DEPOT).toDouble(); +// log.info("loadAtDepot="+loadAtDepot); + stateManager.putRouteState(inRoute, StateTypes.LOAD_AT_DEPOT, new StateImpl(loadAtDepot + job2insert.getCapacityDemand())); + } + if(job2insert instanceof Pickup){ + int loadAtEnd = (int) stateManager.getRouteState(inRoute, StateTypes.LOAD).toDouble(); +// log.info("loadAtEnd="+loadAtEnd); + stateManager.putRouteState(inRoute, StateTypes.LOAD, new StateImpl(loadAtEnd + job2insert.getCapacityDemand())); + } + + iterateForward.iterate(inRoute); + iterateBackward.iterate(inRoute); + } + }; + + vra.getSearchStrategyManager().addSearchStrategyModuleListener(updateLoadAfterJobHasBeenInserted); VehicleRoutingProblemSolution iniSolution = new CreateInitialSolution(bestInsertion).createInitialSolution(vrp); // System.out.println("ini: costs="+iniSolution.getCost()+";#routes="+iniSolution.getRoutes().size()); @@ -85,5 +280,13 @@ public class BuildPDVRPAlgoFromScratchTest { // vra.setPrematureBreak(200); } + + @Test + public void test(){ + Collection solutions = vra.searchSolutions(); + System.out.println(Solutions.getBest(solutions).getCost()); + new VrpXMLWriter(vrp, solutions).write("output/pdvrp_sol.xml"); + + } } diff --git a/jsprit-core/src/test/java/algorithms/GendreauPostOptTest.java b/jsprit-core/src/test/java/algorithms/GendreauPostOptTest.java index 27f75beb..e43ec161 100644 --- a/jsprit-core/src/test/java/algorithms/GendreauPostOptTest.java +++ b/jsprit-core/src/test/java/algorithms/GendreauPostOptTest.java @@ -151,7 +151,7 @@ public class GendreauPostOptTest { activityCosts = new ExampleActivityCostFunction(); - CalculatesServiceInsertion standardServiceInsertion = new CalculatesServiceInsertion(cost, new MarginalsCalculusTriangleInequality(cost, activityCosts, new HardConstraints.HardTimeWindowConstraint(states)), new HardConstraints.HardLoadConstraint(states)); + CalculatesServiceInsertion standardServiceInsertion = new CalculatesServiceInsertion(cost, new MarginalsCalculusTriangleInequality(cost, activityCosts, new HardConstraints.HardTimeWindowConstraint(states, cost)), new HardConstraints.HardLoadConstraint(states)); CalculatesServiceInsertionConsideringFixCost withFixCost = new CalculatesServiceInsertionConsideringFixCost(standardServiceInsertion, states); withFixCost.setWeightOfFixCost(1.2); diff --git a/jsprit-core/src/test/java/algorithms/TestCalculatesServiceInsertion.java b/jsprit-core/src/test/java/algorithms/TestCalculatesServiceInsertion.java index 459ae877..3ac94346 100644 --- a/jsprit-core/src/test/java/algorithms/TestCalculatesServiceInsertion.java +++ b/jsprit-core/src/test/java/algorithms/TestCalculatesServiceInsertion.java @@ -156,7 +156,7 @@ public class TestCalculatesServiceInsertion { ExampleActivityCostFunction activityCosts = new ExampleActivityCostFunction(); - serviceInsertion = new CalculatesServiceInsertion(costs, new MarginalsCalculusTriangleInequality(costs, activityCosts, new HardConstraints.HardTimeWindowConstraint(states)), new HardConstraints.HardLoadConstraint(states)); + serviceInsertion = new CalculatesServiceInsertion(costs, new MarginalsCalculusTriangleInequality(costs, activityCosts, new HardConstraints.HardTimeWindowConstraint(states, costs)), new HardConstraints.HardLoadConstraint(states)); stateUpdater = new UpdateStates(states, costs, activityCosts); diff --git a/jsprit-core/src/test/java/algorithms/TestIterateRouteForwardInTime.java b/jsprit-core/src/test/java/algorithms/TestIterateRouteForwardInTime.java index e3553e2a..714aab00 100644 --- a/jsprit-core/src/test/java/algorithms/TestIterateRouteForwardInTime.java +++ b/jsprit-core/src/test/java/algorithms/TestIterateRouteForwardInTime.java @@ -34,10 +34,6 @@ public class TestIterateRouteForwardInTime { TourActivities anotherTour; - - - RouteStates states; - private VehicleRoute vehicleRoute; private VehicleRoutingTransportCosts cost; @@ -46,6 +42,8 @@ public class TestIterateRouteForwardInTime { ServiceActivity secondAct; + StateManagerImpl stateManager; + @Before public void setUp(){ cost = new VehicleRoutingTransportCosts() { @@ -99,6 +97,8 @@ public class TestIterateRouteForwardInTime { tour.addActivity(secondAct); vehicleRoute = VehicleRoute.newInstance(tour,DriverImpl.noDriver(),vehicle); + + stateManager = new StateManagerImpl(); } @Test @@ -129,12 +129,11 @@ public class TestIterateRouteForwardInTime { @Test public void whenIteratingWithLoadUpdateAtActLocations_itShouldUpdateLoad() { IterateRouteForwardInTime forwardInTime = new IterateRouteForwardInTime(cost); - StateManagerImpl states = new StateManagerImpl(); - forwardInTime.addListener(new UpdateLoadAtAllLevels(states)); + forwardInTime.addListener(new UpdateLoadAtAllLevels(stateManager)); forwardInTime.iterate(vehicleRoute); - assertEquals(5.0, states.getActivityStates(firstAct).getState(StateTypes.LOAD).toDouble(), 0.01); - assertEquals(10.0, states.getActivityStates(secondAct).getState(StateTypes.LOAD).toDouble(), 0.01); + assertEquals(5.0, stateManager.getActivityState(firstAct,StateTypes.LOAD).toDouble(), 0.01); + assertEquals(10.0, stateManager.getActivityState(secondAct,StateTypes.LOAD).toDouble(), 0.01); } @@ -153,42 +152,41 @@ public class TestIterateRouteForwardInTime { @Test public void testStatesOfAct1(){ IterateRouteForwardInTime forwardInTime = new IterateRouteForwardInTime(cost); - StateManagerImpl states = new StateManagerImpl(); - forwardInTime.addListener(new UpdateLoadAtAllLevels(states)); - forwardInTime.addListener(new UpdateEarliestStartTimeWindowAtActLocations(states)); - forwardInTime.addListener(new UpdateCostsAtAllLevels(new DefaultVehicleRoutingActivityCosts(), cost, states)); + forwardInTime.addListener(new UpdateLoadAtAllLevels(stateManager)); + forwardInTime.addListener(new UpdateEarliestStartTimeWindowAtActLocations(stateManager)); + forwardInTime.addListener(new UpdateCostsAtAllLevels(new DefaultVehicleRoutingActivityCosts(), cost, stateManager)); forwardInTime.iterate(vehicleRoute); - assertEquals(10.0, states.getActivityStates(firstAct).getState(StateTypes.COSTS).toDouble(),0.05); - assertEquals(5.0, states.getActivityStates(firstAct).getState(StateTypes.LOAD).toDouble(),0.05); - assertEquals(10.0, states.getActivityStates(firstAct).getState(StateTypes.EARLIEST_OPERATION_START_TIME).toDouble(),0.05); + assertEquals(10.0, stateManager.getActivityState(firstAct, StateTypes.COSTS).toDouble(),0.05); + assertEquals(5.0, stateManager.getActivityState(firstAct, StateTypes.LOAD).toDouble(),0.05); + assertEquals(10.0, stateManager.getActivityState(firstAct, StateTypes.EARLIEST_OPERATION_START_TIME).toDouble(),0.05); // assertEquals(20.0, states.getState(tour.getActivities().get(0)).getLatestOperationStart(),0.05); } @Test public void testStatesOfAct2(){ IterateRouteForwardInTime forwardInTime = new IterateRouteForwardInTime(cost); - StateManagerImpl states = new StateManagerImpl(); - forwardInTime.addListener(new UpdateLoadAtAllLevels(states)); - forwardInTime.addListener(new UpdateEarliestStartTimeWindowAtActLocations(states)); - forwardInTime.addListener(new UpdateCostsAtAllLevels(new DefaultVehicleRoutingActivityCosts(), cost, states)); + + forwardInTime.addListener(new UpdateLoadAtAllLevels(stateManager)); + forwardInTime.addListener(new UpdateEarliestStartTimeWindowAtActLocations(stateManager)); + forwardInTime.addListener(new UpdateCostsAtAllLevels(new DefaultVehicleRoutingActivityCosts(), cost, stateManager)); forwardInTime.iterate(vehicleRoute); - assertEquals(30.0, states.getActivityStates(secondAct).getState(StateTypes.COSTS).toDouble(),0.05); - assertEquals(10.0, states.getActivityStates(secondAct).getState(StateTypes.LOAD).toDouble(),0.05); - assertEquals(30.0, states.getActivityStates(secondAct).getState(StateTypes.EARLIEST_OPERATION_START_TIME).toDouble(),0.05); + assertEquals(30.0, stateManager.getActivityState(secondAct, StateTypes.COSTS).toDouble(),0.05); + assertEquals(10.0, stateManager.getActivityState(secondAct, StateTypes.LOAD).toDouble(),0.05); + assertEquals(30.0, stateManager.getActivityState(secondAct, StateTypes.EARLIEST_OPERATION_START_TIME).toDouble(),0.05); // assertEquals(40.0, states.getState(tour.getActivities().get(1)).getLatestOperationStart(),0.05); } @Test public void testStatesOfAct3(){ IterateRouteForwardInTime forwardInTime = new IterateRouteForwardInTime(cost); - StateManagerImpl states = new StateManagerImpl(); + forwardInTime.addListener(new UpdateActivityTimes()); - forwardInTime.addListener(new UpdateCostsAtAllLevels(new DefaultVehicleRoutingActivityCosts(), cost, states)); + forwardInTime.addListener(new UpdateCostsAtAllLevels(new DefaultVehicleRoutingActivityCosts(), cost, stateManager)); forwardInTime.iterate(vehicleRoute); - assertEquals(40.0, states.getRouteStates(vehicleRoute).getState(StateTypes.COSTS).toDouble(), 0.05); + assertEquals(40.0, stateManager.getRouteState(vehicleRoute,StateTypes.COSTS).toDouble(), 0.05); assertEquals(40.0, vehicleRoute.getEnd().getArrTime(),0.05); assertEquals(50.0, vehicleRoute.getEnd().getTheoreticalLatestOperationStartTime(),0.05); } diff --git a/jsprit-core/src/test/resources/finiteVrpForReaderV2Test.xml b/jsprit-core/src/test/resources/finiteVrpForReaderV2Test.xml index 20d9e7a0..073b87c9 100644 --- a/jsprit-core/src/test/resources/finiteVrpForReaderV2Test.xml +++ b/jsprit-core/src/test/resources/finiteVrpForReaderV2Test.xml @@ -75,7 +75,7 @@ - + j(1,5) 1 @@ -88,7 +88,7 @@ - + i(3,9) 1