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

internal optimization of insertion-issues

This commit is contained in:
Stefan Schroeder 2013-08-16 16:31:32 +02:00
parent e35603ed34
commit 3f7d6b8b01
20 changed files with 315 additions and 282 deletions

View file

@ -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<InsertionListener> listener = new ArrayList<InsertionListener>();
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<VehicleRoute> vehicleRoutes, int nOfJobs2Recreate){
for(InsertionListener l : listener){
if(l instanceof InsertionStartsListener){
((InsertionStartsListener)l).informInsertionStarts(vehicleRoutes,nOfJobs2Recreate);
}
}
}
public void informInsertionEndsListeners(Collection<VehicleRoute> vehicleRoutes) {
for(InsertionListener l : listener){
if(l instanceof InsertionEndsListener){
((InsertionEndsListener)l).informInsertionEnds(vehicleRoutes);
}
}
}
public Collection<InsertionListener> getListener() {
return Collections.unmodifiableCollection(listener);
}
public void addListener(InsertionListener l){
log.info("add insertion-listener " + l);
listener.add(l);
}
public void addAllListener(List<InsertionListener> list) {
for(InsertionListener l : list) addListener(l);
}
}

View file

@ -15,9 +15,7 @@ package algorithms;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Random; import java.util.Random;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
@ -25,6 +23,9 @@ import org.apache.log4j.Logger;
import util.RandomNumberGeneration; import util.RandomNumberGeneration;
import algorithms.InsertionData.NoInsertionFound; import algorithms.InsertionData.NoInsertionFound;
import basics.Job; import basics.Job;
import basics.algo.InsertionListener;
import basics.route.Driver;
import basics.route.Vehicle;
import basics.route.VehicleRoute; import basics.route.VehicleRoute;
@ -35,66 +36,53 @@ import basics.route.VehicleRoute;
* *
*/ */
final class BestInsertion extends AbstractInsertionStrategy{ final class BestInsertion implements InsertionStrategy{
public static BestInsertion newInstance(RouteAlgorithm routeAlgorithm){
return new BestInsertion(routeAlgorithm);
}
private static Logger logger = Logger.getLogger(BestInsertion.class); private static Logger logger = Logger.getLogger(BestInsertion.class);
private Random random = RandomNumberGeneration.getRandom(); 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 InsertionListeners insertionsListeners;
private RouteAlgorithm routeAlgorithm; private Inserter inserter;
public void setExperimentalPreferredRoute(Map<String, VehicleRoute> experimentalPreferredRoute) { private JobInsertionCalculator bestInsertionCostCalculator;
}
private boolean allowUnassignedJobs = false;
private boolean fixRouteSet = false;
private boolean minVehiclesFirst = false; private boolean minVehiclesFirst = false;
public void setFixRouteSet(boolean fixRouteSet) {
this.fixRouteSet = fixRouteSet;
}
public void setRandom(Random random) { public void setRandom(Random random) {
this.random = random; this.random = random;
} }
public BestInsertion(RouteAlgorithm routeAlgorithm) { public BestInsertion(JobInsertionCalculator jobInsertionCalculator) {
super(); super();
this.routeAlgorithm = routeAlgorithm;
this.insertionsListeners = new InsertionListeners(); this.insertionsListeners = new InsertionListeners();
inserter = new Inserter(insertionsListeners);
bestInsertionCostCalculator = jobInsertionCalculator;
logger.info("initialise " + this); logger.info("initialise " + this);
} }
public RouteAlgorithm getRouteAlgorithm(){
return routeAlgorithm;
}
@Override @Override
public String toString() { public String toString() {
return "[name=bestInsertion]"; return "[name=bestInsertion]";
} }
@Override @Override
public void run(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs, double result2beat) { public void insertJobs(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs) {
insertionsListeners.informInsertionStarts(vehicleRoutes,unassignedJobs);
List<Job> unassignedJobList = new ArrayList<Job>(unassignedJobs); List<Job> unassignedJobList = new ArrayList<Job>(unassignedJobs);
Collections.shuffle(unassignedJobList, random); Collections.shuffle(unassignedJobList, random);
informInsertionStarts(vehicleRoutes,unassignedJobs.size());
int inserted = 0;
List<String> reasons = new ArrayList<String>();
for(Job unassignedJob : unassignedJobList){ for(Job unassignedJob : unassignedJobList){
VehicleRoute insertIn = null;
Insertion bestInsertion = null; Insertion bestInsertion = null;
double bestInsertionCost = Double.MAX_VALUE; double bestInsertionCost = Double.MAX_VALUE;
for(VehicleRoute vehicleRoute : vehicleRoutes){ 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) { if(iData instanceof NoInsertionFound) {
continue; continue;
} }
@ -105,56 +93,54 @@ final class BestInsertion extends AbstractInsertionStrategy{
} }
if(!minVehiclesFirst){ if(!minVehiclesFirst){
VehicleRoute newRoute = VehicleRoute.emptyRoute(); 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){ if(newIData.getInsertionCost() < bestInsertionCost){
bestInsertion = new Insertion(newRoute,newIData); bestInsertion = new Insertion(newRoute,newIData);
bestInsertionCost = newIData.getInsertionCost(); bestInsertionCost = newIData.getInsertionCost();
vehicleRoutes.add(newRoute); vehicleRoutes.add(newRoute);
} }
} }
if(bestInsertion != null){ 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");
}
else{
VehicleRoute newRoute = VehicleRoute.emptyRoute(); VehicleRoute newRoute = VehicleRoute.emptyRoute();
InsertionData bestI = routeAlgorithm.calculateBestInsertion(newRoute, unassignedJob, Double.MAX_VALUE); 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){ if(bestI instanceof InsertionData.NoInsertionFound){
if(allowUnassignedJobs){ throw new IllegalStateException(getErrorMsg(unassignedJob));
logger.warn("cannot insert job yet " + unassignedJob);
} }
else{ else{
for(String s : reasons){ bestInsertion = new Insertion(newRoute,bestI);
System.out.println("reason="+s); vehicleRoutes.add(newRoute);
} }
throw new IllegalStateException("given the vehicles, could not insert job\n" + }
inserter.insertJob(unassignedJob, bestInsertion.getInsertionData(), bestInsertion.getRoute());
}
insertionsListeners.informInsertionEndsListeners(vehicleRoutes);
}
private String getErrorMsg(Job unassignedJob) {
return "given the vehicles, could not insert job\n" +
"\t" + unassignedJob + "\t" + unassignedJob +
"\n\tthis might have the following reasons:\n" + "\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- 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- 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]" "\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);
} }
else{
insertIn = newRoute; @Override
informBeforeJobInsertion(unassignedJob,bestI,newRoute); public Collection<InsertionListener> getListeners() {
routeAlgorithm.insertJob(unassignedJob,bestI,newRoute); return Collections.unmodifiableCollection(insertionsListeners.getListeners());
vehicleRoutes.add(newRoute);
} }
}
} @Override
inserted++; public void addListener(InsertionListener insertionListener) {
informJobInserted((unassignedJobList.size()-inserted), unassignedJob, insertIn); insertionsListeners.addListener(insertionListener);
}
informInsertionEndsListeners(vehicleRoutes);
} }
} }

View file

@ -30,6 +30,7 @@ import org.apache.log4j.Logger;
import util.RandomNumberGeneration; import util.RandomNumberGeneration;
import algorithms.InsertionData.NoInsertionFound; import algorithms.InsertionData.NoInsertionFound;
import basics.Job; import basics.Job;
import basics.algo.InsertionListener;
import basics.route.VehicleRoute; 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){ public static BestInsertionConcurrent newInstance(RouteAlgorithm routeAlgorithm, ExecutorService executor, int nuOfThreads){
return new BestInsertionConcurrent(routeAlgorithm, executor, nuOfThreads); return new BestInsertionConcurrent(routeAlgorithm, executor, nuOfThreads);
@ -82,10 +83,10 @@ final class BestInsertionConcurrent extends AbstractInsertionStrategy{
} }
@Override @Override
public void run(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs, double result2beat) { public void insertJobs(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs) {
List<Job> unassignedJobList = new ArrayList<Job>(unassignedJobs); List<Job> unassignedJobList = new ArrayList<Job>(unassignedJobs);
Collections.shuffle(unassignedJobList, random); Collections.shuffle(unassignedJobList, random);
informInsertionStarts(vehicleRoutes,unassignedJobs.size()); // informInsertionStarts(vehicleRoutes,unassignedJobs.size());
int inserted = 0; int inserted = 0;
for(final Job unassignedJob : unassignedJobList){ for(final Job unassignedJob : unassignedJobList){
VehicleRoute insertIn = null; VehicleRoute insertIn = null;
@ -127,7 +128,7 @@ final class BestInsertionConcurrent extends AbstractInsertionStrategy{
} }
if(bestInsertion != null){ if(bestInsertion != null){
informBeforeJobInsertion(unassignedJob, bestInsertion.getInsertionData(), bestInsertion.getRoute()); // informBeforeJobInsertion(unassignedJob, bestInsertion.getInsertionData(), bestInsertion.getRoute());
insertIn = bestInsertion.getRoute(); insertIn = bestInsertion.getRoute();
// logger.debug("insert job="+unassignedJob+" at index=" + bestInsertion.getInsertionData().getInsertionIndex() + " delta cost=" + bestInsertion.getInsertionData().getInsertionCost()); // logger.debug("insert job="+unassignedJob+" at index=" + bestInsertion.getInsertionData().getInsertionIndex() + " delta cost=" + bestInsertion.getInsertionData().getInsertionCost());
routeAlgorithm.insertJob(unassignedJob, bestInsertion.getInsertionData(), bestInsertion.getRoute()); routeAlgorithm.insertJob(unassignedJob, bestInsertion.getInsertionData(), bestInsertion.getRoute());
@ -144,9 +145,9 @@ final class BestInsertionConcurrent extends AbstractInsertionStrategy{
// vehicleRoutes.add(newRoute); // vehicleRoutes.add(newRoute);
} }
inserted++; inserted++;
informJobInserted((unassignedJobList.size()-inserted), unassignedJob, insertIn); // informJobInserted((unassignedJobList.size()-inserted), unassignedJob, insertIn);
} }
informInsertionEndsListeners(vehicleRoutes); // informInsertionEndsListeners(vehicleRoutes);
} }
private Insertion getBestInsertion(Batch batch, Job unassignedJob) { private Insertion getBestInsertion(Batch batch, Job unassignedJob) {
@ -191,9 +192,23 @@ final class BestInsertionConcurrent extends AbstractInsertionStrategy{
return batches; return batches;
} }
@Override @Override
public RouteAlgorithm getRouteAlgorithm() { public void removeListener(InsertionListener insertionListener) {
return routeAlgorithm; // TODO Auto-generated method stub
}
@Override
public Collection<InsertionListener> getListeners() {
// TODO Auto-generated method stub
return null;
}
@Override
public void addListener(InsertionListener insertionListener) {
// TODO Auto-generated method stub
} }
} }

View file

@ -43,6 +43,8 @@ final class ConfigureFixCostCalculator implements InsertionStartsListener, JobIn
CalculatesServiceInsertionConsideringFixCost calcConsideringFix; CalculatesServiceInsertionConsideringFixCost calcConsideringFix;
private int nuOfJobsToRecreate;
public ConfigureFixCostCalculator(VehicleRoutingProblem vrp, CalculatesServiceInsertionConsideringFixCost calcConsideringFix) { public ConfigureFixCostCalculator(VehicleRoutingProblem vrp, CalculatesServiceInsertionConsideringFixCost calcConsideringFix) {
super(); super();
this.vrp = vrp; this.vrp = vrp;
@ -55,15 +57,17 @@ final class ConfigureFixCostCalculator implements InsertionStartsListener, JobIn
} }
@Override @Override
public void informInsertionStarts(Collection<VehicleRoute> routes, int nOfJobs2Recreate) { public void informInsertionStarts(Collection<VehicleRoute> routes, Collection<Job> unassignedJobs) {
double completenessRatio = (1-((double)nOfJobs2Recreate/(double)vrp.getJobs().values().size())); this.nuOfJobsToRecreate = unassignedJobs.size();
double completenessRatio = (1-((double)nuOfJobsToRecreate/(double)vrp.getJobs().values().size()));
calcConsideringFix.setSolutionCompletenessRatio(completenessRatio); calcConsideringFix.setSolutionCompletenessRatio(completenessRatio);
// log.debug("initialise completenessRatio to " + completenessRatio); // log.debug("initialise completenessRatio to " + completenessRatio);
} }
@Override @Override
public void informJobInserted(int nOfJobsStill2Recreate, Job job2insert, VehicleRoute insertedIn) { public void informJobInserted(Job job2insert, VehicleRoute inRoute) {
double completenessRatio = (1-((double)nOfJobsStill2Recreate/(double)vrp.getJobs().values().size())); nuOfJobsToRecreate--;
double completenessRatio = (1-((double)nuOfJobsToRecreate/(double)vrp.getJobs().values().size()));
calcConsideringFix.setSolutionCompletenessRatio(completenessRatio); calcConsideringFix.setSolutionCompletenessRatio(completenessRatio);
// log.debug("set completenessRatio to " + completenessRatio); // log.debug("set completenessRatio to " + completenessRatio);
} }

View file

@ -73,7 +73,7 @@ final class CreateInitialSolution implements InitialSolutionFactory {
vehicleRoutes.add(VehicleRoute.newInstance(TourActivities.emptyTour(), DriverImpl.noDriver(), vehicle)); 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); double totalCost = getTotalCost(vehicleRoutes);
logger.info("creation done"); logger.info("creation done");
return new VehicleRoutingProblemSolution(vehicleRoutes, totalCost); return new VehicleRoutingProblemSolution(vehicleRoutes, totalCost);

View file

@ -24,6 +24,7 @@ import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import basics.Job;
import basics.algo.InsertionStartsListener; import basics.algo.InsertionStartsListener;
import basics.route.VehicleRoute; import basics.route.VehicleRoute;
@ -37,7 +38,7 @@ class FindCheaperVehicle implements InsertionStartsListener{
} }
@Override @Override
public void informInsertionStarts(Collection<VehicleRoute> vehicleRoutes, int nOfJobs2Recreate) { public void informInsertionStarts(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs) {
List<VehicleRoute> newRoutes = new ArrayList<VehicleRoute>(); List<VehicleRoute> newRoutes = new ArrayList<VehicleRoute>();
for(VehicleRoute route : vehicleRoutes){ for(VehicleRoute route : vehicleRoutes){
if(route.isEmpty()) continue; if(route.isEmpty()) continue;

View file

@ -21,6 +21,7 @@
package algorithms; package algorithms;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
@ -30,16 +31,15 @@ import java.util.Set;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import util.RandomNumberGeneration;
import basics.Job; import basics.Job;
import basics.VehicleRoutingProblem; import basics.VehicleRoutingProblem;
import basics.VehicleRoutingProblemSolution; import basics.VehicleRoutingProblemSolution;
import basics.algo.SearchStrategyModule; import basics.algo.SearchStrategyModule;
import basics.algo.SearchStrategyModuleListener; import basics.algo.SearchStrategyModuleListener;
import basics.route.TourActivity; import basics.route.TourActivity;
import basics.route.VehicleRoute;
import basics.route.TourActivity.JobActivity; import basics.route.TourActivity.JobActivity;
import basics.route.VehicleRoute;
import util.RandomNumberGeneration;
final class Gendreau implements SearchStrategyModule{ final class Gendreau implements SearchStrategyModule{
@ -53,7 +53,7 @@ final class Gendreau implements SearchStrategyModule{
private final InsertionStrategy insertionStrategy; private final InsertionStrategy insertionStrategy;
private final RouteAlgorithm routeAlgorithm; private final Inserter inserter;
private VehicleFleetManager fleetManager; private VehicleFleetManager fleetManager;
@ -69,7 +69,9 @@ final class Gendreau implements SearchStrategyModule{
public Gendreau(VehicleRoutingProblem vrp, RuinStrategy ruin, InsertionStrategy insertionStrategy) { public Gendreau(VehicleRoutingProblem vrp, RuinStrategy ruin, InsertionStrategy insertionStrategy) {
super(); super();
this.routeAlgorithm = insertionStrategy.getRouteAlgorithm(); InsertionListeners insertionListeners = new InsertionListeners();
insertionListeners.addAllListeners(insertionStrategy.getListeners());
inserter = new Inserter(insertionListeners);
this.ruin = ruin; this.ruin = ruin;
this.vrp = vrp; this.vrp = vrp;
this.insertionStrategy = insertionStrategy; this.insertionStrategy = insertionStrategy;
@ -119,16 +121,18 @@ final class Gendreau implements SearchStrategyModule{
VehicleRoute emptyRoute1 = VehicleRoute.emptyRoute(); VehicleRoute emptyRoute1 = VehicleRoute.emptyRoute();
copiedRoutes.add(emptyRoute1); 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); unassignedJobs.remove(targetJob);
VehicleRoute emptyRoute2 = VehicleRoute.emptyRoute(); VehicleRoute emptyRoute2 = VehicleRoute.emptyRoute();
copiedRoutes.add(emptyRoute2); copiedRoutes.add(emptyRoute2);
Job job2 = jobsInRoute.get(1); 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); unassignedJobs.remove(job2);
insertionStrategy.run(copiedRoutes, unassignedJobs, Double.MAX_VALUE); insertionStrategy.insertJobs(copiedRoutes, unassignedJobs);
double cost = getCost(copiedRoutes); double cost = getCost(copiedRoutes);
if(cost < bestSolution.getCost()){ if(cost < bestSolution.getCost()){

View file

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

View file

@ -37,7 +37,7 @@ class InsertionFactory {
private static Logger log = Logger.getLogger(InsertionFactory.class); 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<PrioritizedVRAListener> algorithmListeners, ExecutorService executorService, int nuOfThreads){ VehicleFleetManager vehicleFleetManager, RouteStates activityStates, List<PrioritizedVRAListener> algorithmListeners, ExecutorService executorService, int nuOfThreads){
boolean concurrentInsertion = false; boolean concurrentInsertion = false;
if(executorService != null) concurrentInsertion = true; if(executorService != null) concurrentInsertion = true;
@ -46,7 +46,7 @@ class InsertionFactory {
if(!insertionName.equals("bestInsertion") && !insertionName.equals("regretInsertion")){ if(!insertionName.equals("bestInsertion") && !insertionName.equals("regretInsertion")){
new IllegalStateException(insertionName + " is not supported. use either \"bestInsertion\" or \"regretInsertion\""); new IllegalStateException(insertionName + " is not supported. use either \"bestInsertion\" or \"regretInsertion\"");
} }
AbstractInsertionStrategy insertionStrategy = null; InsertionStrategy insertionStrategy = null;
List<InsertionListener> insertionListeners = new ArrayList<InsertionListener>(); List<InsertionListener> insertionListeners = new ArrayList<InsertionListener>();
List<PrioritizedVRAListener> algoListeners = new ArrayList<PrioritizedVRAListener>(); List<PrioritizedVRAListener> algoListeners = new ArrayList<PrioritizedVRAListener>();
@ -96,7 +96,7 @@ class InsertionFactory {
JobInsertionCalculator jic = calcBuilder.build(); JobInsertionCalculator jic = calcBuilder.build();
TourStateUpdater tourStateCalculator = new TourStateUpdater(activityStates, vrp.getTransportCosts(), vrp.getActivityCosts()); TourStateUpdater tourStateCalculator = new TourStateUpdater(activityStates, vrp.getTransportCosts(), vrp.getActivityCosts());
RouteAlgorithm routeAlgorithm = RouteAlgorithmImpl.newInstance(jic, tourStateCalculator); RouteAlgorithm routeAlgorithm = RouteAlgorithmImpl.newInstance(jic, tourStateCalculator);
routeAlgorithm.getListeners().add(new VehicleSwitched(vehicleFleetManager)); // routeAlgorithm.getListeners().add(new VehicleSwitched(vehicleFleetManager));
((RouteAlgorithmImpl) routeAlgorithm).setActivityStates(activityStates); ((RouteAlgorithmImpl) routeAlgorithm).setActivityStates(activityStates);
if(insertionName.equals("bestInsertion")){ if(insertionName.equals("bestInsertion")){
@ -104,24 +104,18 @@ class InsertionFactory {
insertionStrategy = BestInsertionConcurrent.newInstance(routeAlgorithm,executorService,nuOfThreads); insertionStrategy = BestInsertionConcurrent.newInstance(routeAlgorithm,executorService,nuOfThreads);
} }
else{ else{
insertionStrategy = BestInsertion.newInstance(routeAlgorithm); insertionStrategy = new BestInsertion(jic);
} }
} }
else if(insertionName.equals("regretInsertion")){ else if(insertionName.equals("regretInsertion")){
insertionStrategy = RegretInsertion.newInstance(routeAlgorithm); 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.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( // insertionStrategy.addListener(new FindCheaperVehicle(
// new FindCheaperVehicleAlgoNew(vehicleFleetManager, tourStateCalculator, auxCalculator))); // new FindCheaperVehicleAlgoNew(vehicleFleetManager, tourStateCalculator, auxCalculator)));

View file

@ -8,16 +8,29 @@ import basics.algo.InsertionEndsListener;
import basics.algo.InsertionListener; import basics.algo.InsertionListener;
import basics.algo.InsertionStartsListener; import basics.algo.InsertionStartsListener;
import basics.algo.JobInsertedListener; import basics.algo.JobInsertedListener;
import basics.route.Vehicle;
import basics.route.VehicleRoute; import basics.route.VehicleRoute;
class InsertionListeners { class InsertionListeners {
private Collection<InsertionListener> listeners = new ArrayList<InsertionListener>(); private Collection<InsertionListener> listeners = new ArrayList<InsertionListener>();
public void informJobInserted(int nOfJobs2Recreate, Job insertedJob, VehicleRoute insertedIn){ public Collection<InsertionListener> getListeners(){
return listeners;
}
public void informJobInserted(Job insertedJob, VehicleRoute inRoute){
for(InsertionListener l : listeners){ for(InsertionListener l : listeners){
if(l instanceof JobInsertedListener){ 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<VehicleRoute> vehicleRoutes, int nOfJobs2Recreate){ public void informInsertionStarts(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs){
for(InsertionListener l : listeners){ for(InsertionListener l : listeners){
if(l instanceof InsertionStartsListener){ if(l instanceof InsertionStartsListener){
((InsertionStartsListener)l).informInsertionStarts(vehicleRoutes,nOfJobs2Recreate); ((InsertionStartsListener)l).informInsertionStarts(vehicleRoutes, unassignedJobs);
} }
} }
} }
@ -54,4 +67,8 @@ class InsertionListeners {
listeners.remove(insertionListener); listeners.remove(insertionListener);
} }
public void addAllListeners(Collection<InsertionListener> listeners) {
for(InsertionListener l : listeners) addListener(l);
}
} }

View file

@ -60,10 +60,13 @@ interface InsertionStrategy {
* *
* @param vehicleRoutes * @param vehicleRoutes
* @param unassignedJobs * @param unassignedJobs
* @param result2beat
*/ */
public void run(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs, double result2beat); public void insertJobs(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs);
public void addListener(InsertionListener insertionListener); public void addListener(InsertionListener insertionListener);
public void removeListener(InsertionListener insertionListener);
public Collection<InsertionListener> getListeners();
} }

View file

@ -76,14 +76,14 @@ class JobObserver implements JobInsertedListener, BeforeJobInsertionListener, Al
Collection<Info> infos = new ArrayList<Info>(); Collection<Info> infos = new ArrayList<Info>();
@Override @Override
public void informJobInserted(int nOfJobsStill2Recreate, Job job2insert, VehicleRoute insertedIn) { public void informJobInserted(Job job2insert, VehicleRoute inRoute) {
if(job2insert instanceof Service){ if(job2insert instanceof Service){
if(((Service) job2insert).getLocationId().equals(locationId)){ if(((Service) job2insert).getLocationId().equals(locationId)){
double actualMC = insertedIn.getCost()-routeCostBefore; double actualMC = inRoute.getCost()-routeCostBefore;
TourActivity act = getAct(job2insert,insertedIn); TourActivity act = getAct(job2insert,inRoute);
double error = (estimatedMC-actualMC); double error = (estimatedMC-actualMC);
int tourSize = insertedIn.getTourActivities().getActivities().size(); int tourSize = inRoute.getTourActivities().getActivities().size();
int insertionIndex = getIndexOf(job2insert, insertedIn); int insertionIndex = getIndexOf(job2insert, inRoute);
// infos.add(new Info()) // infos.add(new Info())
double depTime = state(act).getEarliestOperationStart()+act.getOperationTime(); double depTime = state(act).getEarliestOperationStart()+act.getOperationTime();
infos.add(new Info(depTime,tourSize,insertionIndex,error)); infos.add(new Info(depTime,tourSize,insertionIndex,error));

View file

@ -21,6 +21,7 @@ import org.apache.log4j.Logger;
import algorithms.InsertionData.NoInsertionFound; import algorithms.InsertionData.NoInsertionFound;
import basics.Job; import basics.Job;
import basics.Service; import basics.Service;
import basics.algo.InsertionListener;
import basics.route.VehicleRoute; import basics.route.VehicleRoute;
@ -35,7 +36,7 @@ import basics.route.VehicleRoute;
* @author stefan schroeder * @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. * 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 @Override
public void run(Collection<VehicleRoute> routes, Collection<Job> unassignedJobs, double resultToBeat) { public void insertJobs(Collection<VehicleRoute> routes, Collection<Job> unassignedJobs) {
List<Job> jobs = new ArrayList<Job>(unassignedJobs); List<Job> jobs = new ArrayList<Job>(unassignedJobs);
informInsertionStarts(routes,unassignedJobs.size()); // informInsertionStarts(routes,unassignedJobs);
int inserted = 0; int inserted = 0;
while(!jobs.isEmpty()){ while(!jobs.isEmpty()){
List<Job> unassignedJobList = new ArrayList<Job>(jobs); List<Job> unassignedJobList = new ArrayList<Job>(jobs);
@ -191,7 +192,7 @@ final class RegretInsertion extends AbstractInsertionStrategy{
jobs.remove(bestScoredJob.getJob()); jobs.remove(bestScoredJob.getJob());
} }
inserted++; inserted++;
informJobInserted((unassignedJobList.size()-inserted), assignedJob, insertIn); // informJobInserted(assignedJob, insertIn);
} }
} }
@ -207,4 +208,22 @@ final class RegretInsertion extends AbstractInsertionStrategy{
} }
@Override
public void removeListener(InsertionListener insertionListener) {
// TODO Auto-generated method stub
}
@Override
public Collection<InsertionListener> getListeners() {
// TODO Auto-generated method stub
return null;
}
@Override
public void addListener(InsertionListener insertionListener) {
// TODO Auto-generated method stub
}
} }

View file

@ -26,11 +26,12 @@ import java.util.List;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import basics.Job;
import basics.algo.InsertionEndsListener; import basics.algo.InsertionEndsListener;
import basics.algo.InsertionStartsListener; import basics.algo.InsertionStartsListener;
import basics.route.VehicleRoute; import basics.route.VehicleRoute;
class RemoveEmptyVehicles implements InsertionStartsListener, InsertionEndsListener{ class RemoveEmptyVehicles implements InsertionEndsListener{
private static Logger log = Logger.getLogger(RemoveEmptyVehicles.class); private static Logger log = Logger.getLogger(RemoveEmptyVehicles.class);
@ -41,21 +42,6 @@ class RemoveEmptyVehicles implements InsertionStartsListener, InsertionEndsListe
this.fleetManager = fleetManager; this.fleetManager = fleetManager;
} }
@Override
public void informInsertionStarts(Collection<VehicleRoute> vehicleRoutes, int nOfJobs2Recreate) {
// List<VehicleRoute> routes = new ArrayList<VehicleRoute>(vehicleRoutes);
// for(VehicleRoute route : routes){
// if(route.isEmpty()) { vehicleRoutes.remove(route); }
// }
// List<VehicleRoute> routes = new ArrayList<VehicleRoute>(vehicleRoutes);
// for(VehicleRoute route : routes){
// if(route.isEmpty()) {
// fleetManager.unlock(route.getVehicle());
// vehicleRoutes.remove(route);
// }
// }
}
@Override @Override
public String toString() { public String toString() {
return "[name=removeEmptyVehicles]"; return "[name=removeEmptyVehicles]";

View file

@ -25,6 +25,7 @@ import java.util.Collection;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import basics.Job;
import basics.algo.InsertionStartsListener; import basics.algo.InsertionStartsListener;
import basics.route.VehicleRoute; import basics.route.VehicleRoute;
@ -40,16 +41,16 @@ class ResetAndIniFleetManager implements InsertionStartsListener{
} }
@Override @Override
public void informInsertionStarts(Collection<VehicleRoute> vehicleRoutes, int nOfJobs2Recreate) { public void informInsertionStarts(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs) {
vehicleFleetManager.unlockAll(); vehicleFleetManager.unlockAll();
Collection<VehicleRoute> routes = new ArrayList<VehicleRoute>(vehicleRoutes); Collection<VehicleRoute> routes = new ArrayList<VehicleRoute>(vehicleRoutes);
for(VehicleRoute route : routes){ for(VehicleRoute route : routes){
if(route.isEmpty()){ // if(route.isEmpty()){
vehicleRoutes.remove(route); // vehicleRoutes.remove(route);
} // }
else{ // else{
vehicleFleetManager.lock(route.getVehicle()); vehicleFleetManager.lock(route.getVehicle());
} // }
} }
} }

View file

@ -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<VehicleRoute> routes) {}
@Override
public void ruinEnds(Collection<VehicleRoute> routes,Collection<Job> unassignedJobs) {
for(VehicleRoute route : routes) routeStateUpdater.updateRoute(route);
}
@Override
public void removed(Job job, VehicleRoute fromRoute) {}
}

View file

@ -37,7 +37,7 @@ import org.apache.log4j.Logger;
import util.RouteUtils; import util.RouteUtils;
import algorithms.RuinStrategy.RuinListener; import algorithms.RuinStrategy.RuinListener;
import algorithms.VehicleRoutingAlgorithms.TypedMap.AbstractInsertionKey; import algorithms.VehicleRoutingAlgorithms.TypedMap.InsertionStrategyKey;
import algorithms.VehicleRoutingAlgorithms.TypedMap.AbstractKey; import algorithms.VehicleRoutingAlgorithms.TypedMap.AbstractKey;
import algorithms.VehicleRoutingAlgorithms.TypedMap.AcceptorKey; import algorithms.VehicleRoutingAlgorithms.TypedMap.AcceptorKey;
import algorithms.VehicleRoutingAlgorithms.TypedMap.RuinStrategyKey; import algorithms.VehicleRoutingAlgorithms.TypedMap.RuinStrategyKey;
@ -260,11 +260,11 @@ public class VehicleRoutingAlgorithms {
} }
static class AbstractInsertionKey implements AbstractKey<AbstractInsertionStrategy>{ static class InsertionStrategyKey implements AbstractKey<InsertionStrategy>{
private ModKey modKey; private ModKey modKey;
public AbstractInsertionKey(ModKey modKey) { public InsertionStrategyKey(ModKey modKey) {
super(); super();
this.modKey = modKey; this.modKey = modKey;
} }
@ -286,7 +286,7 @@ public class VehicleRoutingAlgorithms {
return false; return false;
if (getClass() != obj.getClass()) if (getClass() != obj.getClass())
return false; return false;
AbstractInsertionKey other = (AbstractInsertionKey) obj; InsertionStrategyKey other = (InsertionStrategyKey) obj;
if (modKey == null) { if (modKey == null) {
if (other.modKey != null) if (other.modKey != null)
return false; return false;
@ -298,8 +298,8 @@ public class VehicleRoutingAlgorithms {
@Override @Override
public Class<AbstractInsertionStrategy> getType() { public Class<InsertionStrategy> getType() {
return AbstractInsertionStrategy.class; return InsertionStrategy.class;
} }
} }
@ -535,16 +535,14 @@ public class VehicleRoutingAlgorithms {
private static void registerInsertionListeners(TypedMap definedClasses, List<InsertionListener> insertionListeners) { private static void registerInsertionListeners(TypedMap definedClasses, List<InsertionListener> insertionListeners) {
for(AbstractKey<?> key : definedClasses.keySet()){ for(AbstractKey<?> key : definedClasses.keySet()){
if(key instanceof AbstractInsertionKey){ if(key instanceof InsertionStrategyKey){
AbstractInsertionKey insertionKey = (AbstractInsertionKey) key; InsertionStrategyKey insertionKey = (InsertionStrategyKey) key;
AbstractInsertionStrategy insertionStrategy = definedClasses.get(insertionKey); InsertionStrategy insertionStrategy = definedClasses.get(insertionKey);
for(InsertionListener l : insertionListeners){ for(InsertionListener l : insertionListeners){
// log.info("add insertionListener " + l + " to " + insertionStrategy);
insertionStrategy.addListener(l); insertionStrategy.addListener(l);
} }
} }
} }
// log.warn("cannot register insertion listeners yet");
} }
private static String getName(HierarchicalConfiguration strategyConfig) { private static String getName(HierarchicalConfiguration strategyConfig) {
@ -570,15 +568,15 @@ public class VehicleRoutingAlgorithms {
String insertionId = modConfig.getString("[@id]"); String insertionId = modConfig.getString("[@id]");
if(insertionId == null) insertionId = "noId"; if(insertionId == null) insertionId = "noId";
ModKey modKey = makeKey(insertionName,insertionId); ModKey modKey = makeKey(insertionName,insertionId);
AbstractInsertionKey insertionStrategyKey = new AbstractInsertionKey(modKey); InsertionStrategyKey insertionStrategyKey = new InsertionStrategyKey(modKey);
AbstractInsertionStrategy insertionStrategy = definedClasses.get(insertionStrategyKey); InsertionStrategy insertionStrategy = definedClasses.get(insertionStrategyKey);
if(insertionStrategy == null){ if(insertionStrategy == null){
List<PrioritizedVRAListener> prioListeners = new ArrayList<PrioritizedVRAListener>(); List<PrioritizedVRAListener> prioListeners = new ArrayList<PrioritizedVRAListener>();
insertionStrategy = createInsertionStrategy(modConfig, vrp, vehicleFleetManager, activityStates, prioListeners, executorService, nuOfThreads); insertionStrategy = createInsertionStrategy(modConfig, vrp, vehicleFleetManager, activityStates, prioListeners, executorService, nuOfThreads);
algorithmListeners.addAll(prioListeners); algorithmListeners.addAll(prioListeners);
definedClasses.put(insertionStrategyKey,insertionStrategy); definedClasses.put(insertionStrategyKey,insertionStrategy);
} }
final AbstractInsertionStrategy finalInsertionStrategy = insertionStrategy; final InsertionStrategy finalInsertionStrategy = insertionStrategy;
return new AlgorithmStartsListener() { return new AlgorithmStartsListener() {
@ -699,8 +697,8 @@ public class VehicleRoutingAlgorithms {
String insertionId = moduleConfig.getString("insertion[@id]"); String insertionId = moduleConfig.getString("insertion[@id]");
if(insertionId == null) insertionId = "noId"; if(insertionId == null) insertionId = "noId";
ModKey insertionKey = makeKey(insertionName,insertionId); ModKey insertionKey = makeKey(insertionName,insertionId);
AbstractInsertionKey insertionStrategyKey = new AbstractInsertionKey(insertionKey); InsertionStrategyKey insertionStrategyKey = new InsertionStrategyKey(insertionKey);
AbstractInsertionStrategy insertion = definedClasses.get(insertionStrategyKey); InsertionStrategy insertion = definedClasses.get(insertionStrategyKey);
if(insertion == null){ if(insertion == null){
List<HierarchicalConfiguration> insertionConfigs = moduleConfig.configurationsAt("insertion"); List<HierarchicalConfiguration> insertionConfigs = moduleConfig.configurationsAt("insertion");
if(insertionConfigs.size() != 1) throw new IllegalStateException("this should be 1"); 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); insertion = createInsertionStrategy(insertionConfigs.get(0), vrp, vehicleFleetManager, activityStates, prioListeners, executorService, nuOfThreads);
algorithmListeners.addAll(prioListeners); algorithmListeners.addAll(prioListeners);
} }
final AbstractInsertionStrategy final_insertion = insertion; final InsertionStrategy final_insertion = insertion;
SearchStrategyModule module = new SearchStrategyModule() { SearchStrategyModule module = new SearchStrategyModule() {
private Logger logger = Logger.getLogger(SearchStrategyModule.class); private Logger logger = Logger.getLogger(SearchStrategyModule.class);
@ -716,7 +714,7 @@ public class VehicleRoutingAlgorithms {
@Override @Override
public VehicleRoutingProblemSolution runAndGetSolution(VehicleRoutingProblemSolution vrpSolution) { public VehicleRoutingProblemSolution runAndGetSolution(VehicleRoutingProblemSolution vrpSolution) {
Collection<Job> ruinedJobs = ruin.ruin(vrpSolution.getRoutes()); Collection<Job> 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()); double totalCost = RouteUtils.getTotalCost(vrpSolution.getRoutes());
vrpSolution.setCost(totalCost); vrpSolution.setCost(totalCost);
return vrpSolution; return vrpSolution;
@ -736,7 +734,7 @@ public class VehicleRoutingAlgorithms {
public void addModuleListener(SearchStrategyModuleListener moduleListener) { public void addModuleListener(SearchStrategyModuleListener moduleListener) {
if(moduleListener instanceof InsertionListener){ if(moduleListener instanceof InsertionListener){
InsertionListener iListener = (InsertionListener) moduleListener; InsertionListener iListener = (InsertionListener) moduleListener;
if(!final_insertion.getListener().contains(iListener)){ if(!final_insertion.getListeners().contains(iListener)){
logger.info("register moduleListener " + moduleListener); logger.info("register moduleListener " + moduleListener);
final_insertion.addListener(iListener); final_insertion.addListener(iListener);
} }
@ -785,8 +783,8 @@ public class VehicleRoutingAlgorithms {
String insertionId = moduleConfig.getString("insertion[@id]"); String insertionId = moduleConfig.getString("insertion[@id]");
if(insertionId == null) insertionId = "noId"; if(insertionId == null) insertionId = "noId";
ModKey insertionKey = makeKey(insertionName,insertionId); ModKey insertionKey = makeKey(insertionName,insertionId);
AbstractInsertionKey insertionStrategyKey = new AbstractInsertionKey(insertionKey); InsertionStrategyKey insertionStrategyKey = new InsertionStrategyKey(insertionKey);
AbstractInsertionStrategy insertion = definedClasses.get(insertionStrategyKey); InsertionStrategy insertion = definedClasses.get(insertionStrategyKey);
if(insertion == null){ if(insertion == null){
List<HierarchicalConfiguration> insertionConfigs = moduleConfig.configurationsAt("insertion"); List<HierarchicalConfiguration> insertionConfigs = moduleConfig.configurationsAt("insertion");
if(insertionConfigs.size() != 1) throw new IllegalStateException("this should be 1"); if(insertionConfigs.size() != 1) throw new IllegalStateException("this should be 1");
@ -864,8 +862,8 @@ public class VehicleRoutingAlgorithms {
return ruin; return ruin;
} }
private static AbstractInsertionStrategy createInsertionStrategy(HierarchicalConfiguration moduleConfig, VehicleRoutingProblem vrp,VehicleFleetManager vehicleFleetManager, RouteStates activityStates, List<PrioritizedVRAListener> algorithmListeners, ExecutorService executorService, int nuOfThreads) { private static InsertionStrategy createInsertionStrategy(HierarchicalConfiguration moduleConfig, VehicleRoutingProblem vrp,VehicleFleetManager vehicleFleetManager, RouteStates activityStates, List<PrioritizedVRAListener> algorithmListeners, ExecutorService executorService, int nuOfThreads) {
AbstractInsertionStrategy insertion = InsertionFactory.createInsertion(vrp, moduleConfig, vehicleFleetManager, activityStates, algorithmListeners, executorService, nuOfThreads); InsertionStrategy insertion = InsertionFactory.createInsertion(vrp, moduleConfig, vehicleFleetManager, activityStates, algorithmListeners, executorService, nuOfThreads);
return insertion; return insertion;
} }

View file

@ -21,7 +21,8 @@
package algorithms; package algorithms;
import basics.route.Vehicle; import basics.route.Vehicle;
import algorithms.RouteAlgorithm.VehicleSwitchedListener; import basics.route.VehicleRoute;
class VehicleSwitched implements VehicleSwitchedListener{ class VehicleSwitched implements VehicleSwitchedListener{
@ -32,7 +33,7 @@ class VehicleSwitched implements VehicleSwitchedListener{
} }
@Override @Override
public void vehicleSwitched(Vehicle oldVehicle, Vehicle newVehicle) { public void vehicleSwitched(VehicleRoute vehicleRoute, Vehicle oldVehicle, Vehicle newVehicle) {
fleetManager.unlock(oldVehicle); fleetManager.unlock(oldVehicle);
fleetManager.lock(newVehicle); fleetManager.lock(newVehicle);
} }

View file

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

View file

@ -37,6 +37,7 @@ import basics.Job;
import basics.Service; import basics.Service;
import basics.VehicleRoutingProblem; import basics.VehicleRoutingProblem;
import basics.VehicleRoutingProblemSolution; import basics.VehicleRoutingProblemSolution;
import basics.costs.VehicleRoutingActivityCosts;
import basics.costs.VehicleRoutingTransportCosts; import basics.costs.VehicleRoutingTransportCosts;
import basics.route.Driver; import basics.route.Driver;
import basics.route.DriverImpl; import basics.route.DriverImpl;
@ -60,6 +61,8 @@ public class GendreauPostOptTest {
VehicleRoutingTransportCosts cost; VehicleRoutingTransportCosts cost;
VehicleRoutingActivityCosts activityCosts;
VehicleRoutingProblem vrp; VehicleRoutingProblem vrp;
Service job1; Service job1;
@ -78,6 +81,8 @@ public class GendreauPostOptTest {
private RouteAlgorithmImpl routeAlgorithm; private RouteAlgorithmImpl routeAlgorithm;
private JobInsertionCalculator insertionCalc;
@Before @Before
public void setUp(){ public void setUp(){
@ -148,29 +153,31 @@ public class GendreauPostOptTest {
fleetManager = new VehicleFleetManagerImpl(vehicles); fleetManager = new VehicleFleetManagerImpl(vehicles);
states = new RouteStates(); states = new RouteStates();
ExampleActivityCostFunction activityCosts = new ExampleActivityCostFunction(); activityCosts = new ExampleActivityCostFunction();
CalculatesServiceInsertion standardServiceInsertion = new CalculatesServiceInsertion(cost, activityCosts); CalculatesServiceInsertion standardServiceInsertion = new CalculatesServiceInsertion(cost, activityCosts);
standardServiceInsertion.setActivityStates(states); standardServiceInsertion.setActivityStates(states);
CalculatesServiceInsertionConsideringFixCost withFixCost = new CalculatesServiceInsertionConsideringFixCost(standardServiceInsertion, states); CalculatesServiceInsertionConsideringFixCost withFixCost = new CalculatesServiceInsertionConsideringFixCost(standardServiceInsertion, states);
withFixCost.setWeightOfFixCost(1.2); withFixCost.setWeightOfFixCost(1.2);
final JobInsertionCalculator vehicleTypeDepInsertionCost = new CalculatesVehTypeDepServiceInsertion(fleetManager, withFixCost); insertionCalc = new CalculatesVehTypeDepServiceInsertion(fleetManager, withFixCost);
updater = new TourStateUpdater(states, cost, activityCosts); updater = new TourStateUpdater(states, cost, activityCosts);
//
routeAlgorithm = RouteAlgorithmImpl.newInstance(vehicleTypeDepInsertionCost, updater); //
routeAlgorithm.setActivityStates(states); // routeAlgorithm = RouteAlgorithmImpl.newInstance(insertionCalc, updater);
if(fleetManager != null){ // routeAlgorithm.setActivityStates(states);
routeAlgorithm.getListeners().add(new RouteAlgorithm.VehicleSwitchedListener() { // if(fleetManager != null){
// routeAlgorithm.getListeners().add(new RouteAlgorithm.VehicleSwitchedListener() {
@Override //
public void vehicleSwitched(Vehicle oldVehicle, Vehicle newVehicle) { // @Override
fleetManager.unlock(oldVehicle); // public void vehicleSwitched(Vehicle oldVehicle, Vehicle newVehicle) {
fleetManager.lock(newVehicle); // fleetManager.unlock(oldVehicle);
} // fleetManager.lock(newVehicle);
}); // }
} // });
// }
} }
@ -202,10 +209,17 @@ public class GendreauPostOptTest {
assertEquals(110.0, sol.getCost(), 0.5); 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())); 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); Gendreau postOpt = new Gendreau(vrp, radialRuin, insertionStrategy);
postOpt.setFleetManager(fleetManager); postOpt.setFleetManager(fleetManager);
VehicleRoutingProblemSolution newSolution = postOpt.runAndGetSolution(sol); VehicleRoutingProblemSolution newSolution = postOpt.runAndGetSolution(sol);
assertEquals(2,RouteUtils.getNuOfActiveRoutes(newSolution.getRoutes())); assertEquals(2,RouteUtils.getNuOfActiveRoutes(newSolution.getRoutes()));
@ -236,15 +250,17 @@ public class GendreauPostOptTest {
Collection<VehicleRoute> routes = new ArrayList<VehicleRoute>(); Collection<VehicleRoute> routes = new ArrayList<VehicleRoute>();
routes.add(route); routes.add(route);
// routes.add(new VehicleRoute(getEmptyTour(),getDriver(),getNoVehicle()));
// routes.add(new VehicleRoute(getEmptyTour(),getDriver(),getNoVehicle()));
VehicleRoutingProblemSolution sol = new VehicleRoutingProblemSolution(routes, route.getCost()); VehicleRoutingProblemSolution sol = new VehicleRoutingProblemSolution(routes, route.getCost());
assertEquals(110.0, sol.getCost(), 0.5); 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())); 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); Gendreau postOpt = new Gendreau(vrp, radialRuin, insertionStrategy);
postOpt.setShareOfJobsToRuin(1.0); postOpt.setShareOfJobsToRuin(1.0);
postOpt.setNuOfIterations(1); postOpt.setNuOfIterations(1);