diff --git a/jsprit-core/src/main/java/algorithms/AbstractInsertionStrategy.java b/jsprit-core/src/main/java/algorithms/AbstractInsertionStrategy.java deleted file mode 100644 index f2dfca54..00000000 --- a/jsprit-core/src/main/java/algorithms/AbstractInsertionStrategy.java +++ /dev/null @@ -1,95 +0,0 @@ -/******************************************************************************* - * Copyright (C) 2013 Stefan Schroeder - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Contributors: - * Stefan Schroeder - initial API and implementation - ******************************************************************************/ -package algorithms; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -import org.apache.log4j.Logger; - -import basics.Job; -import basics.algo.InsertionEndsListener; -import basics.algo.InsertionListener; -import basics.algo.InsertionStartsListener; -import basics.algo.JobInsertedListener; -import basics.route.VehicleRoute; - - - - -abstract class AbstractInsertionStrategy implements InsertionStrategy{ - - private static Logger log = Logger.getLogger(AbstractInsertionStrategy.class); - - private Collection listener = new ArrayList(); - - public abstract RouteAlgorithm getRouteAlgorithm(); - - public void informJobInserted(int nOfJobs2Recreate, Job insertedJob, VehicleRoute insertedIn){ - for(InsertionListener l : listener){ - if(l instanceof JobInsertedListener){ - ((JobInsertedListener)l).informJobInserted(nOfJobs2Recreate, insertedJob, insertedIn); - } - } - } - - public void informBeforeJobInsertion(Job job, InsertionData data, VehicleRoute route){ - for(InsertionListener l : listener){ - if(l instanceof BeforeJobInsertionListener){ - ((BeforeJobInsertionListener)l).informBeforeJobInsertion(job, data, route); - } - } - } - - public void informInsertionStarts(Collection vehicleRoutes, int nOfJobs2Recreate){ - for(InsertionListener l : listener){ - if(l instanceof InsertionStartsListener){ - ((InsertionStartsListener)l).informInsertionStarts(vehicleRoutes,nOfJobs2Recreate); - } - } - } - - public void informInsertionEndsListeners(Collection vehicleRoutes) { - for(InsertionListener l : listener){ - if(l instanceof InsertionEndsListener){ - ((InsertionEndsListener)l).informInsertionEnds(vehicleRoutes); - } - } - } - - public Collection getListener() { - return Collections.unmodifiableCollection(listener); - } - - public void addListener(InsertionListener l){ - log.info("add insertion-listener " + l); - listener.add(l); - } - - public void addAllListener(List list) { - for(InsertionListener l : list) addListener(l); - } - - - -} diff --git a/jsprit-core/src/main/java/algorithms/BestInsertion.java b/jsprit-core/src/main/java/algorithms/BestInsertion.java index 8d088b59..bee3394b 100644 --- a/jsprit-core/src/main/java/algorithms/BestInsertion.java +++ b/jsprit-core/src/main/java/algorithms/BestInsertion.java @@ -15,9 +15,7 @@ package algorithms; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.Random; import org.apache.log4j.Logger; @@ -25,6 +23,9 @@ import org.apache.log4j.Logger; import util.RandomNumberGeneration; import algorithms.InsertionData.NoInsertionFound; import basics.Job; +import basics.algo.InsertionListener; +import basics.route.Driver; +import basics.route.Vehicle; import basics.route.VehicleRoute; @@ -35,47 +36,37 @@ import basics.route.VehicleRoute; * */ -final class BestInsertion extends AbstractInsertionStrategy{ - - public static BestInsertion newInstance(RouteAlgorithm routeAlgorithm){ - return new BestInsertion(routeAlgorithm); - } +final class BestInsertion implements InsertionStrategy{ private static Logger logger = Logger.getLogger(BestInsertion.class); private Random random = RandomNumberGeneration.getRandom(); + private final static double NO_NEW_DEPARTURE_TIME_YET = -12345.12345; + + private final static Vehicle NO_NEW_VEHICLE_YET = null; + + private final static Driver NO_NEW_DRIVER_YET = null; + private InsertionListeners insertionsListeners; - private RouteAlgorithm routeAlgorithm; + private Inserter inserter; - public void setExperimentalPreferredRoute(Map experimentalPreferredRoute) { - } + private JobInsertionCalculator bestInsertionCostCalculator; - private boolean allowUnassignedJobs = false; - - private boolean fixRouteSet = false; - private boolean minVehiclesFirst = false; - - public void setFixRouteSet(boolean fixRouteSet) { - this.fixRouteSet = fixRouteSet; - } public void setRandom(Random random) { this.random = random; } - public BestInsertion(RouteAlgorithm routeAlgorithm) { + public BestInsertion(JobInsertionCalculator jobInsertionCalculator) { super(); - this.routeAlgorithm = routeAlgorithm; this.insertionsListeners = new InsertionListeners(); + inserter = new Inserter(insertionsListeners); + bestInsertionCostCalculator = jobInsertionCalculator; logger.info("initialise " + this); } - - public RouteAlgorithm getRouteAlgorithm(){ - return routeAlgorithm; - } @Override public String toString() { @@ -83,18 +74,15 @@ final class BestInsertion extends AbstractInsertionStrategy{ } @Override - public void run(Collection vehicleRoutes, Collection unassignedJobs, double result2beat) { + public void insertJobs(Collection vehicleRoutes, Collection unassignedJobs) { + insertionsListeners.informInsertionStarts(vehicleRoutes,unassignedJobs); List unassignedJobList = new ArrayList(unassignedJobs); Collections.shuffle(unassignedJobList, random); - informInsertionStarts(vehicleRoutes,unassignedJobs.size()); - int inserted = 0; - List reasons = new ArrayList(); for(Job unassignedJob : unassignedJobList){ - VehicleRoute insertIn = null; Insertion bestInsertion = null; double bestInsertionCost = Double.MAX_VALUE; for(VehicleRoute vehicleRoute : vehicleRoutes){ - InsertionData iData = routeAlgorithm.calculateBestInsertion(vehicleRoute, unassignedJob, bestInsertionCost); + InsertionData iData = bestInsertionCostCalculator.calculate(vehicleRoute, unassignedJob, NO_NEW_VEHICLE_YET, NO_NEW_DEPARTURE_TIME_YET, NO_NEW_DRIVER_YET, bestInsertionCost); if(iData instanceof NoInsertionFound) { continue; } @@ -105,56 +93,54 @@ final class BestInsertion extends AbstractInsertionStrategy{ } if(!minVehiclesFirst){ VehicleRoute newRoute = VehicleRoute.emptyRoute(); - InsertionData newIData = routeAlgorithm.calculateBestInsertion(newRoute, unassignedJob, Double.MAX_VALUE); + InsertionData newIData = bestInsertionCostCalculator.calculate(newRoute, unassignedJob, NO_NEW_VEHICLE_YET, NO_NEW_DEPARTURE_TIME_YET, NO_NEW_DRIVER_YET, bestInsertionCost); if(newIData.getInsertionCost() < bestInsertionCost){ bestInsertion = new Insertion(newRoute,newIData); bestInsertionCost = newIData.getInsertionCost(); vehicleRoutes.add(newRoute); } - } - if(bestInsertion != null){ - informBeforeJobInsertion(unassignedJob, bestInsertion.getInsertionData(), bestInsertion.getRoute()); - insertIn = bestInsertion.getRoute(); -// logger.debug("insert job="+unassignedJob+" at index=" + bestInsertion.getInsertionData().getInsertionIndex() + " delta cost=" + bestInsertion.getInsertionData().getInsertionCost()); - routeAlgorithm.insertJob(unassignedJob, bestInsertion.getInsertionData(), bestInsertion.getRoute()); - } - else { - if(fixRouteSet){ - if(allowUnassignedJobs) logger.warn("cannot insert job yet " + unassignedJob); - else throw new IllegalStateException("given the vehicles, could not insert job\n"); + } + if(bestInsertion == null){ + VehicleRoute newRoute = VehicleRoute.emptyRoute(); + InsertionData bestI = bestInsertionCostCalculator.calculate(newRoute, unassignedJob, NO_NEW_VEHICLE_YET, NO_NEW_DEPARTURE_TIME_YET, NO_NEW_DRIVER_YET, Double.MAX_VALUE); + if(bestI instanceof InsertionData.NoInsertionFound){ + throw new IllegalStateException(getErrorMsg(unassignedJob)); } else{ - VehicleRoute newRoute = VehicleRoute.emptyRoute(); - InsertionData bestI = routeAlgorithm.calculateBestInsertion(newRoute, unassignedJob, Double.MAX_VALUE); - if(bestI instanceof InsertionData.NoInsertionFound){ - if(allowUnassignedJobs){ - logger.warn("cannot insert job yet " + unassignedJob); - } - else { - for(String s : reasons){ - System.out.println("reason="+s); - } - throw new IllegalStateException("given the vehicles, could not insert job\n" + - "\t" + unassignedJob + - "\n\tthis might have the following reasons:\n" + - "\t- no vehicle has the capacity to transport the job [check whether there is at least one vehicle that is capable to transport the job]\n" + - "\t- the time-window cannot be met, even in a commuter tour the time-window is missed [check whether it is possible to reach the time-window on the shortest path or make hard time-windows soft]\n" + - "\t- if you deal with finite vehicles, and the available vehicles are already fully employed, no vehicle can be found anymore to transport the job [add penalty-vehicles]" - ); - } - } - else{ - insertIn = newRoute; - informBeforeJobInsertion(unassignedJob,bestI,newRoute); - routeAlgorithm.insertJob(unassignedJob,bestI,newRoute); - vehicleRoutes.add(newRoute); - } + bestInsertion = new Insertion(newRoute,bestI); + vehicleRoutes.add(newRoute); } } - inserted++; - informJobInserted((unassignedJobList.size()-inserted), unassignedJob, insertIn); + + inserter.insertJob(unassignedJob, bestInsertion.getInsertionData(), bestInsertion.getRoute()); + } - informInsertionEndsListeners(vehicleRoutes); + insertionsListeners.informInsertionEndsListeners(vehicleRoutes); + } + + private String getErrorMsg(Job unassignedJob) { + return "given the vehicles, could not insert job\n" + + "\t" + unassignedJob + + "\n\tthis might have the following reasons:\n" + + "\t- no vehicle has the capacity to transport the job [check whether there is at least one vehicle that is capable to transport the job]\n" + + "\t- the time-window cannot be met, even in a commuter tour the time-window is missed [check whether it is possible to reach the time-window on the shortest path or make hard time-windows soft]\n" + + "\t- if you deal with finite vehicles, and the available vehicles are already fully employed, no vehicle can be found anymore to transport the job [add penalty-vehicles]"; + } + + @Override + public void removeListener(InsertionListener insertionListener) { + insertionsListeners.removeListener(insertionListener); + } + + @Override + public Collection getListeners() { + return Collections.unmodifiableCollection(insertionsListeners.getListeners()); + } + + @Override + public void addListener(InsertionListener insertionListener) { + insertionsListeners.addListener(insertionListener); + } } diff --git a/jsprit-core/src/main/java/algorithms/BestInsertionConcurrent.java b/jsprit-core/src/main/java/algorithms/BestInsertionConcurrent.java index cfe56404..742e29b4 100644 --- a/jsprit-core/src/main/java/algorithms/BestInsertionConcurrent.java +++ b/jsprit-core/src/main/java/algorithms/BestInsertionConcurrent.java @@ -30,6 +30,7 @@ import org.apache.log4j.Logger; import util.RandomNumberGeneration; import algorithms.InsertionData.NoInsertionFound; import basics.Job; +import basics.algo.InsertionListener; import basics.route.VehicleRoute; @@ -40,7 +41,7 @@ import basics.route.VehicleRoute; * */ -final class BestInsertionConcurrent extends AbstractInsertionStrategy{ +final class BestInsertionConcurrent implements InsertionStrategy{ public static BestInsertionConcurrent newInstance(RouteAlgorithm routeAlgorithm, ExecutorService executor, int nuOfThreads){ return new BestInsertionConcurrent(routeAlgorithm, executor, nuOfThreads); @@ -82,10 +83,10 @@ final class BestInsertionConcurrent extends AbstractInsertionStrategy{ } @Override - public void run(Collection vehicleRoutes, Collection unassignedJobs, double result2beat) { + public void insertJobs(Collection vehicleRoutes, Collection unassignedJobs) { List unassignedJobList = new ArrayList(unassignedJobs); Collections.shuffle(unassignedJobList, random); - informInsertionStarts(vehicleRoutes,unassignedJobs.size()); +// informInsertionStarts(vehicleRoutes,unassignedJobs.size()); int inserted = 0; for(final Job unassignedJob : unassignedJobList){ VehicleRoute insertIn = null; @@ -127,7 +128,7 @@ final class BestInsertionConcurrent extends AbstractInsertionStrategy{ } if(bestInsertion != null){ - informBeforeJobInsertion(unassignedJob, bestInsertion.getInsertionData(), bestInsertion.getRoute()); +// informBeforeJobInsertion(unassignedJob, bestInsertion.getInsertionData(), bestInsertion.getRoute()); insertIn = bestInsertion.getRoute(); // logger.debug("insert job="+unassignedJob+" at index=" + bestInsertion.getInsertionData().getInsertionIndex() + " delta cost=" + bestInsertion.getInsertionData().getInsertionCost()); routeAlgorithm.insertJob(unassignedJob, bestInsertion.getInsertionData(), bestInsertion.getRoute()); @@ -144,9 +145,9 @@ final class BestInsertionConcurrent extends AbstractInsertionStrategy{ // vehicleRoutes.add(newRoute); } inserted++; - informJobInserted((unassignedJobList.size()-inserted), unassignedJob, insertIn); +// informJobInserted((unassignedJobList.size()-inserted), unassignedJob, insertIn); } - informInsertionEndsListeners(vehicleRoutes); +// informInsertionEndsListeners(vehicleRoutes); } private Insertion getBestInsertion(Batch batch, Job unassignedJob) { @@ -191,9 +192,23 @@ final class BestInsertionConcurrent extends AbstractInsertionStrategy{ return batches; } + @Override - public RouteAlgorithm getRouteAlgorithm() { - return routeAlgorithm; + public void removeListener(InsertionListener insertionListener) { + // TODO Auto-generated method stub + + } + + @Override + public Collection getListeners() { + // TODO Auto-generated method stub + return null; + } + + @Override + public void addListener(InsertionListener insertionListener) { + // TODO Auto-generated method stub + } } diff --git a/jsprit-core/src/main/java/algorithms/ConfigureFixCostCalculator.java b/jsprit-core/src/main/java/algorithms/ConfigureFixCostCalculator.java index 179164da..650cbedf 100644 --- a/jsprit-core/src/main/java/algorithms/ConfigureFixCostCalculator.java +++ b/jsprit-core/src/main/java/algorithms/ConfigureFixCostCalculator.java @@ -42,6 +42,8 @@ final class ConfigureFixCostCalculator implements InsertionStartsListener, JobIn VehicleRoutingProblem vrp; CalculatesServiceInsertionConsideringFixCost calcConsideringFix; + + private int nuOfJobsToRecreate; public ConfigureFixCostCalculator(VehicleRoutingProblem vrp, CalculatesServiceInsertionConsideringFixCost calcConsideringFix) { super(); @@ -55,15 +57,17 @@ final class ConfigureFixCostCalculator implements InsertionStartsListener, JobIn } @Override - public void informInsertionStarts(Collection routes, int nOfJobs2Recreate) { - double completenessRatio = (1-((double)nOfJobs2Recreate/(double)vrp.getJobs().values().size())); + public void informInsertionStarts(Collection routes, Collection unassignedJobs) { + this.nuOfJobsToRecreate = unassignedJobs.size(); + double completenessRatio = (1-((double)nuOfJobsToRecreate/(double)vrp.getJobs().values().size())); calcConsideringFix.setSolutionCompletenessRatio(completenessRatio); // log.debug("initialise completenessRatio to " + completenessRatio); } @Override - public void informJobInserted(int nOfJobsStill2Recreate, Job job2insert, VehicleRoute insertedIn) { - double completenessRatio = (1-((double)nOfJobsStill2Recreate/(double)vrp.getJobs().values().size())); + public void informJobInserted(Job job2insert, VehicleRoute inRoute) { + nuOfJobsToRecreate--; + double completenessRatio = (1-((double)nuOfJobsToRecreate/(double)vrp.getJobs().values().size())); calcConsideringFix.setSolutionCompletenessRatio(completenessRatio); // log.debug("set completenessRatio to " + completenessRatio); } diff --git a/jsprit-core/src/main/java/algorithms/CreateInitialSolution.java b/jsprit-core/src/main/java/algorithms/CreateInitialSolution.java index 08f19f1d..e0b1cd6d 100644 --- a/jsprit-core/src/main/java/algorithms/CreateInitialSolution.java +++ b/jsprit-core/src/main/java/algorithms/CreateInitialSolution.java @@ -73,7 +73,7 @@ final class CreateInitialSolution implements InitialSolutionFactory { vehicleRoutes.add(VehicleRoute.newInstance(TourActivities.emptyTour(), DriverImpl.noDriver(), vehicle)); } } - insertion.run(vehicleRoutes, getUnassignedJobs(vrp), Double.MAX_VALUE); + insertion.insertJobs(vehicleRoutes, getUnassignedJobs(vrp)); double totalCost = getTotalCost(vehicleRoutes); logger.info("creation done"); return new VehicleRoutingProblemSolution(vehicleRoutes, totalCost); diff --git a/jsprit-core/src/main/java/algorithms/FindCheaperVehicle.java b/jsprit-core/src/main/java/algorithms/FindCheaperVehicle.java index 9a19f579..807cc36a 100644 --- a/jsprit-core/src/main/java/algorithms/FindCheaperVehicle.java +++ b/jsprit-core/src/main/java/algorithms/FindCheaperVehicle.java @@ -24,6 +24,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; +import basics.Job; import basics.algo.InsertionStartsListener; import basics.route.VehicleRoute; @@ -37,7 +38,7 @@ class FindCheaperVehicle implements InsertionStartsListener{ } @Override - public void informInsertionStarts(Collection vehicleRoutes, int nOfJobs2Recreate) { + public void informInsertionStarts(Collection vehicleRoutes, Collection unassignedJobs) { List newRoutes = new ArrayList(); for(VehicleRoute route : vehicleRoutes){ if(route.isEmpty()) continue; diff --git a/jsprit-core/src/main/java/algorithms/Gendreau.java b/jsprit-core/src/main/java/algorithms/Gendreau.java index d94c4b1c..70125dc4 100644 --- a/jsprit-core/src/main/java/algorithms/Gendreau.java +++ b/jsprit-core/src/main/java/algorithms/Gendreau.java @@ -21,6 +21,7 @@ package algorithms; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashSet; @@ -30,16 +31,15 @@ import java.util.Set; import org.apache.log4j.Logger; +import util.RandomNumberGeneration; import basics.Job; import basics.VehicleRoutingProblem; import basics.VehicleRoutingProblemSolution; import basics.algo.SearchStrategyModule; import basics.algo.SearchStrategyModuleListener; import basics.route.TourActivity; -import basics.route.VehicleRoute; import basics.route.TourActivity.JobActivity; - -import util.RandomNumberGeneration; +import basics.route.VehicleRoute; final class Gendreau implements SearchStrategyModule{ @@ -53,7 +53,7 @@ final class Gendreau implements SearchStrategyModule{ private final InsertionStrategy insertionStrategy; - private final RouteAlgorithm routeAlgorithm; + private final Inserter inserter; private VehicleFleetManager fleetManager; @@ -69,7 +69,9 @@ final class Gendreau implements SearchStrategyModule{ public Gendreau(VehicleRoutingProblem vrp, RuinStrategy ruin, InsertionStrategy insertionStrategy) { super(); - this.routeAlgorithm = insertionStrategy.getRouteAlgorithm(); + InsertionListeners insertionListeners = new InsertionListeners(); + insertionListeners.addAllListeners(insertionStrategy.getListeners()); + inserter = new Inserter(insertionListeners); this.ruin = ruin; this.vrp = vrp; this.insertionStrategy = insertionStrategy; @@ -119,16 +121,18 @@ final class Gendreau implements SearchStrategyModule{ VehicleRoute emptyRoute1 = VehicleRoute.emptyRoute(); copiedRoutes.add(emptyRoute1); - routeAlgorithm.insertJob(targetJob, routeAlgorithm.calculateBestInsertion(emptyRoute1, targetJob, Double.MAX_VALUE), emptyRoute1); + insertionStrategy.insertJobs(Arrays.asList(emptyRoute1), Arrays.asList(targetJob)); +// routeAlgorithm.insertJob(targetJob, routeAlgorithm.calculateBestInsertion(emptyRoute1, targetJob, Double.MAX_VALUE), emptyRoute1); unassignedJobs.remove(targetJob); VehicleRoute emptyRoute2 = VehicleRoute.emptyRoute(); copiedRoutes.add(emptyRoute2); Job job2 = jobsInRoute.get(1); - routeAlgorithm.insertJob(job2, routeAlgorithm.calculateBestInsertion(emptyRoute2, job2, Double.MAX_VALUE), emptyRoute2); + insertionStrategy.insertJobs(Arrays.asList(emptyRoute2), Arrays.asList(job2)); +// routeAlgorithm.insertJob(job2, routeAlgorithm.calculateBestInsertion(emptyRoute2, job2, Double.MAX_VALUE), emptyRoute2); unassignedJobs.remove(job2); - insertionStrategy.run(copiedRoutes, unassignedJobs, Double.MAX_VALUE); + insertionStrategy.insertJobs(copiedRoutes, unassignedJobs); double cost = getCost(copiedRoutes); if(cost < bestSolution.getCost()){ diff --git a/jsprit-core/src/main/java/algorithms/Inserter.java b/jsprit-core/src/main/java/algorithms/Inserter.java new file mode 100644 index 00000000..4a322790 --- /dev/null +++ b/jsprit-core/src/main/java/algorithms/Inserter.java @@ -0,0 +1,36 @@ +package algorithms; + +import algorithms.InsertionData.NoInsertionFound; +import basics.Job; +import basics.Service; +import basics.route.ServiceActivity; +import basics.route.VehicleRoute; + +class Inserter { + + private InsertionListeners insertionListeners; + + public Inserter(InsertionListeners insertionListeners) { + this.insertionListeners = insertionListeners; + } + + public void insertJob(Job job, InsertionData insertionData, VehicleRoute vehicleRoute){ + insertionListeners.informBeforeJobInsertion(job, insertionData, vehicleRoute); + + if(insertionData == null || (insertionData instanceof NoInsertionFound)) throw new IllegalStateException("insertionData null. cannot insert job."); + if(job == null) throw new IllegalStateException("cannot insert null-job"); + if(!(vehicleRoute.getVehicle().getId().toString().equals(insertionData.getSelectedVehicle().getId().toString()))){ + insertionListeners.informVehicleSwitched(vehicleRoute, vehicleRoute.getVehicle(), insertionData.getSelectedVehicle()); + vehicleRoute.setVehicle(insertionData.getSelectedVehicle(), insertionData.getVehicleDepartureTime()); + } +// if(vehicleRoute.getDepartureTime() != vehicleRoute.g) + if(job instanceof Service) { + vehicleRoute.getTourActivities().addActivity(insertionData.getDeliveryInsertionIndex(), ServiceActivity.newInstance((Service)job)); + vehicleRoute.setDepartureTime(insertionData.getVehicleDepartureTime()); + } + else throw new IllegalStateException("neither service nor shipment. this is not supported."); + + insertionListeners.informJobInserted(job, vehicleRoute); +// updateTour(vehicleRoute); + } +} diff --git a/jsprit-core/src/main/java/algorithms/InsertionFactory.java b/jsprit-core/src/main/java/algorithms/InsertionFactory.java index b7cc4093..de09488d 100644 --- a/jsprit-core/src/main/java/algorithms/InsertionFactory.java +++ b/jsprit-core/src/main/java/algorithms/InsertionFactory.java @@ -37,7 +37,7 @@ class InsertionFactory { private static Logger log = Logger.getLogger(InsertionFactory.class); - public static AbstractInsertionStrategy createInsertion(VehicleRoutingProblem vrp, HierarchicalConfiguration config, + public static InsertionStrategy createInsertion(VehicleRoutingProblem vrp, HierarchicalConfiguration config, VehicleFleetManager vehicleFleetManager, RouteStates activityStates, List algorithmListeners, ExecutorService executorService, int nuOfThreads){ boolean concurrentInsertion = false; if(executorService != null) concurrentInsertion = true; @@ -46,7 +46,7 @@ class InsertionFactory { if(!insertionName.equals("bestInsertion") && !insertionName.equals("regretInsertion")){ new IllegalStateException(insertionName + " is not supported. use either \"bestInsertion\" or \"regretInsertion\""); } - AbstractInsertionStrategy insertionStrategy = null; + InsertionStrategy insertionStrategy = null; List insertionListeners = new ArrayList(); List algoListeners = new ArrayList(); @@ -96,7 +96,7 @@ class InsertionFactory { JobInsertionCalculator jic = calcBuilder.build(); TourStateUpdater tourStateCalculator = new TourStateUpdater(activityStates, vrp.getTransportCosts(), vrp.getActivityCosts()); RouteAlgorithm routeAlgorithm = RouteAlgorithmImpl.newInstance(jic, tourStateCalculator); - routeAlgorithm.getListeners().add(new VehicleSwitched(vehicleFleetManager)); +// routeAlgorithm.getListeners().add(new VehicleSwitched(vehicleFleetManager)); ((RouteAlgorithmImpl) routeAlgorithm).setActivityStates(activityStates); if(insertionName.equals("bestInsertion")){ @@ -104,24 +104,18 @@ class InsertionFactory { insertionStrategy = BestInsertionConcurrent.newInstance(routeAlgorithm,executorService,nuOfThreads); } else{ - insertionStrategy = BestInsertion.newInstance(routeAlgorithm); + insertionStrategy = new BestInsertion(jic); } } else if(insertionName.equals("regretInsertion")){ insertionStrategy = RegretInsertion.newInstance(routeAlgorithm); } -// else if(insertionName.equals("concurrentBestInsertion")){ -// String processorsString = config.getString("[@processors]"); -// int processors = 1; -// if(processorsString != null) processors = Integer.parseInt(processorsString); -//// BestInsertionConcurrent.newInstance(routeAlgorithm,) -// -// -// } -// insertionStrategy.addListener(new RemoveEmptyVehicles(vehicleFleetManager)); + insertionStrategy.addListener(new RemoveEmptyVehicles(vehicleFleetManager)); insertionStrategy.addListener(new ResetAndIniFleetManager(vehicleFleetManager)); - insertionStrategy.addAllListener(insertionListeners); + insertionStrategy.addListener(new VehicleSwitched(vehicleFleetManager)); + insertionStrategy.addListener(new UpdateRoute(activityStates, vrp.getTransportCosts(), vrp.getActivityCosts())); + for(InsertionListener l : insertionListeners) insertionStrategy.addListener(l); // insertionStrategy.addListener(new FindCheaperVehicle( // new FindCheaperVehicleAlgoNew(vehicleFleetManager, tourStateCalculator, auxCalculator))); diff --git a/jsprit-core/src/main/java/algorithms/InsertionListeners.java b/jsprit-core/src/main/java/algorithms/InsertionListeners.java index e0c9d2e3..d35e5434 100644 --- a/jsprit-core/src/main/java/algorithms/InsertionListeners.java +++ b/jsprit-core/src/main/java/algorithms/InsertionListeners.java @@ -8,16 +8,29 @@ import basics.algo.InsertionEndsListener; import basics.algo.InsertionListener; import basics.algo.InsertionStartsListener; import basics.algo.JobInsertedListener; +import basics.route.Vehicle; import basics.route.VehicleRoute; class InsertionListeners { private Collection listeners = new ArrayList(); - public void informJobInserted(int nOfJobs2Recreate, Job insertedJob, VehicleRoute insertedIn){ + public Collection getListeners(){ + return listeners; + } + + public void informJobInserted(Job insertedJob, VehicleRoute inRoute){ for(InsertionListener l : listeners){ if(l instanceof JobInsertedListener){ - ((JobInsertedListener)l).informJobInserted(nOfJobs2Recreate, insertedJob, insertedIn); + ((JobInsertedListener)l).informJobInserted(insertedJob, inRoute); + } + } + } + + public void informVehicleSwitched(VehicleRoute route, Vehicle oldVehicle, Vehicle newVehicle){ + for(InsertionListener l : listeners){ + if(l instanceof VehicleSwitchedListener){ + ((VehicleSwitchedListener) l).vehicleSwitched(route, oldVehicle, newVehicle); } } } @@ -30,10 +43,10 @@ class InsertionListeners { } } - public void informInsertionStarts(Collection vehicleRoutes, int nOfJobs2Recreate){ + public void informInsertionStarts(Collection vehicleRoutes, Collection unassignedJobs){ for(InsertionListener l : listeners){ if(l instanceof InsertionStartsListener){ - ((InsertionStartsListener)l).informInsertionStarts(vehicleRoutes,nOfJobs2Recreate); + ((InsertionStartsListener)l).informInsertionStarts(vehicleRoutes, unassignedJobs); } } } @@ -54,4 +67,8 @@ class InsertionListeners { listeners.remove(insertionListener); } + public void addAllListeners(Collection listeners) { + for(InsertionListener l : listeners) addListener(l); + } + } diff --git a/jsprit-core/src/main/java/algorithms/InsertionStrategy.java b/jsprit-core/src/main/java/algorithms/InsertionStrategy.java index 3d2e07d2..4ebc9ffa 100644 --- a/jsprit-core/src/main/java/algorithms/InsertionStrategy.java +++ b/jsprit-core/src/main/java/algorithms/InsertionStrategy.java @@ -60,10 +60,13 @@ interface InsertionStrategy { * * @param vehicleRoutes * @param unassignedJobs - * @param result2beat */ - public void run(Collection vehicleRoutes, Collection unassignedJobs, double result2beat); + public void insertJobs(Collection vehicleRoutes, Collection unassignedJobs); public void addListener(InsertionListener insertionListener); + + public void removeListener(InsertionListener insertionListener); + + public Collection getListeners(); } diff --git a/jsprit-core/src/main/java/algorithms/JobObserver.java b/jsprit-core/src/main/java/algorithms/JobObserver.java index 43641b04..f45f1799 100644 --- a/jsprit-core/src/main/java/algorithms/JobObserver.java +++ b/jsprit-core/src/main/java/algorithms/JobObserver.java @@ -76,14 +76,14 @@ class JobObserver implements JobInsertedListener, BeforeJobInsertionListener, Al Collection infos = new ArrayList(); @Override - public void informJobInserted(int nOfJobsStill2Recreate, Job job2insert, VehicleRoute insertedIn) { + public void informJobInserted(Job job2insert, VehicleRoute inRoute) { if(job2insert instanceof Service){ if(((Service) job2insert).getLocationId().equals(locationId)){ - double actualMC = insertedIn.getCost()-routeCostBefore; - TourActivity act = getAct(job2insert,insertedIn); + double actualMC = inRoute.getCost()-routeCostBefore; + TourActivity act = getAct(job2insert,inRoute); double error = (estimatedMC-actualMC); - int tourSize = insertedIn.getTourActivities().getActivities().size(); - int insertionIndex = getIndexOf(job2insert, insertedIn); + int tourSize = inRoute.getTourActivities().getActivities().size(); + int insertionIndex = getIndexOf(job2insert, inRoute); // infos.add(new Info()) double depTime = state(act).getEarliestOperationStart()+act.getOperationTime(); infos.add(new Info(depTime,tourSize,insertionIndex,error)); diff --git a/jsprit-core/src/main/java/algorithms/RegretInsertion.java b/jsprit-core/src/main/java/algorithms/RegretInsertion.java index 46ad780b..d6eee459 100644 --- a/jsprit-core/src/main/java/algorithms/RegretInsertion.java +++ b/jsprit-core/src/main/java/algorithms/RegretInsertion.java @@ -21,6 +21,7 @@ import org.apache.log4j.Logger; import algorithms.InsertionData.NoInsertionFound; import basics.Job; import basics.Service; +import basics.algo.InsertionListener; import basics.route.VehicleRoute; @@ -35,7 +36,7 @@ import basics.route.VehicleRoute; * @author stefan schroeder * */ -final class RegretInsertion extends AbstractInsertionStrategy{ +final class RegretInsertion implements InsertionStrategy{ /** * Scorer to include other impacts on score such as time-window length or distance to depot. @@ -127,9 +128,9 @@ final class RegretInsertion extends AbstractInsertionStrategy{ * */ @Override - public void run(Collection routes, Collection unassignedJobs, double resultToBeat) { + public void insertJobs(Collection routes, Collection unassignedJobs) { List jobs = new ArrayList(unassignedJobs); - informInsertionStarts(routes,unassignedJobs.size()); +// informInsertionStarts(routes,unassignedJobs); int inserted = 0; while(!jobs.isEmpty()){ List unassignedJobList = new ArrayList(jobs); @@ -191,7 +192,7 @@ final class RegretInsertion extends AbstractInsertionStrategy{ jobs.remove(bestScoredJob.getJob()); } inserted++; - informJobInserted((unassignedJobList.size()-inserted), assignedJob, insertIn); +// informJobInserted(assignedJob, insertIn); } } @@ -206,5 +207,23 @@ final class RegretInsertion extends AbstractInsertionStrategy{ return (secondBest.getInsertionCost()-best.getInsertionCost()) + scoringFunction.score(unassignedJob); } + + @Override + public void removeListener(InsertionListener insertionListener) { + // TODO Auto-generated method stub + + } + + @Override + public Collection getListeners() { + // TODO Auto-generated method stub + return null; + } + + @Override + public void addListener(InsertionListener insertionListener) { + // TODO Auto-generated method stub + + } } diff --git a/jsprit-core/src/main/java/algorithms/RemoveEmptyVehicles.java b/jsprit-core/src/main/java/algorithms/RemoveEmptyVehicles.java index 49d12618..3a1e7f0b 100644 --- a/jsprit-core/src/main/java/algorithms/RemoveEmptyVehicles.java +++ b/jsprit-core/src/main/java/algorithms/RemoveEmptyVehicles.java @@ -26,11 +26,12 @@ import java.util.List; import org.apache.log4j.Logger; +import basics.Job; import basics.algo.InsertionEndsListener; import basics.algo.InsertionStartsListener; import basics.route.VehicleRoute; -class RemoveEmptyVehicles implements InsertionStartsListener, InsertionEndsListener{ +class RemoveEmptyVehicles implements InsertionEndsListener{ private static Logger log = Logger.getLogger(RemoveEmptyVehicles.class); @@ -41,21 +42,6 @@ class RemoveEmptyVehicles implements InsertionStartsListener, InsertionEndsListe this.fleetManager = fleetManager; } - @Override - public void informInsertionStarts(Collection vehicleRoutes, int nOfJobs2Recreate) { -// List routes = new ArrayList(vehicleRoutes); -// for(VehicleRoute route : routes){ -// if(route.isEmpty()) { vehicleRoutes.remove(route); } -// } -// List routes = new ArrayList(vehicleRoutes); -// for(VehicleRoute route : routes){ -// if(route.isEmpty()) { -// fleetManager.unlock(route.getVehicle()); -// vehicleRoutes.remove(route); -// } -// } - } - @Override public String toString() { return "[name=removeEmptyVehicles]"; diff --git a/jsprit-core/src/main/java/algorithms/ResetAndIniFleetManager.java b/jsprit-core/src/main/java/algorithms/ResetAndIniFleetManager.java index be009119..ff94bbbc 100644 --- a/jsprit-core/src/main/java/algorithms/ResetAndIniFleetManager.java +++ b/jsprit-core/src/main/java/algorithms/ResetAndIniFleetManager.java @@ -25,6 +25,7 @@ import java.util.Collection; import org.apache.log4j.Logger; +import basics.Job; import basics.algo.InsertionStartsListener; import basics.route.VehicleRoute; @@ -40,16 +41,16 @@ class ResetAndIniFleetManager implements InsertionStartsListener{ } @Override - public void informInsertionStarts(Collection vehicleRoutes, int nOfJobs2Recreate) { + public void informInsertionStarts(Collection vehicleRoutes, Collection unassignedJobs) { vehicleFleetManager.unlockAll(); Collection routes = new ArrayList(vehicleRoutes); for(VehicleRoute route : routes){ - if(route.isEmpty()){ - vehicleRoutes.remove(route); - } - else{ +// if(route.isEmpty()){ +// vehicleRoutes.remove(route); +// } +// else{ vehicleFleetManager.lock(route.getVehicle()); - } +// } } } diff --git a/jsprit-core/src/main/java/algorithms/UpdateRoute.java b/jsprit-core/src/main/java/algorithms/UpdateRoute.java new file mode 100644 index 00000000..2fda8f33 --- /dev/null +++ b/jsprit-core/src/main/java/algorithms/UpdateRoute.java @@ -0,0 +1,36 @@ +package algorithms; + +import java.util.Collection; + +import algorithms.RuinStrategy.RuinListener; +import basics.Job; +import basics.algo.JobInsertedListener; +import basics.costs.VehicleRoutingActivityCosts; +import basics.costs.VehicleRoutingTransportCosts; +import basics.route.VehicleRoute; + +public class UpdateRoute implements JobInsertedListener, RuinListener{ + + private TourStateUpdater routeStateUpdater; + + public UpdateRoute(RouteStates routeStates, VehicleRoutingTransportCosts routingCosts, VehicleRoutingActivityCosts activityCosts) { + routeStateUpdater = new TourStateUpdater(routeStates, routingCosts, activityCosts); + } + + @Override + public void informJobInserted(Job job2insert, VehicleRoute inRoute) { + routeStateUpdater.updateRoute(inRoute); + } + + @Override + public void ruinStarts(Collection routes) {} + + @Override + public void ruinEnds(Collection routes,Collection unassignedJobs) { + for(VehicleRoute route : routes) routeStateUpdater.updateRoute(route); + } + + @Override + public void removed(Job job, VehicleRoute fromRoute) {} + +} diff --git a/jsprit-core/src/main/java/algorithms/VehicleRoutingAlgorithms.java b/jsprit-core/src/main/java/algorithms/VehicleRoutingAlgorithms.java index 51e73e7b..b0d5304a 100644 --- a/jsprit-core/src/main/java/algorithms/VehicleRoutingAlgorithms.java +++ b/jsprit-core/src/main/java/algorithms/VehicleRoutingAlgorithms.java @@ -37,7 +37,7 @@ import org.apache.log4j.Logger; import util.RouteUtils; import algorithms.RuinStrategy.RuinListener; -import algorithms.VehicleRoutingAlgorithms.TypedMap.AbstractInsertionKey; +import algorithms.VehicleRoutingAlgorithms.TypedMap.InsertionStrategyKey; import algorithms.VehicleRoutingAlgorithms.TypedMap.AbstractKey; import algorithms.VehicleRoutingAlgorithms.TypedMap.AcceptorKey; import algorithms.VehicleRoutingAlgorithms.TypedMap.RuinStrategyKey; @@ -260,11 +260,11 @@ public class VehicleRoutingAlgorithms { } - static class AbstractInsertionKey implements AbstractKey{ + static class InsertionStrategyKey implements AbstractKey{ private ModKey modKey; - public AbstractInsertionKey(ModKey modKey) { + public InsertionStrategyKey(ModKey modKey) { super(); this.modKey = modKey; } @@ -286,7 +286,7 @@ public class VehicleRoutingAlgorithms { return false; if (getClass() != obj.getClass()) return false; - AbstractInsertionKey other = (AbstractInsertionKey) obj; + InsertionStrategyKey other = (InsertionStrategyKey) obj; if (modKey == null) { if (other.modKey != null) return false; @@ -298,8 +298,8 @@ public class VehicleRoutingAlgorithms { @Override - public Class getType() { - return AbstractInsertionStrategy.class; + public Class getType() { + return InsertionStrategy.class; } } @@ -535,16 +535,14 @@ public class VehicleRoutingAlgorithms { private static void registerInsertionListeners(TypedMap definedClasses, List insertionListeners) { for(AbstractKey key : definedClasses.keySet()){ - if(key instanceof AbstractInsertionKey){ - AbstractInsertionKey insertionKey = (AbstractInsertionKey) key; - AbstractInsertionStrategy insertionStrategy = definedClasses.get(insertionKey); + if(key instanceof InsertionStrategyKey){ + InsertionStrategyKey insertionKey = (InsertionStrategyKey) key; + InsertionStrategy insertionStrategy = definedClasses.get(insertionKey); for(InsertionListener l : insertionListeners){ - // log.info("add insertionListener " + l + " to " + insertionStrategy); insertionStrategy.addListener(l); } } } - // log.warn("cannot register insertion listeners yet"); } private static String getName(HierarchicalConfiguration strategyConfig) { @@ -570,15 +568,15 @@ public class VehicleRoutingAlgorithms { String insertionId = modConfig.getString("[@id]"); if(insertionId == null) insertionId = "noId"; ModKey modKey = makeKey(insertionName,insertionId); - AbstractInsertionKey insertionStrategyKey = new AbstractInsertionKey(modKey); - AbstractInsertionStrategy insertionStrategy = definedClasses.get(insertionStrategyKey); + InsertionStrategyKey insertionStrategyKey = new InsertionStrategyKey(modKey); + InsertionStrategy insertionStrategy = definedClasses.get(insertionStrategyKey); if(insertionStrategy == null){ List prioListeners = new ArrayList(); insertionStrategy = createInsertionStrategy(modConfig, vrp, vehicleFleetManager, activityStates, prioListeners, executorService, nuOfThreads); algorithmListeners.addAll(prioListeners); definedClasses.put(insertionStrategyKey,insertionStrategy); } - final AbstractInsertionStrategy finalInsertionStrategy = insertionStrategy; + final InsertionStrategy finalInsertionStrategy = insertionStrategy; return new AlgorithmStartsListener() { @@ -699,8 +697,8 @@ public class VehicleRoutingAlgorithms { String insertionId = moduleConfig.getString("insertion[@id]"); if(insertionId == null) insertionId = "noId"; ModKey insertionKey = makeKey(insertionName,insertionId); - AbstractInsertionKey insertionStrategyKey = new AbstractInsertionKey(insertionKey); - AbstractInsertionStrategy insertion = definedClasses.get(insertionStrategyKey); + InsertionStrategyKey insertionStrategyKey = new InsertionStrategyKey(insertionKey); + InsertionStrategy insertion = definedClasses.get(insertionStrategyKey); if(insertion == null){ List insertionConfigs = moduleConfig.configurationsAt("insertion"); if(insertionConfigs.size() != 1) throw new IllegalStateException("this should be 1"); @@ -708,7 +706,7 @@ public class VehicleRoutingAlgorithms { insertion = createInsertionStrategy(insertionConfigs.get(0), vrp, vehicleFleetManager, activityStates, prioListeners, executorService, nuOfThreads); algorithmListeners.addAll(prioListeners); } - final AbstractInsertionStrategy final_insertion = insertion; + final InsertionStrategy final_insertion = insertion; SearchStrategyModule module = new SearchStrategyModule() { private Logger logger = Logger.getLogger(SearchStrategyModule.class); @@ -716,7 +714,7 @@ public class VehicleRoutingAlgorithms { @Override public VehicleRoutingProblemSolution runAndGetSolution(VehicleRoutingProblemSolution vrpSolution) { Collection ruinedJobs = ruin.ruin(vrpSolution.getRoutes()); - final_insertion.run(vrpSolution.getRoutes(), ruinedJobs, Double.MAX_VALUE); + final_insertion.insertJobs(vrpSolution.getRoutes(), ruinedJobs); double totalCost = RouteUtils.getTotalCost(vrpSolution.getRoutes()); vrpSolution.setCost(totalCost); return vrpSolution; @@ -736,7 +734,7 @@ public class VehicleRoutingAlgorithms { public void addModuleListener(SearchStrategyModuleListener moduleListener) { if(moduleListener instanceof InsertionListener){ InsertionListener iListener = (InsertionListener) moduleListener; - if(!final_insertion.getListener().contains(iListener)){ + if(!final_insertion.getListeners().contains(iListener)){ logger.info("register moduleListener " + moduleListener); final_insertion.addListener(iListener); } @@ -785,8 +783,8 @@ public class VehicleRoutingAlgorithms { String insertionId = moduleConfig.getString("insertion[@id]"); if(insertionId == null) insertionId = "noId"; ModKey insertionKey = makeKey(insertionName,insertionId); - AbstractInsertionKey insertionStrategyKey = new AbstractInsertionKey(insertionKey); - AbstractInsertionStrategy insertion = definedClasses.get(insertionStrategyKey); + InsertionStrategyKey insertionStrategyKey = new InsertionStrategyKey(insertionKey); + InsertionStrategy insertion = definedClasses.get(insertionStrategyKey); if(insertion == null){ List insertionConfigs = moduleConfig.configurationsAt("insertion"); if(insertionConfigs.size() != 1) throw new IllegalStateException("this should be 1"); @@ -864,8 +862,8 @@ public class VehicleRoutingAlgorithms { return ruin; } - private static AbstractInsertionStrategy createInsertionStrategy(HierarchicalConfiguration moduleConfig, VehicleRoutingProblem vrp,VehicleFleetManager vehicleFleetManager, RouteStates activityStates, List algorithmListeners, ExecutorService executorService, int nuOfThreads) { - AbstractInsertionStrategy insertion = InsertionFactory.createInsertion(vrp, moduleConfig, vehicleFleetManager, activityStates, algorithmListeners, executorService, nuOfThreads); + private static InsertionStrategy createInsertionStrategy(HierarchicalConfiguration moduleConfig, VehicleRoutingProblem vrp,VehicleFleetManager vehicleFleetManager, RouteStates activityStates, List algorithmListeners, ExecutorService executorService, int nuOfThreads) { + InsertionStrategy insertion = InsertionFactory.createInsertion(vrp, moduleConfig, vehicleFleetManager, activityStates, algorithmListeners, executorService, nuOfThreads); return insertion; } diff --git a/jsprit-core/src/main/java/algorithms/VehicleSwitched.java b/jsprit-core/src/main/java/algorithms/VehicleSwitched.java index cd0b6bb4..1ffabe42 100644 --- a/jsprit-core/src/main/java/algorithms/VehicleSwitched.java +++ b/jsprit-core/src/main/java/algorithms/VehicleSwitched.java @@ -21,7 +21,8 @@ package algorithms; import basics.route.Vehicle; -import algorithms.RouteAlgorithm.VehicleSwitchedListener; +import basics.route.VehicleRoute; + class VehicleSwitched implements VehicleSwitchedListener{ @@ -32,7 +33,7 @@ class VehicleSwitched implements VehicleSwitchedListener{ } @Override - public void vehicleSwitched(Vehicle oldVehicle, Vehicle newVehicle) { + public void vehicleSwitched(VehicleRoute vehicleRoute, Vehicle oldVehicle, Vehicle newVehicle) { fleetManager.unlock(oldVehicle); fleetManager.lock(newVehicle); } diff --git a/jsprit-core/src/main/java/algorithms/VehicleSwitchedListener.java b/jsprit-core/src/main/java/algorithms/VehicleSwitchedListener.java new file mode 100644 index 00000000..a3589f5d --- /dev/null +++ b/jsprit-core/src/main/java/algorithms/VehicleSwitchedListener.java @@ -0,0 +1,11 @@ +package algorithms; + +import basics.algo.InsertionListener; +import basics.route.Vehicle; +import basics.route.VehicleRoute; + +interface VehicleSwitchedListener extends InsertionListener{ + + public void vehicleSwitched(VehicleRoute vehicleRoute, Vehicle oldVehicle, Vehicle newVehicle); + +} diff --git a/jsprit-core/src/test/java/algorithms/GendreauPostOptTest.java b/jsprit-core/src/test/java/algorithms/GendreauPostOptTest.java index 2ab58a40..dc0ee95a 100644 --- a/jsprit-core/src/test/java/algorithms/GendreauPostOptTest.java +++ b/jsprit-core/src/test/java/algorithms/GendreauPostOptTest.java @@ -37,6 +37,7 @@ import basics.Job; import basics.Service; import basics.VehicleRoutingProblem; import basics.VehicleRoutingProblemSolution; +import basics.costs.VehicleRoutingActivityCosts; import basics.costs.VehicleRoutingTransportCosts; import basics.route.Driver; import basics.route.DriverImpl; @@ -60,6 +61,8 @@ public class GendreauPostOptTest { VehicleRoutingTransportCosts cost; + VehicleRoutingActivityCosts activityCosts; + VehicleRoutingProblem vrp; Service job1; @@ -77,6 +80,8 @@ public class GendreauPostOptTest { private VehicleFleetManagerImpl fleetManager; private RouteAlgorithmImpl routeAlgorithm; + + private JobInsertionCalculator insertionCalc; @Before public void setUp(){ @@ -148,29 +153,31 @@ public class GendreauPostOptTest { fleetManager = new VehicleFleetManagerImpl(vehicles); states = new RouteStates(); - ExampleActivityCostFunction activityCosts = new ExampleActivityCostFunction(); + activityCosts = new ExampleActivityCostFunction(); CalculatesServiceInsertion standardServiceInsertion = new CalculatesServiceInsertion(cost, activityCosts); standardServiceInsertion.setActivityStates(states); CalculatesServiceInsertionConsideringFixCost withFixCost = new CalculatesServiceInsertionConsideringFixCost(standardServiceInsertion, states); withFixCost.setWeightOfFixCost(1.2); - final JobInsertionCalculator vehicleTypeDepInsertionCost = new CalculatesVehTypeDepServiceInsertion(fleetManager, withFixCost); + insertionCalc = new CalculatesVehTypeDepServiceInsertion(fleetManager, withFixCost); + updater = new TourStateUpdater(states, cost, activityCosts); - - routeAlgorithm = RouteAlgorithmImpl.newInstance(vehicleTypeDepInsertionCost, updater); - routeAlgorithm.setActivityStates(states); - if(fleetManager != null){ - routeAlgorithm.getListeners().add(new RouteAlgorithm.VehicleSwitchedListener() { - - @Override - public void vehicleSwitched(Vehicle oldVehicle, Vehicle newVehicle) { - fleetManager.unlock(oldVehicle); - fleetManager.lock(newVehicle); - } - }); - } +// +// +// routeAlgorithm = RouteAlgorithmImpl.newInstance(insertionCalc, updater); +// routeAlgorithm.setActivityStates(states); +// if(fleetManager != null){ +// routeAlgorithm.getListeners().add(new RouteAlgorithm.VehicleSwitchedListener() { +// +// @Override +// public void vehicleSwitched(Vehicle oldVehicle, Vehicle newVehicle) { +// fleetManager.unlock(oldVehicle); +// fleetManager.lock(newVehicle); +// } +// }); +// } } @@ -202,10 +209,17 @@ public class GendreauPostOptTest { assertEquals(110.0, sol.getCost(), 0.5); + UpdateRoute stateUpdater = new UpdateRoute(states, vrp.getTransportCosts(), vrp.getActivityCosts()); + RuinRadial radialRuin = new RuinRadial(vrp, 0.2, new JobDistanceAvgCosts(vrp.getTransportCosts())); - AbstractInsertionStrategy insertionStrategy = new BestInsertion(routeAlgorithm); + radialRuin.addListener(stateUpdater); + + InsertionStrategy insertionStrategy = new BestInsertion(insertionCalc); + insertionStrategy.addListener(stateUpdater); + insertionStrategy.addListener(new VehicleSwitched(fleetManager)); Gendreau postOpt = new Gendreau(vrp, radialRuin, insertionStrategy); postOpt.setFleetManager(fleetManager); + VehicleRoutingProblemSolution newSolution = postOpt.runAndGetSolution(sol); assertEquals(2,RouteUtils.getNuOfActiveRoutes(newSolution.getRoutes())); @@ -236,15 +250,17 @@ public class GendreauPostOptTest { Collection routes = new ArrayList(); routes.add(route); -// routes.add(new VehicleRoute(getEmptyTour(),getDriver(),getNoVehicle())); -// routes.add(new VehicleRoute(getEmptyTour(),getDriver(),getNoVehicle())); VehicleRoutingProblemSolution sol = new VehicleRoutingProblemSolution(routes, route.getCost()); assertEquals(110.0, sol.getCost(), 0.5); + UpdateRoute stateUpdater = new UpdateRoute(states, vrp.getTransportCosts(), vrp.getActivityCosts()); + RuinRadial radialRuin = new RuinRadial(vrp, 0.2, new JobDistanceAvgCosts(vrp.getTransportCosts())); - AbstractInsertionStrategy insertionStrategy = new BestInsertion(routeAlgorithm); + InsertionStrategy insertionStrategy = new BestInsertion(insertionCalc); + insertionStrategy.addListener(stateUpdater); + insertionStrategy.addListener(new VehicleSwitched(fleetManager)); Gendreau postOpt = new Gendreau(vrp, radialRuin, insertionStrategy); postOpt.setShareOfJobsToRuin(1.0); postOpt.setNuOfIterations(1);