@Override public void informInsertionEnds(Collection<VehicleRoute> vehicleRoutes) { List<VehicleRoute> routes = new ArrayList<VehicleRoute>(vehicleRoutes); for (VehicleRoute route : routes) { if (route.isEmpty()) { fleetManager.unlock(route.getVehicle()); vehicleRoutes.remove(route); } } }
public void write(String filename) { if (!filename.endsWith(".xml")) filename += ".xml"; log.info("write vrp: " + filename); XMLConf xmlConfig = new XMLConf(); xmlConfig.setFileName(filename); xmlConfig.setRootElementName("problem"); xmlConfig.setAttributeSplittingDisabled(true); xmlConfig.setDelimiterParsingDisabled(true); writeProblemType(xmlConfig); writeVehiclesAndTheirTypes(xmlConfig); // might be sorted? List<Job> jobs = new ArrayList<Job>(); jobs.addAll(vrp.getJobs().values()); for (VehicleRoute r : vrp.getInitialVehicleRoutes()) { jobs.addAll(r.getTourActivities().getJobs()); } writeServices(xmlConfig, jobs); writeShipments(xmlConfig, jobs); writeInitialRoutes(xmlConfig); writeSolutions(xmlConfig); OutputFormat format = new OutputFormat(); format.setIndenting(true); format.setIndent(5); try { Document document = xmlConfig.createDoc(); Element element = document.getDocumentElement(); element.setAttribute("xmlns", "http://www.w3schools.com"); element.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); element.setAttribute("xsi:schemaLocation", "http://www.w3schools.com vrp_xml_schema.xsd"); } catch (ConfigurationException e) { logger.error("Exception:", e); e.printStackTrace(); System.exit(1); } try { Writer out = new FileWriter(filename); XMLSerializer serializer = new XMLSerializer(out, format); serializer.serialize(xmlConfig.getDocument()); out.close(); } catch (IOException e) { logger.error("Exception:", e); e.printStackTrace(); System.exit(1); } }
private boolean hasActivityIn(Collection<VehicleRoute> routes, String jobId) { boolean isInRoute = false; for (VehicleRoute route : routes) { for (TourActivity act : route.getActivities()) { if (act instanceof TourActivity.JobActivity) { if (((TourActivity.JobActivity) act).getJob().getId().equals(jobId)) isInRoute = true; } } } return isInRoute; }
private double getDeltaAbsoluteFixCost(VehicleRoute route, Vehicle newVehicle, Job job) { Capacity load = Capacity.addup(getCurrentMaxLoadInRoute(route), job.getSize()); // double load = getCurrentMaxLoadInRoute(route) + job.getCapacityDemand(); double currentFix = 0.0; if (route.getVehicle() != null) { if (!(route.getVehicle() instanceof NoVehicle)) { currentFix += route.getVehicle().getType().getVehicleCostParams().fix; } } if (!newVehicle.getType().getCapacityDimensions().isGreaterOrEqual(load)) { return Double.MAX_VALUE; } return newVehicle.getType().getVehicleCostParams().fix - currentFix; }
@Override public void handleJobInsertion(Job job, InsertionData iData, VehicleRoute route) { if (job instanceof Service) { route.setVehicleAndDepartureTime( iData.getSelectedVehicle(), iData.getVehicleDepartureTime()); if (!iData.getSelectedVehicle().isReturnToDepot()) { if (iData.getDeliveryInsertionIndex() >= route.getTourActivities().getActivities().size()) { setEndLocation(route, (Service) job); } } TourActivity activity = vehicleRoutingProblem.copyAndGetActivities(job).get(0); route.getTourActivities().addActivity(iData.getDeliveryInsertionIndex(), activity); } else delegator.handleJobInsertion(job, iData, route); }
public void visit(TourActivity activity) { for (Vehicle vehicle : vehicles) { double latestArrTimeAtPrevAct = latest_arrTimes_at_prevAct[vehicle.getVehicleTypeIdentifier().getIndex()]; Location prevLocation = location_of_prevAct[vehicle.getVehicleTypeIdentifier().getIndex()]; double potentialLatestArrivalTimeAtCurrAct = latestArrTimeAtPrevAct - transportCosts.getBackwardTransportTime( activity.getLocation(), prevLocation, latestArrTimeAtPrevAct, route.getDriver(), vehicle) - activity.getOperationTime(); double latestArrivalTime = Math.min( activity.getTheoreticalLatestOperationStartTime(), potentialLatestArrivalTimeAtCurrAct); if (latestArrivalTime < activity.getTheoreticalEarliestOperationStartTime()) { stateManager.putTypedInternalRouteState( route, vehicle, InternalStates.SWITCH_NOT_FEASIBLE, true); } stateManager.putInternalTypedActivityState( activity, vehicle, InternalStates.LATEST_OPERATION_START_TIME, latestArrivalTime); latest_arrTimes_at_prevAct[vehicle.getVehicleTypeIdentifier().getIndex()] = latestArrivalTime; location_of_prevAct[vehicle.getVehicleTypeIdentifier().getIndex()] = activity.getLocation(); } }
@Test public void futureMaxLoatAtAct1ShouldBe15() { stateManager.informInsertionStarts(Arrays.asList(serviceRoute), Collections.<Job>emptyList()); Capacity atAct1 = stateManager.getActivityState( serviceRoute.getActivities().get(0), InternalStates.FUTURE_MAXLOAD, Capacity.class); assertEquals(15, atAct1.get(0)); }
@Override public void handleJobInsertion(Job job, InsertionData iData, VehicleRoute route) { if (job instanceof Shipment) { List<AbstractActivity> acts = vehicleRoutingProblem.copyAndGetActivities(job); TourActivity pickupShipment = acts.get(0); TourActivity deliverShipment = acts.get(1); route.setVehicleAndDepartureTime( iData.getSelectedVehicle(), iData.getVehicleDepartureTime()); if (!iData.getSelectedVehicle().isReturnToDepot()) { if (iData.getDeliveryInsertionIndex() >= route.getActivities().size()) { setEndLocation(route, (Shipment) job); } } route.getTourActivities().addActivity(iData.getDeliveryInsertionIndex(), deliverShipment); route.getTourActivities().addActivity(iData.getPickupInsertionIndex(), pickupShipment); } else delegator.handleJobInsertion(job, iData, route); }
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().equals(insertionData.getSelectedVehicle().getId()))) { insertionListeners.informVehicleSwitched( vehicleRoute, vehicleRoute.getVehicle(), insertionData.getSelectedVehicle()); vehicleRoute.setVehicleAndDepartureTime( insertionData.getSelectedVehicle(), insertionData.getVehicleDepartureTime()); } jobInsertionHandler.handleJobInsertion(job, insertionData, vehicleRoute); insertionListeners.informJobInserted( job, vehicleRoute, insertionData.getInsertionCost(), insertionData.getAdditionalTime()); }
@Test public void when_shipmentroute_loadAtAct3ShouldBe10() { stateManager.informInsertionStarts(Arrays.asList(shipment_route), Collections.<Job>emptyList()); Capacity atAct = stateManager.getActivityState( shipment_route.getActivities().get(2), InternalStates.LOAD, Capacity.class); assertEquals(10, atAct.get(0)); }
@Test public void when_shipmentroute_pastMaxLoatAtAct4ShouldBe15() { stateManager.informInsertionStarts(Arrays.asList(shipment_route), Collections.<Job>emptyList()); Capacity atAct = stateManager.getActivityState( shipment_route.getActivities().get(3), InternalStates.PAST_MAXLOAD, Capacity.class); assertEquals(15, atAct.get(0)); }
@Test public void pastMaxLoatAtAct2ShouldBe10() { stateManager.informInsertionStarts(Arrays.asList(serviceRoute), Collections.<Job>emptyList()); Capacity atAct2 = stateManager.getActivityState( serviceRoute.getActivities().get(1), InternalStates.PAST_MAXLOAD, Capacity.class); assertEquals(15, atAct2.get(0)); }
@Test public void whenSolvingProblem2_nuActsShouldBe6() { VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); new VrpXMLReader(vrpBuilder) .read("src/test/resources/simpleProblem_inclShipments_iniRoutes.xml"); VehicleRoutingProblem vrp = vrpBuilder.build(); VehicleRoutingAlgorithm vra = new SchrimpfFactory().createAlgorithm(vrp); Collection<VehicleRoutingProblemSolution> solutions = vra.searchSolutions(); VehicleRoutingProblemSolution solution = Solutions.bestOf(solutions); int nuActs = 0; for (VehicleRoute r : solution.getRoutes()) { nuActs += r.getActivities().size(); } assertEquals(6, nuActs); }
@Override public void visit(VehicleRoute route) { begin(route); Iterator<TourActivity> revIterator = route.getTourActivities().reverseActivityIterator(); while (revIterator.hasNext()) { visit(revIterator.next()); } finish(); }
@Test public void when_pdroute_loadAtAct2ShouldBe10() { stateManager.informInsertionStarts( Arrays.asList(pickup_delivery_route), Collections.<Job>emptyList()); Capacity atAct2 = stateManager.getActivityState( pickup_delivery_route.getActivities().get(1), InternalStates.LOAD, Capacity.class); assertEquals(10, atAct2.get(0)); }
@Test public void when_pdroute_pastMaxLoatAtAct1ShouldBe15() { stateManager.informInsertionStarts( Arrays.asList(pickup_delivery_route), Collections.<Job>emptyList()); Capacity atAct1 = stateManager.getActivityState( pickup_delivery_route.getActivities().get(0), InternalStates.PAST_MAXLOAD, Capacity.class); assertEquals(15, atAct1.get(0)); }
@Test public void whenSolvingProblem2_nuJobsInSolutionShouldBe4() { VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); new VrpXMLReader(vrpBuilder) .read("src/test/resources/simpleProblem_inclShipments_iniRoutes.xml"); VehicleRoutingProblem vrp = vrpBuilder.build(); VehicleRoutingAlgorithm vra = new SchrimpfFactory().createAlgorithm(vrp); Collection<VehicleRoutingProblemSolution> solutions = vra.searchSolutions(); VehicleRoutingProblemSolution solution = Solutions.bestOf(solutions); SolutionPrinter.print(vrp, solution, SolutionPrinter.Print.VERBOSE); int jobsInSolution = 0; for (VehicleRoute r : solution.getRoutes()) { jobsInSolution += r.getTourActivities().jobSize(); } assertEquals(4, jobsInSolution); }
private void writeInitialRoutes(XMLConf xmlConfig) { if (vrp.getInitialVehicleRoutes().isEmpty()) return; String path = "initialRoutes.route"; int routeCounter = 0; for (VehicleRoute route : vrp.getInitialVehicleRoutes()) { xmlConfig.setProperty(path + "(" + routeCounter + ").driverId", route.getDriver().getId()); xmlConfig.setProperty(path + "(" + routeCounter + ").vehicleId", route.getVehicle().getId()); xmlConfig.setProperty(path + "(" + routeCounter + ").start", route.getStart().getEndTime()); int actCounter = 0; for (TourActivity act : route.getTourActivities().getActivities()) { xmlConfig.setProperty( path + "(" + routeCounter + ").act(" + actCounter + ")[@type]", act.getName()); if (act instanceof JobActivity) { Job job = ((JobActivity) act).getJob(); if (job instanceof Service) { xmlConfig.setProperty( path + "(" + routeCounter + ").act(" + actCounter + ").serviceId", job.getId()); } else if (job instanceof Shipment) { xmlConfig.setProperty( path + "(" + routeCounter + ").act(" + actCounter + ").shipmentId", job.getId()); } else { throw new IllegalStateException( "cannot write solution correctly since job-type is not know. make sure you use either service or shipment, or another writer"); } } xmlConfig.setProperty( path + "(" + routeCounter + ").act(" + actCounter + ").arrTime", act.getArrTime()); xmlConfig.setProperty( path + "(" + routeCounter + ").act(" + actCounter + ").endTime", act.getEndTime()); actCounter++; } xmlConfig.setProperty(path + "(" + routeCounter + ").end", route.getEnd().getArrTime()); routeCounter++; } }
private double getDeltaRelativeFixCost(VehicleRoute route, Vehicle newVehicle, Job job) { Capacity currentLoad = getCurrentMaxLoadInRoute(route); // int currentLoad = getCurrentMaxLoadInRoute(route); Capacity load = Capacity.addup(currentLoad, job.getSize()); // double load = currentLoad + job.getCapacityDemand(); double currentRelFix = 0.0; if (route.getVehicle() != null) { if (!(route.getVehicle() instanceof NoVehicle)) { currentRelFix += route.getVehicle().getType().getVehicleCostParams().fix * Capacity.divide( currentLoad, route.getVehicle().getType().getCapacityDimensions()); } } if (!newVehicle.getType().getCapacityDimensions().isGreaterOrEqual(load)) { return Double.MAX_VALUE; } double relativeFixCost = newVehicle.getType().getVehicleCostParams().fix * (Capacity.divide(load, newVehicle.getType().getCapacityDimensions())) - currentRelFix; return relativeFixCost; }
private void writeSolutions(XMLConf xmlConfig) { if (solutions == null) return; String solutionPath = "solutions.solution"; int counter = 0; for (VehicleRoutingProblemSolution solution : solutions) { xmlConfig.setProperty(solutionPath + "(" + counter + ").cost", solution.getCost()); int routeCounter = 0; for (VehicleRoute route : solution.getRoutes()) { // xmlConfig.setProperty(solutionPath + "(" + counter + ").routes.route(" + routeCounter // + ").cost", route.getCost()); xmlConfig.setProperty( solutionPath + "(" + counter + ").routes.route(" + routeCounter + ").driverId", route.getDriver().getId()); xmlConfig.setProperty( solutionPath + "(" + counter + ").routes.route(" + routeCounter + ").vehicleId", route.getVehicle().getId()); xmlConfig.setProperty( solutionPath + "(" + counter + ").routes.route(" + routeCounter + ").start", route.getStart().getEndTime()); int actCounter = 0; for (TourActivity act : route.getTourActivities().getActivities()) { xmlConfig.setProperty( solutionPath + "(" + counter + ").routes.route(" + routeCounter + ").act(" + actCounter + ")[@type]", act.getName()); if (act instanceof JobActivity) { Job job = ((JobActivity) act).getJob(); if (job instanceof Service) { xmlConfig.setProperty( solutionPath + "(" + counter + ").routes.route(" + routeCounter + ").act(" + actCounter + ").serviceId", job.getId()); } else if (job instanceof Shipment) { xmlConfig.setProperty( solutionPath + "(" + counter + ").routes.route(" + routeCounter + ").act(" + actCounter + ").shipmentId", job.getId()); } else { throw new IllegalStateException( "cannot write solution correctly since job-type is not know. make sure you use either service or shipment, or another writer"); } } xmlConfig.setProperty( solutionPath + "(" + counter + ").routes.route(" + routeCounter + ").act(" + actCounter + ").arrTime", act.getArrTime()); xmlConfig.setProperty( solutionPath + "(" + counter + ").routes.route(" + routeCounter + ").act(" + actCounter + ").endTime", act.getEndTime()); actCounter++; } xmlConfig.setProperty( solutionPath + "(" + counter + ").routes.route(" + routeCounter + ").end", route.getEnd().getArrTime()); routeCounter++; } int unassignedJobCounter = 0; for (Job unassignedJob : solution.getUnassignedJobs()) { xmlConfig.setProperty( solutionPath + "(" + counter + ").unassignedJobs.job(" + unassignedJobCounter + ")[@id]", unassignedJob.getId()); unassignedJobCounter++; } counter++; } }
private static String getVehicleString(VehicleRoute route) { return route.getVehicle().getId(); }
private void setEndLocation(VehicleRoute route, Shipment shipment) { route.getEnd().setLocationId(shipment.getDeliveryLocation().getId()); }
@Override public Collection<Vehicle> get(VehicleRoute route) { return Arrays.asList(route.getVehicle()); }
static ScoredJob getScoredJob( Collection<VehicleRoute> routes, Job unassignedJob, JobInsertionCostsCalculator insertionCostsCalculator, ScoringFunction scoringFunction) { InsertionData best = null; InsertionData secondBest = null; VehicleRoute bestRoute = null; double benchmark = Double.MAX_VALUE; for (VehicleRoute route : routes) { if (secondBest != null) { benchmark = secondBest.getInsertionCost(); } InsertionData iData = insertionCostsCalculator.getInsertionData( route, unassignedJob, NO_NEW_VEHICLE_YET, NO_NEW_DEPARTURE_TIME_YET, NO_NEW_DRIVER_YET, benchmark); if (iData instanceof InsertionData.NoInsertionFound) continue; if (best == null) { best = iData; bestRoute = route; } else if (iData.getInsertionCost() < best.getInsertionCost()) { secondBest = best; best = iData; bestRoute = route; } else if (secondBest == null || (iData.getInsertionCost() < secondBest.getInsertionCost())) { secondBest = iData; } } VehicleRoute emptyRoute = VehicleRoute.emptyRoute(); InsertionData iData = insertionCostsCalculator.getInsertionData( emptyRoute, unassignedJob, NO_NEW_VEHICLE_YET, NO_NEW_DEPARTURE_TIME_YET, NO_NEW_DRIVER_YET, benchmark); if (!(iData instanceof InsertionData.NoInsertionFound)) { if (best == null) { best = iData; bestRoute = emptyRoute; } else if (iData.getInsertionCost() < best.getInsertionCost()) { secondBest = best; best = iData; bestRoute = emptyRoute; } else if (secondBest == null || (iData.getInsertionCost() < secondBest.getInsertionCost())) { secondBest = iData; } } if (best == null) { return new RegretInsertion.BadJob(unassignedJob); } double score = score(unassignedJob, best, secondBest, scoringFunction); ScoredJob scoredJob; if (bestRoute == emptyRoute) { scoredJob = new ScoredJob(unassignedJob, score, best, bestRoute, true); } else scoredJob = new ScoredJob(unassignedJob, score, best, bestRoute, false); return scoredJob; }
private void setEndLocation(VehicleRoute route, Service service) { route.getEnd().setLocationId(service.getLocation().getId()); }
private static void printVerbose( PrintWriter out, VehicleRoutingProblem problem, VehicleRoutingProblemSolution solution) { String leftAlgin = "| %-7s | %-20s | %-21s | %-15s | %-15s | %-15s | %-15s |%n"; out.format( "+--------------------------------------------------------------------------------------------------------------------------------+%n"); out.printf( "| detailed solution |%n"); out.format( "+---------+----------------------+-----------------------+-----------------+-----------------+-----------------+-----------------+%n"); out.printf( "| route | vehicle | activity | job | arrTime | endTime | costs |%n"); int routeNu = 1; for (VehicleRoute route : solution.getRoutes()) { out.format( "+---------+----------------------+-----------------------+-----------------+-----------------+-----------------+-----------------+%n"); double costs = 0; out.format( leftAlgin, routeNu, getVehicleString(route), route.getStart().getName(), "-", "undef", Math.round(route.getStart().getEndTime()), Math.round(costs)); TourActivity prevAct = route.getStart(); for (TourActivity act : route.getActivities()) { String jobId; if (act instanceof JobActivity) { jobId = ((JobActivity) act).getJob().getId(); } else { jobId = "-"; } double c = problem .getTransportCosts() .getTransportCost( prevAct.getLocation(), act.getLocation(), prevAct.getEndTime(), route.getDriver(), route.getVehicle()); c += problem .getActivityCosts() .getActivityCost(act, act.getArrTime(), route.getDriver(), route.getVehicle()); costs += c; out.format( leftAlgin, routeNu, getVehicleString(route), act.getName(), jobId, Math.round(act.getArrTime()), Math.round(act.getEndTime()), Math.round(costs)); prevAct = act; } double c = problem .getTransportCosts() .getTransportCost( prevAct.getLocation(), route.getEnd().getLocation(), prevAct.getEndTime(), route.getDriver(), route.getVehicle()); c += problem .getActivityCosts() .getActivityCost( route.getEnd(), route.getEnd().getArrTime(), route.getDriver(), route.getVehicle()); costs += c; out.format( leftAlgin, routeNu, getVehicleString(route), route.getEnd().getName(), "-", Math.round(route.getEnd().getArrTime()), "undef", Math.round(costs)); routeNu++; } out.format( "+--------------------------------------------------------------------------------------------------------------------------------+%n"); if (!solution.getUnassignedJobs().isEmpty()) { out.format("+----------------+%n"); out.format("| unassignedJobs |%n"); out.format("+----------------+%n"); String unassignedJobAlgin = "| %-14s |%n"; for (Job j : solution.getUnassignedJobs()) { out.format(unassignedJobAlgin, j.getId()); } out.format("+----------------+%n"); } }