mirror of
https://github.com/graphhopper/jsprit.git
synced 2020-01-24 07:45:05 +01:00
add concurrent best insertion, remove bestinsertionbuilder
This commit is contained in:
parent
d2151f3e1f
commit
91e49681e1
5 changed files with 39 additions and 217 deletions
|
|
@ -2,6 +2,7 @@ package algorithms;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import basics.VehicleRoutingProblem;
|
||||
import basics.algo.InsertionListener;
|
||||
|
|
@ -29,6 +30,10 @@ public class BestInsertionBuilder implements InsertionStrategyBuilder{
|
|||
private int forwaredLooking;
|
||||
|
||||
private int memory;
|
||||
|
||||
private ExecutorService executor;
|
||||
|
||||
private int nuOfThreads;
|
||||
|
||||
public BestInsertionBuilder(VehicleRoutingProblem vrp, VehicleFleetManager vehicleFleetManager, StateManager stateManager) {
|
||||
super();
|
||||
|
|
@ -57,10 +62,17 @@ public class BestInsertionBuilder implements InsertionStrategyBuilder{
|
|||
return this;
|
||||
}
|
||||
|
||||
public void setActivityInsertionCostCalculator(ActivityInsertionCostsCalculator activityInsertionCostsCalculator){
|
||||
public BestInsertionBuilder setActivityInsertionCostCalculator(ActivityInsertionCostsCalculator activityInsertionCostsCalculator){
|
||||
this.actInsertionCostsCalculator = activityInsertionCostsCalculator;
|
||||
return this;
|
||||
};
|
||||
|
||||
public BestInsertionBuilder setConcurrentMode(ExecutorService executor, int nuOfThreads){
|
||||
this.executor = executor;
|
||||
this.nuOfThreads = nuOfThreads;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InsertionStrategy build() {
|
||||
List<InsertionListener> iListeners = new ArrayList<InsertionListener>();
|
||||
|
|
@ -81,8 +93,15 @@ public class BestInsertionBuilder implements InsertionStrategyBuilder{
|
|||
calcBuilder.considerFixedCosts(weightOfFixedCosts);
|
||||
}
|
||||
JobInsertionCostsCalculator jobInsertions = calcBuilder.build();
|
||||
BestInsertion bestInsertion = new BestInsertion(jobInsertions);
|
||||
for(InsertionListener l : iListeners) bestInsertion.addListener(l);
|
||||
InsertionStrategy bestInsertion;
|
||||
if(executor == null){
|
||||
bestInsertion = new BestInsertion(jobInsertions);
|
||||
|
||||
}
|
||||
else{
|
||||
bestInsertion = new BestInsertionConc(jobInsertions,executor,nuOfThreads);
|
||||
}
|
||||
for(InsertionListener l : iListeners) bestInsertion.addListener(l);
|
||||
return bestInsertion;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -123,14 +123,14 @@ final class BestInsertionConc implements InsertionStrategy{
|
|||
insertionsListeners.informInsertionStarts(vehicleRoutes,unassignedJobs);
|
||||
List<Job> unassignedJobList = new ArrayList<Job>(unassignedJobs);
|
||||
Collections.shuffle(unassignedJobList, random);
|
||||
|
||||
List<Batch> batches = distributeRoutes(vehicleRoutes,nuOfBatches);
|
||||
|
||||
for(final Job unassignedJob : unassignedJobList){
|
||||
|
||||
|
||||
Insertion bestInsertion = null;
|
||||
double bestInsertionCost = Double.MAX_VALUE;
|
||||
|
||||
List<Batch> batches = distributeRoutes(vehicleRoutes,nuOfBatches);
|
||||
|
||||
for(final Batch batch : batches){
|
||||
completionService.submit(new Callable<Insertion>() {
|
||||
|
||||
|
|
@ -163,7 +163,6 @@ final class BestInsertionConc implements InsertionStrategy{
|
|||
System.exit(1);
|
||||
}
|
||||
|
||||
|
||||
if(!minVehiclesFirst){
|
||||
VehicleRoute newRoute = VehicleRoute.emptyRoute();
|
||||
InsertionData newIData = bestInsertionCostCalculator.getInsertionData(newRoute, unassignedJob, NO_NEW_VEHICLE_YET, NO_NEW_DEPARTURE_TIME_YET, NO_NEW_DRIVER_YET, bestInsertionCost);
|
||||
|
|
@ -171,8 +170,10 @@ final class BestInsertionConc implements InsertionStrategy{
|
|||
bestInsertion = new Insertion(newRoute,newIData);
|
||||
bestInsertionCost = newIData.getInsertionCost();
|
||||
vehicleRoutes.add(newRoute);
|
||||
batches.get(0).routes.add(newRoute);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(bestInsertion == null){
|
||||
VehicleRoute newRoute = VehicleRoute.emptyRoute();
|
||||
InsertionData bestI = bestInsertionCostCalculator.getInsertionData(newRoute, unassignedJob, NO_NEW_VEHICLE_YET, NO_NEW_DEPARTURE_TIME_YET, NO_NEW_DRIVER_YET, Double.MAX_VALUE);
|
||||
|
|
|
|||
|
|
@ -1,198 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (C) 2013 Stefan Schroeder
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
******************************************************************************/
|
||||
package algorithms;
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
///**
|
||||
// *
|
||||
// * @author stefan schroeder
|
||||
// *
|
||||
// */
|
||||
//
|
||||
//final class BestInsertionConcurrent implements InsertionStrategy{
|
||||
//
|
||||
// public static BestInsertionConcurrent newInstance(RouteAlgorithm routeAlgorithm, ExecutorService executor, int nuOfThreads){
|
||||
// return new BestInsertionConcurrent(routeAlgorithm, executor, nuOfThreads);
|
||||
// }
|
||||
//
|
||||
// static class Batch {
|
||||
// List<VehicleRoute> routes = new ArrayList<VehicleRoute>();
|
||||
//
|
||||
// }
|
||||
//
|
||||
// private static Logger logger = Logger.getLogger(BestInsertionConcurrent.class);
|
||||
//
|
||||
// private Random random = RandomNumberGeneration.getRandom();
|
||||
//
|
||||
// private RouteAlgorithm routeAlgorithm;
|
||||
//
|
||||
//// private ExecutorService executor;
|
||||
//
|
||||
// private int nuOfBatches;
|
||||
//
|
||||
// private ExecutorCompletionService<Insertion> completionService;
|
||||
//
|
||||
// public void setRandom(Random random) {
|
||||
// this.random = random;
|
||||
// }
|
||||
//
|
||||
// private BestInsertionConcurrent(RouteAlgorithm routeAlgorithm, ExecutorService executor, int nuOfThreads) {
|
||||
// super();
|
||||
// this.routeAlgorithm = routeAlgorithm;
|
||||
//// this.executor = executor;
|
||||
// logger.info("initialise " + this);
|
||||
// this.nuOfBatches = nuOfThreads;
|
||||
// completionService = new ExecutorCompletionService<Insertion>(executor);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public String toString() {
|
||||
// return "[name=concurrentBestInsertion]";
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void insertJobs(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs) {
|
||||
// List<Job> unassignedJobList = new ArrayList<Job>(unassignedJobs);
|
||||
// Collections.shuffle(unassignedJobList, random);
|
||||
//// informInsertionStarts(vehicleRoutes,unassignedJobs.size());
|
||||
// int inserted = 0;
|
||||
// for(final Job unassignedJob : unassignedJobList){
|
||||
// VehicleRoute insertIn = null;
|
||||
// Insertion bestInsertion = null;
|
||||
// double bestInsertionCost = Double.MAX_VALUE;
|
||||
//
|
||||
// List<Batch> batches = distributeRoutes(vehicleRoutes,nuOfBatches);
|
||||
//
|
||||
// for(final Batch batch : batches){
|
||||
// completionService.submit(new Callable<Insertion>() {
|
||||
//
|
||||
// @Override
|
||||
// public Insertion call() throws Exception {
|
||||
// return getBestInsertion(batch,unassignedJob);
|
||||
// }
|
||||
//
|
||||
// });
|
||||
//
|
||||
// }
|
||||
//
|
||||
// try{
|
||||
// for(int i=0;i<batches.size();i++){
|
||||
// Future<Insertion> futureIData = completionService.take();
|
||||
// Insertion insertion = futureIData.get();
|
||||
// if(insertion == null) continue;
|
||||
// if(insertion.getInsertionData().getInsertionCost() < bestInsertionCost){
|
||||
// bestInsertion = insertion;
|
||||
// bestInsertionCost = insertion.getInsertionData().getInsertionCost();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// catch(InterruptedException e){
|
||||
// Thread.currentThread().interrupt();
|
||||
// }
|
||||
// catch (ExecutionException e) {
|
||||
// e.printStackTrace();
|
||||
// logger.error(e.getCause().toString());
|
||||
// System.exit(1);
|
||||
// }
|
||||
//
|
||||
// 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 {
|
||||
//// VehicleRoute newRoute = VehicleRoute.emptyRoute();
|
||||
//// InsertionData bestI = routeAlgorithm.calculateBestInsertion(newRoute, unassignedJob, Double.MAX_VALUE);
|
||||
//// if(bestI instanceof InsertionData.NoInsertionFound)
|
||||
// throw new IllegalStateException("given the vehicles, could not create a valid solution.\n\tthe reason might be" +
|
||||
// " inappropriate vehicle capacity.\n\tthe job that does not fit in any vehicle anymore is \n\t" + unassignedJob);
|
||||
//// insertIn = newRoute;
|
||||
//// informBeforeJobInsertion(unassignedJob,bestI,newRoute);
|
||||
//// routeAlgorithm.insertJob(unassignedJob,bestI,newRoute);
|
||||
//// vehicleRoutes.add(newRoute);
|
||||
// }
|
||||
// inserted++;
|
||||
//// informJobInserted((unassignedJobList.size()-inserted), unassignedJob, insertIn);
|
||||
// }
|
||||
//// informInsertionEndsListeners(vehicleRoutes);
|
||||
// }
|
||||
//
|
||||
// private Insertion getBestInsertion(Batch batch, Job unassignedJob) {
|
||||
// Insertion bestInsertion = null;
|
||||
// double bestInsertionCost = Double.MAX_VALUE;
|
||||
// for(VehicleRoute vehicleRoute : batch.routes){
|
||||
// InsertionData iData = routeAlgorithm.calculateBestInsertion(vehicleRoute, unassignedJob, bestInsertionCost);
|
||||
// if(iData instanceof NoInsertionFound) continue;
|
||||
// if(iData.getInsertionCost() < bestInsertionCost){
|
||||
// bestInsertion = new Insertion(vehicleRoute,iData);
|
||||
// bestInsertionCost = iData.getInsertionCost();
|
||||
// }
|
||||
// }
|
||||
// return bestInsertion;
|
||||
// }
|
||||
//
|
||||
// private List<Batch> distributeRoutes(Collection<VehicleRoute> vehicleRoutes, int nuOfBatches) {
|
||||
// List<Batch> batches = new ArrayList<Batch>();
|
||||
// for(int i=0;i<nuOfBatches;i++) batches.add(new Batch());
|
||||
// /*
|
||||
// * if route.size < nuOfBatches add as much routes as empty batches are available
|
||||
// * else add one empty route anyway
|
||||
// */
|
||||
//// if(vehicleRoutes.size()<nuOfBatches){
|
||||
//// int nOfNewRoutes = nuOfBatches-vehicleRoutes.size();
|
||||
//// for(int i=0;i<nOfNewRoutes;i++){
|
||||
//// vehicleRoutes.add(VehicleRoute.emptyRoute());
|
||||
//// }
|
||||
//// }
|
||||
//// else{
|
||||
// vehicleRoutes.add(VehicleRoute.emptyRoute());
|
||||
//// }
|
||||
// /*
|
||||
// * distribute routes to batches equally
|
||||
// */
|
||||
// int count = 0;
|
||||
// for(VehicleRoute route : vehicleRoutes){
|
||||
// if(count == nuOfBatches) count=0;
|
||||
// batches.get(count).routes.add(route);
|
||||
// count++;
|
||||
// }
|
||||
// return batches;
|
||||
// }
|
||||
//
|
||||
//
|
||||
// @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
|
||||
//
|
||||
// }
|
||||
//
|
||||
//}
|
||||
|
|
@ -8,7 +8,7 @@ import basics.route.PickupShipment;
|
|||
import basics.route.Start;
|
||||
import basics.route.TourActivity;
|
||||
|
||||
class HardPickupAndDeliveryShipmentActivityLevelConstraint implements HardActivityStateLevelConstraint {
|
||||
public class HardPickupAndDeliveryShipmentActivityLevelConstraint implements HardActivityStateLevelConstraint {
|
||||
|
||||
private static Logger logger = Logger.getLogger(HardPickupAndDeliveryShipmentActivityLevelConstraint.class);
|
||||
|
||||
|
|
|
|||
|
|
@ -753,15 +753,15 @@ public class VehicleRoutingAlgorithms {
|
|||
}
|
||||
else if(ruin_name.equals("radialRuin")){
|
||||
String ruin_distance = moduleConfig.getString("ruin.distance");
|
||||
JobDistance jobDistance;
|
||||
if(ruin_distance == null) jobDistance = new JobDistanceAvgCosts(vrp.getTransportCosts());
|
||||
else {
|
||||
if(ruin_distance.equals("euclidean")){
|
||||
jobDistance = new EuclideanServiceDistance();
|
||||
}
|
||||
else throw new IllegalStateException("does not know ruin.distance " + ruin_distance + ". either ommit ruin.distance then the "
|
||||
+ "default is used or use 'euclidean'");
|
||||
}
|
||||
JobDistance jobDistance = new AvgJobDistance(vrp.getTransportCosts());
|
||||
// if(ruin_distance == null) jobDistance
|
||||
// else {
|
||||
// if(ruin_distance.equals("euclidean")){
|
||||
// jobDistance = new EuclideanServiceDistance();
|
||||
// }
|
||||
// else throw new IllegalStateException("does not know ruin.distance " + ruin_distance + ". either ommit ruin.distance then the "
|
||||
// + "default is used or use 'euclidean'");
|
||||
// }
|
||||
ruin = getRadialRuin(vrp, routeStates, definedClasses, ruinKey, shareToRuin, jobDistance);
|
||||
}
|
||||
else throw new IllegalStateException("ruin[@name] " + ruin_name + " is not known. Use either randomRuin or radialRuin.");
|
||||
|
|
@ -796,7 +796,7 @@ public class VehicleRoutingAlgorithms {
|
|||
RuinStrategyKey stratKey = new RuinStrategyKey(ruinKey);
|
||||
RuinStrategy ruin = definedClasses.get(stratKey);
|
||||
if(ruin == null){
|
||||
ruin = new RuinRadial(vrp, 0.3, new JobDistanceAvgCosts(vrp.getTransportCosts()));
|
||||
ruin = new RuinRadial(vrp, 0.3, new AvgJobDistance(vrp.getTransportCosts()));
|
||||
definedClasses.put(stratKey, ruin);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue