mirror of
https://github.com/graphhopper/jsprit.git
synced 2020-01-24 07:45:05 +01:00
speed up regret insertion with breaks
This commit is contained in:
parent
de8689060a
commit
d3510048d5
8 changed files with 79 additions and 12 deletions
|
|
@ -424,6 +424,7 @@ public class Jsprit {
|
|||
.considerFixedCosts(toDouble(getProperty(Parameter.FIXED_COST_PARAM.toString())))
|
||||
.setActivityInsertionCostCalculator(activityInsertion)
|
||||
.build();
|
||||
regretInsertion.setFleetManager(fm);
|
||||
scorer = getRegretScorer(vrp);
|
||||
regretInsertion.setScoringFunction(scorer);
|
||||
regret = regretInsertion;
|
||||
|
|
|
|||
|
|
@ -166,7 +166,10 @@ public class InsertionBuilder {
|
|||
}
|
||||
} else if (strategy.equals(Strategy.REGRET)) {
|
||||
if (executor == null) {
|
||||
insertion = new RegretInsertion(costCalculator, vrp);
|
||||
RegretInsertion regret = new RegretInsertion(costCalculator, vrp);
|
||||
regret.setFleetManager(fleetManager);
|
||||
insertion = regret;
|
||||
|
||||
} else {
|
||||
insertion = new RegretInsertionConcurrent(costCalculator, vrp, executor);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,9 @@ import jsprit.core.problem.job.Job;
|
|||
import jsprit.core.problem.job.Service;
|
||||
import jsprit.core.problem.job.Shipment;
|
||||
import jsprit.core.problem.solution.route.VehicleRoute;
|
||||
import jsprit.core.problem.vehicle.Vehicle;
|
||||
import jsprit.core.problem.vehicle.VehicleFleetManager;
|
||||
import jsprit.core.problem.vehicle.VehicleImpl;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
|
|
@ -215,7 +218,11 @@ public class RegretInsertion extends AbstractInsertionStrategy {
|
|||
|
||||
private JobInsertionCostsCalculator insertionCostsCalculator;
|
||||
|
||||
private VehicleFleetManager fleetManager;
|
||||
|
||||
public void setFleetManager(VehicleFleetManager fleetManager) {
|
||||
this.fleetManager = fleetManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the scoring function.
|
||||
|
|
@ -280,6 +287,7 @@ public class RegretInsertion extends AbstractInsertionStrategy {
|
|||
while (!jobs.isEmpty()) {
|
||||
List<Job> unassignedJobList = new ArrayList<Job>(jobs);
|
||||
List<Job> badJobList = new ArrayList<Job>();
|
||||
if(!firstRun && lastModified == null) throw new IllegalStateException("fooo");
|
||||
if(firstRun){
|
||||
firstRun = false;
|
||||
updateInsertionData(priorityQueues, routes, unassignedJobList, badJobList, updateRound, updates);
|
||||
|
|
@ -289,9 +297,6 @@ public class RegretInsertion extends AbstractInsertionStrategy {
|
|||
}
|
||||
updateRound++;
|
||||
ScoredJob bestScoredJob = getBest(priorityQueues,updates,unassignedJobList,badJobList);
|
||||
// InsertionData d = insertionCostsCalculator.getInsertionData(bestScoredJob.getRoute(), bestScoredJob.getJob(), NO_NEW_VEHICLE_YET, NO_NEW_DEPARTURE_TIME_YET, NO_NEW_DRIVER_YET, Double.MAX_VALUE);
|
||||
//
|
||||
// ScoredJob bestScoredJob = nextJob(routes, unassignedJobList, badJobList);
|
||||
if (bestScoredJob != null) {
|
||||
if (bestScoredJob.isNewRoute()) {
|
||||
routes.add(bestScoredJob.getRoute());
|
||||
|
|
@ -300,7 +305,7 @@ public class RegretInsertion extends AbstractInsertionStrategy {
|
|||
jobs.remove(bestScoredJob.getJob());
|
||||
lastModified = bestScoredJob.getRoute();
|
||||
}
|
||||
else throw new IllegalStateException("fooo");
|
||||
else lastModified = null;
|
||||
for (Job bad : badJobList) {
|
||||
jobs.remove(bad);
|
||||
badJobs.add(bad);
|
||||
|
|
@ -319,7 +324,30 @@ public class RegretInsertion extends AbstractInsertionStrategy {
|
|||
Iterator<VersionedInsertionData> iterator = priorityQueue.iterator();
|
||||
while(iterator.hasNext()){
|
||||
VersionedInsertionData versionedIData = iterator.next();
|
||||
if(bestRoute != null){
|
||||
if(versionedIData.getRoute() == bestRoute){
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if(versionedIData.getiData() instanceof InsertionData.NoInsertionFound) continue;
|
||||
if(versionedIData.getiData().getSelectedVehicle() != versionedIData.getRoute().getVehicle()) {
|
||||
if (fleetManager.isLocked(versionedIData.getiData().getSelectedVehicle())) {
|
||||
Vehicle available = fleetManager.getAvailableVehicle(versionedIData.getiData().getSelectedVehicle().getVehicleTypeIdentifier());
|
||||
if (available != null) {
|
||||
InsertionData oldData = versionedIData.getiData();
|
||||
InsertionData newData = new InsertionData(oldData.getInsertionCost(), oldData.getPickupInsertionIndex(),
|
||||
oldData.getDeliveryInsertionIndex(), available, oldData.getSelectedDriver());
|
||||
newData.setVehicleDepartureTime(oldData.getVehicleDepartureTime());
|
||||
for(Event e : oldData.getEvents()){
|
||||
if(e instanceof SwitchVehicle){
|
||||
newData.getEvents().add(new SwitchVehicle(versionedIData.getRoute(),available,oldData.getVehicleDepartureTime()));
|
||||
}
|
||||
else newData.getEvents().add(e);
|
||||
}
|
||||
versionedIData = new VersionedInsertionData(newData, versionedIData.getVersion(), versionedIData.getRoute());
|
||||
} else continue;
|
||||
}
|
||||
}
|
||||
int currentDataVersion = updates.get(versionedIData.getRoute());
|
||||
if(versionedIData.getVersion() == currentDataVersion){
|
||||
if(best == null) {
|
||||
|
|
@ -382,9 +410,20 @@ public class RegretInsertion extends AbstractInsertionStrategy {
|
|||
priorityQueues[unassignedJob.getIndex()] = new PriorityQueue<VersionedInsertionData>(unassignedJobList.size(), getComparator());
|
||||
}
|
||||
for(VehicleRoute route : routes) {
|
||||
|
||||
InsertionData iData = insertionCostsCalculator.getInsertionData(route, unassignedJob, NO_NEW_VEHICLE_YET, NO_NEW_DEPARTURE_TIME_YET, NO_NEW_DRIVER_YET, Double.MAX_VALUE);
|
||||
priorityQueues[unassignedJob.getIndex()].add(new VersionedInsertionData(iData,updateRound,route));
|
||||
Collection<Vehicle> relevantVehicles = new ArrayList<Vehicle>();
|
||||
if(!(route.getVehicle() instanceof VehicleImpl.NoVehicle)) {
|
||||
relevantVehicles.add(route.getVehicle());
|
||||
relevantVehicles.addAll(fleetManager.getAvailableVehicles(route.getVehicle()));
|
||||
}
|
||||
else relevantVehicles.addAll(fleetManager.getAvailableVehicles());
|
||||
for (Vehicle v : relevantVehicles) {
|
||||
double depTime = v.getEarliestDeparture();
|
||||
InsertionData iData = insertionCostsCalculator.getInsertionData(route, unassignedJob, v, depTime, route.getDriver(), Double.MAX_VALUE);
|
||||
if (iData instanceof InsertionData.NoInsertionFound) {
|
||||
continue;
|
||||
}
|
||||
priorityQueues[unassignedJob.getIndex()].add(new VersionedInsertionData(iData,updateRound,route));
|
||||
}
|
||||
updates.put(route,updateRound);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,11 +16,11 @@ class SwitchVehicleListener implements EventListener {
|
|||
if (event instanceof SwitchVehicle) {
|
||||
SwitchVehicle switchVehicle = (SwitchVehicle) event;
|
||||
if (vehiclesDifferent((SwitchVehicle) event)) {
|
||||
logger.trace("switch vehicle (" + ((SwitchVehicle) event).getRoute().getVehicle().getId() + " to " + ((SwitchVehicle) event).getVehicle().getId() + ")");
|
||||
logger.trace("switch vehicle ({} to {})",((SwitchVehicle) event).getRoute().getVehicle().getId(),((SwitchVehicle) event).getVehicle().getId());
|
||||
Break aBreak = ((SwitchVehicle) event).getRoute().getVehicle().getBreak();
|
||||
if (aBreak != null) {
|
||||
boolean removed = ((SwitchVehicle) event).getRoute().getTourActivities().removeJob(aBreak);
|
||||
if (removed) logger.trace("remove " + aBreak.getId());
|
||||
if (removed) logger.trace("remove {}",aBreak.getId());
|
||||
}
|
||||
}
|
||||
switchVehicle.getRoute().setVehicleAndDepartureTime(switchVehicle.getVehicle(), ((SwitchVehicle) event).getDepartureTime());
|
||||
|
|
|
|||
|
|
@ -45,8 +45,8 @@ class InfiniteVehicles implements VehicleFleetManager {
|
|||
|
||||
private void extractTypes(Collection<Vehicle> vehicles) {
|
||||
for (Vehicle v : vehicles) {
|
||||
VehicleTypeKey typeKey = new VehicleTypeKey(v.getType().getTypeId(), v.getStartLocation().getId(), v.getEndLocation().getId(), v.getEarliestDeparture(), v.getLatestArrival(), v.getSkills(), v.isReturnToDepot());
|
||||
types.put(typeKey, v);
|
||||
// VehicleTypeKey typeKey = new VehicleTypeKey(v.getType().getTypeId(), v.getStartLocation().getId(), v.getEndLocation().getId(), v.getEarliestDeparture(), v.getLatestArrival(), v.getSkills(), v.isReturnToDepot());
|
||||
types.put(v.getVehicleTypeIdentifier(), v);
|
||||
// sortedTypes.add(typeKey);
|
||||
}
|
||||
}
|
||||
|
|
@ -90,4 +90,9 @@ class InfiniteVehicles implements VehicleFleetManager {
|
|||
return vehicles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vehicle getAvailableVehicle(VehicleTypeKey vehicleTypeIdentifier) {
|
||||
return types.get(vehicleTypeIdentifier);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,4 +66,5 @@ public interface VehicleFleetManager {
|
|||
|
||||
public Collection<Vehicle> getAvailableVehicles(Vehicle withoutThisType);
|
||||
|
||||
public Vehicle getAvailableVehicle(VehicleTypeKey vehicleTypeIdentifier);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -143,6 +143,14 @@ class VehicleFleetManagerImpl implements VehicleFleetManager {
|
|||
return vehicles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vehicle getAvailableVehicle(VehicleTypeKey vehicleTypeIdentifier) {
|
||||
if(!vehicleTypes[vehicleTypeIdentifier.getIndex()].isEmpty()){
|
||||
return vehicleTypes[vehicleTypeIdentifier.getIndex()].getVehicle();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.matsim.contrib.freight.vrp.basics.VehicleFleetManager#lock(org.matsim.contrib.freight.vrp.basics.Vehicle)
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -26,7 +26,9 @@ import jsprit.core.problem.job.Service;
|
|||
import jsprit.core.problem.job.Shipment;
|
||||
import jsprit.core.problem.solution.route.VehicleRoute;
|
||||
import jsprit.core.problem.solution.route.activity.TourActivity;
|
||||
import jsprit.core.problem.vehicle.FiniteFleetManagerFactory;
|
||||
import jsprit.core.problem.vehicle.Vehicle;
|
||||
import jsprit.core.problem.vehicle.VehicleFleetManager;
|
||||
import jsprit.core.problem.vehicle.VehicleImpl;
|
||||
import jsprit.core.util.Coordinate;
|
||||
import junit.framework.Assert;
|
||||
|
|
@ -45,8 +47,10 @@ public class RegretInsertionTest {
|
|||
VehicleImpl v = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.newInstance(0, 0)).build();
|
||||
VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance().addJob(s1).addJob(s2).addVehicle(v).build();
|
||||
|
||||
VehicleFleetManager fm = new FiniteFleetManagerFactory(vrp.getVehicles()).createFleetManager();
|
||||
JobInsertionCostsCalculator calculator = getCalculator(vrp);
|
||||
RegretInsertion regretInsertion = new RegretInsertion(calculator, vrp);
|
||||
regretInsertion.setFleetManager(fm);
|
||||
Collection<VehicleRoute> routes = new ArrayList<VehicleRoute>();
|
||||
|
||||
regretInsertion.insertJobs(routes, vrp.getJobs().values());
|
||||
|
|
@ -61,8 +65,10 @@ public class RegretInsertionTest {
|
|||
VehicleImpl v = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.newInstance(0, 0)).build();
|
||||
VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance().addJob(s1).addJob(s2).addVehicle(v).build();
|
||||
|
||||
VehicleFleetManager fm = new FiniteFleetManagerFactory(vrp.getVehicles()).createFleetManager();
|
||||
JobInsertionCostsCalculator calculator = getCalculator(vrp);
|
||||
RegretInsertion regretInsertion = new RegretInsertion(calculator, vrp);
|
||||
regretInsertion.setFleetManager(fm);
|
||||
Collection<VehicleRoute> routes = new ArrayList<VehicleRoute>();
|
||||
|
||||
regretInsertion.insertJobs(routes, vrp.getJobs().values());
|
||||
|
|
@ -77,8 +83,10 @@ public class RegretInsertionTest {
|
|||
VehicleImpl v = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.newInstance(0, 0)).build();
|
||||
final VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance().addJob(s1).addJob(s2).addVehicle(v).build();
|
||||
|
||||
VehicleFleetManager fm = new FiniteFleetManagerFactory(vrp.getVehicles()).createFleetManager();
|
||||
JobInsertionCostsCalculator calculator = getCalculator(vrp);
|
||||
RegretInsertion regretInsertion = new RegretInsertion(calculator, vrp);
|
||||
regretInsertion.setFleetManager(fm);
|
||||
Collection<VehicleRoute> routes = new ArrayList<VehicleRoute>();
|
||||
|
||||
CkeckJobSequence position = new CkeckJobSequence(2, s1);
|
||||
|
|
@ -102,8 +110,10 @@ public class RegretInsertionTest {
|
|||
VehicleImpl v = VehicleImpl.Builder.newInstance("v").setStartLocation(Location.Builder.newInstance().setCoordinate(Coordinate.newInstance(0, 0)).build()).build();
|
||||
final VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance().addJob(s1).addJob(s2).addVehicle(v).build();
|
||||
|
||||
VehicleFleetManager fm = new FiniteFleetManagerFactory(vrp.getVehicles()).createFleetManager();
|
||||
JobInsertionCostsCalculator calculator = getShipmentCalculator(vrp);
|
||||
RegretInsertion regretInsertion = new RegretInsertion(calculator, vrp);
|
||||
regretInsertion.setFleetManager(fm);
|
||||
Collection<VehicleRoute> routes = new ArrayList<VehicleRoute>();
|
||||
|
||||
CkeckJobSequence position = new CkeckJobSequence(2, s2);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue