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:
parent
e35603ed34
commit
3f7d6b8b01
20 changed files with 315 additions and 282 deletions
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -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,66 +36,53 @@ 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<String, VehicleRoute> experimentalPreferredRoute) {
|
||||
}
|
||||
|
||||
private boolean allowUnassignedJobs = false;
|
||||
|
||||
private boolean fixRouteSet = false;
|
||||
private JobInsertionCalculator bestInsertionCostCalculator;
|
||||
|
||||
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() {
|
||||
return "[name=bestInsertion]";
|
||||
}
|
||||
|
||||
@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);
|
||||
Collections.shuffle(unassignedJobList, random);
|
||||
informInsertionStarts(vehicleRoutes,unassignedJobs.size());
|
||||
int inserted = 0;
|
||||
List<String> reasons = new ArrayList<String>();
|
||||
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");
|
||||
}
|
||||
else{
|
||||
if(bestInsertion == null){
|
||||
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(allowUnassignedJobs){
|
||||
logger.warn("cannot insert job yet " + unassignedJob);
|
||||
throw new IllegalStateException(getErrorMsg(unassignedJob));
|
||||
}
|
||||
else{
|
||||
for(String s : reasons){
|
||||
System.out.println("reason="+s);
|
||||
bestInsertion = new Insertion(newRoute,bestI);
|
||||
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 +
|
||||
"\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]"
|
||||
);
|
||||
"\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;
|
||||
informBeforeJobInsertion(unassignedJob,bestI,newRoute);
|
||||
routeAlgorithm.insertJob(unassignedJob,bestI,newRoute);
|
||||
vehicleRoutes.add(newRoute);
|
||||
|
||||
@Override
|
||||
public Collection<InsertionListener> getListeners() {
|
||||
return Collections.unmodifiableCollection(insertionsListeners.getListeners());
|
||||
}
|
||||
}
|
||||
}
|
||||
inserted++;
|
||||
informJobInserted((unassignedJobList.size()-inserted), unassignedJob, insertIn);
|
||||
}
|
||||
informInsertionEndsListeners(vehicleRoutes);
|
||||
|
||||
@Override
|
||||
public void addListener(InsertionListener insertionListener) {
|
||||
insertionsListeners.addListener(insertionListener);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs, double result2beat) {
|
||||
public void insertJobs(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs) {
|
||||
List<Job> unassignedJobList = new ArrayList<Job>(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<InsertionListener> getListeners() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(InsertionListener insertionListener) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,6 +43,8 @@ final class ConfigureFixCostCalculator implements InsertionStartsListener, JobIn
|
|||
|
||||
CalculatesServiceInsertionConsideringFixCost calcConsideringFix;
|
||||
|
||||
private int nuOfJobsToRecreate;
|
||||
|
||||
public ConfigureFixCostCalculator(VehicleRoutingProblem vrp, CalculatesServiceInsertionConsideringFixCost calcConsideringFix) {
|
||||
super();
|
||||
this.vrp = vrp;
|
||||
|
|
@ -55,15 +57,17 @@ final class ConfigureFixCostCalculator implements InsertionStartsListener, JobIn
|
|||
}
|
||||
|
||||
@Override
|
||||
public void informInsertionStarts(Collection<VehicleRoute> routes, int nOfJobs2Recreate) {
|
||||
double completenessRatio = (1-((double)nOfJobs2Recreate/(double)vrp.getJobs().values().size()));
|
||||
public void informInsertionStarts(Collection<VehicleRoute> routes, Collection<Job> 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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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<VehicleRoute> vehicleRoutes, int nOfJobs2Recreate) {
|
||||
public void informInsertionStarts(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs) {
|
||||
List<VehicleRoute> newRoutes = new ArrayList<VehicleRoute>();
|
||||
for(VehicleRoute route : vehicleRoutes){
|
||||
if(route.isEmpty()) continue;
|
||||
|
|
|
|||
|
|
@ -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()){
|
||||
|
|
|
|||
36
jsprit-core/src/main/java/algorithms/Inserter.java
Normal file
36
jsprit-core/src/main/java/algorithms/Inserter.java
Normal 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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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<PrioritizedVRAListener> 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<InsertionListener> insertionListeners = new ArrayList<InsertionListener>();
|
||||
List<PrioritizedVRAListener> algoListeners = new ArrayList<PrioritizedVRAListener>();
|
||||
|
||||
|
|
@ -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)));
|
||||
|
||||
|
|
|
|||
|
|
@ -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<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){
|
||||
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){
|
||||
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<InsertionListener> listeners) {
|
||||
for(InsertionListener l : listeners) addListener(l);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,10 +60,13 @@ interface InsertionStrategy {
|
|||
*
|
||||
* @param vehicleRoutes
|
||||
* @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 removeListener(InsertionListener insertionListener);
|
||||
|
||||
public Collection<InsertionListener> getListeners();
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,14 +76,14 @@ class JobObserver implements JobInsertedListener, BeforeJobInsertionListener, Al
|
|||
Collection<Info> infos = new ArrayList<Info>();
|
||||
|
||||
@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));
|
||||
|
|
|
|||
|
|
@ -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<VehicleRoute> routes, Collection<Job> unassignedJobs, double resultToBeat) {
|
||||
public void insertJobs(Collection<VehicleRoute> routes, Collection<Job> unassignedJobs) {
|
||||
List<Job> jobs = new ArrayList<Job>(unassignedJobs);
|
||||
informInsertionStarts(routes,unassignedJobs.size());
|
||||
// informInsertionStarts(routes,unassignedJobs);
|
||||
int inserted = 0;
|
||||
while(!jobs.isEmpty()){
|
||||
List<Job> unassignedJobList = new ArrayList<Job>(jobs);
|
||||
|
|
@ -191,7 +192,7 @@ final class RegretInsertion extends AbstractInsertionStrategy{
|
|||
jobs.remove(bestScoredJob.getJob());
|
||||
}
|
||||
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
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<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
|
||||
public String toString() {
|
||||
return "[name=removeEmptyVehicles]";
|
||||
|
|
|
|||
|
|
@ -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<VehicleRoute> vehicleRoutes, int nOfJobs2Recreate) {
|
||||
public void informInsertionStarts(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs) {
|
||||
vehicleFleetManager.unlockAll();
|
||||
Collection<VehicleRoute> routes = new ArrayList<VehicleRoute>(vehicleRoutes);
|
||||
for(VehicleRoute route : routes){
|
||||
if(route.isEmpty()){
|
||||
vehicleRoutes.remove(route);
|
||||
}
|
||||
else{
|
||||
// if(route.isEmpty()){
|
||||
// vehicleRoutes.remove(route);
|
||||
// }
|
||||
// else{
|
||||
vehicleFleetManager.lock(route.getVehicle());
|
||||
}
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
36
jsprit-core/src/main/java/algorithms/UpdateRoute.java
Normal file
36
jsprit-core/src/main/java/algorithms/UpdateRoute.java
Normal 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) {}
|
||||
|
||||
}
|
||||
|
|
@ -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<AbstractInsertionStrategy>{
|
||||
static class InsertionStrategyKey implements AbstractKey<InsertionStrategy>{
|
||||
|
||||
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<AbstractInsertionStrategy> getType() {
|
||||
return AbstractInsertionStrategy.class;
|
||||
public Class<InsertionStrategy> getType() {
|
||||
return InsertionStrategy.class;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -535,16 +535,14 @@ public class VehicleRoutingAlgorithms {
|
|||
|
||||
private static void registerInsertionListeners(TypedMap definedClasses, List<InsertionListener> 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<PrioritizedVRAListener> prioListeners = new ArrayList<PrioritizedVRAListener>();
|
||||
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<HierarchicalConfiguration> 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<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());
|
||||
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<HierarchicalConfiguration> 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<PrioritizedVRAListener> 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<PrioritizedVRAListener> algorithmListeners, ExecutorService executorService, int nuOfThreads) {
|
||||
InsertionStrategy insertion = InsertionFactory.createInsertion(vrp, moduleConfig, vehicleFleetManager, activityStates, algorithmListeners, executorService, nuOfThreads);
|
||||
return insertion;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
@ -78,6 +81,8 @@ public class GendreauPostOptTest {
|
|||
|
||||
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<VehicleRoute> routes = new ArrayList<VehicleRoute>();
|
||||
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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue