1
0
Fork 0
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:
oblonski 2015-10-14 22:06:07 +02:00
parent de8689060a
commit d3510048d5
8 changed files with 79 additions and 12 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -66,4 +66,5 @@ public interface VehicleFleetManager {
public Collection<Vehicle> getAvailableVehicles(Vehicle withoutThisType);
public Vehicle getAvailableVehicle(VehicleTypeKey vehicleTypeIdentifier);
}

View file

@ -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)
*/

View file

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