diff --git a/jsprit-analysis/src/main/java/analysis/Plotter.java b/jsprit-analysis/src/main/java/analysis/Plotter.java new file mode 100644 index 00000000..0f32592a --- /dev/null +++ b/jsprit-analysis/src/main/java/analysis/Plotter.java @@ -0,0 +1,387 @@ +/******************************************************************************* + * 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 analysis; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.geom.Ellipse2D; +import java.io.File; +import java.io.IOException; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.apache.log4j.Logger; +import org.jfree.chart.ChartUtilities; +import org.jfree.chart.JFreeChart; +import org.jfree.chart.annotations.XYShapeAnnotation; +import org.jfree.chart.axis.NumberAxis; +import org.jfree.chart.labels.XYItemLabelGenerator; +import org.jfree.chart.plot.XYPlot; +import org.jfree.chart.renderer.xy.XYItemRenderer; +import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer; +import org.jfree.data.xy.XYDataItem; +import org.jfree.data.xy.XYDataset; +import org.jfree.data.xy.XYSeries; +import org.jfree.data.xy.XYSeriesCollection; + +import util.Coordinate; +import util.Locations; +import basics.Delivery; +import basics.Job; +import basics.Pickup; +import basics.Service; +import basics.VehicleRoutingProblem; +import basics.VehicleRoutingProblemSolution; +import basics.route.TourActivity; +import basics.route.Vehicle; +import basics.route.VehicleRoute; + +public class Plotter { + + private static class NoLocationFoundException extends Exception{ + + /** + * + */ + private static final long serialVersionUID = 1L; + + } + + private static Logger log = Logger.getLogger(SolutionPlotter.class); + + + public static enum Label { + ID, SIZE, NO_LABEL + } + + private boolean showFirstActivity = true; + + private Label label = Label.SIZE; + + private VehicleRoutingProblem vrp; + + private VehicleRoutingProblemSolution solution; + + private boolean plotSolutionAsWell = false; + + public void setShowFirstActivity(boolean show){ + showFirstActivity = show; + } + + public void setLabel(Label label){ + this.label = label; + } + + public Plotter(VehicleRoutingProblem vrp) { + super(); + this.vrp = vrp; + } + + public Plotter(VehicleRoutingProblem vrp, VehicleRoutingProblemSolution solution) { + super(); + this.vrp = vrp; + this.solution = solution; + plotSolutionAsWell = true; + } + + public void plot(String pngFileName, String plotTitle){ + if(plotSolutionAsWell){ + plotSolutionAsPNG(vrp, solution, pngFileName, plotTitle); + } + else{ + plotVrpAsPNG(vrp, pngFileName, plotTitle); + } + } + + private void plotVrpAsPNG(VehicleRoutingProblem vrp, String pngFile, String title){ + log.info("plot routes to " + pngFile); + XYSeriesCollection problem; + Map labels = new HashMap(); + try { + problem = makeVrpSeries(vrp, labels); + } catch (NoLocationFoundException e) { + log.warn("cannot plot vrp, since coord is missing"); + return; + } + XYPlot plot = createPlot(problem, labels); + JFreeChart chart = new JFreeChart(title, plot); + save(chart,pngFile); + } + + private void plotSolutionAsPNG(VehicleRoutingProblem vrp, VehicleRoutingProblemSolution solution, String pngFile, String title){ + log.info("plot solution to " + pngFile); + XYSeriesCollection problem; + XYSeriesCollection solutionColl; + Map labels = new HashMap(); + try { + problem = makeVrpSeries(vrp, labels); + solutionColl = makeSolutionSeries(vrp, solution); + } catch (NoLocationFoundException e) { + log.warn("cannot plot vrp, since coord is missing"); + return; + } + XYPlot plot = createPlot(problem, solutionColl, labels); + JFreeChart chart = new JFreeChart(title, plot); + save(chart,pngFile); + + } + + private static XYPlot createPlot(final XYSeriesCollection problem, final Map labels) { + XYPlot plot = new XYPlot(); + plot.setBackgroundPaint(Color.LIGHT_GRAY); + plot.setRangeGridlinePaint(Color.WHITE); + plot.setDomainGridlinePaint(Color.WHITE); + + XYItemRenderer problemRenderer = new XYLineAndShapeRenderer(false, true); // Shapes only + problemRenderer.setBaseItemLabelGenerator(new XYItemLabelGenerator() { + + @Override + public String generateLabel(XYDataset arg0, int arg1, int arg2) { + XYDataItem item = problem.getSeries(arg1).getDataItem(arg2); + return labels.get(item); + } + }); + problemRenderer.setBaseItemLabelsVisible(true); + problemRenderer.setBaseItemLabelPaint(Color.BLACK); + + NumberAxis xAxis = new NumberAxis(); + xAxis.setRangeWithMargins(problem.getDomainBounds(true)); + + NumberAxis yAxis = new NumberAxis(); + yAxis.setRangeWithMargins(problem.getRangeBounds(false)); + + plot.setDataset(0, problem); + plot.setRenderer(0, problemRenderer); + plot.setDomainAxis(0, xAxis); + plot.setRangeAxis(0, yAxis); + + return plot; + } + + private XYPlot createPlot(final XYSeriesCollection problem, XYSeriesCollection solutionColl, final Map labels) { + XYPlot plot = new XYPlot(); + plot.setBackgroundPaint(Color.LIGHT_GRAY); + plot.setRangeGridlinePaint(Color.WHITE); + plot.setDomainGridlinePaint(Color.WHITE); + + XYItemRenderer problemRenderer = new XYLineAndShapeRenderer(false, true); // Shapes only + problemRenderer.setBaseItemLabelGenerator(new XYItemLabelGenerator() { + + @Override + public String generateLabel(XYDataset arg0, int arg1, int arg2) { + XYDataItem item = problem.getSeries(arg1).getDataItem(arg2); + return labels.get(item); + } + }); + problemRenderer.setBaseItemLabelsVisible(true); + problemRenderer.setBaseItemLabelPaint(Color.BLACK); + + + NumberAxis xAxis = new NumberAxis(); + xAxis.setRangeWithMargins(problem.getDomainBounds(true)); + + NumberAxis yAxis = new NumberAxis(); + yAxis.setRangeWithMargins(problem.getRangeBounds(true)); + + plot.setDataset(0, problem); + plot.setRenderer(0, problemRenderer); + plot.setDomainAxis(0, xAxis); + plot.setRangeAxis(0, yAxis); + + + XYItemRenderer solutionRenderer = new XYLineAndShapeRenderer(true, false); // Lines only + if(showFirstActivity){ + for(int i=0;i routes, Locations locations){ + XYSeriesCollection coll = new XYSeriesCollection(); + int counter = 1; + for(VehicleRoute route : routes){ + if(route.isEmpty()) continue; + XYSeries series = new XYSeries(counter, false, true); + + Coordinate startCoord = locations.getCoord(route.getStart().getLocationId()); + series.add(startCoord.getX(), startCoord.getY()); + + for(TourActivity act : route.getTourActivities().getActivities()){ + Coordinate coord = locations.getCoord(act.getLocationId()); + series.add(coord.getX(), coord.getY()); + } + + Coordinate endCoord = locations.getCoord(route.getEnd().getLocationId()); + series.add(endCoord.getX(), endCoord.getY()); + + coll.addSeries(series); + counter++; + } + return coll; + } + + private XYSeriesCollection makeVrpSeries(Collection vehicles, Collection services, Map labels) throws NoLocationFoundException{ + XYSeriesCollection coll = new XYSeriesCollection(); + XYSeries vehicleSeries = new XYSeries("depot", false, true); + for(Vehicle v : vehicles){ + Coordinate coord = v.getCoord(); + if(coord == null) throw new NoLocationFoundException(); + vehicleSeries.add(coord.getX(),coord.getY()); + } + coll.addSeries(vehicleSeries); + + XYSeries serviceSeries = new XYSeries("service", false, true); + XYSeries pickupSeries = new XYSeries("pickup", false, true); + XYSeries deliverySeries = new XYSeries("delivery", false, true); + for(Job job : services){ + if(job instanceof Pickup){ + Pickup service = (Pickup)job; + Coordinate coord = service.getCoord(); + XYDataItem dataItem = new XYDataItem(coord.getX(), coord.getY()); + pickupSeries.add(dataItem); + addLabel(labels, service, dataItem); + } + else if(job instanceof Delivery){ + Delivery service = (Delivery)job; + Coordinate coord = service.getCoord(); + XYDataItem dataItem = new XYDataItem(coord.getX(), coord.getY()); + deliverySeries.add(dataItem); + addLabel(labels, service, dataItem); + } + else if(job instanceof Service){ + Service service = (Service)job; + Coordinate coord = service.getCoord(); + XYDataItem dataItem = new XYDataItem(coord.getX(), coord.getY()); + serviceSeries.add(dataItem); + addLabel(labels, service, dataItem); + } + else{ + throw new IllegalStateException("job instanceof " + job.getClass().toString() + ". this is not supported."); + } + + } + if(!serviceSeries.isEmpty()) coll.addSeries(serviceSeries); + if(!pickupSeries.isEmpty()) coll.addSeries(pickupSeries); + if(!deliverySeries.isEmpty()) coll.addSeries(deliverySeries); + return coll; + } + + private void addLabel(Map labels, Service service, XYDataItem dataItem) { + if(this.label.equals(Label.SIZE)){ + labels.put(dataItem, String.valueOf(service.getCapacityDemand())); + } + else if(this.label.equals(Label.ID)){ + labels.put(dataItem, String.valueOf(service.getId())); + } + } + + private XYSeriesCollection makeVrpSeries(Collection routes, Map labels) throws NoLocationFoundException{ + Set vehicles = new HashSet(); + Set jobs = new HashSet(); + for(VehicleRoute route : routes){ + vehicles.add(route.getVehicle()); + jobs.addAll(route.getTourActivities().getJobs()); + } + return makeVrpSeries(vehicles, jobs, labels); + } + + private XYSeriesCollection makeVrpSeries(VehicleRoutingProblem vrp, Map labels) throws NoLocationFoundException{ + return makeVrpSeries(vrp.getVehicles(), vrp.getJobs().values(), labels); + } + + private Locations retrieveLocations(VehicleRoutingProblem vrp) throws NoLocationFoundException { + final Map locs = new HashMap(); + for(Vehicle v : vrp.getVehicles()){ + String locationId = v.getLocationId(); + if(locationId == null) throw new NoLocationFoundException(); + Coordinate coord = v.getCoord(); + if(coord == null) throw new NoLocationFoundException(); + locs.put(locationId, coord); + } + for(Job j : vrp.getJobs().values()){ + if(j instanceof Service){ + String locationId = ((Service) j).getLocationId(); + if(locationId == null) throw new NoLocationFoundException(); + Coordinate coord = ((Service) j).getCoord(); + if(coord == null) throw new NoLocationFoundException(); + locs.put(locationId, coord); + } + else{ + throw new IllegalStateException("job is not a service. this is not supported yet."); + } + } + return new Locations() { + + @Override + public Coordinate getCoord(String id) { + return locs.get(id); + } + }; + } + +} diff --git a/jsprit-analysis/src/main/java/analysis/SolutionPlotter.java b/jsprit-analysis/src/main/java/analysis/SolutionPlotter.java index 69ccd03f..945f66c6 100644 --- a/jsprit-analysis/src/main/java/analysis/SolutionPlotter.java +++ b/jsprit-analysis/src/main/java/analysis/SolutionPlotter.java @@ -20,7 +20,9 @@ ******************************************************************************/ package analysis; +import java.awt.BasicStroke; import java.awt.Color; +import java.awt.geom.Ellipse2D; import java.io.File; import java.io.IOException; import java.util.Collection; @@ -32,16 +34,22 @@ import java.util.Set; import org.apache.log4j.Logger; import org.jfree.chart.ChartUtilities; import org.jfree.chart.JFreeChart; +import org.jfree.chart.annotations.XYShapeAnnotation; import org.jfree.chart.axis.NumberAxis; +import org.jfree.chart.labels.XYItemLabelGenerator; import org.jfree.chart.plot.XYPlot; import org.jfree.chart.renderer.xy.XYItemRenderer; import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer; +import org.jfree.data.xy.XYDataItem; +import org.jfree.data.xy.XYDataset; import org.jfree.data.xy.XYSeries; import org.jfree.data.xy.XYSeriesCollection; import util.Coordinate; import util.Locations; +import basics.Delivery; import basics.Job; +import basics.Pickup; import basics.Service; import basics.VehicleRoutingProblem; import basics.VehicleRoutingProblemSolution; @@ -80,13 +88,14 @@ public class SolutionPlotter { public static void plotVrpAsPNG(VehicleRoutingProblem vrp, String pngFile, String title){ log.info("plot routes to " + pngFile); XYSeriesCollection problem; + Map labels = new HashMap(); try { - problem = makeVrpSeries(vrp); + problem = makeVrpSeries(vrp, labels); } catch (NoLocationFoundException e) { log.warn("cannot plot vrp, since coord is missing"); return; } - XYPlot plot = createPlot(problem); + XYPlot plot = createPlot(problem, labels); JFreeChart chart = new JFreeChart(title, plot); save(chart,pngFile); } @@ -103,14 +112,15 @@ public class SolutionPlotter { public static void plotRoutesAsPNG(Collection routes, Locations locations, String pngFile, String title) { log.info("plot routes to " + pngFile); XYSeriesCollection problem; + Map labels = new HashMap(); try { - problem = makeVrpSeries(routes); + problem = makeVrpSeries(routes, labels); } catch (NoLocationFoundException e) { log.warn("cannot plot vrp, since coord is missing"); return; } XYSeriesCollection solutionColl = makeSolutionSeries(routes,locations); - XYPlot plot = createPlot(problem, solutionColl); + XYPlot plot = createPlot(problem, solutionColl, labels); JFreeChart chart = new JFreeChart(title, plot); save(chart,pngFile); } @@ -130,14 +140,15 @@ public class SolutionPlotter { log.info("plot solution to " + pngFile); XYSeriesCollection problem; XYSeriesCollection solutionColl; + Map labels = new HashMap(); try { - problem = makeVrpSeries(vrp); + problem = makeVrpSeries(vrp, labels); solutionColl = makeSolutionSeries(vrp, solution); } catch (NoLocationFoundException e) { log.warn("cannot plot vrp, since coord is missing"); return; } - XYPlot plot = createPlot(problem, solutionColl); + XYPlot plot = createPlot(problem, solutionColl, labels); JFreeChart chart = new JFreeChart(title, plot); save(chart,pngFile); @@ -145,13 +156,23 @@ public class SolutionPlotter { - private static XYPlot createPlot(XYSeriesCollection problem) { + private static XYPlot createPlot(final XYSeriesCollection problem, final Map labels) { XYPlot plot = new XYPlot(); plot.setBackgroundPaint(Color.LIGHT_GRAY); plot.setRangeGridlinePaint(Color.WHITE); plot.setDomainGridlinePaint(Color.WHITE); XYItemRenderer problemRenderer = new XYLineAndShapeRenderer(false, true); // Shapes only +// problemRenderer.setBaseItemLabelGenerator(new XYItemLabelGenerator() { +// +// @Override +// public String generateLabel(XYDataset arg0, int arg1, int arg2) { +// XYDataItem item = problem.getSeries(arg1).getDataItem(arg2); +// return labels.get(item); +// } +// }); + problemRenderer.setBaseItemLabelsVisible(true); + problemRenderer.setBaseItemLabelPaint(Color.BLACK); NumberAxis xAxis = new NumberAxis(); xAxis.setRangeWithMargins(problem.getDomainBounds(true)); @@ -167,13 +188,24 @@ public class SolutionPlotter { return plot; } - private static XYPlot createPlot(XYSeriesCollection problem, XYSeriesCollection solutionColl) { + private static XYPlot createPlot(final XYSeriesCollection problem, XYSeriesCollection solutionColl, final Map labels) { XYPlot plot = new XYPlot(); plot.setBackgroundPaint(Color.LIGHT_GRAY); plot.setRangeGridlinePaint(Color.WHITE); plot.setDomainGridlinePaint(Color.WHITE); XYItemRenderer problemRenderer = new XYLineAndShapeRenderer(false, true); // Shapes only +// problemRenderer.setBaseItemLabelGenerator(new XYItemLabelGenerator() { +// +// @Override +// public String generateLabel(XYDataset arg0, int arg1, int arg2) { +// XYDataItem item = problem.getSeries(arg1).getDataItem(arg2); +// return labels.get(item); +// } +// }); + problemRenderer.setBaseItemLabelsVisible(true); + problemRenderer.setBaseItemLabelPaint(Color.BLACK); + NumberAxis xAxis = new NumberAxis(); xAxis.setRangeWithMargins(problem.getDomainBounds(true)); @@ -186,7 +218,13 @@ public class SolutionPlotter { plot.setDomainAxis(0, xAxis); plot.setRangeAxis(0, yAxis); + XYItemRenderer solutionRenderer = new XYLineAndShapeRenderer(true, false); // Lines only +// for(int i=0;i vehicles, Collection services) throws NoLocationFoundException{ + private static XYSeriesCollection makeVrpSeries(Collection vehicles, Collection services, Map labels) throws NoLocationFoundException{ XYSeriesCollection coll = new XYSeriesCollection(); XYSeries vehicleSeries = new XYSeries("depot", false, true); for(Vehicle v : vehicles){ @@ -264,28 +302,54 @@ public class SolutionPlotter { } coll.addSeries(vehicleSeries); - XYSeries jobSeries = new XYSeries("service", false, true); + XYSeries serviceSeries = new XYSeries("service", false, true); + XYSeries pickupSeries = new XYSeries("pickup", false, true); + XYSeries deliverySeries = new XYSeries("delivery", false, true); for(Job job : services){ - Service service = (Service)job; - Coordinate coord = service.getCoord(); - jobSeries.add(coord.getX(), coord.getY()); + if(job instanceof Pickup){ + Pickup service = (Pickup)job; + Coordinate coord = service.getCoord(); + XYDataItem dataItem = new XYDataItem(coord.getX(), coord.getY()); + pickupSeries.add(dataItem); + labels.put(dataItem, String.valueOf(service.getCapacityDemand())); + } + else if(job instanceof Delivery){ + Delivery service = (Delivery)job; + Coordinate coord = service.getCoord(); + XYDataItem dataItem = new XYDataItem(coord.getX(), coord.getY()); + deliverySeries.add(dataItem); + labels.put(dataItem, String.valueOf(service.getCapacityDemand())); + } + else if(job instanceof Service){ + Service service = (Service)job; + Coordinate coord = service.getCoord(); + XYDataItem dataItem = new XYDataItem(coord.getX(), coord.getY()); + serviceSeries.add(dataItem); + labels.put(dataItem, String.valueOf(service.getCapacityDemand())); + } + else{ + throw new IllegalStateException("job instanceof " + job.getClass().toString() + ". this is not supported."); + } + } - coll.addSeries(jobSeries); + if(!serviceSeries.isEmpty()) coll.addSeries(serviceSeries); + if(!pickupSeries.isEmpty()) coll.addSeries(pickupSeries); + if(!deliverySeries.isEmpty()) coll.addSeries(deliverySeries); return coll; } - private static XYSeriesCollection makeVrpSeries(Collection routes) throws NoLocationFoundException{ + private static XYSeriesCollection makeVrpSeries(Collection routes, Map labels) throws NoLocationFoundException{ Set vehicles = new HashSet(); Set jobs = new HashSet(); for(VehicleRoute route : routes){ vehicles.add(route.getVehicle()); jobs.addAll(route.getTourActivities().getJobs()); } - return makeVrpSeries(vehicles, jobs); + return makeVrpSeries(vehicles, jobs, labels); } - private static XYSeriesCollection makeVrpSeries(VehicleRoutingProblem vrp) throws NoLocationFoundException{ - return makeVrpSeries(vrp.getVehicles(), vrp.getJobs().values()); + private static XYSeriesCollection makeVrpSeries(VehicleRoutingProblem vrp, Map labels) throws NoLocationFoundException{ + return makeVrpSeries(vrp.getVehicles(), vrp.getJobs().values(), labels); } private static Locations retrieveLocations(VehicleRoutingProblem vrp) throws NoLocationFoundException { diff --git a/jsprit-core/pom.xml b/jsprit-core/pom.xml index a7f130ff..39ad5986 100644 --- a/jsprit-core/pom.xml +++ b/jsprit-core/pom.xml @@ -52,6 +52,8 @@ 2.4.0 + + diff --git a/jsprit-core/src/main/java/algorithms/BackwardInTimeListeners.java b/jsprit-core/src/main/java/algorithms/BackwardInTimeListeners.java index effaa07a..1fba0946 100644 --- a/jsprit-core/src/main/java/algorithms/BackwardInTimeListeners.java +++ b/jsprit-core/src/main/java/algorithms/BackwardInTimeListeners.java @@ -1,3 +1,23 @@ +/******************************************************************************* + * 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; @@ -49,4 +69,8 @@ class BackwardInTimeListeners { for(BackwardInTimeListener l : listeners){ l.end(start, latestDepartureTime); } } + public boolean isEmpty() { + return listeners.isEmpty(); + } + } diff --git a/jsprit-core/src/main/java/algorithms/CalcUtils.java b/jsprit-core/src/main/java/algorithms/CalcUtils.java index c295881f..67da5ffc 100644 --- a/jsprit-core/src/main/java/algorithms/CalcUtils.java +++ b/jsprit-core/src/main/java/algorithms/CalcUtils.java @@ -1,14 +1,38 @@ +/******************************************************************************* + * 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 basics.route.TourActivity; class CalcUtils { - static double getStartTimeAtAct(double startTimeAtPrevAct, double tpTime_prevAct_nextAct, TourActivity nextAct){ - return Math.max(startTimeAtPrevAct + tpTime_prevAct_nextAct, nextAct.getTheoreticalEarliestOperationStartTime()) + nextAct.getOperationTime(); - } - static double getStartTimeAtAct(double nextActArrTime, TourActivity nextAct){ - return Math.max(nextActArrTime, nextAct.getTheoreticalEarliestOperationStartTime()) + nextAct.getOperationTime(); + /** + * Calculates actEndTime assuming that activity can at earliest start at act.getTheoreticalEarliestOperationStartTime(). + * + * @param actArrTime + * @param act + * @return + */ + static double getActivityEndTime(double actArrTime, TourActivity act){ + return Math.max(actArrTime, act.getTheoreticalEarliestOperationStartTime()) + act.getOperationTime(); } } diff --git a/jsprit-core/src/main/java/algorithms/CalculatesServiceInsertion.java b/jsprit-core/src/main/java/algorithms/CalculatesServiceInsertion.java index bfa09606..a792fb53 100644 --- a/jsprit-core/src/main/java/algorithms/CalculatesServiceInsertion.java +++ b/jsprit-core/src/main/java/algorithms/CalculatesServiceInsertion.java @@ -25,6 +25,8 @@ import basics.route.End; import basics.route.ServiceActivity; import basics.route.Start; import basics.route.TourActivity; +import basics.route.TourActivityFactory; +import basics.route.DefaultTourActivityFactory; import basics.route.Vehicle; import basics.route.VehicleImpl.NoVehicle; import basics.route.VehicleRoute; @@ -49,6 +51,8 @@ final class CalculatesServiceInsertion implements JobInsertionCalculator{ private VehicleRoutingTransportCosts transportCosts; + private TourActivityFactory activityFactory; + public void setNeighborhood(Neighborhood neighborhood) { this.neighborhood = neighborhood; logger.info("initialise neighborhood " + neighborhood); @@ -59,6 +63,7 @@ final class CalculatesServiceInsertion implements JobInsertionCalculator{ this.marginalCalculus = marginalsCalculus; this.hardRouteLevelConstraint = hardRouteLevelConstraint; this.transportCosts = routingCosts; + activityFactory = new DefaultTourActivityFactory(); logger.info("initialise " + this); } @@ -86,7 +91,8 @@ final class CalculatesServiceInsertion implements JobInsertionCalculator{ Marginals bestMarginals = null; Service service = (Service)jobToInsert; int insertionIndex = InsertionData.NO_INDEX; - TourActivity deliveryAct2Insert = ServiceActivity.newInstance(service); + + TourActivity deliveryAct2Insert = activityFactory.createActivity(service); Start start = Start.newInstance(newVehicle.getLocationId(), newVehicle.getEarliestDeparture(), newVehicle.getLatestArrival()); start.setEndTime(newVehicleDepartureTime); @@ -96,11 +102,9 @@ final class CalculatesServiceInsertion implements JobInsertionCalculator{ TourActivity prevAct = start; double prevActStartTime = newVehicleDepartureTime; int actIndex = 0; - +// logger.info("start"); for(TourActivity nextAct : currentRoute.getTourActivities().getActivities()){ - if(deliveryAct2Insert.getTheoreticalLatestOperationStartTime() < prevAct.getTheoreticalEarliestOperationStartTime()){ - break; - } +// logger.info("prevActStartTime="+prevActStartTime); if(neighborhood.areNeighbors(deliveryAct2Insert.getLocationId(), prevAct.getLocationId()) && neighborhood.areNeighbors(deliveryAct2Insert.getLocationId(), nextAct.getLocationId())){ Marginals mc = calculate(insertionContext, prevAct, nextAct, deliveryAct2Insert, prevActStartTime); if(mc != null){ @@ -111,10 +115,16 @@ final class CalculatesServiceInsertion implements JobInsertionCalculator{ } } } - prevActStartTime = CalcUtils.getStartTimeAtAct(prevActStartTime, transportCosts.getTransportTime(prevAct.getLocationId(), nextAct.getLocationId(), prevActStartTime, newDriver, newVehicle), nextAct); + + double nextActArrTime = prevActStartTime + transportCosts.getTransportTime(prevAct.getLocationId(), nextAct.getLocationId(), prevActStartTime, newDriver, newVehicle); + double nextActEndTime = CalcUtils.getActivityEndTime(nextActArrTime, nextAct); + + prevActStartTime = nextActEndTime; + prevAct = nextAct; actIndex++; } +// logger.info("prevActStartTime="+prevActStartTime); End nextAct = end; if(neighborhood.areNeighbors(deliveryAct2Insert.getLocationId(), prevAct.getLocationId()) && neighborhood.areNeighbors(deliveryAct2Insert.getLocationId(), nextAct.getLocationId())){ Marginals mc = calculate(insertionContext, prevAct, nextAct, deliveryAct2Insert, prevActStartTime); diff --git a/jsprit-core/src/main/java/algorithms/CalculatesServiceInsertionOnRouteLevel.java b/jsprit-core/src/main/java/algorithms/CalculatesServiceInsertionOnRouteLevel.java index 1d0d900c..fc255536 100644 --- a/jsprit-core/src/main/java/algorithms/CalculatesServiceInsertionOnRouteLevel.java +++ b/jsprit-core/src/main/java/algorithms/CalculatesServiceInsertionOnRouteLevel.java @@ -23,21 +23,21 @@ import java.util.PriorityQueue; import org.apache.log4j.Logger; import util.Neighborhood; - -import algorithms.RouteStates.ActivityState; import basics.Job; import basics.Service; import basics.costs.VehicleRoutingActivityCosts; import basics.costs.VehicleRoutingTransportCosts; +import basics.route.DefaultTourActivityFactory; import basics.route.Driver; import basics.route.End; import basics.route.ServiceActivity; import basics.route.Start; import basics.route.TourActivities; import basics.route.TourActivity; +import basics.route.TourActivityFactory; import basics.route.Vehicle; -import basics.route.VehicleRoute; import basics.route.VehicleImpl.NoVehicle; +import basics.route.VehicleRoute; @@ -51,6 +51,8 @@ final class CalculatesServiceInsertionOnRouteLevel implements JobInsertionCalcul private AuxilliaryCostCalculator auxilliaryPathCostCalculator; + private TourActivityFactory tourActivityFactory = new DefaultTourActivityFactory(); + private StateManager states; private int nuOfActsForwardLooking = 0; @@ -70,7 +72,9 @@ final class CalculatesServiceInsertionOnRouteLevel implements JobInsertionCalcul }; - + public void setTourActivityFactory(TourActivityFactory tourActivityFactory){ + this.tourActivityFactory=tourActivityFactory; + } public void setNeighborhood(Neighborhood neighborhood) { this.neighborhood = neighborhood; @@ -142,7 +146,7 @@ final class CalculatesServiceInsertionOnRouteLevel implements JobInsertionCalcul /** * some inis */ - TourActivity serviceAct2Insert = ServiceActivity.newInstance(service); + TourActivity serviceAct2Insert = tourActivityFactory.createActivity(service); int best_insertion_index = InsertionData.NO_INDEX; initialiseStartAndEnd(newVehicle, newVehicleDepartureTime); diff --git a/jsprit-core/src/main/java/algorithms/CalculatorBuilder.java b/jsprit-core/src/main/java/algorithms/CalculatorBuilder.java index 6ab8e4c0..0a3898a2 100644 --- a/jsprit-core/src/main/java/algorithms/CalculatorBuilder.java +++ b/jsprit-core/src/main/java/algorithms/CalculatorBuilder.java @@ -23,6 +23,7 @@ package algorithms; import java.util.ArrayList; import java.util.List; +import algorithms.HardConstraints.ConstraintManager; import basics.VehicleRoutingProblem; import basics.algo.InsertionListener; import basics.algo.VehicleRoutingAlgorithmListeners.PrioritizedVRAListener; @@ -81,6 +82,8 @@ class CalculatorBuilder { private double timeSlice; private int neighbors; + + private ConstraintManager constraintManager; /** * Constructs the builder. @@ -213,9 +216,11 @@ class CalculatorBuilder { } } - private CalculatorPlusListeners createStandardLocal(VehicleRoutingProblem vrp, StateManager activityStates2){ - MarginalsCalculus defaultCalc = new MarginalsCalculusTriangleInequality(vrp.getTransportCosts(), vrp.getActivityCosts(), new HardConstraints.HardTimeWindowConstraint(activityStates2) ); - JobInsertionCalculator standardServiceInsertion = new CalculatesServiceInsertion(vrp.getTransportCosts(), defaultCalc, new HardConstraints.HardLoadConstraint(activityStates2)); + private CalculatorPlusListeners createStandardLocal(VehicleRoutingProblem vrp, StateManager statesManager){ + if(constraintManager == null) throw new IllegalStateException("constraint-manager is null"); + + MarginalsCalculus defaultCalc = new MarginalsCalculusTriangleInequality(vrp.getTransportCosts(), vrp.getActivityCosts(), constraintManager); + JobInsertionCalculator standardServiceInsertion = new CalculatesServiceInsertion(vrp.getTransportCosts(), defaultCalc, constraintManager); ((CalculatesServiceInsertion) standardServiceInsertion).setNeighborhood(vrp.getNeighborhood()); CalculatorPlusListeners calcPlusListeners = new CalculatorPlusListeners(standardServiceInsertion); @@ -246,6 +251,10 @@ class CalculatorBuilder { return new CalculatesVehTypeDepServiceInsertion(fleetManager, baseCalc); } + public void setConstraintManager(ConstraintManager constraintManager) { + this.constraintManager = constraintManager; + } + } diff --git a/jsprit-core/src/main/java/algorithms/FindCheaperVehicleAlgo.java b/jsprit-core/src/main/java/algorithms/FindCheaperVehicleAlgo.java index 680a2525..0304643e 100644 --- a/jsprit-core/src/main/java/algorithms/FindCheaperVehicleAlgo.java +++ b/jsprit-core/src/main/java/algorithms/FindCheaperVehicleAlgo.java @@ -21,17 +21,15 @@ package algorithms; import java.util.ArrayList; -import java.util.Collection; import java.util.List; import org.apache.log4j.Logger; -import algorithms.VehicleFleetManager.TypeKey; import basics.route.TourActivities; import basics.route.TourActivity; import basics.route.Vehicle; -import basics.route.VehicleRoute; import basics.route.VehicleImpl.NoVehicle; +import basics.route.VehicleRoute; @@ -47,13 +45,13 @@ final class FindCheaperVehicleAlgo { private double weightFixCosts = 1.0; - private RouteStates states; + private StateManager states; public void setWeightFixCosts(double weightFixCosts) { this.weightFixCosts = weightFixCosts; } - public void setStates(RouteStates states) { + public void setStates(StateManager states) { this.states = states; } @@ -85,11 +83,11 @@ final class FindCheaperVehicleAlgo { if(vehicle.getType().getTypeId().equals(vehicleRoute.getVehicle().getType().getTypeId())){ continue; } - if(states.getRouteState(vehicleRoute).getLoad() <= vehicle.getCapacity()){ + if(states.getRouteState(vehicleRoute,StateTypes.LOAD).toDouble() <= vehicle.getCapacity()){ double fixCostSaving = vehicleRoute.getVehicle().getType().getVehicleCostParams().fix - vehicle.getType().getVehicleCostParams().fix; double departureTime = vehicleRoute.getStart().getEndTime(); double newCost = auxilliaryCostCalculator.costOfPath(path, departureTime, vehicleRoute.getDriver(), vehicle); - double varCostSaving = states.getRouteState(vehicleRoute).getCosts() - newCost; + double varCostSaving = states.getRouteState(vehicleRoute, StateTypes.COSTS).toDouble() - newCost; double totalCostSaving = varCostSaving + weightFixCosts*fixCostSaving; if(totalCostSaving > bestSaving){ bestSaving = totalCostSaving; diff --git a/jsprit-core/src/main/java/algorithms/ForwardInTimeListeners.java b/jsprit-core/src/main/java/algorithms/ForwardInTimeListeners.java index 0f8b68d6..2d544b31 100644 --- a/jsprit-core/src/main/java/algorithms/ForwardInTimeListeners.java +++ b/jsprit-core/src/main/java/algorithms/ForwardInTimeListeners.java @@ -1,3 +1,23 @@ +/******************************************************************************* + * 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; @@ -38,4 +58,8 @@ class ForwardInTimeListeners { for(ForwardInTimeListener l : listeners){ l.end(end, arrivalTime); } } + public boolean isEmpty() { + return listeners.isEmpty(); + } + } diff --git a/jsprit-core/src/main/java/algorithms/Gendreau.java b/jsprit-core/src/main/java/algorithms/Gendreau.java index 70125dc4..183b9a1e 100644 --- a/jsprit-core/src/main/java/algorithms/Gendreau.java +++ b/jsprit-core/src/main/java/algorithms/Gendreau.java @@ -32,9 +32,11 @@ import java.util.Set; import org.apache.log4j.Logger; import util.RandomNumberGeneration; +import algorithms.RuinStrategy.RuinListener; import basics.Job; import basics.VehicleRoutingProblem; import basics.VehicleRoutingProblemSolution; +import basics.algo.InsertionListener; import basics.algo.SearchStrategyModule; import basics.algo.SearchStrategyModuleListener; import basics.route.TourActivity; @@ -53,8 +55,6 @@ final class Gendreau implements SearchStrategyModule{ private final InsertionStrategy insertionStrategy; - private final Inserter inserter; - private VehicleFleetManager fleetManager; private Random random = RandomNumberGeneration.getRandom(); @@ -71,7 +71,7 @@ final class Gendreau implements SearchStrategyModule{ super(); InsertionListeners insertionListeners = new InsertionListeners(); insertionListeners.addAllListeners(insertionStrategy.getListeners()); - inserter = new Inserter(insertionListeners); + new Inserter(insertionListeners); this.ruin = ruin; this.vrp = vrp; this.insertionStrategy = insertionStrategy; @@ -205,7 +205,18 @@ final class Gendreau implements SearchStrategyModule{ @Override public void addModuleListener(SearchStrategyModuleListener moduleListener) { - // TODO Auto-generated method stub + if(moduleListener instanceof InsertionListener){ + InsertionListener iListener = (InsertionListener) moduleListener; + if(!insertionStrategy.getListeners().contains(iListener)){ + insertionStrategy.addListener(iListener); + } + } + if(moduleListener instanceof RuinListener){ + RuinListener rListener = (RuinListener) moduleListener; + if(!ruin.getListeners().contains(rListener)){ + ruin.addListener(rListener); + } + } } } diff --git a/jsprit-core/src/main/java/algorithms/HardConstraints.java b/jsprit-core/src/main/java/algorithms/HardConstraints.java index 28caccfb..ec2533b9 100644 --- a/jsprit-core/src/main/java/algorithms/HardConstraints.java +++ b/jsprit-core/src/main/java/algorithms/HardConstraints.java @@ -1,8 +1,54 @@ +/******************************************************************************* + * 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 org.apache.log4j.Logger; + +import basics.Delivery; +import basics.Pickup; import basics.Service; +import basics.costs.VehicleRoutingTransportCosts; +import basics.route.DeliveryActivity; +import basics.route.PickupActivity; +import basics.route.ServiceActivity; +import basics.route.Start; import basics.route.TourActivity; +/** + * collection of hard constrainters bot at activity and at route level. + * + *

HardPickupAndDeliveryLoadConstraint requires LOAD_AT_DEPOT and LOAD (i.e. load at end) at route-level + * + *

HardTimeWindowConstraint requires LATEST_OPERATION_START_TIME + * + *

HardPickupAndDeliveryConstraint requires LOAD_AT_DEPOT and LOAD at route-level and FUTURE_PICKS and PAST_DELIVIERS on activity-level + * + *

HardPickupAndDeliveryBackhaulConstraint requires LOAD_AT_DEPOT and LOAD at route-level and FUTURE_PICKS and PAST_DELIVIERS on activity-level + * + * @author stefan + * + */ class HardConstraints { interface HardRouteLevelConstraint { @@ -13,10 +59,76 @@ class HardConstraints { interface HardActivityLevelConstraint { - public boolean fulfilled(InsertionContext iFacts, TourActivity act, double arrTime); + public boolean fulfilled(InsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime); } + static class HardRouteLevelConstraintManager implements HardRouteLevelConstraint { + + private Collection hardConstraints = new ArrayList(); + + public void addConstraint(HardRouteLevelConstraint constraint){ + hardConstraints.add(constraint); + } + + @Override + public boolean fulfilled(InsertionContext insertionContext) { + for(HardRouteLevelConstraint constraint : hardConstraints){ + if(!constraint.fulfilled(insertionContext)){ + return false; + } + } + return true; + } + + } + + static class ConstraintManager implements HardActivityLevelConstraint, HardRouteLevelConstraint{ + + private HardActivityLevelConstraintManager actLevelConstraintManager = new HardActivityLevelConstraintManager(); + + private HardRouteLevelConstraintManager routeLevelConstraintManager = new HardRouteLevelConstraintManager(); + + public void addConstraint(HardActivityLevelConstraint actLevelConstraint){ + actLevelConstraintManager.addConstraint(actLevelConstraint); + } + + public void addConstraint(HardRouteLevelConstraint routeLevelConstraint){ + routeLevelConstraintManager.addConstraint(routeLevelConstraint); + } + + @Override + public boolean fulfilled(InsertionContext insertionContext) { + return routeLevelConstraintManager.fulfilled(insertionContext); + } + + @Override + public boolean fulfilled(InsertionContext iFacts, TourActivity prevAct,TourActivity newAct, TourActivity nextAct, double prevActDepTime) { + return actLevelConstraintManager.fulfilled(iFacts, prevAct, newAct, nextAct, prevActDepTime); + } + + } + + static class HardActivityLevelConstraintManager implements HardActivityLevelConstraint { + + private Collection hardConstraints = new ArrayList(); + + public void addConstraint(HardActivityLevelConstraint constraint){ + hardConstraints.add(constraint); + } + + @Override + public boolean fulfilled(InsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) { + for(HardActivityLevelConstraint constraint : hardConstraints){ + if(!constraint.fulfilled(iFacts, prevAct, newAct, nextAct, prevActDepTime)){ + return false; + } + } + return true; + } + + } + static class HardLoadConstraint implements HardRouteLevelConstraint{ private StateManager states; @@ -37,23 +149,163 @@ class HardConstraints { } } - static class HardTimeWindowConstraint implements HardActivityLevelConstraint { + /** + * lsjdfjsdlfjsa + * + * @author stefan + * + */ + static class HardPickupAndDeliveryLoadConstraint implements HardRouteLevelConstraint { - private StateManager states; + private StateManager stateManager; - public HardTimeWindowConstraint(StateManager states) { + public HardPickupAndDeliveryLoadConstraint(StateManager stateManager) { super(); - this.states = states; + this.stateManager = stateManager; } @Override - public boolean fulfilled(InsertionContext iFacts, TourActivity act, double arrTime) { - if(arrTime > states.getActivityState(act, StateTypes.LATEST_OPERATION_START_TIME).toDouble()){ - return false; + public boolean fulfilled(InsertionContext insertionContext) { + if(insertionContext.getJob() instanceof Delivery){ + int loadAtDepot = (int) stateManager.getRouteState(insertionContext.getRoute(), StateTypes.LOAD_AT_DEPOT).toDouble(); + if(loadAtDepot + insertionContext.getJob().getCapacityDemand() > insertionContext.getNewVehicle().getCapacity()){ + return false; + } + } + else if(insertionContext.getJob() instanceof Pickup || insertionContext.getJob() instanceof Service){ + int loadAtEnd = (int) stateManager.getRouteState(insertionContext.getRoute(), StateTypes.LOAD).toDouble(); + if(loadAtEnd + insertionContext.getJob().getCapacityDemand() > insertionContext.getNewVehicle().getCapacity()){ + return false; + } } return true; } - + } + + /** + * ljsljslfjs + * @author stefan + * + */ + public static class HardTimeWindowActivityLevelConstraint implements HardActivityLevelConstraint { + + private static Logger log = Logger.getLogger(HardTimeWindowActivityLevelConstraint.class); + + private StateManager states; + + private VehicleRoutingTransportCosts routingCosts; + + public HardTimeWindowActivityLevelConstraint(StateManager states, VehicleRoutingTransportCosts routingCosts) { + super(); + this.states = states; + this.routingCosts = routingCosts; + } + + @Override + public boolean fulfilled(InsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) { +// log.info("check insertion of " + newAct + " between " + prevAct + " and " + nextAct + ". prevActDepTime=" + prevActDepTime); + double arrTimeAtNewAct = prevActDepTime + routingCosts.getTransportTime(prevAct.getLocationId(), newAct.getLocationId(), prevActDepTime, iFacts.getNewDriver(), iFacts.getNewVehicle()); + double latestArrTimeAtNewAct = states.getActivityState(newAct, StateTypes.LATEST_OPERATION_START_TIME).toDouble(); + if(arrTimeAtNewAct > latestArrTimeAtNewAct){ + return false; + } +// log.info(newAct + " arrTime=" + arrTimeAtNewAct); + double endTimeAtNewAct = CalcUtils.getActivityEndTime(arrTimeAtNewAct, newAct); + double arrTimeAtNextAct = endTimeAtNewAct + routingCosts.getTransportTime(newAct.getLocationId(), nextAct.getLocationId(), endTimeAtNewAct, iFacts.getNewDriver(), iFacts.getNewVehicle()); + double latestArrTimeAtNextAct = states.getActivityState(nextAct, StateTypes.LATEST_OPERATION_START_TIME).toDouble(); + if(arrTimeAtNextAct > latestArrTimeAtNextAct){ + return false; + } +// log.info(nextAct + " arrTime=" + arrTimeAtNextAct); + return true; + } + } + + static class HardPickupAndDeliveryActivityLevelConstraint implements HardActivityLevelConstraint { + + private StateManager stateManager; + + public HardPickupAndDeliveryActivityLevelConstraint(StateManager stateManager) { + super(); + this.stateManager = stateManager; + } + + @Override + public boolean fulfilled(InsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) { + int loadAtPrevAct; + int futurePicks; + int pastDeliveries; + if(prevAct instanceof Start){ + loadAtPrevAct = (int)stateManager.getRouteState(iFacts.getRoute(), StateTypes.LOAD_AT_DEPOT).toDouble(); + futurePicks = (int)stateManager.getRouteState(iFacts.getRoute(), StateTypes.LOAD).toDouble(); + pastDeliveries = 0; + } + else{ + loadAtPrevAct = (int) stateManager.getActivityState(prevAct, StateTypes.LOAD).toDouble(); + futurePicks = (int) stateManager.getActivityState(prevAct, StateTypes.FUTURE_PICKS).toDouble(); + pastDeliveries = (int) stateManager.getActivityState(prevAct, StateTypes.PAST_DELIVERIES).toDouble(); + } + if(newAct instanceof PickupActivity || newAct instanceof ServiceActivity){ + if(loadAtPrevAct + newAct.getCapacityDemand() + futurePicks > iFacts.getNewVehicle().getCapacity()){ + return false; + } + } + if(newAct instanceof DeliveryActivity){ + if(loadAtPrevAct + Math.abs(newAct.getCapacityDemand()) + pastDeliveries > iFacts.getNewVehicle().getCapacity()){ + return false; + } + + } + return true; + } + + } + + static class HardPickupAndDeliveryBackhaulActivityLevelConstraint implements HardActivityLevelConstraint { + + private StateManager stateManager; + + public HardPickupAndDeliveryBackhaulActivityLevelConstraint(StateManager stateManager) { + super(); + this.stateManager = stateManager; + } + + @Override + public boolean fulfilled(InsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) { + if(newAct instanceof PickupActivity && nextAct instanceof DeliveryActivity){ return false; } + if(newAct instanceof ServiceActivity && nextAct instanceof DeliveryActivity){ return false; } + if(newAct instanceof DeliveryActivity && prevAct instanceof PickupActivity){ return false; } + if(newAct instanceof DeliveryActivity && prevAct instanceof ServiceActivity){ return false; } + int loadAtPrevAct; + int futurePicks; + int pastDeliveries; + if(prevAct instanceof Start){ + loadAtPrevAct = (int)stateManager.getRouteState(iFacts.getRoute(), StateTypes.LOAD_AT_DEPOT).toDouble(); + futurePicks = (int)stateManager.getRouteState(iFacts.getRoute(), StateTypes.LOAD).toDouble(); + pastDeliveries = 0; + } + else{ + loadAtPrevAct = (int) stateManager.getActivityState(prevAct, StateTypes.LOAD).toDouble(); + futurePicks = (int) stateManager.getActivityState(prevAct, StateTypes.FUTURE_PICKS).toDouble(); + pastDeliveries = (int) stateManager.getActivityState(prevAct, StateTypes.PAST_DELIVERIES).toDouble(); + } + if(newAct instanceof PickupActivity || newAct instanceof ServiceActivity){ + if(loadAtPrevAct + newAct.getCapacityDemand() + futurePicks > iFacts.getNewVehicle().getCapacity()){ + return false; + } + } + if(newAct instanceof DeliveryActivity){ + if(loadAtPrevAct + Math.abs(newAct.getCapacityDemand()) + pastDeliveries > iFacts.getNewVehicle().getCapacity()){ + return false; + } + + } + return true; + } + + } + + } diff --git a/jsprit-core/src/main/java/algorithms/Inserter.java b/jsprit-core/src/main/java/algorithms/Inserter.java index 24845c01..09b7d116 100644 --- a/jsprit-core/src/main/java/algorithms/Inserter.java +++ b/jsprit-core/src/main/java/algorithms/Inserter.java @@ -1,17 +1,42 @@ +/******************************************************************************* + * 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 algorithms.InsertionData.NoInsertionFound; import basics.Job; import basics.Service; import basics.route.ServiceActivity; +import basics.route.TourActivityFactory; +import basics.route.DefaultTourActivityFactory; import basics.route.VehicleRoute; class Inserter { private InsertionListeners insertionListeners; + private TourActivityFactory activityFactory; + public Inserter(InsertionListeners insertionListeners) { this.insertionListeners = insertionListeners; + activityFactory = new DefaultTourActivityFactory(); } public void insertJob(Job job, InsertionData insertionData, VehicleRoute vehicleRoute){ @@ -25,7 +50,7 @@ class Inserter { } // if(vehicleRoute.getDepartureTime() != vehicleRoute.g) if(job instanceof Service) { - vehicleRoute.getTourActivities().addActivity(insertionData.getDeliveryInsertionIndex(), ServiceActivity.newInstance((Service)job)); + vehicleRoute.getTourActivities().addActivity(insertionData.getDeliveryInsertionIndex(), activityFactory.createActivity((Service)job)); vehicleRoute.setDepartureTime(insertionData.getVehicleDepartureTime()); } else throw new IllegalStateException("neither service nor shipment. this is not supported."); diff --git a/jsprit-core/src/main/java/algorithms/InsertionContext.java b/jsprit-core/src/main/java/algorithms/InsertionContext.java index 245ac90a..8b3b2593 100644 --- a/jsprit-core/src/main/java/algorithms/InsertionContext.java +++ b/jsprit-core/src/main/java/algorithms/InsertionContext.java @@ -1,3 +1,23 @@ +/******************************************************************************* + * 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 basics.Job; diff --git a/jsprit-core/src/main/java/algorithms/InsertionFactory.java b/jsprit-core/src/main/java/algorithms/InsertionFactory.java index ed82df20..182efa0f 100644 --- a/jsprit-core/src/main/java/algorithms/InsertionFactory.java +++ b/jsprit-core/src/main/java/algorithms/InsertionFactory.java @@ -25,11 +25,11 @@ import java.util.List; import java.util.concurrent.ExecutorService; import org.apache.commons.configuration.HierarchicalConfiguration; -import org.apache.commons.configuration.XMLConfiguration; import org.apache.log4j.Logger; +import algorithms.HardConstraints.ConstraintManager; +import algorithms.StateUpdates.UpdateStates; import basics.VehicleRoutingProblem; -import basics.VehicleRoutingProblem.FleetComposition; import basics.algo.InsertionListener; import basics.algo.VehicleRoutingAlgorithmListeners.PrioritizedVRAListener; @@ -38,7 +38,7 @@ class InsertionFactory { private static Logger log = Logger.getLogger(InsertionFactory.class); public static InsertionStrategy createInsertion(VehicleRoutingProblem vrp, HierarchicalConfiguration config, - VehicleFleetManager vehicleFleetManager, StateManagerImpl routeStates, List algorithmListeners, ExecutorService executorService, int nuOfThreads){ + VehicleFleetManager vehicleFleetManager, StateManagerImpl routeStates, List algorithmListeners, ExecutorService executorService, int nuOfThreads, ConstraintManager constraintManager){ boolean concurrentInsertion = false; if(executorService != null) concurrentInsertion = true; if(config.containsKey("[@name]")){ @@ -54,6 +54,7 @@ class InsertionFactory { calcBuilder.setStates(routeStates); calcBuilder.setVehicleRoutingProblem(vrp); calcBuilder.setVehicleFleetManager(vehicleFleetManager); + calcBuilder.setConstraintManager(constraintManager); if(config.containsKey("level")){ String level = config.getString("level"); @@ -103,13 +104,13 @@ class InsertionFactory { // insertionStrategy = RegretInsertion.newInstance(routeAlgorithm); // } - insertionStrategy.addListener(new RemoveEmptyVehicles(vehicleFleetManager)); - insertionStrategy.addListener(new ResetAndIniFleetManager(vehicleFleetManager)); - insertionStrategy.addListener(new VehicleSwitched(vehicleFleetManager)); +// insertionStrategy.addListener(new RemoveEmptyVehicles(vehicleFleetManager)); +// insertionStrategy.addListener(new ResetAndIniFleetManager(vehicleFleetManager)); +// insertionStrategy.addListener(new VehicleSwitched(vehicleFleetManager)); // insertionStrategy.addListener(new UpdateLoadAtRouteLevel(routeStates)); - insertionStrategy.addListener(new UpdateStates(routeStates, vrp.getTransportCosts(), vrp.getActivityCosts())); +// insertionStrategy.addListener(new UpdateStates(routeStates, vrp.getTransportCosts(), vrp.getActivityCosts())); for(InsertionListener l : insertionListeners) insertionStrategy.addListener(l); // insertionStrategy.addListener(new FindCheaperVehicle( // new FindCheaperVehicleAlgoNew(vehicleFleetManager, tourStateCalculator, auxCalculator))); diff --git a/jsprit-core/src/main/java/algorithms/InsertionListeners.java b/jsprit-core/src/main/java/algorithms/InsertionListeners.java index 72183a1c..cf026024 100644 --- a/jsprit-core/src/main/java/algorithms/InsertionListeners.java +++ b/jsprit-core/src/main/java/algorithms/InsertionListeners.java @@ -1,3 +1,23 @@ +/******************************************************************************* + * 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; diff --git a/jsprit-core/src/main/java/algorithms/IterateRouteBackwardInTime.java b/jsprit-core/src/main/java/algorithms/IterateRouteBackwardInTime.java index afafcde2..925b3322 100644 --- a/jsprit-core/src/main/java/algorithms/IterateRouteBackwardInTime.java +++ b/jsprit-core/src/main/java/algorithms/IterateRouteBackwardInTime.java @@ -46,6 +46,7 @@ class IterateRouteBackwardInTime implements VehicleRouteUpdater{ * */ public void iterate(VehicleRoute vehicleRoute) { + if(listeners.isEmpty()) return; listeners.start(vehicleRoute, vehicleRoute.getEnd(), vehicleRoute.getEnd().getTheoreticalLatestOperationStartTime()); Iterator reverseActIter = vehicleRoute.getTourActivities().reverseActivityIterator(); diff --git a/jsprit-core/src/main/java/algorithms/IterateRouteForwardInTime.java b/jsprit-core/src/main/java/algorithms/IterateRouteForwardInTime.java index 868a84d7..62c6062d 100644 --- a/jsprit-core/src/main/java/algorithms/IterateRouteForwardInTime.java +++ b/jsprit-core/src/main/java/algorithms/IterateRouteForwardInTime.java @@ -48,6 +48,7 @@ class IterateRouteForwardInTime implements VehicleRouteUpdater{ * */ public void iterate(VehicleRoute vehicleRoute) { + if(listeners.isEmpty()) return; listeners.start(vehicleRoute, vehicleRoute.getStart(), vehicleRoute.getStart().getEndTime()); Vehicle vehicle = vehicleRoute.getVehicle(); diff --git a/jsprit-core/src/main/java/algorithms/JobObserver.java b/jsprit-core/src/main/java/algorithms/JobObserver.java deleted file mode 100644 index 0643bb36..00000000 --- a/jsprit-core/src/main/java/algorithms/JobObserver.java +++ /dev/null @@ -1,156 +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.io.BufferedWriter; -import java.io.FileWriter; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; - -import algorithms.RouteStates.ActivityState; -import basics.algo.AlgorithmEndsListener; -import basics.algo.JobInsertedListener; -import basics.route.TourActivity; -import basics.route.VehicleRoute; -import basics.route.TourActivity.JobActivity; -import basics.Job; -import basics.Service; -import basics.VehicleRoutingProblem; -import basics.VehicleRoutingProblemSolution; - -class JobObserver implements JobInsertedListener, BeforeJobInsertionListener, AlgorithmEndsListener{ - - private static class Info { - double depTime; - double tourSize; - double insertionIndex; - double error; - public Info(double depTime, double tourSize, double insertionIndex, - double error) { - super(); - this.depTime = depTime; - this.tourSize = tourSize; - this.insertionIndex = insertionIndex; - this.error = error; - } - - } - - private String locationId = "70"; - - private double routeCostBefore; - private double estimatedMC; - private boolean beforeFirst = false; - - private RouteStates actStates; - - public void setActivityStates(RouteStates actStates){ - this.actStates = actStates; - } - - public ActivityState state(TourActivity act){ - return actStates.getState(act); - } - - - Collection infos = new ArrayList(); - - @Override - public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) { - if(job2insert instanceof Service){ - if(((Service) job2insert).getLocationId().equals(locationId)){ - double actualMC = inRoute.getCost()-routeCostBefore; - TourActivity act = getAct(job2insert,inRoute); - double error = (estimatedMC-actualMC); - 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)); -// System.out.println("[id=1][tourSize="+tourSize+"][index="+insertionIndex+ -// "][earliestDeparture="+depTime+ -// "][tourCostBefore="+routeCostBefore+"][routeCostAfter="+insertedIn.getCost()+"]" + -// "[estimated="+Math.round(estimatedMC)+"][actual="+Math.round(actualMC)+"][error(abs)="+error + -// "][errorPerNextCustomer="+ (error/(double)(tourSize-insertionIndex)) + "]"); - routeCostBefore = 0.0; - estimatedMC = 0.0; - if(!beforeFirst) throw new IllegalStateException("ähhh"); - beforeFirst = false; - } - } - } - - private TourActivity getAct(Job job2insert, VehicleRoute insertedIn) { - for(TourActivity act : insertedIn.getTourActivities().getActivities()){ - if(act instanceof JobActivity){ - if(((JobActivity) act).getJob().getId().equals(job2insert.getId())){ - return act; - } - } - } - return null; - } - - private int getIndexOf(Job job2insert, VehicleRoute insertedIn) { - int index=0; - for(TourActivity act : insertedIn.getTourActivities().getActivities()){ - if(act instanceof JobActivity){ - if(((JobActivity) act).getJob().getId().equals(job2insert.getId())){ - return index; - } - } - index++; - } - return -1; - } - - @Override - public void informBeforeJobInsertion(Job job, InsertionData data, VehicleRoute route) { - if(job instanceof Service){ - if(((Service) job).getLocationId().equals(locationId)){ -// System.out.println("[id=1][tourSize="+route.getTour().getActivities().size()+"][tourCost="+route.getCost()+"]" + -// "[estimatedMarginalInsertionCost="+data.getInsertionCost()+"]"); - routeCostBefore = route.getCost(); - estimatedMC = data.getInsertionCost(); - beforeFirst = true; - } - } - } - - @Override - public void informAlgorithmEnds(VehicleRoutingProblem problem, Collection solutions) { - try { - BufferedWriter writer = new BufferedWriter(new FileWriter("output/errorAna.txt")); - for(Info info : infos){ - writer.write(new StringBuilder().append(info.depTime).append(";").append(info.tourSize).append(";").append(info.insertionIndex).append(";") - .append(info.error).append("\n").toString()); - } - writer.close(); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - } - -} diff --git a/jsprit-core/src/main/java/algorithms/MarginalsCalculus.java b/jsprit-core/src/main/java/algorithms/MarginalsCalculus.java index d702de25..d17e9bfc 100644 --- a/jsprit-core/src/main/java/algorithms/MarginalsCalculus.java +++ b/jsprit-core/src/main/java/algorithms/MarginalsCalculus.java @@ -1,3 +1,23 @@ +/******************************************************************************* + * 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 basics.route.TourActivity; diff --git a/jsprit-core/src/main/java/algorithms/MarginalsCalculusTriangleInequality.java b/jsprit-core/src/main/java/algorithms/MarginalsCalculusTriangleInequality.java index aeb6d2e5..f4ab4005 100644 --- a/jsprit-core/src/main/java/algorithms/MarginalsCalculusTriangleInequality.java +++ b/jsprit-core/src/main/java/algorithms/MarginalsCalculusTriangleInequality.java @@ -1,3 +1,23 @@ +/******************************************************************************* + * 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 algorithms.HardConstraints.HardActivityLevelConstraint; @@ -21,16 +41,16 @@ class MarginalsCalculusTriangleInequality implements MarginalsCalculus{ @Override public Marginals calculate(InsertionContext iFacts, TourActivity prevAct, TourActivity nextAct, TourActivity newAct, double depTimeAtPrevAct) { + if(!hardConstraint.fulfilled(iFacts, prevAct, newAct, nextAct, depTimeAtPrevAct)){ + return null; + } + double tp_costs_prevAct_newAct = routingCosts.getTransportCost(prevAct.getLocationId(), newAct.getLocationId(), depTimeAtPrevAct, iFacts.getNewDriver(), iFacts.getNewVehicle()); double tp_time_prevAct_newAct = routingCosts.getTransportTime(prevAct.getLocationId(), newAct.getLocationId(), depTimeAtPrevAct, iFacts.getNewDriver(), iFacts.getNewVehicle()); double newAct_arrTime = depTimeAtPrevAct + tp_time_prevAct_newAct; - if(!hardConstraint.fulfilled(iFacts, newAct, newAct_arrTime)){ - return null; - } - - double newAct_endTime = CalcUtils.getStartTimeAtAct(newAct_arrTime, newAct); + double newAct_endTime = CalcUtils.getActivityEndTime(newAct_arrTime, newAct); double act_costs_newAct = activityCosts.getActivityCost(newAct, newAct_arrTime, iFacts.getNewDriver(), iFacts.getNewVehicle()); @@ -38,11 +58,7 @@ class MarginalsCalculusTriangleInequality implements MarginalsCalculus{ double tp_time_newAct_nextAct = routingCosts.getTransportTime(newAct.getLocationId(), nextAct.getLocationId(), newAct_endTime, iFacts.getNewDriver(), iFacts.getNewVehicle()); double nextAct_arrTime = newAct_endTime + tp_time_newAct_nextAct; - - if(!hardConstraint.fulfilled(iFacts, nextAct, nextAct_arrTime)){ - return null; - } - + double act_costs_nextAct = activityCosts.getActivityCost(nextAct, nextAct_arrTime, iFacts.getNewDriver(), iFacts.getNewVehicle()); double totalCosts = tp_costs_prevAct_newAct + tp_costs_newAct_nextAct + act_costs_newAct + act_costs_nextAct; diff --git a/jsprit-core/src/main/java/algorithms/RegretInsertion.java b/jsprit-core/src/main/java/algorithms/RegretInsertion.java index fd8806d7..51ffccbb 100644 --- a/jsprit-core/src/main/java/algorithms/RegretInsertion.java +++ b/jsprit-core/src/main/java/algorithms/RegretInsertion.java @@ -1,3 +1,23 @@ +/******************************************************************************* + * 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 + ******************************************************************************/ ///******************************************************************************* // * Copyright (c) 2011 Stefan Schroeder. // * eMail: stefan.schroeder@kit.edu diff --git a/jsprit-core/src/main/java/algorithms/RouteStates.java b/jsprit-core/src/main/java/algorithms/RouteStates.java deleted file mode 100644 index 19c770c7..00000000 --- a/jsprit-core/src/main/java/algorithms/RouteStates.java +++ /dev/null @@ -1,208 +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.Collection; -import java.util.HashMap; -import java.util.Map; - -import org.apache.log4j.Logger; - -import basics.Job; -import basics.Service; -import basics.VehicleRoutingProblem; -import basics.VehicleRoutingProblemSolution; -import basics.algo.AlgorithmEndsListener; -import basics.algo.IterationEndsListener; -import basics.algo.IterationStartsListener; -import basics.route.ServiceActivity; -import basics.route.TourActivity; -import basics.route.VehicleRoute; - -class RouteStates implements IterationStartsListener{ - - Logger log = Logger.getLogger(RouteStates.class); - - static class RouteState { - private double costs; - private int load; - private VehicleRoute route; - public RouteState(VehicleRoute route) { - super(); - this.route = route; - } - /** - * @return the costs - */ - public double getCosts() { - return costs; - } - /** - * @param costs the costs to set - */ - public void setCosts(double costs) { - this.costs = costs; - } - /** - * @return the load - */ - public int getLoad() { - return load; - } - /** - * @param load the load to set - */ - public void setLoad(int load) { - this.load = load; - } - - } - - static class ActivityState { - private double earliestOperationStart; - private double latestOperationStart; - private double currentLoad; - private double currentCost; - private TourActivity act; - - public ActivityState(TourActivity activity){ - this.earliestOperationStart=activity.getTheoreticalEarliestOperationStartTime(); - this.latestOperationStart=activity.getTheoreticalLatestOperationStartTime(); - this.act = activity; - } - - @Override - public String toString() { - return "[earliestStart="+earliestOperationStart+"][latestStart="+ - latestOperationStart+"][currLoad="+currentLoad+"][currCost="+currentCost+"]"; - } - - public double getEarliestOperationStart() { - return earliestOperationStart; - } - - void setEarliestOperationStart(double earliestOperationStart) { - this.earliestOperationStart = earliestOperationStart; - } - - public double getLatestOperationStart() { - return latestOperationStart; - } - - void setLatestOperationStart(double latestOperationStart) { - this.latestOperationStart = latestOperationStart; - } - - public double getCurrentLoad() { - return currentLoad; - } - - void setCurrentLoad(double currentLoad) { - this.currentLoad = currentLoad; - } - - public double getCurrentCost() { - return currentCost; - } - - void setCurrentCost(double currentCost) { - this.currentCost = currentCost; - } - - public void reset() { - earliestOperationStart = act.getTheoreticalEarliestOperationStartTime(); - latestOperationStart = act.getTheoreticalLatestOperationStartTime() ; - currentLoad = 0.0; - currentCost = 0.0; - } - } - - - private Map activityStates; - - private Map tourActivities; - - private Map routeStates; - - public RouteStates() { - activityStates = new HashMap(); - tourActivities = new HashMap(); - routeStates = new HashMap(); - } - - ActivityState getState(TourActivity act){ - if(!activityStates.containsKey(act)) return null; - return activityStates.get(act); - } - - public void clearStates(){ - activityStates.clear(); - } - - public Map getActivityStates() { - return activityStates; - } - - TourActivity getActivity(Service service, boolean resetState){ - TourActivity tourActivity = tourActivities.get(service); - getState(tourActivity).reset(); - return tourActivity; - } - - public void resetRouteStates(){ - routeStates.clear(); - } - - public RouteState getRouteState(VehicleRoute route){ - RouteState routeState = routeStates.get(route); - if(routeState == null){ - routeState = new RouteState(route); - putRouteState(route, routeState); - } - return routeState; - } - - private void putRouteState(VehicleRoute route, RouteState routeState){ - routeStates.put(route, routeState); - } - - void initialiseStateOfJobs(Collection jobs){ - for(Job job : jobs){ - if(job instanceof Service){ - ServiceActivity service = ServiceActivity.newInstance((Service)job); - ActivityState state = new ActivityState(service); - tourActivities.put((Service) job, service); - activityStates.put(service, state); - } - else{ - throw new IllegalStateException(); - } - } - } - - @Override - public void informIterationStarts(int i, VehicleRoutingProblem problem, Collection solutions) { - resetRouteStates(); - } - - - -} diff --git a/jsprit-core/src/main/java/algorithms/RuinAndRecreateModule.java b/jsprit-core/src/main/java/algorithms/RuinAndRecreateModule.java index f6d12397..b296dd0f 100644 --- a/jsprit-core/src/main/java/algorithms/RuinAndRecreateModule.java +++ b/jsprit-core/src/main/java/algorithms/RuinAndRecreateModule.java @@ -1,3 +1,23 @@ +/******************************************************************************* + * 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.Collection; diff --git a/jsprit-core/src/main/java/algorithms/RuinListeners.java b/jsprit-core/src/main/java/algorithms/RuinListeners.java index 08b91488..f9be7c42 100644 --- a/jsprit-core/src/main/java/algorithms/RuinListeners.java +++ b/jsprit-core/src/main/java/algorithms/RuinListeners.java @@ -1,3 +1,23 @@ +/******************************************************************************* + * 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; diff --git a/jsprit-core/src/main/java/algorithms/StateManager.java b/jsprit-core/src/main/java/algorithms/StateManager.java index e0734ae4..efd8ad1b 100644 --- a/jsprit-core/src/main/java/algorithms/StateManager.java +++ b/jsprit-core/src/main/java/algorithms/StateManager.java @@ -1,3 +1,23 @@ +/******************************************************************************* + * 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 basics.route.TourActivity; diff --git a/jsprit-core/src/main/java/algorithms/StateManagerImpl.java b/jsprit-core/src/main/java/algorithms/StateManagerImpl.java index b16f0d2c..fc4af220 100644 --- a/jsprit-core/src/main/java/algorithms/StateManagerImpl.java +++ b/jsprit-core/src/main/java/algorithms/StateManagerImpl.java @@ -1,6 +1,25 @@ +/******************************************************************************* + * 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.Collections; import java.util.HashMap; import java.util.Map; @@ -28,30 +47,6 @@ class StateManagerImpl implements StateManager{ private Map activityStates = new HashMap(); - public Map getRouteStates() { - return Collections.unmodifiableMap(vehicleRouteStates); - } - - public States getRouteStates(VehicleRoute route){ - return vehicleRouteStates.get(route); - } - - public void put(VehicleRoute route, States states) { - vehicleRouteStates.put(route, states); - } - - public Map getActivityStates() { - return Collections.unmodifiableMap(activityStates); - } - - public States getActivityStates(TourActivity act){ - return activityStates.get(act); - } - - public void put(TourActivity act, States states) { - activityStates.put(act, states); - } - public void clear(){ vehicleRouteStates.clear(); activityStates.clear(); @@ -85,11 +80,14 @@ class StateManagerImpl implements StateManager{ if(stateType.equals(StateTypes.DURATION)) return new StateImpl(0); if(stateType.equals(StateTypes.EARLIEST_OPERATION_START_TIME)) return new StateImpl(act.getTheoreticalEarliestOperationStartTime()); if(stateType.equals(StateTypes.LATEST_OPERATION_START_TIME)) return new StateImpl(act.getTheoreticalLatestOperationStartTime()); + if(stateType.equals(StateTypes.FUTURE_PICKS)) return new StateImpl(0); + if(stateType.equals(StateTypes.PAST_DELIVERIES)) return new StateImpl(0); return null; } private State getDefaultRouteState(String stateType, VehicleRoute route){ if(stateType.equals(StateTypes.LOAD)) return new StateImpl(0); + if(stateType.equals(StateTypes.LOAD_AT_DEPOT)) return new StateImpl(0); if(stateType.equals(StateTypes.COSTS)) return new StateImpl(0); if(stateType.equals(StateTypes.DURATION)) return new StateImpl(0); return null; diff --git a/jsprit-core/src/main/java/algorithms/StateTypes.java b/jsprit-core/src/main/java/algorithms/StateTypes.java index 2306281d..812a4ea8 100644 --- a/jsprit-core/src/main/java/algorithms/StateTypes.java +++ b/jsprit-core/src/main/java/algorithms/StateTypes.java @@ -1,13 +1,39 @@ +/******************************************************************************* + * 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; class StateTypes { final static String LOAD = "load"; + final static String LOAD_AT_DEPOT = "loadAtDepot"; + final static String DURATION = "duration"; final static String LATEST_OPERATION_START_TIME = "latestOST"; final static String EARLIEST_OPERATION_START_TIME = "earliestOST"; - public static final String COSTS = "costs"; + static final String COSTS = "costs"; + + final static String FUTURE_PICKS = "futurePicks"; + + final static String PAST_DELIVERIES = "pastDeliveries"; } diff --git a/jsprit-core/src/main/java/algorithms/StateUpdates.java b/jsprit-core/src/main/java/algorithms/StateUpdates.java new file mode 100644 index 00000000..6f4429fd --- /dev/null +++ b/jsprit-core/src/main/java/algorithms/StateUpdates.java @@ -0,0 +1,678 @@ +/******************************************************************************* + * 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.HashMap; +import java.util.Map; + +import org.apache.log4j.Logger; + +import algorithms.BackwardInTimeListeners.BackwardInTimeListener; +import algorithms.ForwardInTimeListeners.ForwardInTimeListener; +import algorithms.RuinStrategy.RuinListener; +import algorithms.StateManager.StateImpl; +import basics.Delivery; +import basics.Job; +import basics.Pickup; +import basics.Service; +import basics.VehicleRoutingProblem; +import basics.VehicleRoutingProblemSolution; +import basics.algo.InsertionEndsListener; +import basics.algo.InsertionStartsListener; +import basics.algo.IterationEndsListener; +import basics.algo.IterationStartsListener; +import basics.algo.JobInsertedListener; +import basics.algo.VehicleRoutingAlgorithmListener; +import basics.costs.ForwardTransportCost; +import basics.costs.VehicleRoutingActivityCosts; +import basics.costs.VehicleRoutingTransportCosts; +import basics.route.DeliveryActivity; +import basics.route.End; +import basics.route.PickupActivity; +import basics.route.ServiceActivity; +import basics.route.Start; +import basics.route.TourActivity; +import basics.route.VehicleRoute; + +class StateUpdates { + + static class VRAListenersManager implements IterationStartsListener, IterationEndsListener, InsertionStartsListener, InsertionEndsListener, JobInsertedListener, RuinListener{ + + private Map,Collection> listeners = new HashMap,Collection>(); + + public void addListener(VehicleRoutingAlgorithmListener vraListener){ + if(!listeners.containsKey(vraListener.getClass())){ + listeners.put(vraListener.getClass(), new ArrayList()); + } + listeners.get(vraListener.getClass()).add(vraListener); + } + + @Override + public void ruinStarts(Collection routes) { + if(listeners.containsKey(RuinListener.class)){ + for(VehicleRoutingAlgorithmListener l : listeners.get(RuinListener.class)){ + ((RuinListener)l).ruinStarts(routes); + } + } + } + + @Override + public void ruinEnds(Collection routes,Collection unassignedJobs) { + if(listeners.containsKey(RuinListener.class)){ + for(VehicleRoutingAlgorithmListener l : listeners.get(RuinListener.class)){ + ((RuinListener)l).ruinEnds(routes,unassignedJobs); + } + } + } + + @Override + public void removed(Job job, VehicleRoute fromRoute) { + if(listeners.containsKey(RuinListener.class)){ + for(VehicleRoutingAlgorithmListener l : listeners.get(RuinListener.class)){ + ((RuinListener)l).removed(job, fromRoute); + } + } + } + + @Override + public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) { + if(listeners.containsKey(JobInsertedListener.class)){ + for(VehicleRoutingAlgorithmListener l : listeners.get(RuinListener.class)){ + ((JobInsertedListener)l).informJobInserted(job2insert, inRoute, additionalCosts, additionalTime); + } + } + + } + + @Override + public void informInsertionEnds(Collection vehicleRoutes) { +// if(listeners.containsKey(JobInsertedListener.class)){ +// for(VehicleRoutingAlgorithmListener l : listeners.get(RuinListener.class)){ +// ((JobInsertedListener)l).informJobInserted(job2insert, inRoute, additionalCosts, additionalTime); +// } +// } + } + + @Override + public void informInsertionStarts(Collection vehicleRoutes,Collection unassignedJobs) { + // TODO Auto-generated method stub + + } + + @Override + public void informIterationEnds(int i, VehicleRoutingProblem problem,Collection solutions) { + // TODO Auto-generated method stub + + } + + @Override + public void informIterationStarts(int i, VehicleRoutingProblem problem,Collection solutions) { + // TODO Auto-generated method stub + + } + + } + + static class UpdateCostsAtRouteLevel implements JobInsertedListener, InsertionStartsListener, InsertionEndsListener{ + + private StateManagerImpl states; + + private VehicleRoutingTransportCosts tpCosts; + + private VehicleRoutingActivityCosts actCosts; + + public UpdateCostsAtRouteLevel(StateManagerImpl states, VehicleRoutingTransportCosts tpCosts, VehicleRoutingActivityCosts actCosts) { + super(); + this.states = states; + this.tpCosts = tpCosts; + this.actCosts = actCosts; + } + + @Override + public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) { +// inRoute.getVehicleRouteCostCalculator().addTransportCost(additionalCosts); + double oldCosts = states.getRouteState(inRoute, StateTypes.COSTS).toDouble(); + oldCosts += additionalCosts; + states.putRouteState(inRoute, StateTypes.COSTS, new StateImpl(oldCosts)); + } + + @Override + public void informInsertionStarts(Collection vehicleRoutes, Collection unassignedJobs) { + IterateRouteForwardInTime forwardInTime = new IterateRouteForwardInTime(tpCosts); + forwardInTime.addListener(new UpdateCostsAtAllLevels(actCosts, tpCosts, states)); + for(VehicleRoute route : vehicleRoutes){ + forwardInTime.iterate(route); + } + + } + + @Override + public void informInsertionEnds(Collection vehicleRoutes) { + +// IterateRouteForwardInTime forwardInTime = new IterateRouteForwardInTime(tpCosts); +// forwardInTime.addListener(new UpdateCostsAtAllLevels(actCosts, tpCosts, states)); + for(VehicleRoute route : vehicleRoutes){ + if(route.isEmpty()) continue; + route.getVehicleRouteCostCalculator().reset(); + route.getVehicleRouteCostCalculator().addOtherCost(states.getRouteState(route, StateTypes.COSTS).toDouble()); + route.getVehicleRouteCostCalculator().price(route.getVehicle()); +// forwardInTime.iterate(route); + } + + } + + } + + static class UpdateActivityTimes implements ForwardInTimeListener{ + + private Logger log = Logger.getLogger(UpdateActivityTimes.class); + + @Override + public void start(VehicleRoute route, Start start, double departureTime) { + start.setEndTime(departureTime); + } + + @Override + public void nextActivity(TourActivity act, double arrTime, double endTime) { + act.setArrTime(arrTime); + act.setEndTime(endTime); + } + + @Override + public void end(End end, double arrivalTime) { + end.setArrTime(arrivalTime); + } + + } + + static class UpdateCostsAtAllLevels implements ForwardInTimeListener{ + + private static Logger log = Logger.getLogger(UpdateCostsAtAllLevels.class); + + private VehicleRoutingActivityCosts activityCost; + + private ForwardTransportCost transportCost; + + private StateManagerImpl states; + + private double totalOperationCost = 0.0; + + private VehicleRoute vehicleRoute = null; + + private TourActivity prevAct = null; + + private double startTimeAtPrevAct = 0.0; + + public UpdateCostsAtAllLevels(VehicleRoutingActivityCosts activityCost, ForwardTransportCost transportCost, StateManagerImpl states) { + super(); + this.activityCost = activityCost; + this.transportCost = transportCost; + this.states = states; + } + + @Override + public void start(VehicleRoute route, Start start, double departureTime) { + vehicleRoute = route; + vehicleRoute.getVehicleRouteCostCalculator().reset(); + prevAct = start; + startTimeAtPrevAct = departureTime; +// log.info(start + " depTime=" + departureTime); + } + + @Override + public void nextActivity(TourActivity act, double arrTime, double endTime) { +// log.info(act + " job " + ((JobActivity)act).getJob().getId() + " arrTime=" + arrTime + " endTime=" + endTime); + double transportCost = this.transportCost.getTransportCost(prevAct.getLocationId(), act.getLocationId(), startTimeAtPrevAct, vehicleRoute.getDriver(), vehicleRoute.getVehicle()); + double actCost = activityCost.getActivityCost(act, arrTime, vehicleRoute.getDriver(), vehicleRoute.getVehicle()); + + vehicleRoute.getVehicleRouteCostCalculator().addTransportCost(transportCost); + vehicleRoute.getVehicleRouteCostCalculator().addActivityCost(actCost); + + if(transportCost > 10000 || actCost > 100000){ + throw new IllegalStateException("aaaääähh"); + } + + totalOperationCost += transportCost; + totalOperationCost += actCost; + + states.putActivityState(act, StateTypes.COSTS, new StateImpl(totalOperationCost)); + + prevAct = act; + startTimeAtPrevAct = endTime; + } + + @Override + public void end(End end, double arrivalTime) { +// log.info(end + " arrTime=" + arrivalTime); + double transportCost = this.transportCost.getTransportCost(prevAct.getLocationId(), end.getLocationId(), startTimeAtPrevAct, vehicleRoute.getDriver(), vehicleRoute.getVehicle()); + double actCost = activityCost.getActivityCost(end, arrivalTime, vehicleRoute.getDriver(), vehicleRoute.getVehicle()); + + vehicleRoute.getVehicleRouteCostCalculator().addTransportCost(transportCost); + vehicleRoute.getVehicleRouteCostCalculator().addActivityCost(actCost); + + if(transportCost > 10000 || actCost > 100000){ + throw new IllegalStateException("aaaääähh"); + } + + totalOperationCost += transportCost; + totalOperationCost += actCost; + + states.putRouteState(vehicleRoute, StateTypes.COSTS, new StateImpl(totalOperationCost)); + + //this is rather strange and likely to change + vehicleRoute.getVehicleRouteCostCalculator().price(vehicleRoute.getDriver()); + vehicleRoute.getVehicleRouteCostCalculator().price(vehicleRoute.getVehicle()); + vehicleRoute.getVehicleRouteCostCalculator().finish(); + + startTimeAtPrevAct = 0.0; + prevAct = null; + vehicleRoute = null; + totalOperationCost = 0.0; + } + + } + + static class UpdateEarliestStartTimeWindowAtActLocations implements ForwardInTimeListener{ + + private StateManagerImpl states; + + public UpdateEarliestStartTimeWindowAtActLocations(StateManagerImpl states) { + super(); + this.states = states; + } + + @Override + public void start(VehicleRoute route, Start start, double departureTime) {} + + @Override + public void nextActivity(TourActivity act, double arrTime, double endTime) { + states.putActivityState(act, StateTypes.EARLIEST_OPERATION_START_TIME, new StateImpl(Math.max(arrTime, act.getTheoreticalEarliestOperationStartTime()))); + } + + @Override + public void end(End end, double arrivalTime) {} + + } + + static class UpdateLatestOperationStartTimeAtActLocations implements BackwardInTimeListener{ + + private static Logger log = Logger.getLogger(UpdateLatestOperationStartTimeAtActLocations.class); + + private StateManagerImpl states; + + public UpdateLatestOperationStartTimeAtActLocations(StateManagerImpl states) { + super(); + this.states = states; + } + + @Override + public void start(VehicleRoute route, End end, double latestArrivalTime) {} + + @Override + public void prevActivity(TourActivity act,double latestDepartureTime, double latestOperationStartTime) { +// log.info(act + " jobId=" + ((JobActivity)act).getJob().getId() + " " + latestOperationStartTime); + states.putActivityState(act, StateTypes.LATEST_OPERATION_START_TIME, new StateImpl(latestOperationStartTime)); + } + + @Override + public void end(Start start, double latestDepartureTime) {} + + + + } + + static class UpdateLoadAtAllLevels implements ForwardInTimeListener{ + + private double load = 0.0; + + private StateManagerImpl states; + + private VehicleRoute vehicleRoute; + + public UpdateLoadAtAllLevels(StateManagerImpl states) { + super(); + this.states = states; + } + + @Override + public void start(VehicleRoute route, Start start, double departureTime) { vehicleRoute = route; } + + @Override + public void nextActivity(TourActivity act, double arrTime, double endTime) { + load += (double)act.getCapacityDemand(); + states.putActivityState(act, StateTypes.LOAD, new StateImpl(load)); + } + + @Override + public void end(End end, double arrivalTime) { + states.putRouteState(vehicleRoute, StateTypes.LOAD, new StateImpl(load)); + load=0; + vehicleRoute = null; + } + + } + + static class UpdateLoadAtRouteLevel implements JobInsertedListener, InsertionStartsListener{ + + private StateManagerImpl states; + + public UpdateLoadAtRouteLevel(StateManagerImpl states) { + super(); + this.states = states; + } + + @Override + public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) { + if(!(job2insert instanceof Service)){ + return; + } + double oldLoad = states.getRouteState(inRoute, StateTypes.LOAD).toDouble(); + states.putRouteState(inRoute, StateTypes.LOAD, new StateImpl(oldLoad + job2insert.getCapacityDemand())); + } + + @Override + public void informInsertionStarts(Collection vehicleRoutes, Collection unassignedJobs) { + for(VehicleRoute route : vehicleRoutes){ + int load = 0; + for(Job j : route.getTourActivities().getJobs()){ + load += j.getCapacityDemand(); + } + states.putRouteState(route, StateTypes.LOAD, new StateImpl(load)); + } + + } + + } + + static class UpdateStates implements JobInsertedListener, RuinListener{ + + private IterateRouteForwardInTime iterateForward; + + private IterateRouteBackwardInTime iterateBackward; + + public UpdateStates(StateManagerImpl states, VehicleRoutingTransportCosts routingCosts, VehicleRoutingActivityCosts activityCosts) { + + iterateForward = new IterateRouteForwardInTime(routingCosts); + iterateForward.addListener(new UpdateActivityTimes()); + iterateForward.addListener(new UpdateCostsAtAllLevels(activityCosts, routingCosts, states)); + iterateForward.addListener(new UpdateLoadAtAllLevels(states)); +// iterateForward.addListener(new UpdateEarliestStartTimeWindowAtActLocations(states)); + + iterateBackward = new IterateRouteBackwardInTime(routingCosts); + iterateBackward.addListener(new UpdateLatestOperationStartTimeAtActLocations(states)); + } + + public void update(VehicleRoute route){ + iterateForward.iterate(route); + iterateBackward.iterate(route); + } + + @Override + public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) { + iterateForward.iterate(inRoute); + iterateBackward.iterate(inRoute); + } + + @Override + public void ruinStarts(Collection routes) {} + + @Override + public void ruinEnds(Collection routes,Collection unassignedJobs) { + for(VehicleRoute route : routes) { + iterateForward.iterate(route); + iterateBackward.iterate(route); + } + } + + @Override + public void removed(Job job, VehicleRoute fromRoute) {} + + } + + static class UpdateFuturePickupsAtActivityLevel implements BackwardInTimeListener { + private StateManagerImpl stateManager; + private int futurePicks = 0; + private VehicleRoute route; + + public UpdateFuturePickupsAtActivityLevel(StateManagerImpl stateManager) { + super(); + this.stateManager = stateManager; + } + + @Override + public void start(VehicleRoute route, End end, double latestArrivalTime) { + this.route = route; + } + + @Override + public void prevActivity(TourActivity act, double latestDepartureTime, double latestOperationStartTime) { + stateManager.putActivityState(act, StateTypes.FUTURE_PICKS, new StateImpl(futurePicks)); + if(act instanceof PickupActivity || act instanceof ServiceActivity){ + futurePicks += act.getCapacityDemand(); + } + assert futurePicks <= route.getVehicle().getCapacity() : "sum of pickups must not be > vehicleCap"; + assert futurePicks >= 0 : "sum of pickups must not < 0"; + } + + @Override + public void end(Start start, double latestDepartureTime) { + futurePicks = 0; + route = null; + } + } + + static class UpdateOccuredDeliveriesAtActivityLevel implements ForwardInTimeListener { + private StateManagerImpl stateManager; + private int deliveries = 0; + private VehicleRoute route; + + public UpdateOccuredDeliveriesAtActivityLevel(StateManagerImpl stateManager) { + super(); + this.stateManager = stateManager; + } + + @Override + public void start(VehicleRoute route, Start start, double departureTime) { + this.route = route; + } + + @Override + public void nextActivity(TourActivity act, double arrTime, double endTime) { + if(act instanceof DeliveryActivity){ + deliveries += Math.abs(act.getCapacityDemand()); + } + stateManager.putActivityState(act, StateTypes.PAST_DELIVERIES, new StateImpl(deliveries)); + assert deliveries >= 0 : "deliveries < 0"; + assert deliveries <= route.getVehicle().getCapacity() : "deliveries > vehicleCap"; + } + + @Override + public void end(End end, double arrivalTime) { + deliveries = 0; + route = null; + } + } + + /** + * Updates load at activity level. Note that this assumed that StateTypes.LOAD_AT_DEPOT is already updated, i.e. it starts by setting loadAtDepot to StateTypes.LOAD_AT_DEPOT. + * If StateTypes.LOAD_AT_DEPOT is not set, it starts with 0 load at depot. + * + * @author stefan + * + */ + static class UpdateLoadAtActivityLevel implements ForwardInTimeListener { + private StateManagerImpl stateManager; + private int currentLoad = 0; + private VehicleRoute route; + + public UpdateLoadAtActivityLevel(StateManagerImpl stateManager) { + super(); + this.stateManager = stateManager; + } + + @Override + public void start(VehicleRoute route, Start start, double departureTime) { + currentLoad = (int) stateManager.getRouteState(route, StateTypes.LOAD_AT_DEPOT).toDouble(); + this.route = route; + } + + @Override + public void nextActivity(TourActivity act, double arrTime, double endTime) { + currentLoad += act.getCapacityDemand(); + stateManager.putActivityState(act, StateTypes.LOAD, new StateImpl(currentLoad)); + assert currentLoad <= route.getVehicle().getCapacity() : "currentLoad at activity must not be > vehicleCapacity"; + assert currentLoad >= 0 : "currentLoad at act must not be < 0"; + } + + @Override + public void end(End end, double arrivalTime) { + currentLoad = 0; + } + } + + static class ResetStateManager implements IterationStartsListener { + + private StateManagerImpl stateManager; + + public ResetStateManager(StateManagerImpl stateManager) { + super(); + this.stateManager = stateManager; + } + + @Override + public void informIterationStarts(int i, VehicleRoutingProblem problem, Collection solutions) { + stateManager.clear(); + } + } + + static interface InsertionStarts { + + void insertionStarts(VehicleRoute route); + + } + + static class UpdateLoadsAtStartAndEndOfRouteWhenInsertionStarts implements InsertionStarts { + + private StateManagerImpl stateManager; + + public UpdateLoadsAtStartAndEndOfRouteWhenInsertionStarts(StateManagerImpl stateManager) { + super(); + this.stateManager = stateManager; + } + + @Override + public void insertionStarts(VehicleRoute route) { + int loadAtDepot = 0; + int loadAtEnd = 0; + for(Job j : route.getTourActivities().getJobs()){ + if(j instanceof Delivery){ + loadAtDepot += j.getCapacityDemand(); + } + else if(j instanceof Pickup || j instanceof Service){ + loadAtEnd += j.getCapacityDemand(); + } + } + stateManager.putRouteState(route, StateTypes.LOAD_AT_DEPOT, new StateImpl(loadAtDepot)); + stateManager.putRouteState(route, StateTypes.LOAD, new StateImpl(loadAtEnd)); + } + + } + + static class UpdateLoadsAtStartAndEndOfRouteWhenJobHasBeenInserted implements JobInsertedListener { + + private StateManagerImpl stateManager; + + public UpdateLoadsAtStartAndEndOfRouteWhenJobHasBeenInserted(StateManagerImpl stateManager) { + super(); + this.stateManager = stateManager; + } + + @Override + public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) { + if(job2insert instanceof Delivery){ + int loadAtDepot = (int) stateManager.getRouteState(inRoute, StateTypes.LOAD_AT_DEPOT).toDouble(); +// log.info("loadAtDepot="+loadAtDepot); + stateManager.putRouteState(inRoute, StateTypes.LOAD_AT_DEPOT, new StateImpl(loadAtDepot + job2insert.getCapacityDemand())); + } + else if(job2insert instanceof Pickup || job2insert instanceof Service){ + int loadAtEnd = (int) stateManager.getRouteState(inRoute, StateTypes.LOAD).toDouble(); +// log.info("loadAtEnd="+loadAtEnd); + stateManager.putRouteState(inRoute, StateTypes.LOAD, new StateImpl(loadAtEnd + job2insert.getCapacityDemand())); + } + } + + } + + static class UpdateRouteStatesOnceTheRouteHasBeenChanged implements InsertionStartsListener, JobInsertedListener { + + private IterateRouteForwardInTime forwardInTimeIterator; + + private IterateRouteBackwardInTime backwardInTimeIterator; + + private Collection insertionStartsListeners; + + private Collection jobInsertionListeners; + + public UpdateRouteStatesOnceTheRouteHasBeenChanged(VehicleRoutingTransportCosts routingCosts) { + forwardInTimeIterator = new IterateRouteForwardInTime(routingCosts); + backwardInTimeIterator = new IterateRouteBackwardInTime(routingCosts); + insertionStartsListeners = new ArrayList(); + jobInsertionListeners = new ArrayList(); + } + + void addListener(ForwardInTimeListener l){ + forwardInTimeIterator.addListener(l); + } + + void addListener(BackwardInTimeListener l){ + backwardInTimeIterator.addListener(l); + } + + void addInsertionStartsListener(InsertionStarts insertionStartListener){ + insertionStartsListeners.add(insertionStartListener); + } + + void addJobInsertedListener(JobInsertedListener jobInsertedListener){ + jobInsertionListeners.add(jobInsertedListener); + } + + @Override + public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) { + for(JobInsertedListener l : jobInsertionListeners){ l.informJobInserted(job2insert, inRoute, additionalCosts, additionalTime); } + forwardInTimeIterator.iterate(inRoute); + backwardInTimeIterator.iterate(inRoute); + } + + @Override + public void informInsertionStarts(Collection vehicleRoutes, Collection unassignedJobs) { + for(VehicleRoute route : vehicleRoutes){ + for(InsertionStarts insertionsStartsHandler : insertionStartsListeners){ + insertionsStartsHandler.insertionStarts(route); + } + forwardInTimeIterator.iterate(route); + backwardInTimeIterator.iterate(route); + } + } + + } +} diff --git a/jsprit-core/src/main/java/algorithms/UdateCostsAtRouteLevel.java b/jsprit-core/src/main/java/algorithms/UdateCostsAtRouteLevel.java deleted file mode 100644 index b058549f..00000000 --- a/jsprit-core/src/main/java/algorithms/UdateCostsAtRouteLevel.java +++ /dev/null @@ -1,62 +0,0 @@ -package algorithms; - -import java.util.Collection; - -import algorithms.StateManager.StateImpl; -import basics.Job; -import basics.algo.InsertionEndsListener; -import basics.algo.InsertionStartsListener; -import basics.algo.JobInsertedListener; -import basics.costs.VehicleRoutingActivityCosts; -import basics.costs.VehicleRoutingTransportCosts; -import basics.route.VehicleRoute; - -class UdateCostsAtRouteLevel implements JobInsertedListener, InsertionStartsListener, InsertionEndsListener{ - - private StateManagerImpl states; - - private VehicleRoutingTransportCosts tpCosts; - - private VehicleRoutingActivityCosts actCosts; - - public UdateCostsAtRouteLevel(StateManagerImpl states, VehicleRoutingTransportCosts tpCosts, VehicleRoutingActivityCosts actCosts) { - super(); - this.states = states; - this.tpCosts = tpCosts; - this.actCosts = actCosts; - } - - @Override - public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) { -// inRoute.getVehicleRouteCostCalculator().addTransportCost(additionalCosts); - double oldCosts = states.getRouteState(inRoute, StateTypes.COSTS).toDouble(); - oldCosts += additionalCosts; - states.putRouteState(inRoute, StateTypes.COSTS, new StateImpl(oldCosts)); - } - - @Override - public void informInsertionStarts(Collection vehicleRoutes, Collection unassignedJobs) { - IterateRouteForwardInTime forwardInTime = new IterateRouteForwardInTime(tpCosts); - forwardInTime.addListener(new UpdateCostsAtAllLevels(actCosts, tpCosts, states)); - for(VehicleRoute route : vehicleRoutes){ - forwardInTime.iterate(route); - } - - } - - @Override - public void informInsertionEnds(Collection vehicleRoutes) { - -// IterateRouteForwardInTime forwardInTime = new IterateRouteForwardInTime(tpCosts); -// forwardInTime.addListener(new UpdateCostsAtAllLevels(actCosts, tpCosts, states)); - for(VehicleRoute route : vehicleRoutes){ - if(route.isEmpty()) continue; - route.getVehicleRouteCostCalculator().reset(); - route.getVehicleRouteCostCalculator().addOtherCost(states.getRouteState(route, StateTypes.COSTS).toDouble()); - route.getVehicleRouteCostCalculator().price(route.getVehicle()); -// forwardInTime.iterate(route); - } - - } - -} diff --git a/jsprit-core/src/main/java/algorithms/UpdateActivityTimes.java b/jsprit-core/src/main/java/algorithms/UpdateActivityTimes.java deleted file mode 100644 index 308739c6..00000000 --- a/jsprit-core/src/main/java/algorithms/UpdateActivityTimes.java +++ /dev/null @@ -1,31 +0,0 @@ -package algorithms; - -import org.apache.log4j.Logger; - -import algorithms.ForwardInTimeListeners.ForwardInTimeListener; -import basics.route.End; -import basics.route.Start; -import basics.route.TourActivity; -import basics.route.VehicleRoute; - -class UpdateActivityTimes implements ForwardInTimeListener{ - - private Logger log = Logger.getLogger(UpdateActivityTimes.class); - - @Override - public void start(VehicleRoute route, Start start, double departureTime) { - start.setEndTime(departureTime); - } - - @Override - public void nextActivity(TourActivity act, double arrTime, double endTime) { - act.setArrTime(arrTime); - act.setEndTime(endTime); - } - - @Override - public void end(End end, double arrivalTime) { - end.setArrTime(arrivalTime); - } - -} diff --git a/jsprit-core/src/main/java/algorithms/UpdateCostsAtAllLevels.java b/jsprit-core/src/main/java/algorithms/UpdateCostsAtAllLevels.java deleted file mode 100644 index 2cc6bcf7..00000000 --- a/jsprit-core/src/main/java/algorithms/UpdateCostsAtAllLevels.java +++ /dev/null @@ -1,84 +0,0 @@ -package algorithms; - -import algorithms.ForwardInTimeListeners.ForwardInTimeListener; -import algorithms.StateManager.StateImpl; -import basics.costs.ForwardTransportCost; -import basics.costs.VehicleRoutingActivityCosts; -import basics.route.End; -import basics.route.Start; -import basics.route.TourActivity; -import basics.route.VehicleRoute; - -class UpdateCostsAtAllLevels implements ForwardInTimeListener{ - - private VehicleRoutingActivityCosts activityCost; - - private ForwardTransportCost transportCost; - - private StateManagerImpl states; - - private double totalOperationCost = 0.0; - - private VehicleRoute vehicleRoute = null; - - private TourActivity prevAct = null; - - private double startTimeAtPrevAct = 0.0; - - public UpdateCostsAtAllLevels(VehicleRoutingActivityCosts activityCost, ForwardTransportCost transportCost, StateManagerImpl states) { - super(); - this.activityCost = activityCost; - this.transportCost = transportCost; - this.states = states; - } - - @Override - public void start(VehicleRoute route, Start start, double departureTime) { - vehicleRoute = route; - vehicleRoute.getVehicleRouteCostCalculator().reset(); - prevAct = start; - startTimeAtPrevAct = departureTime; - } - - @Override - public void nextActivity(TourActivity act, double arrTime, double endTime) { - double transportCost = this.transportCost.getTransportCost(prevAct.getLocationId(), act.getLocationId(), startTimeAtPrevAct, vehicleRoute.getDriver(), vehicleRoute.getVehicle()); - double actCost = activityCost.getActivityCost(act, arrTime, vehicleRoute.getDriver(), vehicleRoute.getVehicle()); - - vehicleRoute.getVehicleRouteCostCalculator().addTransportCost(transportCost); - vehicleRoute.getVehicleRouteCostCalculator().addActivityCost(actCost); - - totalOperationCost += transportCost; - totalOperationCost += actCost; - - states.putActivityState(act, StateTypes.COSTS, new StateImpl(totalOperationCost)); - - prevAct = act; - startTimeAtPrevAct = endTime; - } - - @Override - public void end(End end, double arrivalTime) { - double transportCost = this.transportCost.getTransportCost(prevAct.getLocationId(), end.getLocationId(), startTimeAtPrevAct, vehicleRoute.getDriver(), vehicleRoute.getVehicle()); - double actCost = activityCost.getActivityCost(end, arrivalTime, vehicleRoute.getDriver(), vehicleRoute.getVehicle()); - - vehicleRoute.getVehicleRouteCostCalculator().addTransportCost(transportCost); - vehicleRoute.getVehicleRouteCostCalculator().addActivityCost(actCost); - - totalOperationCost += transportCost; - totalOperationCost += actCost; - - states.putRouteState(vehicleRoute, StateTypes.COSTS, new StateImpl(totalOperationCost)); - - //this is rather strange and likely to change - vehicleRoute.getVehicleRouteCostCalculator().price(vehicleRoute.getDriver()); - vehicleRoute.getVehicleRouteCostCalculator().price(vehicleRoute.getVehicle()); - vehicleRoute.getVehicleRouteCostCalculator().finish(); - - startTimeAtPrevAct = 0.0; - prevAct = null; - vehicleRoute = null; - totalOperationCost = 0.0; - } - -} diff --git a/jsprit-core/src/main/java/algorithms/UpdateEarliestStartTimeWindowAtActLocations.java b/jsprit-core/src/main/java/algorithms/UpdateEarliestStartTimeWindowAtActLocations.java deleted file mode 100644 index 1fab69ef..00000000 --- a/jsprit-core/src/main/java/algorithms/UpdateEarliestStartTimeWindowAtActLocations.java +++ /dev/null @@ -1,30 +0,0 @@ -package algorithms; - -import algorithms.ForwardInTimeListeners.ForwardInTimeListener; -import algorithms.StateManager.StateImpl; -import basics.route.End; -import basics.route.Start; -import basics.route.TourActivity; -import basics.route.VehicleRoute; - -class UpdateEarliestStartTimeWindowAtActLocations implements ForwardInTimeListener{ - - private StateManagerImpl states; - - public UpdateEarliestStartTimeWindowAtActLocations(StateManagerImpl states) { - super(); - this.states = states; - } - - @Override - public void start(VehicleRoute route, Start start, double departureTime) {} - - @Override - public void nextActivity(TourActivity act, double arrTime, double endTime) { - states.putActivityState(act, StateTypes.EARLIEST_OPERATION_START_TIME, new StateImpl(Math.max(arrTime, act.getTheoreticalEarliestOperationStartTime()))); - } - - @Override - public void end(End end, double arrivalTime) {} - -} diff --git a/jsprit-core/src/main/java/algorithms/UpdateLatestOperationStartTimeAtActLocations.java b/jsprit-core/src/main/java/algorithms/UpdateLatestOperationStartTimeAtActLocations.java deleted file mode 100644 index 6c65282e..00000000 --- a/jsprit-core/src/main/java/algorithms/UpdateLatestOperationStartTimeAtActLocations.java +++ /dev/null @@ -1,32 +0,0 @@ -package algorithms; - -import algorithms.BackwardInTimeListeners.BackwardInTimeListener; -import algorithms.StateManager.StateImpl; -import basics.route.End; -import basics.route.Start; -import basics.route.TourActivity; -import basics.route.VehicleRoute; - -class UpdateLatestOperationStartTimeAtActLocations implements BackwardInTimeListener{ - - private StateManagerImpl states; - - public UpdateLatestOperationStartTimeAtActLocations(StateManagerImpl states) { - super(); - this.states = states; - } - - @Override - public void start(VehicleRoute route, End end, double latestArrivalTime) {} - - @Override - public void prevActivity(TourActivity act,double latestDepartureTime, double latestOperationStartTime) { - states.putActivityState(act, StateTypes.LATEST_OPERATION_START_TIME, new StateImpl(latestOperationStartTime)); - } - - @Override - public void end(Start start, double latestDepartureTime) {} - - - -} diff --git a/jsprit-core/src/main/java/algorithms/UpdateLoadAtAllLevels.java b/jsprit-core/src/main/java/algorithms/UpdateLoadAtAllLevels.java deleted file mode 100644 index 5de4cdc2..00000000 --- a/jsprit-core/src/main/java/algorithms/UpdateLoadAtAllLevels.java +++ /dev/null @@ -1,45 +0,0 @@ -package algorithms; - -import algorithms.ForwardInTimeListeners.ForwardInTimeListener; -import algorithms.StateManager.StateImpl; -import basics.route.End; -import basics.route.Start; -import basics.route.TourActivity; -import basics.route.VehicleRoute; - -/** - * It does not update start and end activities. - * - * @author stefan - * - */ -class UpdateLoadAtAllLevels implements ForwardInTimeListener{ - - private double load = 0.0; - - private StateManagerImpl states; - - private VehicleRoute vehicleRoute; - - public UpdateLoadAtAllLevels(StateManagerImpl states) { - super(); - this.states = states; - } - - @Override - public void start(VehicleRoute route, Start start, double departureTime) { vehicleRoute = route; } - - @Override - public void nextActivity(TourActivity act, double arrTime, double endTime) { - load += (double)act.getCapacityDemand(); - states.putActivityState(act, StateTypes.LOAD, new StateImpl(load)); - } - - @Override - public void end(End end, double arrivalTime) { - states.putRouteState(vehicleRoute, StateTypes.LOAD, new StateImpl(load)); - load=0; - vehicleRoute = null; - } - -} diff --git a/jsprit-core/src/main/java/algorithms/UpdateLoadAtRouteLevel.java b/jsprit-core/src/main/java/algorithms/UpdateLoadAtRouteLevel.java deleted file mode 100644 index 5ed2adc1..00000000 --- a/jsprit-core/src/main/java/algorithms/UpdateLoadAtRouteLevel.java +++ /dev/null @@ -1,42 +0,0 @@ -package algorithms; - -import java.util.Collection; - -import algorithms.StateManager.StateImpl; -import basics.Job; -import basics.Service; -import basics.algo.InsertionStartsListener; -import basics.algo.JobInsertedListener; -import basics.route.VehicleRoute; - -class UpdateLoadAtRouteLevel implements JobInsertedListener, InsertionStartsListener{ - - private StateManagerImpl states; - - public UpdateLoadAtRouteLevel(StateManagerImpl states) { - super(); - this.states = states; - } - - @Override - public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) { - if(!(job2insert instanceof Service)){ - return; - } - double oldLoad = states.getRouteState(inRoute, StateTypes.LOAD).toDouble(); - states.putRouteState(inRoute, StateTypes.LOAD, new StateImpl(oldLoad + job2insert.getCapacityDemand())); - } - - @Override - public void informInsertionStarts(Collection vehicleRoutes, Collection unassignedJobs) { - for(VehicleRoute route : vehicleRoutes){ - int load = 0; - for(Job j : route.getTourActivities().getJobs()){ - load += j.getCapacityDemand(); - } - states.putRouteState(route, StateTypes.LOAD, new StateImpl(load)); - } - - } - -} diff --git a/jsprit-core/src/main/java/algorithms/UpdateStates.java b/jsprit-core/src/main/java/algorithms/UpdateStates.java deleted file mode 100644 index 0d61558d..00000000 --- a/jsprit-core/src/main/java/algorithms/UpdateStates.java +++ /dev/null @@ -1,55 +0,0 @@ -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; - -class UpdateStates implements JobInsertedListener, RuinListener{ - - private IterateRouteForwardInTime iterateForward; - - private IterateRouteBackwardInTime iterateBackward; - - public UpdateStates(StateManagerImpl states, VehicleRoutingTransportCosts routingCosts, VehicleRoutingActivityCosts activityCosts) { - - iterateForward = new IterateRouteForwardInTime(routingCosts); - iterateForward.addListener(new UpdateActivityTimes()); - iterateForward.addListener(new UpdateCostsAtAllLevels(activityCosts, routingCosts, states)); - iterateForward.addListener(new UpdateLoadAtAllLevels(states)); -// iterateForward.addListener(new UpdateEarliestStartTimeWindowAtActLocations(states)); - - iterateBackward = new IterateRouteBackwardInTime(routingCosts); - iterateBackward.addListener(new UpdateLatestOperationStartTimeAtActLocations(states)); - } - - public void update(VehicleRoute route){ - iterateForward.iterate(route); - iterateBackward.iterate(route); - } - - @Override - public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) { - iterateForward.iterate(inRoute); - iterateBackward.iterate(inRoute); - } - - @Override - public void ruinStarts(Collection routes) {} - - @Override - public void ruinEnds(Collection routes,Collection unassignedJobs) { - for(VehicleRoute route : routes) { - iterateForward.iterate(route); - iterateBackward.iterate(route); - } - } - - @Override - public void removed(Job job, VehicleRoute fromRoute) {} - -} diff --git a/jsprit-core/src/main/java/algorithms/VehicleRoutingAlgorithms.java b/jsprit-core/src/main/java/algorithms/VehicleRoutingAlgorithms.java index 0f52a27c..d3c77390 100644 --- a/jsprit-core/src/main/java/algorithms/VehicleRoutingAlgorithms.java +++ b/jsprit-core/src/main/java/algorithms/VehicleRoutingAlgorithms.java @@ -35,11 +35,16 @@ import org.apache.commons.configuration.HierarchicalConfiguration; import org.apache.commons.configuration.XMLConfiguration; import org.apache.log4j.Logger; -import util.RouteUtils; -import algorithms.RuinStrategy.RuinListener; -import algorithms.VehicleRoutingAlgorithms.TypedMap.InsertionStrategyKey; +import algorithms.HardConstraints.ConstraintManager; +import algorithms.HardConstraints.HardTimeWindowActivityLevelConstraint; +import algorithms.StateUpdates.UpdateActivityTimes; +import algorithms.StateUpdates.UpdateCostsAtAllLevels; +import algorithms.StateUpdates.UpdateEarliestStartTimeWindowAtActLocations; +import algorithms.StateUpdates.UpdateLatestOperationStartTimeAtActLocations; +import algorithms.StateUpdates.UpdateStates; import algorithms.VehicleRoutingAlgorithms.TypedMap.AbstractKey; import algorithms.VehicleRoutingAlgorithms.TypedMap.AcceptorKey; +import algorithms.VehicleRoutingAlgorithms.TypedMap.InsertionStrategyKey; import algorithms.VehicleRoutingAlgorithms.TypedMap.RuinStrategyKey; import algorithms.VehicleRoutingAlgorithms.TypedMap.SelectorKey; import algorithms.VehicleRoutingAlgorithms.TypedMap.StrategyModuleKey; @@ -50,28 +55,25 @@ import algorithms.acceptors.SolutionAcceptor; import algorithms.selectors.SelectBest; import algorithms.selectors.SelectRandomly; import algorithms.selectors.SolutionSelector; -import basics.Job; import basics.VehicleRoutingAlgorithm; import basics.VehicleRoutingProblem; +import basics.VehicleRoutingProblem.Constraint; import basics.VehicleRoutingProblem.FleetSize; import basics.VehicleRoutingProblemSolution; import basics.algo.AlgorithmStartsListener; import basics.algo.InsertionListener; -import basics.algo.IterationStartsListener; import basics.algo.IterationWithoutImprovementBreaker; import basics.algo.PrematureAlgorithmBreaker; import basics.algo.SearchStrategy; import basics.algo.SearchStrategy.DiscoveredSolution; import basics.algo.SearchStrategyManager; import basics.algo.SearchStrategyModule; -import basics.algo.SearchStrategyModuleListener; import basics.algo.TimeBreaker; import basics.algo.VariationCoefficientBreaker; import basics.algo.VehicleRoutingAlgorithmListeners.PrioritizedVRAListener; import basics.algo.VehicleRoutingAlgorithmListeners.Priority; import basics.io.AlgorithmConfig; import basics.io.AlgorithmConfigXmlReader; -import basics.route.VehicleRoute; @@ -428,50 +430,43 @@ public class VehicleRoutingAlgorithms { } private static VehicleRoutingAlgorithm createAlgo(final VehicleRoutingProblem vrp, XMLConfiguration config, ExecutorService executorService, int nuOfThreads){ - - //fleetmanager - final VehicleFleetManager vehicleFleetManager; - if(vrp.getFleetSize().equals(FleetSize.INFINITE)){ - vehicleFleetManager = new InfiniteVehicles(vrp.getVehicles()); - - } - else if(vrp.getFleetSize().equals(FleetSize.FINITE)){ - vehicleFleetManager = new VehicleFleetManagerImpl(vrp.getVehicles()); - } - else{ - throw new IllegalStateException("fleet size can only be infinite or finite. " + - "makes sure your config file contains one of these options"); - } - + + // map to store constructed modules + TypedMap definedClasses = new TypedMap(); + + // algorithm listeners Set algorithmListeners = new HashSet(); + + // insertion listeners List insertionListeners = new ArrayList(); - algorithmListeners.add(new PrioritizedVRAListener(Priority.LOW, new SolutionVerifier())); - - final StateManagerImpl routeStates = new StateManagerImpl(); - IterationStartsListener resetStates = new IterationStartsListener() { - - @Override - public void informIterationStarts(int i, VehicleRoutingProblem problem, Collection solutions) { - routeStates.clear(); - } - }; - algorithmListeners.add(new PrioritizedVRAListener(Priority.LOW, resetStates)); + //create fleetmanager + final VehicleFleetManager vehicleFleetManager = createFleetManager(vrp); -// insertionListeners.add(new UdateCostsAtRouteLevel(routeStates,vrp.getTransportCosts(),vrp.getActivityCosts())); + //create state-manager + final StateManagerImpl stateManager = new StateManagerImpl(); -// RouteStates routeStates = new RouteStates(); -// routeStates.initialiseStateOfJobs(vrp.getJobs().values()); -// algorithmListeners.add(new PrioritizedVRAListener(Priority.LOW, routeStates)); - - TypedMap definedClasses = new TypedMap(); - /* - * initial solution - construction + * define constraints */ - AlgorithmStartsListener createInitialSolution = createInitialSolution(config,vrp,vehicleFleetManager,routeStates,algorithmListeners,definedClasses,executorService,nuOfThreads); + //constraint manager + ConstraintManager constraintManager = new ConstraintManager(); + constraintManager.addConstraint(new HardConstraints.HardTimeWindowActivityLevelConstraint(stateManager, vrp.getTransportCosts())); + + if(vrp.getProblemConstraints().contains(Constraint.DELIVERIES_FIRST)){ + constraintManager.addConstraint(new HardConstraints.HardPickupAndDeliveryBackhaulActivityLevelConstraint(stateManager)); + } + else{ + constraintManager.addConstraint(new HardConstraints.HardPickupAndDeliveryActivityLevelConstraint(stateManager)); + } + + constraintManager.addConstraint(new HardConstraints.HardPickupAndDeliveryLoadConstraint(stateManager)); + + //construct initial solution creator + AlgorithmStartsListener createInitialSolution = createInitialSolution(config,vrp,vehicleFleetManager,stateManager,algorithmListeners,definedClasses,executorService,nuOfThreads,constraintManager); if(createInitialSolution != null) algorithmListeners.add(new PrioritizedVRAListener(Priority.MEDIUM, createInitialSolution)); + //construct algorithm, i.e. search-strategies and its modules int solutionMemory = config.getInt("strategy.memory"); SearchStrategyManager searchStratManager = new SearchStrategyManager(); List strategyConfigs = config.configurationsAt("strategy.searchStrategies.searchStrategy"); @@ -483,26 +478,72 @@ public class VehicleRoutingAlgorithms { strategy.setName(name); List modulesConfig = strategyConfig.configurationsAt("modules.module"); for(HierarchicalConfiguration moduleConfig : modulesConfig){ - SearchStrategyModule module = buildModule(moduleConfig,vrp,vehicleFleetManager,routeStates,algorithmListeners,definedClasses,executorService,nuOfThreads); + SearchStrategyModule module = buildModule(moduleConfig,vrp,vehicleFleetManager,stateManager,algorithmListeners,definedClasses,executorService,nuOfThreads, constraintManager); strategy.addModule(module); } searchStratManager.addStrategy(strategy, strategyConfig.getDouble("probability")); } + + //construct algorithm VehicleRoutingAlgorithm metaAlgorithm = new VehicleRoutingAlgorithm(vrp, searchStratManager); if(config.containsKey("iterations")){ int iter = config.getInt("iterations"); metaAlgorithm.setNuOfIterations(iter); log.info("set nuOfIterations to " + iter); } - //prematureBreak + + + /* + * define stateUpdates + */ + + //reset stateManager + algorithmListeners.add(new PrioritizedVRAListener(Priority.LOW, new StateUpdates.ResetStateManager(stateManager))); + //update states +// metaAlgorithm.getSearchStrategyManager().addSearchStrategyModuleListener(new UpdateStates(stateManager, vrp.getTransportCosts(), vrp.getActivityCosts())); + StateUpdates.UpdateRouteStatesOnceTheRouteHasBeenChanged routeChangedListener = new StateUpdates.UpdateRouteStatesOnceTheRouteHasBeenChanged(vrp.getTransportCosts()); + + routeChangedListener.addInsertionStartsListener(new StateUpdates.UpdateLoadsAtStartAndEndOfRouteWhenInsertionStarts(stateManager)); + routeChangedListener.addJobInsertedListener(new StateUpdates.UpdateLoadsAtStartAndEndOfRouteWhenJobHasBeenInserted(stateManager)); + + routeChangedListener.addListener(new StateUpdates.UpdateActivityTimes()); + routeChangedListener.addListener(new StateUpdates.UpdateLoadAtActivityLevel(stateManager)); + routeChangedListener.addListener(new StateUpdates.UpdateCostsAtAllLevels(vrp.getActivityCosts(), vrp.getTransportCosts(), stateManager)); + + routeChangedListener.addListener(new StateUpdates.UpdateOccuredDeliveriesAtActivityLevel(stateManager)); + routeChangedListener.addListener(new StateUpdates.UpdateLatestOperationStartTimeAtActLocations(stateManager)); + routeChangedListener.addListener(new StateUpdates.UpdateFuturePickupsAtActivityLevel(stateManager)); + + metaAlgorithm.getSearchStrategyManager().addSearchStrategyModuleListener(routeChangedListener); + metaAlgorithm.getSearchStrategyManager().addSearchStrategyModuleListener(new RemoveEmptyVehicles(vehicleFleetManager)); + metaAlgorithm.getSearchStrategyManager().addSearchStrategyModuleListener(new ResetAndIniFleetManager(vehicleFleetManager)); + metaAlgorithm.getSearchStrategyManager().addSearchStrategyModuleListener(new VehicleSwitched(vehicleFleetManager)); + + //define prematureBreak PrematureAlgorithmBreaker prematureAlgoBreaker = getPrematureBreaker(config,algorithmListeners); metaAlgorithm.setPrematureAlgorithmBreaker(prematureAlgoBreaker); + //misc + algorithmListeners.add(new PrioritizedVRAListener(Priority.LOW, new SolutionVerifier())); + + //register listeners registerListeners(metaAlgorithm,algorithmListeners); registerInsertionListeners(definedClasses,insertionListeners); return metaAlgorithm; } + private static VehicleFleetManager createFleetManager(final VehicleRoutingProblem vrp) { + if(vrp.getFleetSize().equals(FleetSize.INFINITE)){ + return new InfiniteVehicles(vrp.getVehicles()); + + } + else if(vrp.getFleetSize().equals(FleetSize.FINITE)){ + return new VehicleFleetManagerImpl(vrp.getVehicles()); + } + throw new IllegalStateException("fleet size can only be infinite or finite. " + + "makes sure your config file contains one of these options"); + } + private static PrematureAlgorithmBreaker getPrematureBreaker(XMLConfiguration config, Set algorithmListeners) { String basedOn = config.getString("prematureBreak[@basedOn]"); if(basedOn == null){ @@ -570,7 +611,7 @@ public class VehicleRoutingAlgorithms { metaAlgorithm.getAlgorithmListeners().addAll(algorithmListeners); } - private static AlgorithmStartsListener createInitialSolution(XMLConfiguration config, final VehicleRoutingProblem vrp, VehicleFleetManager vehicleFleetManager, StateManagerImpl routeStates, Set algorithmListeners, TypedMap definedClasses, ExecutorService executorService, int nuOfThreads) { + private static AlgorithmStartsListener createInitialSolution(XMLConfiguration config, final VehicleRoutingProblem vrp, VehicleFleetManager vehicleFleetManager, StateManagerImpl routeStates, Set algorithmListeners, TypedMap definedClasses, ExecutorService executorService, int nuOfThreads, ConstraintManager constraintManager) { List modConfigs = config.configurationsAt("construction.insertion"); if(modConfigs == null) return null; if(modConfigs.isEmpty()) return null; @@ -585,7 +626,7 @@ public class VehicleRoutingAlgorithms { InsertionStrategy insertionStrategy = definedClasses.get(insertionStrategyKey); if(insertionStrategy == null){ List prioListeners = new ArrayList(); - insertionStrategy = createInsertionStrategy(modConfig, vrp, vehicleFleetManager, routeStates, prioListeners, executorService, nuOfThreads); + insertionStrategy = createInsertionStrategy(modConfig, vrp, vehicleFleetManager, routeStates, prioListeners, executorService, nuOfThreads, constraintManager); algorithmListeners.addAll(prioListeners); definedClasses.put(insertionStrategyKey,insertionStrategy); } @@ -667,7 +708,7 @@ public class VehicleRoutingAlgorithms { } private static SearchStrategyModule buildModule(HierarchicalConfiguration moduleConfig, final VehicleRoutingProblem vrp, VehicleFleetManager vehicleFleetManager, - final StateManagerImpl routeStates, Set algorithmListeners, TypedMap definedClasses, ExecutorService executorService, int nuOfThreads) { + final StateManagerImpl routeStates, Set algorithmListeners, TypedMap definedClasses, ExecutorService executorService, int nuOfThreads, ConstraintManager constraintManager) { String moduleName = moduleConfig.getString("[@name]"); if(moduleName == null) throw new IllegalStateException("module(-name) is missing."); String moduleId = moduleConfig.getString("[@id]"); @@ -716,49 +757,14 @@ public class VehicleRoutingAlgorithms { List insertionConfigs = moduleConfig.configurationsAt("insertion"); if(insertionConfigs.size() != 1) throw new IllegalStateException("this should be 1"); List prioListeners = new ArrayList(); - insertion = createInsertionStrategy(insertionConfigs.get(0), vrp, vehicleFleetManager, routeStates, prioListeners, executorService, nuOfThreads); + insertion = createInsertionStrategy(insertionConfigs.get(0), vrp, vehicleFleetManager, routeStates, prioListeners, executorService, nuOfThreads, constraintManager); algorithmListeners.addAll(prioListeners); } final InsertionStrategy final_insertion = insertion; - SearchStrategyModule module = new SearchStrategyModule() { - - private Logger logger = Logger.getLogger(SearchStrategyModule.class); - - @Override - public VehicleRoutingProblemSolution runAndGetSolution(VehicleRoutingProblemSolution vrpSolution) { - Collection ruinedJobs = ruin.ruin(vrpSolution.getRoutes()); - final_insertion.insertJobs(vrpSolution.getRoutes(), ruinedJobs); - double totalCost = RouteUtils.getTotalCost(vrpSolution.getRoutes()); - vrpSolution.setCost(totalCost); - return vrpSolution; - } - - @Override - public String toString() { - return getName(); - } - - @Override - public String getName() { - return "[name=ruin_and_recreate][ruin="+ruin+"][recreate="+final_insertion+"]"; - } - - @Override - public void addModuleListener(SearchStrategyModuleListener moduleListener) { - if(moduleListener instanceof InsertionListener){ - InsertionListener iListener = (InsertionListener) moduleListener; - if(!final_insertion.getListeners().contains(iListener)){ - logger.info("register moduleListener " + moduleListener); - final_insertion.addListener(iListener); - } - - } - - } - }; - return module; + + RuinAndRecreateModule rrModule = new RuinAndRecreateModule("ruin_and_recreate", final_insertion, ruin); + return rrModule; } - if(moduleName.equals("gendreau")){ int iterations = moduleConfig.getInt("iterations"); double share = moduleConfig.getDouble("share"); @@ -771,7 +777,6 @@ public class VehicleRoutingAlgorithms { RuinStrategy ruin = definedClasses.get(stratKey); if(ruin == null){ ruin = new RuinRadial(vrp, 0.3, new JobDistanceAvgCosts(vrp.getTransportCosts())); - ruin.addListener(new UpdateStates(routeStates, vrp.getTransportCosts(), vrp.getActivityCosts())); definedClasses.put(stratKey, ruin); } @@ -786,7 +791,7 @@ public class VehicleRoutingAlgorithms { List insertionConfigs = moduleConfig.configurationsAt("insertion"); if(insertionConfigs.size() != 1) throw new IllegalStateException("this should be 1"); List prioListeners = new ArrayList(); - insertion = createInsertionStrategy(insertionConfigs.get(0), vrp, vehicleFleetManager, routeStates, prioListeners, executorService, nuOfThreads); + insertion = createInsertionStrategy(insertionConfigs.get(0), vrp, vehicleFleetManager, routeStates, prioListeners, executorService, nuOfThreads, constraintManager); algorithmListeners.addAll(prioListeners); } Gendreau gendreau = new Gendreau(vrp, ruin, insertion); @@ -810,7 +815,6 @@ public class VehicleRoutingAlgorithms { RuinStrategy ruin = definedClasses.get(stratKey); if(ruin == null){ ruin = new RuinRadial(vrp, shareToRuin, jobDistance); - ruin.addListener(new UpdateStates(routeStates, vrp.getTransportCosts(), vrp.getActivityCosts())); definedClasses.put(stratKey, ruin); } return ruin; @@ -821,14 +825,13 @@ public class VehicleRoutingAlgorithms { RuinStrategy ruin = definedClasses.get(stratKey); if(ruin == null){ ruin = new RuinRandom(vrp, shareToRuin); - ruin.addListener(new UpdateStates(routeStates, vrp.getTransportCosts(), vrp.getActivityCosts())); definedClasses.put(stratKey, ruin); } return ruin; } - private static InsertionStrategy createInsertionStrategy(HierarchicalConfiguration moduleConfig, VehicleRoutingProblem vrp,VehicleFleetManager vehicleFleetManager, StateManagerImpl routeStates, List algorithmListeners, ExecutorService executorService, int nuOfThreads) { - InsertionStrategy insertion = InsertionFactory.createInsertion(vrp, moduleConfig, vehicleFleetManager, routeStates, algorithmListeners, executorService, nuOfThreads); + private static InsertionStrategy createInsertionStrategy(HierarchicalConfiguration moduleConfig, VehicleRoutingProblem vrp,VehicleFleetManager vehicleFleetManager, StateManagerImpl routeStates, List algorithmListeners, ExecutorService executorService, int nuOfThreads, ConstraintManager constraintManager) { + InsertionStrategy insertion = InsertionFactory.createInsertion(vrp, moduleConfig, vehicleFleetManager, routeStates, algorithmListeners, executorService, nuOfThreads, constraintManager); return insertion; } diff --git a/jsprit-core/src/main/java/algorithms/VehicleSwitchedListener.java b/jsprit-core/src/main/java/algorithms/VehicleSwitchedListener.java index a3589f5d..bd2bf713 100644 --- a/jsprit-core/src/main/java/algorithms/VehicleSwitchedListener.java +++ b/jsprit-core/src/main/java/algorithms/VehicleSwitchedListener.java @@ -1,3 +1,23 @@ +/******************************************************************************* + * 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 basics.algo.InsertionListener; diff --git a/jsprit-core/src/main/java/basics/Delivery.java b/jsprit-core/src/main/java/basics/Delivery.java new file mode 100644 index 00000000..a48dd3b5 --- /dev/null +++ b/jsprit-core/src/main/java/basics/Delivery.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * 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 basics; + + +public final class Delivery extends Service{ + + public static class Builder extends Service.Builder { + + public static Builder newInstance(String id, int size){ + return new Builder(id,size); + } + + Builder(String id, int size) { + super(id, size); + } + + public Delivery build(){ + if(locationId == null) { + if(coord == null) throw new IllegalStateException("either locationId or a coordinate must be given. But is not."); + locationId = coord.toString(); + } + this.setType("delivery"); + return new Delivery(this); + } + + } + + Delivery(Builder builder) { + super(builder); + + } + +} diff --git a/jsprit-core/src/main/java/basics/Pickup.java b/jsprit-core/src/main/java/basics/Pickup.java new file mode 100644 index 00000000..17ca689c --- /dev/null +++ b/jsprit-core/src/main/java/basics/Pickup.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * 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 basics; + +public final class Pickup extends Service { + + public static class Builder extends Service.Builder { + + public static Builder newInstance(String id, int size){ + return new Builder(id,size); + } + + Builder(String id, int size) { + super(id, size); + } + + public Pickup build(){ + if(locationId == null) { + if(coord == null) throw new IllegalStateException("either locationId or a coordinate must be given. But is not."); + locationId = coord.toString(); + } + this.setType("pickup"); + return new Pickup(this); + } + + } + + Pickup(Builder builder) { + super(builder); + } + +} diff --git a/jsprit-core/src/main/java/basics/Service.java b/jsprit-core/src/main/java/basics/Service.java index 43ea2d4c..17c52371 100644 --- a/jsprit-core/src/main/java/basics/Service.java +++ b/jsprit-core/src/main/java/basics/Service.java @@ -26,8 +26,6 @@ import util.Coordinate; public class Service implements Job { - - public static class Builder { public static Builder newInstance(String id, int size){ @@ -35,21 +33,21 @@ public class Service implements Job { } private String id; - private String locationId; - private String name = "service"; - private Coordinate coord; - private double serviceTime; - private TimeWindow timeWindow = TimeWindow.newInstance(0.0, Double.MAX_VALUE); - private int demand; + protected String locationId; + private String type = "service"; + protected Coordinate coord; + protected double serviceTime; + protected TimeWindow timeWindow = TimeWindow.newInstance(0.0, Double.MAX_VALUE); + protected int demand; - private Builder(String id, int size) { - super(); + Builder(String id, int size) { + if(size < 0) throw new IllegalArgumentException("size must be greater than or equal to zero"); this.id = id; this.demand = size; } - public Builder setName(String name){ - this.name = name; + protected Builder setType(String name){ + this.type = name; return this; } @@ -64,6 +62,7 @@ public class Service implements Job { } public Builder setServiceTime(double serviceTime){ + if(serviceTime < 0) throw new IllegalArgumentException("serviceTime must be greate than or equal to zero"); this.serviceTime = serviceTime; return this; } @@ -78,7 +77,7 @@ public class Service implements Job { if(coord == null) throw new IllegalStateException("either locationId or a coordinate must be given. But is not."); locationId = coord.toString(); } - + this.setType("service"); return new Service(this); } @@ -89,7 +88,7 @@ public class Service implements Job { private final String locationId; - private final String name; + private final String type; private final Coordinate coord; @@ -99,14 +98,14 @@ public class Service implements Job { private final int demand; - private Service(Builder builder){ + Service(Builder builder){ id = builder.id; locationId = builder.locationId; coord = builder.coord; serviceTime = builder.serviceTime; timeWindow = builder.timeWindow; demand = builder.demand; - name = builder.name; + type = builder.type; } @Override @@ -139,7 +138,7 @@ public class Service implements Job { * @return the name */ public String getType() { - return name; + return type; } @Override diff --git a/jsprit-core/src/main/java/basics/VehicleRoutingProblem.java b/jsprit-core/src/main/java/basics/VehicleRoutingProblem.java index 0fc612f2..aec7fbde 100644 --- a/jsprit-core/src/main/java/basics/VehicleRoutingProblem.java +++ b/jsprit-core/src/main/java/basics/VehicleRoutingProblem.java @@ -49,6 +49,18 @@ import basics.route.VehicleTypeImpl; */ public class VehicleRoutingProblem { + /** + * Overall problem constraints. + * + *

DELIIVERIES_FIRST corresponds to the vehicle routing problem with back hauls, i.e. before a vehicle is not entirely unloaded, no pickup can be made. + * + * @author stefan + * + */ + public enum Constraint { + DELIVERIES_FIRST + } + /** * Builder to build the routing-problem. * @@ -81,6 +93,8 @@ public class VehicleRoutingProblem { private FleetComposition fleetComposition = FleetComposition.HOMOGENEOUS; private Collection vehicleTypes; + + private Collection problemConstraints; /** * by default all locations are neighbors @@ -99,6 +113,7 @@ public class VehicleRoutingProblem { coordinates = new HashMap(); vehicleTypes = new ArrayList(); services = new ArrayList(); + problemConstraints = new ArrayList(); } /** @@ -117,6 +132,7 @@ public class VehicleRoutingProblem { } return id; } + /** * Returns the unmodifiable map of locations (mapped by their id). @@ -145,6 +161,12 @@ public class VehicleRoutingProblem { }; } + + public void addProblemConstraint(Constraint constraint){ + if(!problemConstraints.contains(constraint)) problemConstraints.add(constraint); + } + + /** * Sets routing costs. * @@ -387,6 +409,8 @@ public class VehicleRoutingProblem { private FleetComposition fleetComposition; + private Collection problemConstraints; + private VehicleRoutingProblem(Builder builder) { this.jobs = builder.jobs; this.fleetComposition = builder.fleetComposition; @@ -396,6 +420,7 @@ public class VehicleRoutingProblem { this.transportCosts = builder.transportCosts; this.activityCosts = builder.activityCosts; this.neighborhood = builder.neighborhood; + this.problemConstraints = builder.problemConstraints; log.info("initialise " + this); } @@ -441,6 +466,14 @@ public class VehicleRoutingProblem { return Collections.unmodifiableMap(jobs); } + /** + * Returns unmodifiable collection of problem-constraints. + * + * @return + */ + public Collection getProblemConstraints(){ + return Collections.unmodifiableCollection(problemConstraints); + } /** * Returns the entire, unmodifiable collection of types. diff --git a/jsprit-core/src/main/java/basics/algo/SearchStrategyListener.java b/jsprit-core/src/main/java/basics/algo/SearchStrategyListener.java index b3aea8f3..a232003d 100644 --- a/jsprit-core/src/main/java/basics/algo/SearchStrategyListener.java +++ b/jsprit-core/src/main/java/basics/algo/SearchStrategyListener.java @@ -20,6 +20,6 @@ ******************************************************************************/ package basics.algo; -public class SearchStrategyListener { +public interface SearchStrategyListener extends VehicleRoutingAlgorithmListener{ } diff --git a/jsprit-core/src/main/java/basics/algo/SearchStrategyModuleListener.java b/jsprit-core/src/main/java/basics/algo/SearchStrategyModuleListener.java index 05d171e3..f216f197 100644 --- a/jsprit-core/src/main/java/basics/algo/SearchStrategyModuleListener.java +++ b/jsprit-core/src/main/java/basics/algo/SearchStrategyModuleListener.java @@ -20,6 +20,6 @@ ******************************************************************************/ package basics.algo; -public interface SearchStrategyModuleListener { +public interface SearchStrategyModuleListener extends VehicleRoutingAlgorithmListener{ } diff --git a/jsprit-core/src/main/java/basics/io/VrpXMLReader.java b/jsprit-core/src/main/java/basics/io/VrpXMLReader.java index e7c93c63..2ede157b 100644 --- a/jsprit-core/src/main/java/basics/io/VrpXMLReader.java +++ b/jsprit-core/src/main/java/basics/io/VrpXMLReader.java @@ -38,25 +38,52 @@ import org.xml.sax.SAXException; import util.Coordinate; import util.Resource; +import basics.Delivery; +import basics.Pickup; import basics.Service; import basics.VehicleRoutingProblem; import basics.VehicleRoutingProblem.FleetComposition; import basics.VehicleRoutingProblem.FleetSize; import basics.VehicleRoutingProblemSolution; +import basics.route.DefaultTourActivityFactory; +import basics.route.DeliveryActivity; import basics.route.Driver; import basics.route.DriverImpl; import basics.route.End; +import basics.route.PickupActivity; import basics.route.ServiceActivity; import basics.route.Start; import basics.route.TimeWindow; +import basics.route.TourActivity; +import basics.route.TourActivityFactory; import basics.route.Vehicle; import basics.route.VehicleImpl; import basics.route.VehicleImpl.Builder; import basics.route.VehicleRoute; -import basics.route.VehicleType; import basics.route.VehicleTypeImpl; public class VrpXMLReader{ + + public interface ServiceBuilderFactory { + Service.Builder createBuilder(String serviceType, String id, int size); + } + + static class DefaultServiceBuilderFactory implements ServiceBuilderFactory{ + + @Override + public basics.Service.Builder createBuilder(String serviceType, String id, int size) { + if(serviceType.equals("pickup")){ + return Pickup.Builder.newInstance(id, size); + } + else if(serviceType.equals("delivery")){ + return Delivery.Builder.newInstance(id, size); + } + else{ + return Service.Builder.newInstance(id, size); + } + } + } + private static Logger logger = Logger.getLogger(VrpXMLReader.class); @@ -70,6 +97,18 @@ public class VrpXMLReader{ private Collection solutions; + private ServiceBuilderFactory serviceBuilderFactory = new DefaultServiceBuilderFactory(); + + private TourActivityFactory tourActivityFactory = new DefaultTourActivityFactory(); + + public void setTourActivityFactory(TourActivityFactory tourActivityFactory){ + this.tourActivityFactory = tourActivityFactory; + } + + public void setServiceBuilderFactory(ServiceBuilderFactory serviceBuilderFactory){ + this.serviceBuilderFactory=serviceBuilderFactory; + } + /** * @param schemaValidation the schemaValidation to set */ @@ -170,10 +209,10 @@ public class VrpXMLReader{ if(arrTime == null) throw new IllegalStateException("act.arrTime is missing."); String endTime = actConfig.getString("endTime"); if(endTime == null) throw new IllegalStateException("act.endTime is missing."); - ServiceActivity serviceActivity = ServiceActivity.newInstance(service); - serviceActivity.setArrTime(Double.parseDouble(arrTime)); - serviceActivity.setEndTime(Double.parseDouble(endTime)); - routeBuilder.addActivity(serviceActivity); + TourActivity tourActivity = tourActivityFactory.createActivity(service); + tourActivity.setArrTime(Double.parseDouble(arrTime)); + tourActivity.setEndTime(Double.parseDouble(endTime)); + routeBuilder.addActivity(tourActivity); } routes.add(routeBuilder.build()); } @@ -210,13 +249,12 @@ public class VrpXMLReader{ for(HierarchicalConfiguration serviceConfig : serviceConfigs){ String id = serviceConfig.getString("[@id]"); if(id == null) throw new IllegalStateException("service[@id] is missing."); - String name = serviceConfig.getString("[@type]"); - if(name == null) name = "service"; + String type = serviceConfig.getString("[@type]"); + if(type == null) type = "service"; String capacityDemand = serviceConfig.getString("capacity-demand"); int cap = 0; if(capacityDemand != null) cap = Integer.parseInt(capacityDemand); - Service.Builder builder = Service.Builder.newInstance(id, cap); - builder.setName(name); + Service.Builder builder = serviceBuilderFactory.createBuilder(type, id, cap); String serviceLocationId = serviceConfig.getString("locationId"); builder.setLocationId(serviceLocationId); Coordinate serviceCoord = null; @@ -235,8 +273,6 @@ public class VrpXMLReader{ builder.setLocationId(serviceCoord.toString()); } } - - if(serviceConfig.containsKey("duration")){ builder.setServiceTime(serviceConfig.getDouble("duration")); } @@ -264,15 +300,12 @@ public class VrpXMLReader{ Double fix = typeConfig.getDouble("costs.fixed"); Double timeC = typeConfig.getDouble("costs.time"); Double distC = typeConfig.getDouble("costs.distance"); -// Double start = typeConfig.getDouble("timeSchedule.start"); -// Double end = typeConfig.getDouble("timeSchedule.end"); if(typeId == null) throw new IllegalStateException("typeId is missing."); if(capacity == null) throw new IllegalStateException("capacity is missing."); VehicleTypeImpl.Builder typeBuilder = VehicleTypeImpl.Builder.newInstance(typeId, capacity); if(fix != null) typeBuilder.setFixedCost(fix); if(timeC != null) typeBuilder.setCostPerTime(timeC); if(distC != null) typeBuilder.setCostPerDistance(distC); -// if(start != null && end != null) typeBuilder.setTimeSchedule(new TimeSchedule(start, end)); VehicleTypeImpl type = typeBuilder.build(); types.put(type.getTypeId(), type); vrpBuilder.addVehicleType(type); @@ -310,7 +343,6 @@ public class VrpXMLReader{ if(start != null) builder.setEarliestStart(Double.parseDouble(start)); if(end != null) builder.setLatestArrival(Double.parseDouble(end)); VehicleImpl vehicle = builder.build(); -// vehicleMap.put(vehicle.getId(), vehicle); vrpBuilder.addVehicle(vehicle); vehicleMap.put(vehicleId, vehicle); } diff --git a/jsprit-core/src/main/java/basics/io/VrpXMLWriter.java b/jsprit-core/src/main/java/basics/io/VrpXMLWriter.java index cf2fe549..f38d874a 100644 --- a/jsprit-core/src/main/java/basics/io/VrpXMLWriter.java +++ b/jsprit-core/src/main/java/basics/io/VrpXMLWriter.java @@ -39,6 +39,7 @@ import basics.VehicleRoutingProblem; import basics.VehicleRoutingProblemSolution; import basics.route.ServiceActivity; import basics.route.TourActivity; +import basics.route.TourActivity.JobActivity; import basics.route.Vehicle; import basics.route.VehicleRoute; import basics.route.VehicleType; @@ -84,7 +85,6 @@ public class VrpXMLWriter { writeProblemType(xmlConfig); writeVehiclesAndTheirTypes(xmlConfig); writerServices(xmlConfig); -// writeShipments(xmlConfig); writeSolutions(xmlConfig); OutputFormat format = new OutputFormat(); @@ -133,8 +133,8 @@ public class VrpXMLWriter { int actCounter = 0; for(TourActivity act : route.getTourActivities().getActivities()){ xmlConfig.setProperty(solutionPath + "(" + counter + ").routes.route(" + routeCounter + ").act("+actCounter+")[@type]", act.getName()); - if(act instanceof ServiceActivity){ - xmlConfig.setProperty(solutionPath + "(" + counter + ").routes.route(" + routeCounter + ").act("+actCounter+").serviceId", ((ServiceActivity) act).getJob().getId()); + if(act instanceof JobActivity){ + xmlConfig.setProperty(solutionPath + "(" + counter + ").routes.route(" + routeCounter + ").act("+actCounter+").serviceId", ((JobActivity) act).getJob().getId()); } xmlConfig.setProperty(solutionPath + "(" + counter + ").routes.route(" + routeCounter + ").act("+actCounter+").arrTime", act.getArrTime()); xmlConfig.setProperty(solutionPath + "(" + counter + ").routes.route(" + routeCounter + ").act("+actCounter+").endTime", act.getEndTime()); @@ -169,36 +169,6 @@ public class VrpXMLWriter { } - -// private void writeShipments(XMLConf xmlConfig) { -// String shipmentPathString = "shipments.shipment"; -// int counter = 0; -// for(Job j : vrp.getJobs().values()){ -// Shipment shipment = (Shipment) j; -// xmlConfig.setProperty(shipmentPathString + "("+counter+")[@id]", shipment.getId()); -// if(shipment.getFromId() != null) xmlConfig.setProperty(shipmentPathString + "("+counter+").pickup.locationId", shipment.getFromId()); -// if(shipment.getFromCoord() != null) { -// xmlConfig.setProperty(shipmentPathString + "("+counter+").pickup.coord[@x]", shipment.getFromCoord().getX()); -// xmlConfig.setProperty(shipmentPathString + "("+counter+").pickup.coord[@y]", shipment.getFromCoord().getY()); -// } -// if(shipment.getToId() != null) xmlConfig.setProperty(shipmentPathString + "("+counter+").delivery.locationId", shipment.getToId()); -// if(shipment.getFromCoord() != null) { -// xmlConfig.setProperty(shipmentPathString + "("+counter+").delivery.coord[@x]", shipment.getToCoord().getX()); -// xmlConfig.setProperty(shipmentPathString + "("+counter+").delivery.coord[@y]", shipment.getToCoord().getY()); -// } -// xmlConfig.setProperty(shipmentPathString + "("+counter+").size", shipment.getSize()); -// xmlConfig.setProperty(shipmentPathString + "("+counter+").pickup.serviceTime", shipment.getPickupServiceTime()); -// xmlConfig.setProperty(shipmentPathString + "("+counter+").pickup.timeWindows.timeWindow(0).start", shipment.getPickupTW().getStart()); -// xmlConfig.setProperty(shipmentPathString + "("+counter+").pickup.timeWindows.timeWindow(0).end", shipment.getPickupTW().getEnd()); -// -// xmlConfig.setProperty(shipmentPathString + "("+counter+").delivery.serviceTime", shipment.getDeliveryServiceTime()); -// xmlConfig.setProperty(shipmentPathString + "("+counter+").delivery.timeWindows.timeWindow(0).start", shipment.getDeliveryTW().getStart()); -// xmlConfig.setProperty(shipmentPathString + "("+counter+").delivery.timeWindows.timeWindow(0).end", shipment.getDeliveryTW().getEnd()); -// -// counter++; -// } -// -// } private void writeProblemType(XMLConfiguration xmlConfig){ xmlConfig.setProperty("problemType.fleetSize", vrp.getFleetSize()); @@ -206,19 +176,6 @@ public class VrpXMLWriter { } private void writeVehiclesAndTheirTypes(XMLConfiguration xmlConfig) { - -// //depots -// Map depot2id = new HashMap(); -// int depotCounter = 0; -// for(Depot depot : vrp.getDepots()){ -// int depotId = depotCounter+1; -// depot2id.put(depot, depotId); -// xmlConfig.setProperty("depots.depot" + "("+depotCounter+")[@id]", (depotId)); -// xmlConfig.setProperty("depots.depot" + "("+depotCounter+").locationId", depot.getId()); -// xmlConfig.setProperty("depots.depot" + "("+depotCounter+").coord[@x]", depot.getCoord().getX()); -// xmlConfig.setProperty("depots.depot" + "("+depotCounter+").coord[@y]", depot.getCoord().getY()); -// depotCounter++; -// } //vehicles String vehiclePathString = new StringBuilder().append(Schema.VEHICLES).append("."). @@ -234,13 +191,7 @@ public class VrpXMLWriter { } xmlConfig.setProperty(vehiclePathString + "("+counter+").timeSchedule.start", vehicle.getEarliestDeparture()); xmlConfig.setProperty(vehiclePathString + "("+counter+").timeSchedule.end", vehicle.getLatestArrival()); -// if(vehicle.getLocationId() != null) xmlConfig.setProperty(vehiclePathString + "("+counter+").locationId", vehicle.getLocationId()); -// if(vehicle.getCoord() != null) { -// xmlConfig.setProperty(vehiclePathString + "("+counter+").coord[@x]", vehicle.getCoord().getX()); -// xmlConfig.setProperty(vehiclePathString + "("+counter+").coord[@y]", vehicle.getCoord().getY()); -// } -// xmlConfig.setProperty(vehiclePathString + "("+counter+").earliestStart", vehicle.getEarliestDeparture()); -// xmlConfig.setProperty(vehiclePathString + "("+counter+").latestEnd", vehicle.getLatestArrival()); + counter++; } @@ -250,44 +201,13 @@ public class VrpXMLWriter { for(VehicleType type : vrp.getTypes()){ xmlConfig.setProperty(typePathString + "("+typeCounter+").id", type.getTypeId()); xmlConfig.setProperty(typePathString + "("+typeCounter+").capacity", type.getCapacity()); -// xmlConfig.setProperty(typePathString + "("+typeCounter+").timeSchedule.start", type.getTimeSchedule().getEarliestStart()); -// xmlConfig.setProperty(typePathString + "("+typeCounter+").timeSchedule.end", type.getTimeSchedule().getLatestEnd()); xmlConfig.setProperty(typePathString + "("+typeCounter+").costs.fixed", type.getVehicleCostParams().fix); xmlConfig.setProperty(typePathString + "("+typeCounter+").costs.distance", type.getVehicleCostParams().perDistanceUnit); xmlConfig.setProperty(typePathString + "("+typeCounter+").costs.time", type.getVehicleCostParams().perTimeUnit); typeCounter++; } - -// //type2depot assignments -// int assignmentCounter = 0; -// boolean first = true; -// for(Depot depot : vrp.getDepotToVehicleTypeAssignments().keySet()){ -// if(first){ -// xmlConfig.setProperty("assignments[@type]", "vehicleType2depot"); -// } -// for(VehicleType type : vrp.getDepotToVehicleTypeAssignments().get(depot)){ -// xmlConfig.setProperty("assignments.assignment" + "("+assignmentCounter+").depotId", depot2id.get(depot)); -// xmlConfig.setProperty("assignments.assignment" + "("+assignmentCounter+").vehicleTypeId", type.getTypeId()); -// assignmentCounter++; -// } -// } -// -// //vehicle2depot assignments -// int vehicleAssignmentCounter = 0; -// boolean first_ = true; -// for(Depot depot : vrp.getDepotToVehicleAssignments().keySet()){ -// if(first_){ -// xmlConfig.setProperty("assignments[@type]", "vehicle2depot"); -// } -// for(Vehicle vehicle : vrp.getDepotToVehicleAssignments().get(depot)){ -// xmlConfig.setProperty("assignments.assignment" + "("+vehicleAssignmentCounter+").depotId", depot2id.get(depot)); -// xmlConfig.setProperty("assignments.assignment" + "("+vehicleAssignmentCounter+").vehicleId", vehicle.getId()); -// vehicleAssignmentCounter++; -// } -// } -// - + } diff --git a/jsprit-core/src/main/java/basics/route/DefaultTourActivityFactory.java b/jsprit-core/src/main/java/basics/route/DefaultTourActivityFactory.java new file mode 100644 index 00000000..449d2051 --- /dev/null +++ b/jsprit-core/src/main/java/basics/route/DefaultTourActivityFactory.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * 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 basics.route; + +import basics.Delivery; +import basics.Pickup; +import basics.Service; + +public class DefaultTourActivityFactory implements TourActivityFactory{ + + @Override + public TourActivity createActivity(Service service) { + TourActivity act; + if(service instanceof Pickup){ + act = new PickupActivity((Pickup) service); + } + else if(service instanceof Delivery){ + act = new DeliveryActivity((Delivery) service); + } + else{ + act = ServiceActivity.newInstance(service); + } + return act; + } + +} diff --git a/jsprit-core/src/main/java/basics/route/DeliveryActivity.java b/jsprit-core/src/main/java/basics/route/DeliveryActivity.java new file mode 100644 index 00000000..2a0a4f56 --- /dev/null +++ b/jsprit-core/src/main/java/basics/route/DeliveryActivity.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * 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 basics.route; + +import basics.Delivery; +import basics.route.TourActivity.JobActivity; + +public class DeliveryActivity implements JobActivity{ + + private Delivery delivery; + + private double arrTime; + + private double endTime; + + public DeliveryActivity(Delivery delivery) { + super(); + this.delivery = delivery; + } + + private DeliveryActivity(DeliveryActivity deliveryActivity){ + this.delivery=deliveryActivity.getJob(); + this.arrTime=deliveryActivity.getArrTime(); + this.endTime=deliveryActivity.getEndTime(); + } + + @Override + public int getCapacityDemand() { + return delivery.getCapacityDemand()*-1; + } + + @Override + public String getName() { + return delivery.getType(); + } + + @Override + public String getLocationId() { + return delivery.getLocationId(); + } + + @Override + public double getTheoreticalEarliestOperationStartTime() { + return delivery.getTimeWindow().getStart(); + } + + @Override + public double getTheoreticalLatestOperationStartTime() { + return delivery.getTimeWindow().getEnd(); + } + + @Override + public double getOperationTime() { + return delivery.getServiceDuration(); + } + + @Override + public double getArrTime() { + return arrTime; + } + + @Override + public double getEndTime() { + return endTime; + } + + @Override + public void setArrTime(double arrTime) { + this.arrTime=arrTime; + } + + @Override + public void setEndTime(double endTime) { + this.endTime=endTime; + } + + @Override + public TourActivity duplicate() { + return new DeliveryActivity(this); + } + + @Override + public Delivery getJob() { + return delivery; + } + +} diff --git a/jsprit-core/src/main/java/basics/route/PenaltyVehicleType.java b/jsprit-core/src/main/java/basics/route/PenaltyVehicleType.java index 29582267..9c19eb02 100644 --- a/jsprit-core/src/main/java/basics/route/PenaltyVehicleType.java +++ b/jsprit-core/src/main/java/basics/route/PenaltyVehicleType.java @@ -1,3 +1,23 @@ +/******************************************************************************* + * 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 basics.route; import basics.route.VehicleTypeImpl.VehicleCostParams; diff --git a/jsprit-core/src/main/java/basics/route/PickupActivity.java b/jsprit-core/src/main/java/basics/route/PickupActivity.java new file mode 100644 index 00000000..81907694 --- /dev/null +++ b/jsprit-core/src/main/java/basics/route/PickupActivity.java @@ -0,0 +1,106 @@ +/******************************************************************************* + * 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 basics.route; + +import basics.Pickup; +import basics.route.TourActivity.JobActivity; + +public class PickupActivity implements JobActivity{ + + private Pickup pickup; + + private double arrTime; + + private double depTime; + + public PickupActivity(Pickup pickup) { + super(); + this.pickup = pickup; + } + + private PickupActivity(PickupActivity pickupActivity){ + this.pickup=pickupActivity.getJob(); + this.arrTime=pickupActivity.getArrTime(); + this.depTime=pickupActivity.getEndTime(); + } + + @Override + public String getName() { + return pickup.getType(); + } + + @Override + public String getLocationId() { + return pickup.getLocationId(); + } + + @Override + public double getTheoreticalEarliestOperationStartTime() { + return pickup.getTimeWindow().getStart(); + } + + @Override + public double getTheoreticalLatestOperationStartTime() { + return pickup.getTimeWindow().getEnd(); + } + + @Override + public double getOperationTime() { + return pickup.getServiceDuration(); + } + + @Override + public double getArrTime() { + return arrTime; + } + + @Override + public double getEndTime() { + return depTime; + } + + @Override + public void setArrTime(double arrTime) { + this.arrTime=arrTime; + } + + @Override + public void setEndTime(double endTime) { + this.depTime=endTime; + } + + @Override + public TourActivity duplicate() { + return new PickupActivity(this); + } + + @Override + public Pickup getJob() { + return pickup; + } + + @Override + public int getCapacityDemand() { + return pickup.getCapacityDemand(); + } + + +} diff --git a/jsprit-core/src/main/java/basics/route/ServiceActivity.java b/jsprit-core/src/main/java/basics/route/ServiceActivity.java index c93334bf..838f6276 100644 --- a/jsprit-core/src/main/java/basics/route/ServiceActivity.java +++ b/jsprit-core/src/main/java/basics/route/ServiceActivity.java @@ -31,6 +31,8 @@ public class ServiceActivity implements JobActivity{ public double endTime; + public int capacityDemand; + /** * @return the arrTime */ @@ -67,18 +69,31 @@ public class ServiceActivity implements JobActivity{ return new ServiceActivity(service); } + /** + * creates a new instance of {@link ServiceActivity} with a flag that indicates whether smthing is unloaded or loaded. + * + * @param service + * @param capacityDemand + * @return + */ +// public static ServiceActivity newInstance(Service service, boolean isPickup){ +// return new ServiceActivity(service, capacityDemand); +// } + private final Service service; - private ServiceActivity(Service service) { + protected ServiceActivity(Service service) { counter++; this.service = service; + this.capacityDemand = service.getCapacityDemand(); } - - private ServiceActivity(ServiceActivity serviceActivity) { + + protected ServiceActivity(ServiceActivity serviceActivity) { counter++; this.service = serviceActivity.getJob(); this.arrTime = serviceActivity.getArrTime(); this.endTime = serviceActivity.getEndTime(); + this.capacityDemand = serviceActivity.getCapacityDemand(); } @@ -123,7 +138,7 @@ public class ServiceActivity implements JobActivity{ @Override public int getCapacityDemand() { - return service.getCapacityDemand(); + return this.capacityDemand; } @Override diff --git a/jsprit-core/src/main/java/basics/route/TourActivityFactory.java b/jsprit-core/src/main/java/basics/route/TourActivityFactory.java new file mode 100644 index 00000000..b092f8b2 --- /dev/null +++ b/jsprit-core/src/main/java/basics/route/TourActivityFactory.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * 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 basics.route; + +import basics.Service; + +public interface TourActivityFactory { + + public TourActivity createActivity(Service service); + +} diff --git a/jsprit-core/src/main/java/basics/route/VehicleType.java b/jsprit-core/src/main/java/basics/route/VehicleType.java index 9558ba62..5232fcd0 100644 --- a/jsprit-core/src/main/java/basics/route/VehicleType.java +++ b/jsprit-core/src/main/java/basics/route/VehicleType.java @@ -1,3 +1,23 @@ +/******************************************************************************* + * 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 basics.route; import basics.route.VehicleTypeImpl.VehicleCostParams; @@ -13,4 +33,4 @@ public interface VehicleType { public VehicleCostParams getVehicleCostParams(); -} \ No newline at end of file +} diff --git a/jsprit-core/src/main/java/basics/route/VehicleTypeImpl.java b/jsprit-core/src/main/java/basics/route/VehicleTypeImpl.java index 3e62c292..8b35f91d 100644 --- a/jsprit-core/src/main/java/basics/route/VehicleTypeImpl.java +++ b/jsprit-core/src/main/java/basics/route/VehicleTypeImpl.java @@ -1,3 +1,23 @@ +/******************************************************************************* + * 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 basics.route; @@ -148,4 +168,4 @@ public class VehicleTypeImpl implements VehicleType { public double getMaxVelocity() { return maxVelocity; } -} \ No newline at end of file +} diff --git a/jsprit-core/src/main/java/util/BenchmarkInstance.java b/jsprit-core/src/main/java/util/BenchmarkInstance.java index 8fa0bb68..eabc5b0f 100644 --- a/jsprit-core/src/main/java/util/BenchmarkInstance.java +++ b/jsprit-core/src/main/java/util/BenchmarkInstance.java @@ -1,3 +1,23 @@ +/******************************************************************************* + * 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 util; import basics.VehicleRoutingProblem; @@ -14,4 +34,4 @@ public class BenchmarkInstance { this.bestKnownResult = bestKnownResult; this.bestKnownVehicles = bestKnowVehicles; } -} \ No newline at end of file +} diff --git a/jsprit-core/src/main/java/util/BenchmarkResult.java b/jsprit-core/src/main/java/util/BenchmarkResult.java index a61c0398..88dfd947 100644 --- a/jsprit-core/src/main/java/util/BenchmarkResult.java +++ b/jsprit-core/src/main/java/util/BenchmarkResult.java @@ -1,3 +1,23 @@ +/******************************************************************************* + * 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 util; import org.apache.commons.math.stat.descriptive.DescriptiveStatistics; @@ -53,4 +73,4 @@ public class BenchmarkResult { return statsTimes; } -} \ No newline at end of file +} diff --git a/jsprit-core/src/main/java/util/VehicleRoutingTransportCostsMatrix.java b/jsprit-core/src/main/java/util/VehicleRoutingTransportCostsMatrix.java index 4410e18f..8caf2fc5 100644 --- a/jsprit-core/src/main/java/util/VehicleRoutingTransportCostsMatrix.java +++ b/jsprit-core/src/main/java/util/VehicleRoutingTransportCostsMatrix.java @@ -1,3 +1,23 @@ +/******************************************************************************* + * 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 util; import java.util.HashMap; diff --git a/jsprit-core/src/test/java/algorithms/BuildCVRPAlgoFromScratchTest.java b/jsprit-core/src/test/java/algorithms/BuildCVRPAlgoFromScratchTest.java index b255891e..5fa6e7d3 100644 --- a/jsprit-core/src/test/java/algorithms/BuildCVRPAlgoFromScratchTest.java +++ b/jsprit-core/src/test/java/algorithms/BuildCVRPAlgoFromScratchTest.java @@ -1,6 +1,26 @@ +/******************************************************************************* + * 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 static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; import java.util.Collection; @@ -9,6 +29,8 @@ import org.junit.Test; import util.Solutions; import algorithms.HardConstraints.HardActivityLevelConstraint; +import algorithms.StateUpdates.UpdateCostsAtRouteLevel; +import algorithms.StateUpdates.UpdateLoadAtRouteLevel; import algorithms.acceptors.AcceptNewIfBetterThanWorst; import algorithms.selectors.SelectBest; import basics.VehicleRoutingAlgorithm; @@ -36,7 +58,7 @@ public class BuildCVRPAlgoFromScratchTest { HardActivityLevelConstraint hardActLevelConstraint = new HardActivityLevelConstraint() { @Override - public boolean fulfilled(InsertionContext iFacts, TourActivity act, double arrTime) { + public boolean fulfilled(InsertionContext iFacts, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double prevActDepTime) { return true; } }; @@ -76,7 +98,7 @@ public class BuildCVRPAlgoFromScratchTest { vra.getAlgorithmListeners().addListener(clearStateManager); vra.getSearchStrategyManager().addSearchStrategyModuleListener(new RemoveEmptyVehicles(fleetManager)); - vra.getSearchStrategyManager().addSearchStrategyModuleListener(new UdateCostsAtRouteLevel(stateManager, vrp.getTransportCosts(), vrp.getActivityCosts())); + vra.getSearchStrategyManager().addSearchStrategyModuleListener(new UpdateCostsAtRouteLevel(stateManager, vrp.getTransportCosts(), vrp.getActivityCosts())); vra.getSearchStrategyManager().addSearchStrategyModuleListener(new UpdateLoadAtRouteLevel(stateManager)); VehicleRoutingProblemSolution iniSolution = new CreateInitialSolution(bestInsertion).createInitialSolution(vrp); diff --git a/jsprit-core/src/test/java/algorithms/BuildPDVRPAlgoFromScratchTest.java b/jsprit-core/src/test/java/algorithms/BuildPDVRPAlgoFromScratchTest.java new file mode 100644 index 00000000..7279b242 --- /dev/null +++ b/jsprit-core/src/test/java/algorithms/BuildPDVRPAlgoFromScratchTest.java @@ -0,0 +1,192 @@ +/******************************************************************************* + * 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.Collection; + +import org.apache.log4j.Logger; +import org.junit.Before; +import org.junit.Test; + +import util.Solutions; +import algorithms.BackwardInTimeListeners.BackwardInTimeListener; +import algorithms.ForwardInTimeListeners.ForwardInTimeListener; +import algorithms.HardConstraints.HardActivityLevelConstraintManager; +import algorithms.StateManager.StateImpl; +import algorithms.StateUpdates.UpdateActivityTimes; +import algorithms.StateUpdates.UpdateCostsAtAllLevels; +import algorithms.StateUpdates.UpdateEarliestStartTimeWindowAtActLocations; +import algorithms.StateUpdates.UpdateLatestOperationStartTimeAtActLocations; +import algorithms.acceptors.AcceptNewIfBetterThanWorst; +import algorithms.selectors.SelectBest; +import basics.Delivery; +import basics.Job; +import basics.Pickup; +import basics.VehicleRoutingAlgorithm; +import basics.VehicleRoutingProblem; +import basics.VehicleRoutingProblemSolution; +import basics.algo.InsertionStartsListener; +import basics.algo.IterationStartsListener; +import basics.algo.JobInsertedListener; +import basics.algo.SearchStrategy; +import basics.algo.SearchStrategyManager; +import basics.io.VrpXMLReader; +import basics.io.VrpXMLWriter; +import basics.route.DeliveryActivity; +import basics.route.End; +import basics.route.PickupActivity; +import basics.route.Start; +import basics.route.TourActivity; +import basics.route.VehicleRoute; + +public class BuildPDVRPAlgoFromScratchTest { + + VehicleRoutingProblem vrp; + + VehicleRoutingAlgorithm vra; + + static Logger log = Logger.getLogger(BuildPDVRPAlgoFromScratchTest.class); + + @Before + public void setup(){ + + VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance(); + new VrpXMLReader(builder).read("src/test/resources/pd_solomon_r101.xml"); + vrp = builder.build(); + + final StateManagerImpl stateManager = new StateManagerImpl(); + + HardActivityLevelConstraintManager actLevelConstraintAccumulator = new HardActivityLevelConstraintManager(); + actLevelConstraintAccumulator.addConstraint(new HardConstraints.HardPickupAndDeliveryActivityLevelConstraint(stateManager)); + actLevelConstraintAccumulator.addConstraint(new HardConstraints.HardTimeWindowActivityLevelConstraint(stateManager, vrp.getTransportCosts())); + + MarginalsCalculus marginalCalculus = new MarginalsCalculusTriangleInequality(vrp.getTransportCosts(), vrp.getActivityCosts(), actLevelConstraintAccumulator); + + CalculatesServiceInsertion serviceInsertion = new CalculatesServiceInsertion(vrp.getTransportCosts(), marginalCalculus, new HardConstraints.HardPickupAndDeliveryLoadConstraint(stateManager)); +// CalculatesServiceInsertion serviceInsertion = new CalculatesServiceInsertion(vrp.getTransportCosts(), marginalCalculus, new HardConstraints.HardLoadConstraint(stateManager)); + + VehicleFleetManager fleetManager = new InfiniteVehicles(vrp.getVehicles()); + JobInsertionCalculator finalServiceInsertion = new CalculatesVehTypeDepServiceInsertion(fleetManager, serviceInsertion); + + BestInsertion bestInsertion = new BestInsertion(finalServiceInsertion); + + RuinRadial radial = new RuinRadial(vrp, 0.15, new JobDistanceAvgCosts(vrp.getTransportCosts())); + RuinRandom random = new RuinRandom(vrp, 0.25); + + SearchStrategy randomStrategy = new SearchStrategy(new SelectBest(), new AcceptNewIfBetterThanWorst(1)); + RuinAndRecreateModule randomModule = new RuinAndRecreateModule("randomRuin_bestInsertion", bestInsertion, random); + randomStrategy.addModule(randomModule); + + SearchStrategy radialStrategy = new SearchStrategy(new SelectBest(), new AcceptNewIfBetterThanWorst(1)); + RuinAndRecreateModule radialModule = new RuinAndRecreateModule("radialRuin_bestInsertion", bestInsertion, radial); + radialStrategy.addModule(radialModule); + + SearchStrategyManager strategyManager = new SearchStrategyManager(); + strategyManager.addStrategy(radialStrategy, 0.5); + strategyManager.addStrategy(randomStrategy, 0.5); + + vra = new VehicleRoutingAlgorithm(vrp, strategyManager); + + + vra.getAlgorithmListeners().addListener(new StateUpdates.ResetStateManager(stateManager)); + + final IterateRouteForwardInTime iterateForward = new IterateRouteForwardInTime(vrp.getTransportCosts()); + + iterateForward.addListener(new UpdateActivityTimes()); + iterateForward.addListener(new UpdateEarliestStartTimeWindowAtActLocations(stateManager)); + iterateForward.addListener(new UpdateCostsAtAllLevels(vrp.getActivityCosts(), vrp.getTransportCosts(), stateManager)); + + iterateForward.addListener(new StateUpdates.UpdateOccuredDeliveriesAtActivityLevel(stateManager)); + iterateForward.addListener(new StateUpdates.UpdateLoadAtActivityLevel(stateManager)); + + final IterateRouteBackwardInTime iterateBackward = new IterateRouteBackwardInTime(vrp.getTransportCosts()); + iterateBackward.addListener(new UpdateLatestOperationStartTimeAtActLocations(stateManager)); + iterateBackward.addListener(new StateUpdates.UpdateFuturePickupsAtActivityLevel(stateManager)); + + + InsertionStartsListener loadVehicleInDepot = new InsertionStartsListener() { + + @Override + public void informInsertionStarts(Collection vehicleRoutes, Collection unassignedJobs) { + for(VehicleRoute route : vehicleRoutes){ + int loadAtDepot = 0; + int loadAtEnd = 0; + for(Job j : route.getTourActivities().getJobs()){ + if(j instanceof Delivery){ + loadAtDepot += j.getCapacityDemand(); + } + if(j instanceof Pickup){ + loadAtEnd += j.getCapacityDemand(); + } + } + stateManager.putRouteState(route, StateTypes.LOAD_AT_DEPOT, new StateImpl(loadAtDepot)); + stateManager.putRouteState(route, StateTypes.LOAD, new StateImpl(loadAtEnd)); + iterateForward.iterate(route); + iterateBackward.iterate(route); + } + } + + }; + + vra.getSearchStrategyManager().addSearchStrategyModuleListener(new RemoveEmptyVehicles(fleetManager)); + + JobInsertedListener updateLoadAfterJobHasBeenInserted = new JobInsertedListener() { + + @Override + public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) { +// log.info("insert job " + job2insert.getClass().toString() + " job " + job2insert + "" + job2insert.getCapacityDemand() + " in route " + inRoute.getTourActivities()); + + if(job2insert instanceof Delivery){ + int loadAtDepot = (int) stateManager.getRouteState(inRoute, StateTypes.LOAD_AT_DEPOT).toDouble(); +// log.info("loadAtDepot="+loadAtDepot); + stateManager.putRouteState(inRoute, StateTypes.LOAD_AT_DEPOT, new StateImpl(loadAtDepot + job2insert.getCapacityDemand())); + } + if(job2insert instanceof Pickup){ + int loadAtEnd = (int) stateManager.getRouteState(inRoute, StateTypes.LOAD).toDouble(); +// log.info("loadAtEnd="+loadAtEnd); + stateManager.putRouteState(inRoute, StateTypes.LOAD, new StateImpl(loadAtEnd + job2insert.getCapacityDemand())); + } + iterateForward.iterate(inRoute); + iterateBackward.iterate(inRoute); + } + }; + + bestInsertion.addListener(loadVehicleInDepot); + bestInsertion.addListener(updateLoadAfterJobHasBeenInserted); + + VehicleRoutingProblemSolution iniSolution = new CreateInitialSolution(bestInsertion).createInitialSolution(vrp); +// System.out.println("ini: costs="+iniSolution.getCost()+";#routes="+iniSolution.getRoutes().size()); + vra.addInitialSolution(iniSolution); + + vra.setNuOfIterations(10000); + vra.setPrematureBreak(1000); + + } + + @Test + public void test(){ + Collection solutions = vra.searchSolutions(); +// System.out.println(Solutions.getBest(solutions).getCost()); +// new VrpXMLWriter(vrp, solutions).write("output/pd_solomon_r101.xml"); + + } + +} diff --git a/jsprit-core/src/test/java/algorithms/GendreauPostOptTest.java b/jsprit-core/src/test/java/algorithms/GendreauPostOptTest.java index 27f75beb..7642b043 100644 --- a/jsprit-core/src/test/java/algorithms/GendreauPostOptTest.java +++ b/jsprit-core/src/test/java/algorithms/GendreauPostOptTest.java @@ -33,6 +33,7 @@ import org.junit.Test; import util.Coordinate; import util.ManhattanDistanceCalculator; import util.RouteUtils; +import algorithms.StateUpdates.UpdateStates; import basics.Job; import basics.Service; import basics.VehicleRoutingProblem; @@ -151,7 +152,7 @@ public class GendreauPostOptTest { activityCosts = new ExampleActivityCostFunction(); - CalculatesServiceInsertion standardServiceInsertion = new CalculatesServiceInsertion(cost, new MarginalsCalculusTriangleInequality(cost, activityCosts, new HardConstraints.HardTimeWindowConstraint(states)), new HardConstraints.HardLoadConstraint(states)); + CalculatesServiceInsertion standardServiceInsertion = new CalculatesServiceInsertion(cost, new MarginalsCalculusTriangleInequality(cost, activityCosts, new HardConstraints.HardTimeWindowActivityLevelConstraint(states, cost)), new HardConstraints.HardLoadConstraint(states)); CalculatesServiceInsertionConsideringFixCost withFixCost = new CalculatesServiceInsertionConsideringFixCost(standardServiceInsertion, states); withFixCost.setWeightOfFixCost(1.2); diff --git a/jsprit-core/src/test/java/algorithms/RefuseCollectionTest.java b/jsprit-core/src/test/java/algorithms/RefuseCollectionTest.java index 21c9574a..277b8e08 100644 --- a/jsprit-core/src/test/java/algorithms/RefuseCollectionTest.java +++ b/jsprit-core/src/test/java/algorithms/RefuseCollectionTest.java @@ -1,3 +1,23 @@ +/******************************************************************************* + * 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 static org.junit.Assert.*; diff --git a/jsprit-core/src/test/java/algorithms/TestCalculatesServiceInsertion.java b/jsprit-core/src/test/java/algorithms/TestCalculatesServiceInsertion.java index 459ae877..8ab72ed7 100644 --- a/jsprit-core/src/test/java/algorithms/TestCalculatesServiceInsertion.java +++ b/jsprit-core/src/test/java/algorithms/TestCalculatesServiceInsertion.java @@ -32,17 +32,18 @@ import org.apache.log4j.Logger; import org.junit.Before; import org.junit.Test; +import algorithms.StateUpdates.UpdateStates; import basics.Job; import basics.Service; import basics.costs.VehicleRoutingTransportCosts; import basics.route.DriverImpl; +import basics.route.DriverImpl.NoDriver; import basics.route.ServiceActivity; import basics.route.TimeWindow; import basics.route.TourActivities; import basics.route.TourActivity; import basics.route.Vehicle; import basics.route.VehicleRoute; -import basics.route.DriverImpl.NoDriver; @@ -156,7 +157,7 @@ public class TestCalculatesServiceInsertion { ExampleActivityCostFunction activityCosts = new ExampleActivityCostFunction(); - serviceInsertion = new CalculatesServiceInsertion(costs, new MarginalsCalculusTriangleInequality(costs, activityCosts, new HardConstraints.HardTimeWindowConstraint(states)), new HardConstraints.HardLoadConstraint(states)); + serviceInsertion = new CalculatesServiceInsertion(costs, new MarginalsCalculusTriangleInequality(costs, activityCosts, new HardConstraints.HardTimeWindowActivityLevelConstraint(states, costs)), new HardConstraints.HardLoadConstraint(states)); stateUpdater = new UpdateStates(states, costs, activityCosts); diff --git a/jsprit-core/src/test/java/algorithms/TestCalculatesServiceInsertionOnRouteLevel.java b/jsprit-core/src/test/java/algorithms/TestCalculatesServiceInsertionOnRouteLevel.java index 9844917b..7798a263 100644 --- a/jsprit-core/src/test/java/algorithms/TestCalculatesServiceInsertionOnRouteLevel.java +++ b/jsprit-core/src/test/java/algorithms/TestCalculatesServiceInsertionOnRouteLevel.java @@ -34,18 +34,19 @@ import org.junit.Test; import util.Coordinate; import util.ManhattanDistanceCalculator; +import algorithms.StateUpdates.UpdateStates; import basics.Job; import basics.Service; import basics.costs.VehicleRoutingTransportCosts; import basics.route.Driver; import basics.route.DriverImpl; +import basics.route.DriverImpl.NoDriver; import basics.route.ServiceActivity; import basics.route.TimeWindow; import basics.route.TourActivities; import basics.route.TourActivity; import basics.route.Vehicle; import basics.route.VehicleRoute; -import basics.route.DriverImpl.NoDriver; diff --git a/jsprit-core/src/test/java/algorithms/TestIterateRouteForwardInTime.java b/jsprit-core/src/test/java/algorithms/TestIterateRouteForwardInTime.java index e3553e2a..98f37f69 100644 --- a/jsprit-core/src/test/java/algorithms/TestIterateRouteForwardInTime.java +++ b/jsprit-core/src/test/java/algorithms/TestIterateRouteForwardInTime.java @@ -1,3 +1,23 @@ +/******************************************************************************* + * 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 static org.junit.Assert.assertEquals; @@ -10,6 +30,10 @@ import org.junit.Test; import util.Coordinate; import util.ManhattanDistanceCalculator; +import algorithms.StateUpdates.UpdateActivityTimes; +import algorithms.StateUpdates.UpdateCostsAtAllLevels; +import algorithms.StateUpdates.UpdateEarliestStartTimeWindowAtActLocations; +import algorithms.StateUpdates.UpdateLoadAtAllLevels; import basics.Job; import basics.Service; import basics.costs.DefaultVehicleRoutingActivityCosts; @@ -34,10 +58,6 @@ public class TestIterateRouteForwardInTime { TourActivities anotherTour; - - - RouteStates states; - private VehicleRoute vehicleRoute; private VehicleRoutingTransportCosts cost; @@ -46,6 +66,8 @@ public class TestIterateRouteForwardInTime { ServiceActivity secondAct; + StateManagerImpl stateManager; + @Before public void setUp(){ cost = new VehicleRoutingTransportCosts() { @@ -99,6 +121,8 @@ public class TestIterateRouteForwardInTime { tour.addActivity(secondAct); vehicleRoute = VehicleRoute.newInstance(tour,DriverImpl.noDriver(),vehicle); + + stateManager = new StateManagerImpl(); } @Test @@ -129,12 +153,11 @@ public class TestIterateRouteForwardInTime { @Test public void whenIteratingWithLoadUpdateAtActLocations_itShouldUpdateLoad() { IterateRouteForwardInTime forwardInTime = new IterateRouteForwardInTime(cost); - StateManagerImpl states = new StateManagerImpl(); - forwardInTime.addListener(new UpdateLoadAtAllLevels(states)); + forwardInTime.addListener(new UpdateLoadAtAllLevels(stateManager)); forwardInTime.iterate(vehicleRoute); - assertEquals(5.0, states.getActivityStates(firstAct).getState(StateTypes.LOAD).toDouble(), 0.01); - assertEquals(10.0, states.getActivityStates(secondAct).getState(StateTypes.LOAD).toDouble(), 0.01); + assertEquals(5.0, stateManager.getActivityState(firstAct,StateTypes.LOAD).toDouble(), 0.01); + assertEquals(10.0, stateManager.getActivityState(secondAct,StateTypes.LOAD).toDouble(), 0.01); } @@ -153,42 +176,41 @@ public class TestIterateRouteForwardInTime { @Test public void testStatesOfAct1(){ IterateRouteForwardInTime forwardInTime = new IterateRouteForwardInTime(cost); - StateManagerImpl states = new StateManagerImpl(); - forwardInTime.addListener(new UpdateLoadAtAllLevels(states)); - forwardInTime.addListener(new UpdateEarliestStartTimeWindowAtActLocations(states)); - forwardInTime.addListener(new UpdateCostsAtAllLevels(new DefaultVehicleRoutingActivityCosts(), cost, states)); + forwardInTime.addListener(new UpdateLoadAtAllLevels(stateManager)); + forwardInTime.addListener(new UpdateEarliestStartTimeWindowAtActLocations(stateManager)); + forwardInTime.addListener(new UpdateCostsAtAllLevels(new DefaultVehicleRoutingActivityCosts(), cost, stateManager)); forwardInTime.iterate(vehicleRoute); - assertEquals(10.0, states.getActivityStates(firstAct).getState(StateTypes.COSTS).toDouble(),0.05); - assertEquals(5.0, states.getActivityStates(firstAct).getState(StateTypes.LOAD).toDouble(),0.05); - assertEquals(10.0, states.getActivityStates(firstAct).getState(StateTypes.EARLIEST_OPERATION_START_TIME).toDouble(),0.05); + assertEquals(10.0, stateManager.getActivityState(firstAct, StateTypes.COSTS).toDouble(),0.05); + assertEquals(5.0, stateManager.getActivityState(firstAct, StateTypes.LOAD).toDouble(),0.05); + assertEquals(10.0, stateManager.getActivityState(firstAct, StateTypes.EARLIEST_OPERATION_START_TIME).toDouble(),0.05); // assertEquals(20.0, states.getState(tour.getActivities().get(0)).getLatestOperationStart(),0.05); } @Test public void testStatesOfAct2(){ IterateRouteForwardInTime forwardInTime = new IterateRouteForwardInTime(cost); - StateManagerImpl states = new StateManagerImpl(); - forwardInTime.addListener(new UpdateLoadAtAllLevels(states)); - forwardInTime.addListener(new UpdateEarliestStartTimeWindowAtActLocations(states)); - forwardInTime.addListener(new UpdateCostsAtAllLevels(new DefaultVehicleRoutingActivityCosts(), cost, states)); + + forwardInTime.addListener(new UpdateLoadAtAllLevels(stateManager)); + forwardInTime.addListener(new UpdateEarliestStartTimeWindowAtActLocations(stateManager)); + forwardInTime.addListener(new UpdateCostsAtAllLevels(new DefaultVehicleRoutingActivityCosts(), cost, stateManager)); forwardInTime.iterate(vehicleRoute); - assertEquals(30.0, states.getActivityStates(secondAct).getState(StateTypes.COSTS).toDouble(),0.05); - assertEquals(10.0, states.getActivityStates(secondAct).getState(StateTypes.LOAD).toDouble(),0.05); - assertEquals(30.0, states.getActivityStates(secondAct).getState(StateTypes.EARLIEST_OPERATION_START_TIME).toDouble(),0.05); + assertEquals(30.0, stateManager.getActivityState(secondAct, StateTypes.COSTS).toDouble(),0.05); + assertEquals(10.0, stateManager.getActivityState(secondAct, StateTypes.LOAD).toDouble(),0.05); + assertEquals(30.0, stateManager.getActivityState(secondAct, StateTypes.EARLIEST_OPERATION_START_TIME).toDouble(),0.05); // assertEquals(40.0, states.getState(tour.getActivities().get(1)).getLatestOperationStart(),0.05); } @Test public void testStatesOfAct3(){ IterateRouteForwardInTime forwardInTime = new IterateRouteForwardInTime(cost); - StateManagerImpl states = new StateManagerImpl(); + forwardInTime.addListener(new UpdateActivityTimes()); - forwardInTime.addListener(new UpdateCostsAtAllLevels(new DefaultVehicleRoutingActivityCosts(), cost, states)); + forwardInTime.addListener(new UpdateCostsAtAllLevels(new DefaultVehicleRoutingActivityCosts(), cost, stateManager)); forwardInTime.iterate(vehicleRoute); - assertEquals(40.0, states.getRouteStates(vehicleRoute).getState(StateTypes.COSTS).toDouble(), 0.05); + assertEquals(40.0, stateManager.getRouteState(vehicleRoute,StateTypes.COSTS).toDouble(), 0.05); assertEquals(40.0, vehicleRoute.getEnd().getArrTime(),0.05); assertEquals(50.0, vehicleRoute.getEnd().getTheoreticalLatestOperationStartTime(),0.05); } diff --git a/jsprit-core/src/test/java/algorithms/TestSchrimpf.java b/jsprit-core/src/test/java/algorithms/TestSchrimpf.java index a9c99e6e..c506aa3a 100644 --- a/jsprit-core/src/test/java/algorithms/TestSchrimpf.java +++ b/jsprit-core/src/test/java/algorithms/TestSchrimpf.java @@ -1,3 +1,23 @@ +/******************************************************************************* + * 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 org.junit.Test; diff --git a/jsprit-core/src/test/java/algorithms/TestTourStateUpdaterWithService.java b/jsprit-core/src/test/java/algorithms/TestTourStateUpdaterWithService.java index 6ced378f..1ded2d91 100644 --- a/jsprit-core/src/test/java/algorithms/TestTourStateUpdaterWithService.java +++ b/jsprit-core/src/test/java/algorithms/TestTourStateUpdaterWithService.java @@ -27,6 +27,7 @@ import org.junit.Test; import util.Coordinate; import util.ManhattanDistanceCalculator; +import algorithms.StateUpdates.UpdateStates; import basics.Job; import basics.Service; import basics.costs.VehicleRoutingTransportCosts; @@ -38,7 +39,6 @@ import basics.route.TourActivities; import basics.route.Vehicle; import basics.route.VehicleImpl; import basics.route.VehicleRoute; -import basics.route.VehicleType; import basics.route.VehicleTypeImpl; diff --git a/jsprit-core/src/test/java/basics/io/VrpReaderV2Test.java b/jsprit-core/src/test/java/basics/io/VrpReaderV2Test.java index e666cbb6..d7c12a01 100644 --- a/jsprit-core/src/test/java/basics/io/VrpReaderV2Test.java +++ b/jsprit-core/src/test/java/basics/io/VrpReaderV2Test.java @@ -125,7 +125,7 @@ public class VrpReaderV2Test { new VrpXMLReader(builder, null).read(inFileName); VehicleRoutingProblem vrp = builder.build(); Service s1 = (Service) vrp.getJobs().get("1"); - assertEquals("delivery",s1.getType()); + assertEquals("service",s1.getType()); assertEquals(1,s1.getCapacityDemand()); assertEquals(0.0,s1.getServiceDuration(),0.01); assertEquals(2, vrp.getJobs().size()); diff --git a/jsprit-core/src/test/java/basics/io/VrpWriterV2Test.java b/jsprit-core/src/test/java/basics/io/VrpWriterV2Test.java index 063ad521..65bc136a 100644 --- a/jsprit-core/src/test/java/basics/io/VrpWriterV2Test.java +++ b/jsprit-core/src/test/java/basics/io/VrpWriterV2Test.java @@ -130,8 +130,8 @@ public class VrpWriterV2Test { builder.addVehicle(v1); builder.addVehicle(v2); - Service s1 = Service.Builder.newInstance("1", 1).setLocationId("loc").setName("delivery").setServiceTime(2.0).build(); - Service s2 = Service.Builder.newInstance("2", 1).setLocationId("loc2").setName("delivery").setServiceTime(4.0).build(); + Service s1 = Service.Builder.newInstance("1", 1).setLocationId("loc").setServiceTime(2.0).build(); + Service s2 = Service.Builder.newInstance("2", 1).setLocationId("loc2").setServiceTime(4.0).build(); VehicleRoutingProblem vrp = builder.addService(s1).addService(s2).build(); new VrpXMLWriter(vrp, null).write(infileName); @@ -144,7 +144,7 @@ public class VrpWriterV2Test { Service s1_read = (Service) vrp.getJobs().get("1"); assertEquals("1", s1_read.getId()); assertEquals("loc", s1_read.getLocationId()); - assertEquals("delivery", s1_read.getType()); + assertEquals("service", s1_read.getType()); assertEquals(2.0,s1_read.getServiceDuration(),0.01); } @@ -162,8 +162,8 @@ public class VrpWriterV2Test { builder.addVehicle(v1); builder.addVehicle(v2); - Service s1 = Service.Builder.newInstance("1", 1).setLocationId("loc").setName("delivery").setServiceTime(2.0).build(); - Service s2 = Service.Builder.newInstance("2", 1).setLocationId("loc2").setName("delivery").setServiceTime(4.0).build(); + Service s1 = Service.Builder.newInstance("1", 1).setLocationId("loc").setServiceTime(2.0).build(); + Service s2 = Service.Builder.newInstance("2", 1).setLocationId("loc2").setServiceTime(4.0).build(); builder.addService(s1).addService(s2); VehicleRoutingProblem vrp = builder.build(); diff --git a/jsprit-core/src/test/java/basics/io/VrpWriterV3Test.java b/jsprit-core/src/test/java/basics/io/VrpWriterV3Test.java index 96628fff..8419968a 100644 --- a/jsprit-core/src/test/java/basics/io/VrpWriterV3Test.java +++ b/jsprit-core/src/test/java/basics/io/VrpWriterV3Test.java @@ -20,8 +20,6 @@ ******************************************************************************/ package basics.io; -import static org.junit.Assert.assertEquals; - import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -31,19 +29,15 @@ import org.junit.Test; import basics.Service; import basics.VehicleRoutingProblem; -import basics.VehicleRoutingProblemSolution; -import basics.Service.Builder; import basics.VehicleRoutingProblem.FleetComposition; import basics.VehicleRoutingProblem.FleetSize; -import basics.io.VrpXMLReader; -import basics.io.VrpXMLWriter; +import basics.VehicleRoutingProblemSolution; import basics.route.End; import basics.route.ServiceActivity; import basics.route.Start; import basics.route.Vehicle; import basics.route.VehicleImpl; import basics.route.VehicleRoute; -import basics.route.VehicleType; import basics.route.VehicleTypeImpl; public class VrpWriterV3Test { @@ -69,8 +63,8 @@ public class VrpWriterV3Test { builder.addVehicle(v1); builder.addVehicle(v2); - Service s1 = Service.Builder.newInstance("1", 1).setLocationId("loc").setName("delivery").setServiceTime(2.0).build(); - Service s2 = Service.Builder.newInstance("2", 1).setLocationId("loc2").setName("delivery").setServiceTime(4.0).build(); + Service s1 = Service.Builder.newInstance("1", 1).setLocationId("loc").setServiceTime(2.0).build(); + Service s2 = Service.Builder.newInstance("2", 1).setLocationId("loc2").setServiceTime(4.0).build(); builder.addService(s1).addService(s2); VehicleRoutingProblem vrp = builder.build(); diff --git a/jsprit-core/src/test/resources/finiteVrpForReaderV2Test.xml b/jsprit-core/src/test/resources/finiteVrpForReaderV2Test.xml index 20d9e7a0..073b87c9 100644 --- a/jsprit-core/src/test/resources/finiteVrpForReaderV2Test.xml +++ b/jsprit-core/src/test/resources/finiteVrpForReaderV2Test.xml @@ -75,7 +75,7 @@ - + j(1,5) 1 @@ -88,7 +88,7 @@ - + i(3,9) 1 diff --git a/jsprit-core/src/test/resources/infiniteWriterV2Test.xml b/jsprit-core/src/test/resources/infiniteWriterV2Test.xml index d5ce756c..5761c975 100644 --- a/jsprit-core/src/test/resources/infiniteWriterV2Test.xml +++ b/jsprit-core/src/test/resources/infiniteWriterV2Test.xml @@ -50,7 +50,7 @@ - + loc2 1 4.0 @@ -61,7 +61,7 @@ - + loc 1 2.0 @@ -82,12 +82,12 @@ noDriver v1 10.0 - + 1 20.0 30.0 - + 2 40.0 80.0 diff --git a/jsprit-core/src/test/resources/pdVRP_vrpnc1_jsprit.xml b/jsprit-core/src/test/resources/pdVRP_vrpnc1_jsprit.xml new file mode 100644 index 00000000..d35d0432 --- /dev/null +++ b/jsprit-core/src/test/resources/pdVRP_vrpnc1_jsprit.xml @@ -0,0 +1,635 @@ + + + + INFINITE + HOMOGENEOUS + + + + christophidesVehicle + christophidesType + + [x=30.0][y=40.0] + + + + 0.0 + 999999.0 + + + + + + christophidesType + 50 + + 0.0 + 1.0 + + + + + + + [x=62.0][y=63.0] + + 17 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=63.0][y=69.0] + + 6 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=46.0][y=10.0] + + 23 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=61.0][y=33.0] + + 26 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=59.0][y=15.0] + + 14 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=32.0][y=22.0] + + 9 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=45.0][y=35.0] + + 15 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=5.0][y=64.0] + + 11 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=21.0][y=10.0] + + 13 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=10.0][y=17.0] + + 27 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=5.0][y=6.0] + + 7 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=42.0][y=57.0] + + 8 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=16.0][y=57.0] + + 16 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=8.0][y=52.0] + + 10 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=7.0][y=38.0] + + 28 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=27.0][y=68.0] + + 7 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=30.0][y=48.0] + + 15 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=43.0][y=67.0] + + 14 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=58.0][y=48.0] + + 6 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=52.0][y=64.0] + + 16 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=49.0][y=49.0] + + 30 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=37.0][y=52.0] + + 7 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=17.0][y=63.0] + + 19 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=58.0][y=27.0] + + 19 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=21.0][y=47.0] + + 15 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=40.0][y=30.0] + + 21 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=38.0][y=46.0] + + 12 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=20.0][y=26.0] + + 9 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=37.0][y=69.0] + + 11 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=52.0][y=33.0] + + 11 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=31.0][y=62.0] + + 23 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=13.0][y=13.0] + + 9 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=27.0][y=23.0] + + 3 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=17.0][y=33.0] + + 41 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=36.0][y=16.0] + + 10 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=52.0][y=41.0] + + 15 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=5.0][y=25.0] + + 23 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=12.0][y=42.0] + + 21 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=42.0][y=41.0] + + 19 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=31.0][y=32.0] + + 29 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=62.0][y=42.0] + + 8 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=57.0][y=58.0] + + 28 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=48.0][y=28.0] + + 18 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=25.0][y=55.0] + + 17 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=39.0][y=10.0] + + 10 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=30.0][y=15.0] + + 16 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=25.0][y=32.0] + + 25 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=32.0][y=39.0] + + 5 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=51.0][y=21.0] + + 5 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=56.0][y=37.0] + + 10 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + diff --git a/jsprit-core/src/test/resources/pd_solomon_r101.xml b/jsprit-core/src/test/resources/pd_solomon_r101.xml new file mode 100644 index 00000000..df35bceb --- /dev/null +++ b/jsprit-core/src/test/resources/pd_solomon_r101.xml @@ -0,0 +1,1235 @@ + + + + INFINITE + HOMOGENEOUS + + + + solomonVehicle + solomonType + + 0 + + + + 0.0 + 230.0 + + + + + + solomonType + 200 + + 0.0 + 1.0 + + + + + + + [x=63.0][y=65.0] + + 8 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=2.0][y=60.0] + + 5 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=53.0][y=52.0] + + 11 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=65.0][y=55.0] + + 14 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=60.0][y=12.0] + + 31 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=20.0][y=20.0] + + 8 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=5.0][y=5.0] + + 16 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=23.0][y=3.0] + + 7 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=24.0][y=12.0] + + 5 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=42.0][y=7.0] + + 5 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=40.0][y=25.0] + + 9 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=45.0][y=10.0] + + 18 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=55.0][y=5.0] + + 29 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=65.0][y=35.0] + + 3 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=65.0][y=20.0] + + 6 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=45.0][y=30.0] + + 17 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=35.0][y=40.0] + + 16 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=41.0][y=37.0] + + 16 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=64.0][y=42.0] + + 9 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=55.0][y=45.0] + + 13 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=35.0][y=17.0] + + 7 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=41.0][y=49.0] + + 10 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=40.0][y=60.0] + + 21 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=20.0][y=50.0] + + 5 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=25.0][y=30.0] + + 3 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=15.0][y=30.0] + + 26 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=35.0][y=69.0] + + 23 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=55.0][y=20.0] + + 19 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=31.0][y=52.0] + + 27 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=55.0][y=60.0] + + 16 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=10.0][y=43.0] + + 9 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=15.0][y=60.0] + + 17 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=5.0][y=30.0] + + 2 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=20.0][y=40.0] + + 12 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=30.0][y=5.0] + + 8 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=10.0][y=20.0] + + 19 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=30.0][y=25.0] + + 23 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=15.0][y=10.0] + + 20 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=20.0][y=65.0] + + 12 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=50.0][y=35.0] + + 19 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=45.0][y=20.0] + + 11 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=45.0][y=65.0] + + 9 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=20.0][y=26.0] + + 9 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=18.0][y=18.0] + + 17 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=19.0][y=21.0] + + 10 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=25.0][y=21.0] + + 12 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=22.0][y=27.0] + + 11 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=25.0][y=24.0] + + 20 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=26.0][y=27.0] + + 27 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=18.0][y=24.0] + + 22 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=22.0][y=22.0] + + 2 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=15.0][y=19.0] + + 1 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=31.0][y=67.0] + + 3 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=30.0][y=60.0] + + 16 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=26.0][y=52.0] + + 9 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=26.0][y=35.0] + + 15 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=57.0][y=48.0] + + 23 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=61.0][y=52.0] + + 3 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=53.0][y=43.0] + + 14 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=15.0][y=47.0] + + 16 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=14.0][y=37.0] + + 11 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=56.0][y=37.0] + + 6 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=55.0][y=54.0] + + 26 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=4.0][y=18.0] + + 35 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=28.0][y=18.0] + + 26 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=11.0][y=31.0] + + 7 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=16.0][y=22.0] + + 41 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=67.0][y=5.0] + + 25 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=49.0][y=73.0] + + 25 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=37.0][y=47.0] + + 6 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=56.0][y=39.0] + + 36 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=37.0][y=56.0] + + 5 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=57.0][y=68.0] + + 15 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=47.0][y=16.0] + + 25 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=44.0][y=17.0] + + 9 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=46.0][y=13.0] + + 8 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=49.0][y=11.0] + + 18 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=49.0][y=42.0] + + 13 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=21.0][y=24.0] + + 28 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=36.0][y=26.0] + + 18 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=32.0][y=12.0] + + 7 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=53.0][y=12.0] + + 6 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=63.0][y=23.0] + + 2 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=15.0][y=77.0] + + 9 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=62.0][y=77.0] + + 20 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=24.0][y=58.0] + + 19 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=27.0][y=69.0] + + 10 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=17.0][y=34.0] + + 3 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=12.0][y=24.0] + + 13 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=6.0][y=68.0] + + 30 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=13.0][y=52.0] + + 36 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=6.0][y=38.0] + + 16 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=11.0][y=14.0] + + 18 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=8.0][y=56.0] + + 27 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=2.0][y=48.0] + + 1 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=49.0][y=58.0] + + 10 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=27.0][y=43.0] + + 9 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=37.0][y=31.0] + + 14 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=57.0][y=29.0] + + 18 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=47.0][y=47.0] + + 13 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + diff --git a/jsprit-examples/input/R101.txt b/jsprit-examples/input/R101.txt new file mode 100644 index 00000000..8a9b6e59 --- /dev/null +++ b/jsprit-examples/input/R101.txt @@ -0,0 +1,110 @@ +R101 + +VEHICLE +NUMBER CAPACITY + 25 200 + +CUSTOMER +CUST NO. XCOORD. YCOORD. DEMAND READY TIME DUE DATE SERVICE TIME + + 0 35 35 0 0 230 0 + 1 41 49 10 161 171 10 + 2 35 17 7 50 60 10 + 3 55 45 13 116 126 10 + 4 55 20 19 149 159 10 + 5 15 30 26 34 44 10 + 6 25 30 3 99 109 10 + 7 20 50 5 81 91 10 + 8 10 43 9 95 105 10 + 9 55 60 16 97 107 10 + 10 30 60 16 124 134 10 + 11 20 65 12 67 77 10 + 12 50 35 19 63 73 10 + 13 30 25 23 159 169 10 + 14 15 10 20 32 42 10 + 15 30 5 8 61 71 10 + 16 10 20 19 75 85 10 + 17 5 30 2 157 167 10 + 18 20 40 12 87 97 10 + 19 15 60 17 76 86 10 + 20 45 65 9 126 136 10 + 21 45 20 11 62 72 10 + 22 45 10 18 97 107 10 + 23 55 5 29 68 78 10 + 24 65 35 3 153 163 10 + 25 65 20 6 172 182 10 + 26 45 30 17 132 142 10 + 27 35 40 16 37 47 10 + 28 41 37 16 39 49 10 + 29 64 42 9 63 73 10 + 30 40 60 21 71 81 10 + 31 31 52 27 50 60 10 + 32 35 69 23 141 151 10 + 33 53 52 11 37 47 10 + 34 65 55 14 117 127 10 + 35 63 65 8 143 153 10 + 36 2 60 5 41 51 10 + 37 20 20 8 134 144 10 + 38 5 5 16 83 93 10 + 39 60 12 31 44 54 10 + 40 40 25 9 85 95 10 + 41 42 7 5 97 107 10 + 42 24 12 5 31 41 10 + 43 23 3 7 132 142 10 + 44 11 14 18 69 79 10 + 45 6 38 16 32 42 10 + 46 2 48 1 117 127 10 + 47 8 56 27 51 61 10 + 48 13 52 36 165 175 10 + 49 6 68 30 108 118 10 + 50 47 47 13 124 134 10 + 51 49 58 10 88 98 10 + 52 27 43 9 52 62 10 + 53 37 31 14 95 105 10 + 54 57 29 18 140 150 10 + 55 63 23 2 136 146 10 + 56 53 12 6 130 140 10 + 57 32 12 7 101 111 10 + 58 36 26 18 200 210 10 + 59 21 24 28 18 28 10 + 60 17 34 3 162 172 10 + 61 12 24 13 76 86 10 + 62 24 58 19 58 68 10 + 63 27 69 10 34 44 10 + 64 15 77 9 73 83 10 + 65 62 77 20 51 61 10 + 66 49 73 25 127 137 10 + 67 67 5 25 83 93 10 + 68 56 39 36 142 152 10 + 69 37 47 6 50 60 10 + 70 37 56 5 182 192 10 + 71 57 68 15 77 87 10 + 72 47 16 25 35 45 10 + 73 44 17 9 78 88 10 + 74 46 13 8 149 159 10 + 75 49 11 18 69 79 10 + 76 49 42 13 73 83 10 + 77 53 43 14 179 189 10 + 78 61 52 3 96 106 10 + 79 57 48 23 92 102 10 + 80 56 37 6 182 192 10 + 81 55 54 26 94 104 10 + 82 15 47 16 55 65 10 + 83 14 37 11 44 54 10 + 84 11 31 7 101 111 10 + 85 16 22 41 91 101 10 + 86 4 18 35 94 104 10 + 87 28 18 26 93 103 10 + 88 26 52 9 74 84 10 + 89 26 35 15 176 186 10 + 90 31 67 3 95 105 10 + 91 15 19 1 160 170 10 + 92 22 22 2 18 28 10 + 93 18 24 22 188 198 10 + 94 26 27 27 100 110 10 + 95 25 24 20 39 49 10 + 96 22 27 11 135 145 10 + 97 25 21 12 133 143 10 + 98 19 21 10 58 68 10 + 99 20 26 9 83 93 10 + 100 18 18 17 185 195 10 diff --git a/jsprit-examples/input/cordeau_p01.xml b/jsprit-examples/input/cordeau_p01.xml new file mode 100644 index 00000000..10970505 --- /dev/null +++ b/jsprit-examples/input/cordeau_p01.xml @@ -0,0 +1,842 @@ + + + + INFINITE + HOMOGENEOUS + + + + 1_1_cordeauVehicle + 1_cordeauType + + [x=20.0][y=20.0] + + + + 0.0 + 999999.0 + + + + 1_2_cordeauVehicle + 1_cordeauType + + [x=20.0][y=20.0] + + + + 0.0 + 999999.0 + + + + 1_3_cordeauVehicle + 1_cordeauType + + [x=20.0][y=20.0] + + + + 0.0 + 999999.0 + + + + 1_4_cordeauVehicle + 1_cordeauType + + [x=20.0][y=20.0] + + + + 0.0 + 999999.0 + + + + 2_1_cordeauVehicle + 2_cordeauType + + [x=30.0][y=40.0] + + + + 0.0 + 999999.0 + + + + 2_2_cordeauVehicle + 2_cordeauType + + [x=30.0][y=40.0] + + + + 0.0 + 999999.0 + + + + 2_3_cordeauVehicle + 2_cordeauType + + [x=30.0][y=40.0] + + + + 0.0 + 999999.0 + + + + 2_4_cordeauVehicle + 2_cordeauType + + [x=30.0][y=40.0] + + + + 0.0 + 999999.0 + + + + 3_1_cordeauVehicle + 3_cordeauType + + [x=50.0][y=30.0] + + + + 0.0 + 999999.0 + + + + 3_2_cordeauVehicle + 3_cordeauType + + [x=50.0][y=30.0] + + + + 0.0 + 999999.0 + + + + 3_3_cordeauVehicle + 3_cordeauType + + [x=50.0][y=30.0] + + + + 0.0 + 999999.0 + + + + 3_4_cordeauVehicle + 3_cordeauType + + [x=50.0][y=30.0] + + + + 0.0 + 999999.0 + + + + 4_1_cordeauVehicle + 4_cordeauType + + [x=60.0][y=50.0] + + + + 0.0 + 999999.0 + + + + 4_2_cordeauVehicle + 4_cordeauType + + [x=60.0][y=50.0] + + + + 0.0 + 999999.0 + + + + 4_3_cordeauVehicle + 4_cordeauType + + [x=60.0][y=50.0] + + + + 0.0 + 999999.0 + + + + 4_4_cordeauVehicle + 4_cordeauType + + [x=60.0][y=50.0] + + + + 0.0 + 999999.0 + + + + + + 1_cordeauType + 80 + + 0.0 + 1.0 + + + + + 2_cordeauType + 80 + + 0.0 + 1.0 + + + + + 3_cordeauType + 80 + + 0.0 + 1.0 + + + + + 4_cordeauType + 80 + + 0.0 + 1.0 + + + + + + + [x=62.0][y=63.0] + + 17 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=63.0][y=69.0] + + 6 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=46.0][y=10.0] + + 23 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=61.0][y=33.0] + + 26 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=59.0][y=15.0] + + 14 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=32.0][y=22.0] + + 9 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=45.0][y=35.0] + + 15 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=5.0][y=64.0] + + 11 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=21.0][y=10.0] + + 13 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=10.0][y=17.0] + + 27 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=5.0][y=6.0] + + 7 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=42.0][y=57.0] + + 8 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=16.0][y=57.0] + + 16 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=8.0][y=52.0] + + 10 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=7.0][y=38.0] + + 28 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=27.0][y=68.0] + + 7 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=30.0][y=48.0] + + 15 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=43.0][y=67.0] + + 14 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=58.0][y=48.0] + + 6 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=52.0][y=64.0] + + 16 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=49.0][y=49.0] + + 30 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=37.0][y=52.0] + + 7 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=58.0][y=27.0] + + 19 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=17.0][y=63.0] + + 19 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=21.0][y=47.0] + + 15 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=40.0][y=30.0] + + 21 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=38.0][y=46.0] + + 12 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=20.0][y=26.0] + + 9 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=37.0][y=69.0] + + 11 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=52.0][y=33.0] + + 11 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=31.0][y=62.0] + + 23 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=13.0][y=13.0] + + 9 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=27.0][y=23.0] + + 3 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=17.0][y=33.0] + + 41 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=36.0][y=16.0] + + 10 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=52.0][y=41.0] + + 15 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=5.0][y=25.0] + + 23 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=12.0][y=42.0] + + 21 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=42.0][y=41.0] + + 19 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=31.0][y=32.0] + + 29 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=62.0][y=42.0] + + 8 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=57.0][y=58.0] + + 28 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=48.0][y=28.0] + + 18 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=25.0][y=55.0] + + 17 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=39.0][y=10.0] + + 10 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=30.0][y=15.0] + + 16 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=25.0][y=32.0] + + 25 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=32.0][y=39.0] + + 5 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=51.0][y=21.0] + + 5 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=56.0][y=37.0] + + 10 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + diff --git a/jsprit-examples/input/cordeau_p08.xml b/jsprit-examples/input/cordeau_p08.xml new file mode 100644 index 00000000..e2d57e61 --- /dev/null +++ b/jsprit-examples/input/cordeau_p08.xml @@ -0,0 +1,3356 @@ + + + + INFINITE + HOMOGENEOUS + + + + 1_1_cordeauVehicle + 1_cordeauType + + [x=-33.0][y=33.0] + + + + 0.0 + 310.0 + + + + 1_2_cordeauVehicle + 1_cordeauType + + [x=-33.0][y=33.0] + + + + 0.0 + 310.0 + + + + 1_3_cordeauVehicle + 1_cordeauType + + [x=-33.0][y=33.0] + + + + 0.0 + 310.0 + + + + 1_4_cordeauVehicle + 1_cordeauType + + [x=-33.0][y=33.0] + + + + 0.0 + 310.0 + + + + 1_5_cordeauVehicle + 1_cordeauType + + [x=-33.0][y=33.0] + + + + 0.0 + 310.0 + + + + 1_6_cordeauVehicle + 1_cordeauType + + [x=-33.0][y=33.0] + + + + 0.0 + 310.0 + + + + 1_7_cordeauVehicle + 1_cordeauType + + [x=-33.0][y=33.0] + + + + 0.0 + 310.0 + + + + 1_8_cordeauVehicle + 1_cordeauType + + [x=-33.0][y=33.0] + + + + 0.0 + 310.0 + + + + 1_9_cordeauVehicle + 1_cordeauType + + [x=-33.0][y=33.0] + + + + 0.0 + 310.0 + + + + 1_10_cordeauVehicle + 1_cordeauType + + [x=-33.0][y=33.0] + + + + 0.0 + 310.0 + + + + 1_11_cordeauVehicle + 1_cordeauType + + [x=-33.0][y=33.0] + + + + 0.0 + 310.0 + + + + 1_12_cordeauVehicle + 1_cordeauType + + [x=-33.0][y=33.0] + + + + 0.0 + 310.0 + + + + 1_13_cordeauVehicle + 1_cordeauType + + [x=-33.0][y=33.0] + + + + 0.0 + 310.0 + + + + 1_14_cordeauVehicle + 1_cordeauType + + [x=-33.0][y=33.0] + + + + 0.0 + 310.0 + + + + 2_1_cordeauVehicle + 2_cordeauType + + [x=33.0][y=-33.0] + + + + 0.0 + 310.0 + + + + 2_2_cordeauVehicle + 2_cordeauType + + [x=33.0][y=-33.0] + + + + 0.0 + 310.0 + + + + 2_3_cordeauVehicle + 2_cordeauType + + [x=33.0][y=-33.0] + + + + 0.0 + 310.0 + + + + 2_4_cordeauVehicle + 2_cordeauType + + [x=33.0][y=-33.0] + + + + 0.0 + 310.0 + + + + 2_5_cordeauVehicle + 2_cordeauType + + [x=33.0][y=-33.0] + + + + 0.0 + 310.0 + + + + 2_6_cordeauVehicle + 2_cordeauType + + [x=33.0][y=-33.0] + + + + 0.0 + 310.0 + + + + 2_7_cordeauVehicle + 2_cordeauType + + [x=33.0][y=-33.0] + + + + 0.0 + 310.0 + + + + 2_8_cordeauVehicle + 2_cordeauType + + [x=33.0][y=-33.0] + + + + 0.0 + 310.0 + + + + 2_9_cordeauVehicle + 2_cordeauType + + [x=33.0][y=-33.0] + + + + 0.0 + 310.0 + + + + 2_10_cordeauVehicle + 2_cordeauType + + [x=33.0][y=-33.0] + + + + 0.0 + 310.0 + + + + 2_11_cordeauVehicle + 2_cordeauType + + [x=33.0][y=-33.0] + + + + 0.0 + 310.0 + + + + 2_12_cordeauVehicle + 2_cordeauType + + [x=33.0][y=-33.0] + + + + 0.0 + 310.0 + + + + 2_13_cordeauVehicle + 2_cordeauType + + [x=33.0][y=-33.0] + + + + 0.0 + 310.0 + + + + 2_14_cordeauVehicle + 2_cordeauType + + [x=33.0][y=-33.0] + + + + 0.0 + 310.0 + + + + + + 1_cordeauType + 500 + + 0.0 + 1.0 + + + + + 2_cordeauType + 500 + + 0.0 + 1.0 + + + + + + + [x=37.0][y=-90.0] + + 9 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-83.0][y=49.0] + + 74 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-54.0][y=-50.0] + + 47 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=99.0][y=81.0] + + 46 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=8.0][y=-84.0] + + 57 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=93.0][y=49.0] + + 79 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=12.0][y=48.0] + + 42 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-17.0][y=49.0] + + 79 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=32.0][y=-68.0] + + 97 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=35.0][y=-1.0] + + 83 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-44.0][y=-95.0] + + 65 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=7.0][y=59.0] + + 96 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-25.0][y=-89.0] + + 97 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=39.0][y=-49.0] + + 24 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-67.0][y=72.0] + + 69 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-80.0][y=55.0] + + 83 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=81.0][y=-86.0] + + 22 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-7.0][y=52.0] + + 43 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-3.0][y=97.0] + + 56 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=92.0][y=28.0] + + 22 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=57.0][y=95.0] + + 80 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-73.0][y=-96.0] + + 92 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-29.0][y=72.0] + + 1 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-47.0][y=12.0] + + 2 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-88.0][y=-61.0] + + 63 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=50.0][y=-37.0] + + 11 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=59.0][y=71.0] + + 98 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=54.0][y=-21.0] + + 40 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=64.0][y=-17.0] + + 8 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=40.0][y=27.0] + + 49 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=55.0][y=89.0] + + 69 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=17.0][y=-25.0] + + 93 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-88.0][y=36.0] + + 57 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-61.0][y=66.0] + + 29 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-42.0][y=-6.0] + + 23 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-46.0][y=-3.0] + + 50 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-61.0][y=26.0] + + 5 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=38.0][y=8.0] + + 3 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=26.0][y=-37.0] + + 19 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=17.0][y=-72.0] + + 53 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=19.0][y=93.0] + + 40 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-39.0][y=-67.0] + + 24 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=79.0][y=38.0] + + 8 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-67.0][y=88.0] + + 19 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=0.0][y=14.0] + + 93 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=63.0][y=-41.0] + + 39 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-59.0][y=50.0] + + 72 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=38.0][y=39.0] + + 94 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-28.0][y=39.0] + + 97 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-99.0][y=-97.0] + + 6 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-2.0][y=-47.0] + + 18 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-62.0][y=-2.0] + + 24 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=5.0][y=-41.0] + + 1 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=31.0][y=12.0] + + 43 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=52.0][y=66.0] + + 13 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-69.0][y=-19.0] + + 5 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=10.0][y=-49.0] + + 52 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-90.0][y=-68.0] + + 53 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-17.0][y=-66.0] + + 28 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-64.0][y=70.0] + + 53 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-12.0][y=10.0] + + 36 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-80.0][y=-31.0] + + 18 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=93.0][y=-50.0] + + 77 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=92.0][y=27.0] + + 14 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-4.0][y=-7.0] + + 49 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=54.0][y=-48.0] + + 58 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-47.0][y=-26.0] + + 88 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-20.0][y=-5.0] + + 28 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-22.0][y=73.0] + + 72 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=60.0][y=-39.0] + + 59 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=42.0][y=96.0] + + 51 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=29.0][y=41.0] + + 41 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=91.0][y=15.0] + + 84 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-65.0][y=0.0] + + 47 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-16.0][y=36.0] + + 36 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=24.0][y=41.0] + + 66 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-70.0][y=39.0] + + 84 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=25.0][y=58.0] + + 10 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=17.0][y=21.0] + + 37 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=54.0][y=-82.0] + + 58 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-53.0][y=88.0] + + 57 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=83.0][y=-24.0] + + 1 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-18.0][y=64.0] + + 25 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-77.0][y=-16.0] + + 50 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-61.0][y=56.0] + + 96 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-35.0][y=-54.0] + + 48 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=43.0][y=33.0] + + 58 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=85.0][y=36.0] + + 75 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=75.0][y=-18.0] + + 56 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=31.0][y=85.0] + + 67 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-18.0][y=-39.0] + + 15 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-69.0][y=19.0] + + 21 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-87.0][y=51.0] + + 98 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-96.0][y=-36.0] + + 77 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=49.0][y=8.0] + + 57 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-5.0][y=54.0] + + 39 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-26.0][y=43.0] + + 99 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-11.0][y=60.0] + + 83 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=40.0][y=61.0] + + 54 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=82.0][y=35.0] + + 86 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-92.0][y=12.0] + + 2 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=0.0][y=-78.0] + + 18 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-93.0][y=-86.0] + + 14 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=69.0][y=-46.0] + + 99 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-84.0][y=74.0] + + 55 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=49.0][y=-47.0] + + 85 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-12.0][y=85.0] + + 63 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=42.0][y=33.0] + + 60 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=16.0][y=-81.0] + + 33 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-78.0][y=53.0] + + 62 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=53.0][y=-80.0] + + 70 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-46.0][y=-26.0] + + 79 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-25.0][y=-54.0] + + 98 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=7.0][y=-4.0] + + 5 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-61.0][y=-26.0] + + 48 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=95.0][y=-9.0] + + 93 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=51.0][y=70.0] + + 31 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-53.0][y=62.0] + + 78 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=79.0][y=-62.0] + + 8 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-28.0][y=-71.0] + + 64 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-24.0][y=4.0] + + 71 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=11.0][y=96.0] + + 85 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=91.0][y=36.0] + + 50 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=62.0][y=-8.0] + + 42 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-3.0][y=17.0] + + 18 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=53.0][y=-90.0] + + 38 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-20.0][y=51.0] + + 99 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-81.0][y=37.0] + + 29 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=6.0][y=94.0] + + 3 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-19.0][y=-62.0] + + 52 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=83.0][y=-91.0] + + 98 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-7.0][y=-92.0] + + 4 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=7.0][y=31.0] + + 12 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=52.0][y=12.0] + + 50 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=60.0][y=58.0] + + 56 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-43.0][y=47.0] + + 86 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=14.0][y=89.0] + + 56 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=6.0][y=-6.0] + + 2 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-18.0][y=34.0] + + 39 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=70.0][y=99.0] + + 31 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-63.0][y=-75.0] + + 9 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=68.0][y=-29.0] + + 54 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-83.0][y=84.0] + + 81 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-1.0][y=49.0] + + 4 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-4.0][y=17.0] + + 23 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-82.0][y=-3.0] + + 11 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-94.0][y=-30.0] + + 87 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-46.0][y=-82.0] + + 15 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-86.0][y=-79.0] + + 4 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=58.0][y=-19.0] + + 29 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-43.0][y=-30.0] + + 58 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-44.0][y=7.0] + + 73 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-3.0][y=-20.0] + + 5 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=36.0][y=41.0] + + 12 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-30.0][y=-94.0] + + 3 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=88.0][y=65.0] + + 50 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=2.0][y=29.0] + + 25 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=64.0][y=37.0] + + 72 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=41.0][y=42.0] + + 90 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-70.0][y=-19.0] + + 10 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-76.0][y=55.0] + + 62 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-38.0][y=-56.0] + + 51 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-28.0][y=73.0] + + 100 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-80.0][y=-95.0] + + 29 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=7.0][y=73.0] + + 37 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=33.0][y=57.0] + + 71 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=28.0][y=93.0] + + 5 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-70.0][y=6.0] + + 85 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-37.0][y=46.0] + + 60 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-97.0][y=35.0] + + 95 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-12.0][y=42.0] + + 37 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=51.0][y=-45.0] + + 80 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=92.0][y=40.0] + + 57 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-21.0][y=77.0] + + 81 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-84.0][y=-29.0] + + 44 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-94.0][y=-20.0] + + 17 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-82.0][y=-14.0] + + 79 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=76.0][y=-22.0] + + 38 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=69.0][y=-19.0] + + 79 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=49.0][y=-71.0] + + 11 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-30.0][y=-68.0] + + 82 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=1.0][y=34.0] + + 50 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=77.0][y=-43.0] + + 73 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=77.0][y=79.0] + + 39 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=42.0][y=-15.0] + + 12 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-58.0][y=64.0] + + 6 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=25.0][y=91.0] + + 8 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=82.0][y=-97.0] + + 87 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=59.0][y=-49.0] + + 32 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=69.0][y=59.0] + + 14 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=29.0][y=33.0] + + 17 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-97.0][y=9.0] + + 19 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-58.0][y=9.0] + + 44 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-5.0][y=-39.0] + + 55 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-61.0][y=-76.0] + + 100 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=8.0][y=-22.0] + + 45 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=74.0][y=-70.0] + + 4 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=86.0][y=35.0] + + 68 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-40.0][y=-84.0] + + 77 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=93.0][y=-29.0] + + 42 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-96.0][y=85.0] + + 39 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=64.0][y=20.0] + + 25 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=1.0][y=-17.0] + + 93 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=15.0][y=98.0] + + 74 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=20.0][y=42.0] + + 84 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-46.0][y=-79.0] + + 21 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-42.0][y=63.0] + + 33 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-30.0][y=-63.0] + + 99 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=92.0][y=-17.0] + + 84 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=66.0][y=39.0] + + 71 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-36.0][y=4.0] + + 26 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=9.0][y=-79.0] + + 72 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=78.0][y=-87.0] + + 36 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=66.0][y=-48.0] + + 4 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=85.0][y=11.0] + + 98 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=71.0][y=-61.0] + + 45 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-83.0][y=-30.0] + + 33 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=82.0][y=-74.0] + + 56 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-70.0][y=85.0] + + 24 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=98.0][y=-17.0] + + 53 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-16.0][y=62.0] + + 15 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-55.0][y=39.0] + + 19 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=5.0][y=97.0] + + 19 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=0.0][y=95.0] + + 35 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=70.0][y=-14.0] + + 90 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-63.0][y=-14.0] + + 94 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-16.0][y=16.0] + + 75 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-39.0][y=61.0] + + 13 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=51.0][y=-77.0] + + 89 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-45.0][y=7.0] + + 76 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=38.0][y=-24.0] + + 3 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=70.0][y=-80.0] + + 92 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-38.0][y=-81.0] + + 78 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=26.0][y=22.0] + + 98 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=3.0][y=66.0] + + 36 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-14.0][y=44.0] + + 50 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-77.0][y=80.0] + + 43 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=96.0][y=-83.0] + + 64 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=17.0][y=-35.0] + + 65 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-66.0][y=63.0] + + 42 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=44.0][y=-84.0] + + 96 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-57.0][y=-84.0] + + 55 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-72.0][y=-87.0] + + 14 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-56.0][y=-62.0] + + 18 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=23.0][y=52.0] + + 2 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=63.0][y=-14.0] + + 22 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-19.0][y=59.0] + + 17 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-19.0][y=87.0] + + 3 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=-13.0][y=38.0] + + 28 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + diff --git a/jsprit-examples/input/deliveries_solomon_c101.xml b/jsprit-examples/input/deliveries_solomon_c101.xml new file mode 100644 index 00000000..00b54342 --- /dev/null +++ b/jsprit-examples/input/deliveries_solomon_c101.xml @@ -0,0 +1,1235 @@ + + + + INFINITE + HOMOGENEOUS + + + + solomonVehicle + solomonType + + 0 + + + + 0.0 + 1236.0 + + + + + + solomonType + 200 + + 0.0 + 1.0 + + + + + + + [x=5.0][y=35.0] + + 10 + 90.0 + + + 283.0 + 344.0 + + + + + [x=5.0][y=45.0] + + 10 + 90.0 + + + 665.0 + 716.0 + + + + + [x=8.0][y=40.0] + + 40 + 90.0 + + + 87.0 + 158.0 + + + + + [x=8.0][y=45.0] + + 20 + 90.0 + + + 751.0 + 816.0 + + + + + [x=0.0][y=45.0] + + 20 + 90.0 + + + 567.0 + 624.0 + + + + + [x=2.0][y=40.0] + + 20 + 90.0 + + + 383.0 + 434.0 + + + + + [x=0.0][y=40.0] + + 30 + 90.0 + + + 479.0 + 522.0 + + + + + [x=33.0][y=35.0] + + 10 + 90.0 + + + 16.0 + 80.0 + + + + + [x=33.0][y=32.0] + + 20 + 90.0 + + + 68.0 + 149.0 + + + + + [x=35.0][y=32.0] + + 10 + 90.0 + + + 166.0 + 235.0 + + + + + [x=35.0][y=30.0] + + 10 + 90.0 + + + 264.0 + 321.0 + + + + + [x=28.0][y=52.0] + + 20 + 90.0 + + + 812.0 + 883.0 + + + + + [x=28.0][y=55.0] + + 10 + 90.0 + + + 732.0 + 777.0 + + + + + [x=25.0][y=50.0] + + 10 + 90.0 + + + 65.0 + 144.0 + + + + + [x=25.0][y=52.0] + + 40 + 90.0 + + + 169.0 + 224.0 + + + + + [x=25.0][y=55.0] + + 10 + 90.0 + + + 622.0 + 701.0 + + + + + [x=23.0][y=52.0] + + 10 + 90.0 + + + 261.0 + 316.0 + + + + + [x=23.0][y=55.0] + + 20 + 90.0 + + + 546.0 + 593.0 + + + + + [x=20.0][y=50.0] + + 10 + 90.0 + + + 358.0 + 405.0 + + + + + [x=42.0][y=66.0] + + 10 + 90.0 + + + 65.0 + 146.0 + + + + + [x=45.0][y=70.0] + + 30 + 90.0 + + + 825.0 + 870.0 + + + + + [x=45.0][y=68.0] + + 10 + 90.0 + + + 912.0 + 967.0 + + + + + [x=20.0][y=55.0] + + 10 + 90.0 + + + 449.0 + 504.0 + + + + + [x=40.0][y=66.0] + + 20 + 90.0 + + + 170.0 + 225.0 + + + + + [x=40.0][y=69.0] + + 20 + 90.0 + + + 621.0 + 702.0 + + + + + [x=42.0][y=65.0] + + 10 + 90.0 + + + 15.0 + 67.0 + + + + + [x=10.0][y=40.0] + + 30 + 90.0 + + + 31.0 + 100.0 + + + + + [x=42.0][y=68.0] + + 10 + 90.0 + + + 727.0 + 782.0 + + + + + [x=10.0][y=35.0] + + 20 + 90.0 + + + 200.0 + 237.0 + + + + + [x=38.0][y=70.0] + + 10 + 90.0 + + + 534.0 + 605.0 + + + + + [x=38.0][y=68.0] + + 20 + 90.0 + + + 255.0 + 324.0 + + + + + [x=15.0][y=80.0] + + 10 + 90.0 + + + 278.0 + 345.0 + + + + + [x=18.0][y=75.0] + + 20 + 90.0 + + + 99.0 + 148.0 + + + + + [x=15.0][y=75.0] + + 20 + 90.0 + + + 179.0 + 254.0 + + + + + [x=20.0][y=80.0] + + 40 + 90.0 + + + 384.0 + 429.0 + + + + + [x=20.0][y=85.0] + + 40 + 90.0 + + + 475.0 + 528.0 + + + + + [x=22.0][y=75.0] + + 30 + 90.0 + + + 30.0 + 92.0 + + + + + [x=22.0][y=85.0] + + 10 + 90.0 + + + 567.0 + 620.0 + + + + + [x=35.0][y=69.0] + + 10 + 90.0 + + + 448.0 + 505.0 + + + + + [x=25.0][y=85.0] + + 20 + 90.0 + + + 652.0 + 721.0 + + + + + [x=30.0][y=52.0] + + 20 + 90.0 + + + 914.0 + 965.0 + + + + + [x=30.0][y=50.0] + + 10 + 90.0 + + + 10.0 + 73.0 + + + + + [x=55.0][y=80.0] + + 10 + 90.0 + + + 743.0 + 820.0 + + + + + [x=55.0][y=85.0] + + 20 + 90.0 + + + 647.0 + 726.0 + + + + + [x=58.0][y=75.0] + + 20 + 90.0 + + + 30.0 + 84.0 + + + + + [x=60.0][y=85.0] + + 30 + 90.0 + + + 561.0 + 622.0 + + + + + [x=60.0][y=80.0] + + 10 + 90.0 + + + 95.0 + 156.0 + + + + + [x=62.0][y=80.0] + + 30 + 90.0 + + + 196.0 + 239.0 + + + + + [x=65.0][y=82.0] + + 10 + 90.0 + + + 285.0 + 336.0 + + + + + [x=65.0][y=85.0] + + 40 + 90.0 + + + 475.0 + 518.0 + + + + + [x=67.0][y=85.0] + + 20 + 90.0 + + + 368.0 + 441.0 + + + + + [x=60.0][y=60.0] + + 10 + 90.0 + + + 836.0 + 889.0 + + + + + [x=60.0][y=55.0] + + 10 + 90.0 + + + 20.0 + 84.0 + + + + + [x=35.0][y=66.0] + + 10 + 90.0 + + + 357.0 + 410.0 + + + + + [x=65.0][y=60.0] + + 30 + 90.0 + + + 645.0 + 708.0 + + + + + [x=63.0][y=58.0] + + 10 + 90.0 + + + 737.0 + 802.0 + + + + + [x=87.0][y=30.0] + + 10 + 90.0 + + + 668.0 + 731.0 + + + + + [x=88.0][y=35.0] + + 20 + 90.0 + + + 109.0 + 170.0 + + + + + [x=88.0][y=30.0] + + 10 + 90.0 + + + 574.0 + 643.0 + + + + + [x=75.0][y=55.0] + + 20 + 90.0 + + + 369.0 + 420.0 + + + + + [x=72.0][y=55.0] + + 10 + 90.0 + + + 265.0 + 338.0 + + + + + [x=85.0][y=25.0] + + 10 + 90.0 + + + 769.0 + 820.0 + + + + + [x=85.0][y=35.0] + + 30 + 90.0 + + + 47.0 + 124.0 + + + + + [x=66.0][y=55.0] + + 10 + 90.0 + + + 173.0 + 238.0 + + + + + [x=65.0][y=55.0] + + 20 + 90.0 + + + 85.0 + 144.0 + + + + + [x=70.0][y=58.0] + + 20 + 90.0 + + + 458.0 + 523.0 + + + + + [x=68.0][y=60.0] + + 30 + 90.0 + + + 555.0 + 612.0 + + + + + [x=47.0][y=40.0] + + 10 + 90.0 + + + 12.0 + 77.0 + + + + + [x=47.0][y=35.0] + + 10 + 90.0 + + + 826.0 + 875.0 + + + + + [x=45.0][y=35.0] + + 10 + 90.0 + + + 916.0 + 969.0 + + + + + [x=45.0][y=30.0] + + 10 + 90.0 + + + 734.0 + 777.0 + + + + + [x=95.0][y=30.0] + + 30 + 90.0 + + + 387.0 + 456.0 + + + + + [x=95.0][y=35.0] + + 20 + 90.0 + + + 293.0 + 360.0 + + + + + [x=53.0][y=30.0] + + 10 + 90.0 + + + 450.0 + 505.0 + + + + + [x=92.0][y=30.0] + + 10 + 90.0 + + + 478.0 + 551.0 + + + + + [x=53.0][y=35.0] + + 50 + 90.0 + + + 353.0 + 412.0 + + + + + [x=45.0][y=65.0] + + 20 + 90.0 + + + 997.0 + 1068.0 + + + + + [x=90.0][y=35.0] + + 10 + 90.0 + + + 203.0 + 260.0 + + + + + [x=38.0][y=15.0] + + 10 + 90.0 + + + 651.0 + 740.0 + + + + + [x=38.0][y=5.0] + + 30 + 90.0 + + + 471.0 + 534.0 + + + + + [x=40.0][y=15.0] + + 40 + 90.0 + + + 35.0 + 87.0 + + + + + [x=40.0][y=5.0] + + 30 + 90.0 + + + 385.0 + 436.0 + + + + + [x=42.0][y=15.0] + + 10 + 90.0 + + + 95.0 + 158.0 + + + + + [x=48.0][y=30.0] + + 10 + 90.0 + + + 632.0 + 693.0 + + + + + [x=48.0][y=40.0] + + 10 + 90.0 + + + 76.0 + 129.0 + + + + + [x=50.0][y=35.0] + + 20 + 90.0 + + + 262.0 + 317.0 + + + + + [x=50.0][y=40.0] + + 50 + 90.0 + + + 171.0 + 218.0 + + + + + [x=35.0][y=5.0] + + 20 + 90.0 + + + 562.0 + 629.0 + + + + + [x=50.0][y=30.0] + + 10 + 90.0 + + + 531.0 + 610.0 + + + + + [x=28.0][y=35.0] + + 10 + 90.0 + + + 1001.0 + 1066.0 + + + + + [x=28.0][y=30.0] + + 10 + 90.0 + + + 632.0 + 693.0 + + + + + [x=30.0][y=30.0] + + 10 + 90.0 + + + 541.0 + 600.0 + + + + + [x=32.0][y=30.0] + + 10 + 90.0 + + + 359.0 + 412.0 + + + + + [x=30.0][y=35.0] + + 10 + 90.0 + + + 1054.0 + 1127.0 + + + + + [x=30.0][y=32.0] + + 30 + 90.0 + + + 448.0 + 509.0 + + + + + [x=25.0][y=30.0] + + 10 + 90.0 + + + 725.0 + 786.0 + + + + + [x=25.0][y=35.0] + + 10 + 90.0 + + + 912.0 + 969.0 + + + + + [x=44.0][y=5.0] + + 20 + 90.0 + + + 286.0 + 347.0 + + + + + [x=42.0][y=10.0] + + 40 + 90.0 + + + 186.0 + 257.0 + + + + + [x=26.0][y=32.0] + + 10 + 90.0 + + + 815.0 + 880.0 + + + + + diff --git a/jsprit-examples/input/pd_christophides_vrpnc1_vcap50.xml b/jsprit-examples/input/pd_christophides_vrpnc1_vcap50.xml new file mode 100644 index 00000000..d35d0432 --- /dev/null +++ b/jsprit-examples/input/pd_christophides_vrpnc1_vcap50.xml @@ -0,0 +1,635 @@ + + + + INFINITE + HOMOGENEOUS + + + + christophidesVehicle + christophidesType + + [x=30.0][y=40.0] + + + + 0.0 + 999999.0 + + + + + + christophidesType + 50 + + 0.0 + 1.0 + + + + + + + [x=62.0][y=63.0] + + 17 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=63.0][y=69.0] + + 6 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=46.0][y=10.0] + + 23 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=61.0][y=33.0] + + 26 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=59.0][y=15.0] + + 14 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=32.0][y=22.0] + + 9 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=45.0][y=35.0] + + 15 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=5.0][y=64.0] + + 11 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=21.0][y=10.0] + + 13 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=10.0][y=17.0] + + 27 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=5.0][y=6.0] + + 7 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=42.0][y=57.0] + + 8 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=16.0][y=57.0] + + 16 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=8.0][y=52.0] + + 10 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=7.0][y=38.0] + + 28 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=27.0][y=68.0] + + 7 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=30.0][y=48.0] + + 15 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=43.0][y=67.0] + + 14 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=58.0][y=48.0] + + 6 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=52.0][y=64.0] + + 16 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=49.0][y=49.0] + + 30 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=37.0][y=52.0] + + 7 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=17.0][y=63.0] + + 19 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=58.0][y=27.0] + + 19 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=21.0][y=47.0] + + 15 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=40.0][y=30.0] + + 21 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=38.0][y=46.0] + + 12 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=20.0][y=26.0] + + 9 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=37.0][y=69.0] + + 11 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=52.0][y=33.0] + + 11 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=31.0][y=62.0] + + 23 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=13.0][y=13.0] + + 9 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=27.0][y=23.0] + + 3 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=17.0][y=33.0] + + 41 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=36.0][y=16.0] + + 10 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=52.0][y=41.0] + + 15 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=5.0][y=25.0] + + 23 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=12.0][y=42.0] + + 21 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=42.0][y=41.0] + + 19 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=31.0][y=32.0] + + 29 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=62.0][y=42.0] + + 8 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=57.0][y=58.0] + + 28 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=48.0][y=28.0] + + 18 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=25.0][y=55.0] + + 17 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=39.0][y=10.0] + + 10 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=30.0][y=15.0] + + 16 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=25.0][y=32.0] + + 25 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=32.0][y=39.0] + + 5 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=51.0][y=21.0] + + 5 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=56.0][y=37.0] + + 10 + 0.0 + + + 0.0 + 1.7976931348623157E308 + + + + + diff --git a/jsprit-examples/input/pickups_and_deliveries_solomon_c101.xml b/jsprit-examples/input/pickups_and_deliveries_solomon_c101.xml new file mode 100644 index 00000000..b7cdbd74 --- /dev/null +++ b/jsprit-examples/input/pickups_and_deliveries_solomon_c101.xml @@ -0,0 +1,1235 @@ + + + + INFINITE + HOMOGENEOUS + + + + solomonVehicle + solomonType + + 0 + + + + 0.0 + 1236.0 + + + + + + solomonType + 200 + + 0.0 + 1.0 + + + + + + + [x=5.0][y=35.0] + + 10 + 90.0 + + + 283.0 + 344.0 + + + + + [x=5.0][y=45.0] + + 10 + 90.0 + + + 665.0 + 716.0 + + + + + [x=8.0][y=40.0] + + 40 + 90.0 + + + 87.0 + 158.0 + + + + + [x=8.0][y=45.0] + + 20 + 90.0 + + + 751.0 + 816.0 + + + + + [x=0.0][y=45.0] + + 20 + 90.0 + + + 567.0 + 624.0 + + + + + [x=2.0][y=40.0] + + 20 + 90.0 + + + 383.0 + 434.0 + + + + + [x=0.0][y=40.0] + + 30 + 90.0 + + + 479.0 + 522.0 + + + + + [x=33.0][y=35.0] + + 10 + 90.0 + + + 16.0 + 80.0 + + + + + [x=33.0][y=32.0] + + 20 + 90.0 + + + 68.0 + 149.0 + + + + + [x=35.0][y=32.0] + + 10 + 90.0 + + + 166.0 + 235.0 + + + + + [x=35.0][y=30.0] + + 10 + 90.0 + + + 264.0 + 321.0 + + + + + [x=28.0][y=52.0] + + 20 + 90.0 + + + 812.0 + 883.0 + + + + + [x=28.0][y=55.0] + + 10 + 90.0 + + + 732.0 + 777.0 + + + + + [x=25.0][y=50.0] + + 10 + 90.0 + + + 65.0 + 144.0 + + + + + [x=25.0][y=52.0] + + 40 + 90.0 + + + 169.0 + 224.0 + + + + + [x=25.0][y=55.0] + + 10 + 90.0 + + + 622.0 + 701.0 + + + + + [x=23.0][y=52.0] + + 10 + 90.0 + + + 261.0 + 316.0 + + + + + [x=23.0][y=55.0] + + 20 + 90.0 + + + 546.0 + 593.0 + + + + + [x=20.0][y=50.0] + + 10 + 90.0 + + + 358.0 + 405.0 + + + + + [x=42.0][y=66.0] + + 10 + 90.0 + + + 65.0 + 146.0 + + + + + [x=45.0][y=70.0] + + 30 + 90.0 + + + 825.0 + 870.0 + + + + + [x=45.0][y=68.0] + + 10 + 90.0 + + + 912.0 + 967.0 + + + + + [x=20.0][y=55.0] + + 10 + 90.0 + + + 449.0 + 504.0 + + + + + [x=40.0][y=66.0] + + 20 + 90.0 + + + 170.0 + 225.0 + + + + + [x=40.0][y=69.0] + + 20 + 90.0 + + + 621.0 + 702.0 + + + + + [x=42.0][y=65.0] + + 10 + 90.0 + + + 15.0 + 67.0 + + + + + [x=10.0][y=40.0] + + 30 + 90.0 + + + 31.0 + 100.0 + + + + + [x=42.0][y=68.0] + + 10 + 90.0 + + + 727.0 + 782.0 + + + + + [x=10.0][y=35.0] + + 20 + 90.0 + + + 200.0 + 237.0 + + + + + [x=38.0][y=70.0] + + 10 + 90.0 + + + 534.0 + 605.0 + + + + + [x=38.0][y=68.0] + + 20 + 90.0 + + + 255.0 + 324.0 + + + + + [x=15.0][y=80.0] + + 10 + 90.0 + + + 278.0 + 345.0 + + + + + [x=18.0][y=75.0] + + 20 + 90.0 + + + 99.0 + 148.0 + + + + + [x=15.0][y=75.0] + + 20 + 90.0 + + + 179.0 + 254.0 + + + + + [x=20.0][y=80.0] + + 40 + 90.0 + + + 384.0 + 429.0 + + + + + [x=20.0][y=85.0] + + 40 + 90.0 + + + 475.0 + 528.0 + + + + + [x=22.0][y=75.0] + + 30 + 90.0 + + + 30.0 + 92.0 + + + + + [x=22.0][y=85.0] + + 10 + 90.0 + + + 567.0 + 620.0 + + + + + [x=35.0][y=69.0] + + 10 + 90.0 + + + 448.0 + 505.0 + + + + + [x=25.0][y=85.0] + + 20 + 90.0 + + + 652.0 + 721.0 + + + + + [x=30.0][y=52.0] + + 20 + 90.0 + + + 914.0 + 965.0 + + + + + [x=30.0][y=50.0] + + 10 + 90.0 + + + 10.0 + 73.0 + + + + + [x=55.0][y=80.0] + + 10 + 90.0 + + + 743.0 + 820.0 + + + + + [x=55.0][y=85.0] + + 20 + 90.0 + + + 647.0 + 726.0 + + + + + [x=58.0][y=75.0] + + 20 + 90.0 + + + 30.0 + 84.0 + + + + + [x=60.0][y=85.0] + + 30 + 90.0 + + + 561.0 + 622.0 + + + + + [x=60.0][y=80.0] + + 10 + 90.0 + + + 95.0 + 156.0 + + + + + [x=62.0][y=80.0] + + 30 + 90.0 + + + 196.0 + 239.0 + + + + + [x=65.0][y=82.0] + + 10 + 90.0 + + + 285.0 + 336.0 + + + + + [x=65.0][y=85.0] + + 40 + 90.0 + + + 475.0 + 518.0 + + + + + [x=67.0][y=85.0] + + 20 + 90.0 + + + 368.0 + 441.0 + + + + + [x=60.0][y=60.0] + + 10 + 90.0 + + + 836.0 + 889.0 + + + + + [x=60.0][y=55.0] + + 10 + 90.0 + + + 20.0 + 84.0 + + + + + [x=35.0][y=66.0] + + 10 + 90.0 + + + 357.0 + 410.0 + + + + + [x=65.0][y=60.0] + + 30 + 90.0 + + + 645.0 + 708.0 + + + + + [x=63.0][y=58.0] + + 10 + 90.0 + + + 737.0 + 802.0 + + + + + [x=87.0][y=30.0] + + 10 + 90.0 + + + 668.0 + 731.0 + + + + + [x=88.0][y=35.0] + + 20 + 90.0 + + + 109.0 + 170.0 + + + + + [x=88.0][y=30.0] + + 10 + 90.0 + + + 574.0 + 643.0 + + + + + [x=75.0][y=55.0] + + 20 + 90.0 + + + 369.0 + 420.0 + + + + + [x=72.0][y=55.0] + + 10 + 90.0 + + + 265.0 + 338.0 + + + + + [x=85.0][y=25.0] + + 10 + 90.0 + + + 769.0 + 820.0 + + + + + [x=85.0][y=35.0] + + 30 + 90.0 + + + 47.0 + 124.0 + + + + + [x=66.0][y=55.0] + + 10 + 90.0 + + + 173.0 + 238.0 + + + + + [x=65.0][y=55.0] + + 20 + 90.0 + + + 85.0 + 144.0 + + + + + [x=70.0][y=58.0] + + 20 + 90.0 + + + 458.0 + 523.0 + + + + + [x=68.0][y=60.0] + + 30 + 90.0 + + + 555.0 + 612.0 + + + + + [x=47.0][y=40.0] + + 10 + 90.0 + + + 12.0 + 77.0 + + + + + [x=47.0][y=35.0] + + 10 + 90.0 + + + 826.0 + 875.0 + + + + + [x=45.0][y=35.0] + + 10 + 90.0 + + + 916.0 + 969.0 + + + + + [x=45.0][y=30.0] + + 10 + 90.0 + + + 734.0 + 777.0 + + + + + [x=95.0][y=30.0] + + 30 + 90.0 + + + 387.0 + 456.0 + + + + + [x=95.0][y=35.0] + + 20 + 90.0 + + + 293.0 + 360.0 + + + + + [x=53.0][y=30.0] + + 10 + 90.0 + + + 450.0 + 505.0 + + + + + [x=92.0][y=30.0] + + 10 + 90.0 + + + 478.0 + 551.0 + + + + + [x=53.0][y=35.0] + + 50 + 90.0 + + + 353.0 + 412.0 + + + + + [x=45.0][y=65.0] + + 20 + 90.0 + + + 997.0 + 1068.0 + + + + + [x=90.0][y=35.0] + + 10 + 90.0 + + + 203.0 + 260.0 + + + + + [x=38.0][y=15.0] + + 10 + 90.0 + + + 651.0 + 740.0 + + + + + [x=38.0][y=5.0] + + 30 + 90.0 + + + 471.0 + 534.0 + + + + + [x=40.0][y=15.0] + + 40 + 90.0 + + + 35.0 + 87.0 + + + + + [x=40.0][y=5.0] + + 30 + 90.0 + + + 385.0 + 436.0 + + + + + [x=42.0][y=15.0] + + 10 + 90.0 + + + 95.0 + 158.0 + + + + + [x=48.0][y=30.0] + + 10 + 90.0 + + + 632.0 + 693.0 + + + + + [x=48.0][y=40.0] + + 10 + 90.0 + + + 76.0 + 129.0 + + + + + [x=50.0][y=35.0] + + 20 + 90.0 + + + 262.0 + 317.0 + + + + + [x=50.0][y=40.0] + + 50 + 90.0 + + + 171.0 + 218.0 + + + + + [x=35.0][y=5.0] + + 20 + 90.0 + + + 562.0 + 629.0 + + + + + [x=50.0][y=30.0] + + 10 + 90.0 + + + 531.0 + 610.0 + + + + + [x=28.0][y=35.0] + + 10 + 90.0 + + + 1001.0 + 1066.0 + + + + + [x=28.0][y=30.0] + + 10 + 90.0 + + + 632.0 + 693.0 + + + + + [x=30.0][y=30.0] + + 10 + 90.0 + + + 541.0 + 600.0 + + + + + [x=32.0][y=30.0] + + 10 + 90.0 + + + 359.0 + 412.0 + + + + + [x=30.0][y=35.0] + + 10 + 90.0 + + + 1054.0 + 1127.0 + + + + + [x=30.0][y=32.0] + + 30 + 90.0 + + + 448.0 + 509.0 + + + + + [x=25.0][y=30.0] + + 10 + 90.0 + + + 725.0 + 786.0 + + + + + [x=25.0][y=35.0] + + 10 + 90.0 + + + 912.0 + 969.0 + + + + + [x=44.0][y=5.0] + + 20 + 90.0 + + + 286.0 + 347.0 + + + + + [x=42.0][y=10.0] + + 40 + 90.0 + + + 186.0 + 257.0 + + + + + [x=26.0][y=32.0] + + 10 + 90.0 + + + 815.0 + 880.0 + + + + + diff --git a/jsprit-examples/input/pickups_and_deliveries_solomon_c101_withoutTWs.xml b/jsprit-examples/input/pickups_and_deliveries_solomon_c101_withoutTWs.xml new file mode 100644 index 00000000..928e7774 --- /dev/null +++ b/jsprit-examples/input/pickups_and_deliveries_solomon_c101_withoutTWs.xml @@ -0,0 +1,1235 @@ + + + + INFINITE + HOMOGENEOUS + + + + solomonVehicle + solomonType + + 0 + + + + 0.0 + 1236.0 + + + + + + solomonType + 200 + + 0.0 + 1.0 + + + + + + + [x=5.0][y=35.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=5.0][y=45.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=8.0][y=40.0] + + 40 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=8.0][y=45.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=0.0][y=45.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=2.0][y=40.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=0.0][y=40.0] + + 30 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=33.0][y=35.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=33.0][y=32.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=35.0][y=32.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=35.0][y=30.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=28.0][y=52.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=28.0][y=55.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=25.0][y=50.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=25.0][y=52.0] + + 40 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=25.0][y=55.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=23.0][y=52.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=23.0][y=55.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=20.0][y=50.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=42.0][y=66.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=45.0][y=70.0] + + 30 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=45.0][y=68.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=20.0][y=55.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=40.0][y=66.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=40.0][y=69.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=42.0][y=65.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=10.0][y=40.0] + + 30 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=42.0][y=68.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=10.0][y=35.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=38.0][y=70.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=38.0][y=68.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=15.0][y=80.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=18.0][y=75.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=15.0][y=75.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=20.0][y=80.0] + + 40 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=20.0][y=85.0] + + 40 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=22.0][y=75.0] + + 30 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=22.0][y=85.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=35.0][y=69.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=25.0][y=85.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=30.0][y=52.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=30.0][y=50.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=55.0][y=80.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=55.0][y=85.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=58.0][y=75.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=60.0][y=85.0] + + 30 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=60.0][y=80.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=62.0][y=80.0] + + 30 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=65.0][y=82.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=65.0][y=85.0] + + 40 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=67.0][y=85.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=60.0][y=60.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=60.0][y=55.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=35.0][y=66.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=65.0][y=60.0] + + 30 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=63.0][y=58.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=87.0][y=30.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=88.0][y=35.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=88.0][y=30.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=75.0][y=55.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=72.0][y=55.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=85.0][y=25.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=85.0][y=35.0] + + 30 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=66.0][y=55.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=65.0][y=55.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=70.0][y=58.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=68.0][y=60.0] + + 30 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=47.0][y=40.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=47.0][y=35.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=45.0][y=35.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=45.0][y=30.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=95.0][y=30.0] + + 30 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=95.0][y=35.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=53.0][y=30.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=92.0][y=30.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=53.0][y=35.0] + + 50 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=45.0][y=65.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=90.0][y=35.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=38.0][y=15.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=38.0][y=5.0] + + 30 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=40.0][y=15.0] + + 40 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=40.0][y=5.0] + + 30 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=42.0][y=15.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=48.0][y=30.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=48.0][y=40.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=50.0][y=35.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=50.0][y=40.0] + + 50 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=35.0][y=5.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=50.0][y=30.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=28.0][y=35.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=28.0][y=30.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=30.0][y=30.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=32.0][y=30.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=30.0][y=35.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=30.0][y=32.0] + + 30 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=25.0][y=30.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=25.0][y=35.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=44.0][y=5.0] + + 20 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=42.0][y=10.0] + + 40 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=26.0][y=32.0] + + 10 + 90.0 + + + 0.0 + 1.7976931348623157E308 + + + + + diff --git a/jsprit-examples/input/pickups_and_deliveries_solomon_r101.xml b/jsprit-examples/input/pickups_and_deliveries_solomon_r101.xml new file mode 100644 index 00000000..cda89ffa --- /dev/null +++ b/jsprit-examples/input/pickups_and_deliveries_solomon_r101.xml @@ -0,0 +1,1235 @@ + + + + INFINITE + HOMOGENEOUS + + + + solomonVehicle + solomonType + + 0 + + + + 0.0 + 230.0 + + + + + + solomonType + 200 + + 0.0 + 1.0 + + + + + + + [x=63.0][y=65.0] + + 8 + 10.0 + + + 143.0 + 153.0 + + + + + [x=2.0][y=60.0] + + 5 + 10.0 + + + 41.0 + 51.0 + + + + + [x=53.0][y=52.0] + + 11 + 10.0 + + + 37.0 + 47.0 + + + + + [x=65.0][y=55.0] + + 14 + 10.0 + + + 117.0 + 127.0 + + + + + [x=60.0][y=12.0] + + 31 + 10.0 + + + 44.0 + 54.0 + + + + + [x=20.0][y=20.0] + + 8 + 10.0 + + + 134.0 + 144.0 + + + + + [x=5.0][y=5.0] + + 16 + 10.0 + + + 83.0 + 93.0 + + + + + [x=23.0][y=3.0] + + 7 + 10.0 + + + 132.0 + 142.0 + + + + + [x=24.0][y=12.0] + + 5 + 10.0 + + + 31.0 + 41.0 + + + + + [x=42.0][y=7.0] + + 5 + 10.0 + + + 97.0 + 107.0 + + + + + [x=40.0][y=25.0] + + 9 + 10.0 + + + 85.0 + 95.0 + + + + + [x=45.0][y=10.0] + + 18 + 10.0 + + + 97.0 + 107.0 + + + + + [x=55.0][y=5.0] + + 29 + 10.0 + + + 68.0 + 78.0 + + + + + [x=65.0][y=35.0] + + 3 + 10.0 + + + 153.0 + 163.0 + + + + + [x=65.0][y=20.0] + + 6 + 10.0 + + + 172.0 + 182.0 + + + + + [x=45.0][y=30.0] + + 17 + 10.0 + + + 132.0 + 142.0 + + + + + [x=35.0][y=40.0] + + 16 + 10.0 + + + 37.0 + 47.0 + + + + + [x=41.0][y=37.0] + + 16 + 10.0 + + + 39.0 + 49.0 + + + + + [x=64.0][y=42.0] + + 9 + 10.0 + + + 63.0 + 73.0 + + + + + [x=55.0][y=45.0] + + 13 + 10.0 + + + 116.0 + 126.0 + + + + + [x=35.0][y=17.0] + + 7 + 10.0 + + + 50.0 + 60.0 + + + + + [x=41.0][y=49.0] + + 10 + 10.0 + + + 161.0 + 171.0 + + + + + [x=40.0][y=60.0] + + 21 + 10.0 + + + 71.0 + 81.0 + + + + + [x=20.0][y=50.0] + + 5 + 10.0 + + + 81.0 + 91.0 + + + + + [x=25.0][y=30.0] + + 3 + 10.0 + + + 99.0 + 109.0 + + + + + [x=15.0][y=30.0] + + 26 + 10.0 + + + 34.0 + 44.0 + + + + + [x=35.0][y=69.0] + + 23 + 10.0 + + + 141.0 + 151.0 + + + + + [x=55.0][y=20.0] + + 19 + 10.0 + + + 149.0 + 159.0 + + + + + [x=31.0][y=52.0] + + 27 + 10.0 + + + 50.0 + 60.0 + + + + + [x=55.0][y=60.0] + + 16 + 10.0 + + + 97.0 + 107.0 + + + + + [x=10.0][y=43.0] + + 9 + 10.0 + + + 95.0 + 105.0 + + + + + [x=15.0][y=60.0] + + 17 + 10.0 + + + 76.0 + 86.0 + + + + + [x=5.0][y=30.0] + + 2 + 10.0 + + + 157.0 + 167.0 + + + + + [x=20.0][y=40.0] + + 12 + 10.0 + + + 87.0 + 97.0 + + + + + [x=30.0][y=5.0] + + 8 + 10.0 + + + 61.0 + 71.0 + + + + + [x=10.0][y=20.0] + + 19 + 10.0 + + + 75.0 + 85.0 + + + + + [x=30.0][y=25.0] + + 23 + 10.0 + + + 159.0 + 169.0 + + + + + [x=15.0][y=10.0] + + 20 + 10.0 + + + 32.0 + 42.0 + + + + + [x=20.0][y=65.0] + + 12 + 10.0 + + + 67.0 + 77.0 + + + + + [x=50.0][y=35.0] + + 19 + 10.0 + + + 63.0 + 73.0 + + + + + [x=45.0][y=20.0] + + 11 + 10.0 + + + 62.0 + 72.0 + + + + + [x=45.0][y=65.0] + + 9 + 10.0 + + + 126.0 + 136.0 + + + + + [x=20.0][y=26.0] + + 9 + 10.0 + + + 83.0 + 93.0 + + + + + [x=18.0][y=18.0] + + 17 + 10.0 + + + 185.0 + 195.0 + + + + + [x=19.0][y=21.0] + + 10 + 10.0 + + + 58.0 + 68.0 + + + + + [x=25.0][y=21.0] + + 12 + 10.0 + + + 133.0 + 143.0 + + + + + [x=22.0][y=27.0] + + 11 + 10.0 + + + 135.0 + 145.0 + + + + + [x=25.0][y=24.0] + + 20 + 10.0 + + + 39.0 + 49.0 + + + + + [x=26.0][y=27.0] + + 27 + 10.0 + + + 100.0 + 110.0 + + + + + [x=18.0][y=24.0] + + 22 + 10.0 + + + 188.0 + 198.0 + + + + + [x=22.0][y=22.0] + + 2 + 10.0 + + + 18.0 + 28.0 + + + + + [x=15.0][y=19.0] + + 1 + 10.0 + + + 160.0 + 170.0 + + + + + [x=31.0][y=67.0] + + 3 + 10.0 + + + 95.0 + 105.0 + + + + + [x=30.0][y=60.0] + + 16 + 10.0 + + + 124.0 + 134.0 + + + + + [x=26.0][y=52.0] + + 9 + 10.0 + + + 74.0 + 84.0 + + + + + [x=26.0][y=35.0] + + 15 + 10.0 + + + 176.0 + 186.0 + + + + + [x=57.0][y=48.0] + + 23 + 10.0 + + + 92.0 + 102.0 + + + + + [x=61.0][y=52.0] + + 3 + 10.0 + + + 96.0 + 106.0 + + + + + [x=53.0][y=43.0] + + 14 + 10.0 + + + 179.0 + 189.0 + + + + + [x=15.0][y=47.0] + + 16 + 10.0 + + + 55.0 + 65.0 + + + + + [x=14.0][y=37.0] + + 11 + 10.0 + + + 44.0 + 54.0 + + + + + [x=56.0][y=37.0] + + 6 + 10.0 + + + 182.0 + 192.0 + + + + + [x=55.0][y=54.0] + + 26 + 10.0 + + + 94.0 + 104.0 + + + + + [x=4.0][y=18.0] + + 35 + 10.0 + + + 94.0 + 104.0 + + + + + [x=28.0][y=18.0] + + 26 + 10.0 + + + 93.0 + 103.0 + + + + + [x=11.0][y=31.0] + + 7 + 10.0 + + + 101.0 + 111.0 + + + + + [x=16.0][y=22.0] + + 41 + 10.0 + + + 91.0 + 101.0 + + + + + [x=67.0][y=5.0] + + 25 + 10.0 + + + 83.0 + 93.0 + + + + + [x=49.0][y=73.0] + + 25 + 10.0 + + + 127.0 + 137.0 + + + + + [x=37.0][y=47.0] + + 6 + 10.0 + + + 50.0 + 60.0 + + + + + [x=56.0][y=39.0] + + 36 + 10.0 + + + 142.0 + 152.0 + + + + + [x=37.0][y=56.0] + + 5 + 10.0 + + + 182.0 + 192.0 + + + + + [x=57.0][y=68.0] + + 15 + 10.0 + + + 77.0 + 87.0 + + + + + [x=47.0][y=16.0] + + 25 + 10.0 + + + 35.0 + 45.0 + + + + + [x=44.0][y=17.0] + + 9 + 10.0 + + + 78.0 + 88.0 + + + + + [x=46.0][y=13.0] + + 8 + 10.0 + + + 149.0 + 159.0 + + + + + [x=49.0][y=11.0] + + 18 + 10.0 + + + 69.0 + 79.0 + + + + + [x=49.0][y=42.0] + + 13 + 10.0 + + + 73.0 + 83.0 + + + + + [x=21.0][y=24.0] + + 28 + 10.0 + + + 18.0 + 28.0 + + + + + [x=36.0][y=26.0] + + 18 + 10.0 + + + 200.0 + 210.0 + + + + + [x=32.0][y=12.0] + + 7 + 10.0 + + + 101.0 + 111.0 + + + + + [x=53.0][y=12.0] + + 6 + 10.0 + + + 130.0 + 140.0 + + + + + [x=63.0][y=23.0] + + 2 + 10.0 + + + 136.0 + 146.0 + + + + + [x=15.0][y=77.0] + + 9 + 10.0 + + + 73.0 + 83.0 + + + + + [x=62.0][y=77.0] + + 20 + 10.0 + + + 51.0 + 61.0 + + + + + [x=24.0][y=58.0] + + 19 + 10.0 + + + 58.0 + 68.0 + + + + + [x=27.0][y=69.0] + + 10 + 10.0 + + + 34.0 + 44.0 + + + + + [x=17.0][y=34.0] + + 3 + 10.0 + + + 162.0 + 172.0 + + + + + [x=12.0][y=24.0] + + 13 + 10.0 + + + 76.0 + 86.0 + + + + + [x=6.0][y=68.0] + + 30 + 10.0 + + + 108.0 + 118.0 + + + + + [x=13.0][y=52.0] + + 36 + 10.0 + + + 165.0 + 175.0 + + + + + [x=6.0][y=38.0] + + 16 + 10.0 + + + 32.0 + 42.0 + + + + + [x=11.0][y=14.0] + + 18 + 10.0 + + + 69.0 + 79.0 + + + + + [x=8.0][y=56.0] + + 27 + 10.0 + + + 51.0 + 61.0 + + + + + [x=2.0][y=48.0] + + 1 + 10.0 + + + 117.0 + 127.0 + + + + + [x=49.0][y=58.0] + + 10 + 10.0 + + + 88.0 + 98.0 + + + + + [x=27.0][y=43.0] + + 9 + 10.0 + + + 52.0 + 62.0 + + + + + [x=37.0][y=31.0] + + 14 + 10.0 + + + 95.0 + 105.0 + + + + + [x=57.0][y=29.0] + + 18 + 10.0 + + + 140.0 + 150.0 + + + + + [x=47.0][y=47.0] + + 13 + 10.0 + + + 124.0 + 134.0 + + + + + diff --git a/jsprit-examples/input/pickups_and_deliveries_solomon_r101_withoutTWs.xml b/jsprit-examples/input/pickups_and_deliveries_solomon_r101_withoutTWs.xml new file mode 100644 index 00000000..df35bceb --- /dev/null +++ b/jsprit-examples/input/pickups_and_deliveries_solomon_r101_withoutTWs.xml @@ -0,0 +1,1235 @@ + + + + INFINITE + HOMOGENEOUS + + + + solomonVehicle + solomonType + + 0 + + + + 0.0 + 230.0 + + + + + + solomonType + 200 + + 0.0 + 1.0 + + + + + + + [x=63.0][y=65.0] + + 8 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=2.0][y=60.0] + + 5 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=53.0][y=52.0] + + 11 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=65.0][y=55.0] + + 14 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=60.0][y=12.0] + + 31 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=20.0][y=20.0] + + 8 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=5.0][y=5.0] + + 16 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=23.0][y=3.0] + + 7 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=24.0][y=12.0] + + 5 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=42.0][y=7.0] + + 5 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=40.0][y=25.0] + + 9 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=45.0][y=10.0] + + 18 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=55.0][y=5.0] + + 29 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=65.0][y=35.0] + + 3 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=65.0][y=20.0] + + 6 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=45.0][y=30.0] + + 17 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=35.0][y=40.0] + + 16 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=41.0][y=37.0] + + 16 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=64.0][y=42.0] + + 9 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=55.0][y=45.0] + + 13 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=35.0][y=17.0] + + 7 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=41.0][y=49.0] + + 10 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=40.0][y=60.0] + + 21 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=20.0][y=50.0] + + 5 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=25.0][y=30.0] + + 3 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=15.0][y=30.0] + + 26 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=35.0][y=69.0] + + 23 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=55.0][y=20.0] + + 19 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=31.0][y=52.0] + + 27 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=55.0][y=60.0] + + 16 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=10.0][y=43.0] + + 9 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=15.0][y=60.0] + + 17 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=5.0][y=30.0] + + 2 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=20.0][y=40.0] + + 12 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=30.0][y=5.0] + + 8 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=10.0][y=20.0] + + 19 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=30.0][y=25.0] + + 23 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=15.0][y=10.0] + + 20 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=20.0][y=65.0] + + 12 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=50.0][y=35.0] + + 19 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=45.0][y=20.0] + + 11 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=45.0][y=65.0] + + 9 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=20.0][y=26.0] + + 9 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=18.0][y=18.0] + + 17 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=19.0][y=21.0] + + 10 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=25.0][y=21.0] + + 12 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=22.0][y=27.0] + + 11 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=25.0][y=24.0] + + 20 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=26.0][y=27.0] + + 27 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=18.0][y=24.0] + + 22 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=22.0][y=22.0] + + 2 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=15.0][y=19.0] + + 1 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=31.0][y=67.0] + + 3 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=30.0][y=60.0] + + 16 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=26.0][y=52.0] + + 9 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=26.0][y=35.0] + + 15 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=57.0][y=48.0] + + 23 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=61.0][y=52.0] + + 3 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=53.0][y=43.0] + + 14 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=15.0][y=47.0] + + 16 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=14.0][y=37.0] + + 11 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=56.0][y=37.0] + + 6 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=55.0][y=54.0] + + 26 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=4.0][y=18.0] + + 35 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=28.0][y=18.0] + + 26 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=11.0][y=31.0] + + 7 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=16.0][y=22.0] + + 41 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=67.0][y=5.0] + + 25 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=49.0][y=73.0] + + 25 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=37.0][y=47.0] + + 6 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=56.0][y=39.0] + + 36 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=37.0][y=56.0] + + 5 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=57.0][y=68.0] + + 15 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=47.0][y=16.0] + + 25 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=44.0][y=17.0] + + 9 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=46.0][y=13.0] + + 8 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=49.0][y=11.0] + + 18 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=49.0][y=42.0] + + 13 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=21.0][y=24.0] + + 28 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=36.0][y=26.0] + + 18 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=32.0][y=12.0] + + 7 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=53.0][y=12.0] + + 6 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=63.0][y=23.0] + + 2 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=15.0][y=77.0] + + 9 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=62.0][y=77.0] + + 20 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=24.0][y=58.0] + + 19 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=27.0][y=69.0] + + 10 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=17.0][y=34.0] + + 3 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=12.0][y=24.0] + + 13 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=6.0][y=68.0] + + 30 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=13.0][y=52.0] + + 36 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=6.0][y=38.0] + + 16 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=11.0][y=14.0] + + 18 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=8.0][y=56.0] + + 27 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=2.0][y=48.0] + + 1 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=49.0][y=58.0] + + 10 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=27.0][y=43.0] + + 9 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=37.0][y=31.0] + + 14 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=57.0][y=29.0] + + 18 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + [x=47.0][y=47.0] + + 13 + 10.0 + + + 0.0 + 1.7976931348623157E308 + + + + + diff --git a/jsprit-examples/input/pickups_solomon_c101.xml b/jsprit-examples/input/pickups_solomon_c101.xml new file mode 100644 index 00000000..90d6cea1 --- /dev/null +++ b/jsprit-examples/input/pickups_solomon_c101.xml @@ -0,0 +1,1235 @@ + + + + INFINITE + HOMOGENEOUS + + + + solomonVehicle + solomonType + + 0 + + + + 0.0 + 1236.0 + + + + + + solomonType + 200 + + 0.0 + 1.0 + + + + + + + [x=5.0][y=35.0] + + 10 + 90.0 + + + 283.0 + 344.0 + + + + + [x=5.0][y=45.0] + + 10 + 90.0 + + + 665.0 + 716.0 + + + + + [x=8.0][y=40.0] + + 40 + 90.0 + + + 87.0 + 158.0 + + + + + [x=8.0][y=45.0] + + 20 + 90.0 + + + 751.0 + 816.0 + + + + + [x=0.0][y=45.0] + + 20 + 90.0 + + + 567.0 + 624.0 + + + + + [x=2.0][y=40.0] + + 20 + 90.0 + + + 383.0 + 434.0 + + + + + [x=0.0][y=40.0] + + 30 + 90.0 + + + 479.0 + 522.0 + + + + + [x=33.0][y=35.0] + + 10 + 90.0 + + + 16.0 + 80.0 + + + + + [x=33.0][y=32.0] + + 20 + 90.0 + + + 68.0 + 149.0 + + + + + [x=35.0][y=32.0] + + 10 + 90.0 + + + 166.0 + 235.0 + + + + + [x=35.0][y=30.0] + + 10 + 90.0 + + + 264.0 + 321.0 + + + + + [x=28.0][y=52.0] + + 20 + 90.0 + + + 812.0 + 883.0 + + + + + [x=28.0][y=55.0] + + 10 + 90.0 + + + 732.0 + 777.0 + + + + + [x=25.0][y=50.0] + + 10 + 90.0 + + + 65.0 + 144.0 + + + + + [x=25.0][y=52.0] + + 40 + 90.0 + + + 169.0 + 224.0 + + + + + [x=25.0][y=55.0] + + 10 + 90.0 + + + 622.0 + 701.0 + + + + + [x=23.0][y=52.0] + + 10 + 90.0 + + + 261.0 + 316.0 + + + + + [x=23.0][y=55.0] + + 20 + 90.0 + + + 546.0 + 593.0 + + + + + [x=20.0][y=50.0] + + 10 + 90.0 + + + 358.0 + 405.0 + + + + + [x=42.0][y=66.0] + + 10 + 90.0 + + + 65.0 + 146.0 + + + + + [x=45.0][y=70.0] + + 30 + 90.0 + + + 825.0 + 870.0 + + + + + [x=45.0][y=68.0] + + 10 + 90.0 + + + 912.0 + 967.0 + + + + + [x=20.0][y=55.0] + + 10 + 90.0 + + + 449.0 + 504.0 + + + + + [x=40.0][y=66.0] + + 20 + 90.0 + + + 170.0 + 225.0 + + + + + [x=40.0][y=69.0] + + 20 + 90.0 + + + 621.0 + 702.0 + + + + + [x=42.0][y=65.0] + + 10 + 90.0 + + + 15.0 + 67.0 + + + + + [x=10.0][y=40.0] + + 30 + 90.0 + + + 31.0 + 100.0 + + + + + [x=42.0][y=68.0] + + 10 + 90.0 + + + 727.0 + 782.0 + + + + + [x=10.0][y=35.0] + + 20 + 90.0 + + + 200.0 + 237.0 + + + + + [x=38.0][y=70.0] + + 10 + 90.0 + + + 534.0 + 605.0 + + + + + [x=38.0][y=68.0] + + 20 + 90.0 + + + 255.0 + 324.0 + + + + + [x=15.0][y=80.0] + + 10 + 90.0 + + + 278.0 + 345.0 + + + + + [x=18.0][y=75.0] + + 20 + 90.0 + + + 99.0 + 148.0 + + + + + [x=15.0][y=75.0] + + 20 + 90.0 + + + 179.0 + 254.0 + + + + + [x=20.0][y=80.0] + + 40 + 90.0 + + + 384.0 + 429.0 + + + + + [x=20.0][y=85.0] + + 40 + 90.0 + + + 475.0 + 528.0 + + + + + [x=22.0][y=75.0] + + 30 + 90.0 + + + 30.0 + 92.0 + + + + + [x=22.0][y=85.0] + + 10 + 90.0 + + + 567.0 + 620.0 + + + + + [x=35.0][y=69.0] + + 10 + 90.0 + + + 448.0 + 505.0 + + + + + [x=25.0][y=85.0] + + 20 + 90.0 + + + 652.0 + 721.0 + + + + + [x=30.0][y=52.0] + + 20 + 90.0 + + + 914.0 + 965.0 + + + + + [x=30.0][y=50.0] + + 10 + 90.0 + + + 10.0 + 73.0 + + + + + [x=55.0][y=80.0] + + 10 + 90.0 + + + 743.0 + 820.0 + + + + + [x=55.0][y=85.0] + + 20 + 90.0 + + + 647.0 + 726.0 + + + + + [x=58.0][y=75.0] + + 20 + 90.0 + + + 30.0 + 84.0 + + + + + [x=60.0][y=85.0] + + 30 + 90.0 + + + 561.0 + 622.0 + + + + + [x=60.0][y=80.0] + + 10 + 90.0 + + + 95.0 + 156.0 + + + + + [x=62.0][y=80.0] + + 30 + 90.0 + + + 196.0 + 239.0 + + + + + [x=65.0][y=82.0] + + 10 + 90.0 + + + 285.0 + 336.0 + + + + + [x=65.0][y=85.0] + + 40 + 90.0 + + + 475.0 + 518.0 + + + + + [x=67.0][y=85.0] + + 20 + 90.0 + + + 368.0 + 441.0 + + + + + [x=60.0][y=60.0] + + 10 + 90.0 + + + 836.0 + 889.0 + + + + + [x=60.0][y=55.0] + + 10 + 90.0 + + + 20.0 + 84.0 + + + + + [x=35.0][y=66.0] + + 10 + 90.0 + + + 357.0 + 410.0 + + + + + [x=65.0][y=60.0] + + 30 + 90.0 + + + 645.0 + 708.0 + + + + + [x=63.0][y=58.0] + + 10 + 90.0 + + + 737.0 + 802.0 + + + + + [x=87.0][y=30.0] + + 10 + 90.0 + + + 668.0 + 731.0 + + + + + [x=88.0][y=35.0] + + 20 + 90.0 + + + 109.0 + 170.0 + + + + + [x=88.0][y=30.0] + + 10 + 90.0 + + + 574.0 + 643.0 + + + + + [x=75.0][y=55.0] + + 20 + 90.0 + + + 369.0 + 420.0 + + + + + [x=72.0][y=55.0] + + 10 + 90.0 + + + 265.0 + 338.0 + + + + + [x=85.0][y=25.0] + + 10 + 90.0 + + + 769.0 + 820.0 + + + + + [x=85.0][y=35.0] + + 30 + 90.0 + + + 47.0 + 124.0 + + + + + [x=66.0][y=55.0] + + 10 + 90.0 + + + 173.0 + 238.0 + + + + + [x=65.0][y=55.0] + + 20 + 90.0 + + + 85.0 + 144.0 + + + + + [x=70.0][y=58.0] + + 20 + 90.0 + + + 458.0 + 523.0 + + + + + [x=68.0][y=60.0] + + 30 + 90.0 + + + 555.0 + 612.0 + + + + + [x=47.0][y=40.0] + + 10 + 90.0 + + + 12.0 + 77.0 + + + + + [x=47.0][y=35.0] + + 10 + 90.0 + + + 826.0 + 875.0 + + + + + [x=45.0][y=35.0] + + 10 + 90.0 + + + 916.0 + 969.0 + + + + + [x=45.0][y=30.0] + + 10 + 90.0 + + + 734.0 + 777.0 + + + + + [x=95.0][y=30.0] + + 30 + 90.0 + + + 387.0 + 456.0 + + + + + [x=95.0][y=35.0] + + 20 + 90.0 + + + 293.0 + 360.0 + + + + + [x=53.0][y=30.0] + + 10 + 90.0 + + + 450.0 + 505.0 + + + + + [x=92.0][y=30.0] + + 10 + 90.0 + + + 478.0 + 551.0 + + + + + [x=53.0][y=35.0] + + 50 + 90.0 + + + 353.0 + 412.0 + + + + + [x=45.0][y=65.0] + + 20 + 90.0 + + + 997.0 + 1068.0 + + + + + [x=90.0][y=35.0] + + 10 + 90.0 + + + 203.0 + 260.0 + + + + + [x=38.0][y=15.0] + + 10 + 90.0 + + + 651.0 + 740.0 + + + + + [x=38.0][y=5.0] + + 30 + 90.0 + + + 471.0 + 534.0 + + + + + [x=40.0][y=15.0] + + 40 + 90.0 + + + 35.0 + 87.0 + + + + + [x=40.0][y=5.0] + + 30 + 90.0 + + + 385.0 + 436.0 + + + + + [x=42.0][y=15.0] + + 10 + 90.0 + + + 95.0 + 158.0 + + + + + [x=48.0][y=30.0] + + 10 + 90.0 + + + 632.0 + 693.0 + + + + + [x=48.0][y=40.0] + + 10 + 90.0 + + + 76.0 + 129.0 + + + + + [x=50.0][y=35.0] + + 20 + 90.0 + + + 262.0 + 317.0 + + + + + [x=50.0][y=40.0] + + 50 + 90.0 + + + 171.0 + 218.0 + + + + + [x=35.0][y=5.0] + + 20 + 90.0 + + + 562.0 + 629.0 + + + + + [x=50.0][y=30.0] + + 10 + 90.0 + + + 531.0 + 610.0 + + + + + [x=28.0][y=35.0] + + 10 + 90.0 + + + 1001.0 + 1066.0 + + + + + [x=28.0][y=30.0] + + 10 + 90.0 + + + 632.0 + 693.0 + + + + + [x=30.0][y=30.0] + + 10 + 90.0 + + + 541.0 + 600.0 + + + + + [x=32.0][y=30.0] + + 10 + 90.0 + + + 359.0 + 412.0 + + + + + [x=30.0][y=35.0] + + 10 + 90.0 + + + 1054.0 + 1127.0 + + + + + [x=30.0][y=32.0] + + 30 + 90.0 + + + 448.0 + 509.0 + + + + + [x=25.0][y=30.0] + + 10 + 90.0 + + + 725.0 + 786.0 + + + + + [x=25.0][y=35.0] + + 10 + 90.0 + + + 912.0 + 969.0 + + + + + [x=44.0][y=5.0] + + 20 + 90.0 + + + 286.0 + 347.0 + + + + + [x=42.0][y=10.0] + + 40 + 90.0 + + + 186.0 + 257.0 + + + + + [x=26.0][y=32.0] + + 10 + 90.0 + + + 815.0 + 880.0 + + + + + diff --git a/jsprit-examples/src/main/java/examples/CVRPExample.java b/jsprit-examples/src/main/java/examples/CVRPExample.java index 3196a732..8ea4d1c6 100644 --- a/jsprit-examples/src/main/java/examples/CVRPExample.java +++ b/jsprit-examples/src/main/java/examples/CVRPExample.java @@ -1,3 +1,23 @@ +/******************************************************************************* + * 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 examples; import readers.ChristofidesReader; diff --git a/jsprit-examples/src/main/java/examples/CostMatrixExample.java b/jsprit-examples/src/main/java/examples/CostMatrixExample.java index 0ab81b4e..706ed627 100644 --- a/jsprit-examples/src/main/java/examples/CostMatrixExample.java +++ b/jsprit-examples/src/main/java/examples/CostMatrixExample.java @@ -1,3 +1,23 @@ +/******************************************************************************* + * 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 examples; import java.io.File; diff --git a/jsprit-examples/src/main/java/examples/MultipleDepotExample.java b/jsprit-examples/src/main/java/examples/MultipleDepotExample.java index fc963747..b10b2eff 100644 --- a/jsprit-examples/src/main/java/examples/MultipleDepotExample.java +++ b/jsprit-examples/src/main/java/examples/MultipleDepotExample.java @@ -1,3 +1,23 @@ +/******************************************************************************* + * 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 examples; import java.io.File; diff --git a/jsprit-examples/src/main/java/examples/MultipleDepotExampleWithPenaltyVehicles.java b/jsprit-examples/src/main/java/examples/MultipleDepotExampleWithPenaltyVehicles.java index 51992690..de2edbfb 100644 --- a/jsprit-examples/src/main/java/examples/MultipleDepotExampleWithPenaltyVehicles.java +++ b/jsprit-examples/src/main/java/examples/MultipleDepotExampleWithPenaltyVehicles.java @@ -1,3 +1,23 @@ +/******************************************************************************* + * 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 examples; import java.io.File; diff --git a/jsprit-examples/src/main/java/examples/PickupAndDeliveryExample.java b/jsprit-examples/src/main/java/examples/PickupAndDeliveryExample.java new file mode 100644 index 00000000..b3a1d564 --- /dev/null +++ b/jsprit-examples/src/main/java/examples/PickupAndDeliveryExample.java @@ -0,0 +1,113 @@ +/******************************************************************************* + * 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 examples; + +import java.io.File; +import java.util.Collection; + +import algorithms.VehicleRoutingAlgorithms; +import algorithms.selectors.SelectBest; +import analysis.AlgorithmSearchProgressChartListener; +import analysis.Plotter; +import analysis.Plotter.Label; +import analysis.SolutionPlotter; +import analysis.SolutionPrinter; +import analysis.SolutionPrinter.Print; +import basics.VehicleRoutingAlgorithm; +import basics.VehicleRoutingProblem; +import basics.VehicleRoutingProblemSolution; +import basics.VehicleRoutingProblem.Constraint; +import basics.io.VrpXMLReader; + +public class PickupAndDeliveryExample { + + public static void main(String[] args) { + + /* + * some preparation - create output folder + */ + File dir = new File("output"); + // if the directory does not exist, create it + if (!dir.exists()){ + System.out.println("creating directory ./output"); + boolean result = dir.mkdir(); + if(result) System.out.println("./output created"); + } + + /* + * Build the problem. + * + * But define a problem-builder first. + */ + VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); + + /* + * A solomonReader reads solomon-instance files, and stores the required information in the builder. + */ + new VrpXMLReader(vrpBuilder).read("input/pickups_and_deliveries_solomon_r101.xml"); + + /* + * Finally, the problem can be built. By default, transportCosts are crowFlyDistances (as usually used for vrp-instances). + */ + + VehicleRoutingProblem vrp = vrpBuilder.build(); + + SolutionPlotter.plotVrpAsPNG(vrp, "output/pd_solomon_r101.png", "pd_r101"); + + /* + * Define the required vehicle-routing algorithms to solve the above problem. + * + * The algorithm can be defined and configured in an xml-file. + */ +// VehicleRoutingAlgorithm vra = new SchrimpfFactory().createAlgorithm(vrp); + VehicleRoutingAlgorithm vra = VehicleRoutingAlgorithms.readAndCreateAlgorithm(vrp, "input/algorithmConfig_solomon.xml"); + vra.getAlgorithmListeners().addListener(new AlgorithmSearchProgressChartListener("output/sol_progress.png")); + /* + * Solve the problem. + * + * + */ + Collection solutions = vra.searchSolutions(); + + /* + * Retrieve best solution. + */ + VehicleRoutingProblemSolution solution = new SelectBest().selectSolution(solutions); + + /* + * print solution + */ + SolutionPrinter.print(solution, Print.VERBOSE); + + /* + * Plot solution. + */ +// SolutionPlotter.plotSolutionAsPNG(vrp, solution, "output/pd_solomon_r101_solution.png","pd_r101"); + Plotter plotter = new Plotter(vrp, solution); + plotter.setLabel(Label.SIZE); + plotter.setShowFirstActivity(true); + plotter.plot("output/pd_solomon_r101_solution.png","pd_r101"); + + + + } + +} diff --git a/jsprit-examples/src/main/java/examples/PickupAndDeliveryExample2.java b/jsprit-examples/src/main/java/examples/PickupAndDeliveryExample2.java new file mode 100644 index 00000000..573e62b4 --- /dev/null +++ b/jsprit-examples/src/main/java/examples/PickupAndDeliveryExample2.java @@ -0,0 +1,113 @@ +/******************************************************************************* + * 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 examples; + +import java.io.File; +import java.util.Collection; + +import algorithms.VehicleRoutingAlgorithms; +import algorithms.selectors.SelectBest; +import analysis.AlgorithmSearchProgressChartListener; +import analysis.Plotter; +import analysis.Plotter.Label; +import analysis.SolutionPlotter; +import analysis.SolutionPrinter; +import analysis.SolutionPrinter.Print; +import basics.VehicleRoutingAlgorithm; +import basics.VehicleRoutingProblem; +import basics.VehicleRoutingProblemSolution; +import basics.VehicleRoutingProblem.Constraint; +import basics.io.VrpXMLReader; + +public class PickupAndDeliveryExample2 { + + public static void main(String[] args) { + + /* + * some preparation - create output folder + */ + File dir = new File("output"); + // if the directory does not exist, create it + if (!dir.exists()){ + System.out.println("creating directory ./output"); + boolean result = dir.mkdir(); + if(result) System.out.println("./output created"); + } + + /* + * Build the problem. + * + * But define a problem-builder first. + */ + VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); + + /* + * A solomonReader reads solomon-instance files, and stores the required information in the builder. + */ + new VrpXMLReader(vrpBuilder).read("input/pd_christophides_vrpnc1_vcap50.xml"); + + /* + * Finally, the problem can be built. By default, transportCosts are crowFlyDistances (as usually used for vrp-instances). + */ + + VehicleRoutingProblem vrp = vrpBuilder.build(); + + SolutionPlotter.plotVrpAsPNG(vrp, "output/pd_christophides_vrpnc1.png", "pd_vrpnc1"); + + /* + * Define the required vehicle-routing algorithms to solve the above problem. + * + * The algorithm can be defined and configured in an xml-file. + */ +// VehicleRoutingAlgorithm vra = new SchrimpfFactory().createAlgorithm(vrp); + VehicleRoutingAlgorithm vra = VehicleRoutingAlgorithms.readAndCreateAlgorithm(vrp, "input/algorithmConfig_solomon.xml"); + vra.getAlgorithmListeners().addListener(new AlgorithmSearchProgressChartListener("output/sol_progress.png")); + /* + * Solve the problem. + * + * + */ + Collection solutions = vra.searchSolutions(); + + /* + * Retrieve best solution. + */ + VehicleRoutingProblemSolution solution = new SelectBest().selectSolution(solutions); + + /* + * print solution + */ + SolutionPrinter.print(solution, Print.VERBOSE); + + /* + * Plot solution. + */ +// SolutionPlotter.plotSolutionAsPNG(vrp, solution, "output/pd_solomon_r101_solution.png","pd_r101"); + Plotter plotter = new Plotter(vrp, solution); + plotter.setLabel(Label.SIZE); + plotter.setShowFirstActivity(true); + plotter.plot("output/pd_christophides_vrpnc1.png","pd_vrpnc1"); + + + + } + +} diff --git a/jsprit-examples/src/main/java/examples/RefuseCollectionExample.java b/jsprit-examples/src/main/java/examples/RefuseCollectionExample.java index 58a3133d..61d9db1b 100644 --- a/jsprit-examples/src/main/java/examples/RefuseCollectionExample.java +++ b/jsprit-examples/src/main/java/examples/RefuseCollectionExample.java @@ -201,7 +201,7 @@ public class RefuseCollectionExample { VehicleRoutingProblem vrp = vrpBuilder.build(); VehicleRoutingAlgorithm vra = new GreedySchrimpfFactory().createAlgorithm(vrp); - vra.setPrematureBreak(10); + vra.setPrematureBreak(100); Collection solutions = vra.searchSolutions(); SolutionPrinter.print(Solutions.getBest(solutions),Print.VERBOSE); diff --git a/jsprit-examples/src/main/java/examples/SolomonExample.java b/jsprit-examples/src/main/java/examples/SolomonExample.java index 1b13d865..d4cbe843 100644 --- a/jsprit-examples/src/main/java/examples/SolomonExample.java +++ b/jsprit-examples/src/main/java/examples/SolomonExample.java @@ -26,7 +26,6 @@ import java.util.Collection; import readers.SolomonReader; import algorithms.VehicleRoutingAlgorithms; import algorithms.selectors.SelectBest; -import analysis.AlgorithmSearchProgressChartListener; import analysis.SolutionPlotter; import analysis.SolutionPrinter; import analysis.SolutionPrinter.Print; diff --git a/jsprit-examples/src/main/java/examples/SolomonR101Example.java b/jsprit-examples/src/main/java/examples/SolomonR101Example.java new file mode 100644 index 00000000..9a490568 --- /dev/null +++ b/jsprit-examples/src/main/java/examples/SolomonR101Example.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * 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 examples; + +import java.io.File; +import java.util.Collection; + +import readers.SolomonReader; +import algorithms.VehicleRoutingAlgorithms; +import algorithms.selectors.SelectBest; +import analysis.SolutionPlotter; +import analysis.SolutionPrinter; +import analysis.SolutionPrinter.Print; +import basics.VehicleRoutingAlgorithm; +import basics.VehicleRoutingProblem; +import basics.VehicleRoutingProblemSolution; + +public class SolomonR101Example { + + public static void main(String[] args) { + /* + * some preparation - create output folder + */ + File dir = new File("output"); + // if the directory does not exist, create it + if (!dir.exists()){ + System.out.println("creating directory ./output"); + boolean result = dir.mkdir(); + if(result) System.out.println("./output created"); + } + + /* + * Build the problem. + * + * But define a problem-builder first. + */ + VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); + + /* + * A solomonReader reads solomon-instance files, and stores the required information in the builder. + */ + new SolomonReader(vrpBuilder).read("input/R101.txt"); + + /* + * Finally, the problem can be built. By default, transportCosts are crowFlyDistances (as usually used for vrp-instances). + */ + VehicleRoutingProblem vrp = vrpBuilder.build(); + + SolutionPlotter.plotVrpAsPNG(vrp, "output/solomon_R101.png", "R101"); + + /* + * Define the required vehicle-routing algorithms to solve the above problem. + * + * The algorithm can be defined and configured in an xml-file. + */ +// VehicleRoutingAlgorithm vra = new SchrimpfFactory().createAlgorithm(vrp); + VehicleRoutingAlgorithm vra = VehicleRoutingAlgorithms.readAndCreateAlgorithm(vrp, "input/algorithmConfig_solomon.xml"); +// vra.setPrematureBreak(100); +// vra.getAlgorithmListeners().addListener(new AlgorithmSearchProgressChartListener("output/sol_progress.png")); + /* + * Solve the problem. + * + * + */ + Collection solutions = vra.searchSolutions(); + + /* + * Retrieve best solution. + */ + VehicleRoutingProblemSolution solution = new SelectBest().selectSolution(solutions); + + /* + * print solution + */ + SolutionPrinter.print(solution, Print.VERBOSE); + + /* + * Plot solution. + */ + SolutionPlotter.plotSolutionAsPNG(vrp, solution, "output/solomon_R101_solution.png","R101"); + + + + } + +} diff --git a/jsprit-examples/src/main/java/examples/VRPWithBackhaulsExample.java b/jsprit-examples/src/main/java/examples/VRPWithBackhaulsExample.java new file mode 100644 index 00000000..e4782681 --- /dev/null +++ b/jsprit-examples/src/main/java/examples/VRPWithBackhaulsExample.java @@ -0,0 +1,111 @@ +/******************************************************************************* + * 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 examples; + +import java.io.File; +import java.util.Collection; + +import algorithms.VehicleRoutingAlgorithms; +import algorithms.selectors.SelectBest; +import analysis.AlgorithmSearchProgressChartListener; +import analysis.Plotter; +import analysis.SolutionPlotter; +import analysis.SolutionPrinter; +import analysis.Plotter.Label; +import analysis.SolutionPrinter.Print; +import basics.VehicleRoutingAlgorithm; +import basics.VehicleRoutingProblem; +import basics.VehicleRoutingProblemSolution; +import basics.VehicleRoutingProblem.Constraint; +import basics.io.VrpXMLReader; + +public class VRPWithBackhaulsExample { + + public static void main(String[] args) { + + /* + * some preparation - create output folder + */ + File dir = new File("output"); + // if the directory does not exist, create it + if (!dir.exists()){ + System.out.println("creating directory ./output"); + boolean result = dir.mkdir(); + if(result) System.out.println("./output created"); + } + + /* + * Build the problem. + * + * But define a problem-builder first. + */ + VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); + + /* + * A solomonReader reads solomon-instance files, and stores the required information in the builder. + */ + new VrpXMLReader(vrpBuilder).read("input/pickups_and_deliveries_solomon_r101.xml"); + + /* + * Finally, the problem can be built. By default, transportCosts are crowFlyDistances (as usually used for vrp-instances). + */ + vrpBuilder.addProblemConstraint(Constraint.DELIVERIES_FIRST); + VehicleRoutingProblem vrp = vrpBuilder.build(); + + SolutionPlotter.plotVrpAsPNG(vrp, "output/pd_solomon_r101.png", "pd_r101"); + + /* + * Define the required vehicle-routing algorithms to solve the above problem. + * + * The algorithm can be defined and configured in an xml-file. + */ +// VehicleRoutingAlgorithm vra = new SchrimpfFactory().createAlgorithm(vrp); + VehicleRoutingAlgorithm vra = VehicleRoutingAlgorithms.readAndCreateAlgorithm(vrp, "input/algorithmConfig_solomon.xml"); + vra.getAlgorithmListeners().addListener(new AlgorithmSearchProgressChartListener("output/sol_progress.png")); + /* + * Solve the problem. + * + * + */ + Collection solutions = vra.searchSolutions(); + + /* + * Retrieve best solution. + */ + VehicleRoutingProblemSolution solution = new SelectBest().selectSolution(solutions); + + /* + * print solution + */ + SolutionPrinter.print(solution, Print.VERBOSE); + + /* + * Plot solution. + */ + Plotter plotter = new Plotter(vrp, solution); + plotter.setLabel(Label.SIZE); + plotter.setShowFirstActivity(true); + plotter.plot("output/pd_withBackhauls_solomon_r101_solution.png","pd_withBackhauls_r101"); + + + } + +} diff --git a/jsprit-examples/src/main/java/examples/VRPWithBackhaulsExample2.java b/jsprit-examples/src/main/java/examples/VRPWithBackhaulsExample2.java new file mode 100644 index 00000000..99aabc15 --- /dev/null +++ b/jsprit-examples/src/main/java/examples/VRPWithBackhaulsExample2.java @@ -0,0 +1,113 @@ +/******************************************************************************* + * 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 examples; + +import java.io.File; +import java.util.Collection; + +import algorithms.VehicleRoutingAlgorithms; +import algorithms.selectors.SelectBest; +import analysis.AlgorithmSearchProgressChartListener; +import analysis.Plotter; +import analysis.Plotter.Label; +import analysis.SolutionPlotter; +import analysis.SolutionPrinter; +import analysis.SolutionPrinter.Print; +import basics.VehicleRoutingAlgorithm; +import basics.VehicleRoutingProblem; +import basics.VehicleRoutingProblemSolution; +import basics.VehicleRoutingProblem.Constraint; +import basics.io.VrpXMLReader; + +public class VRPWithBackhaulsExample2 { + + public static void main(String[] args) { + + /* + * some preparation - create output folder + */ + File dir = new File("output"); + // if the directory does not exist, create it + if (!dir.exists()){ + System.out.println("creating directory ./output"); + boolean result = dir.mkdir(); + if(result) System.out.println("./output created"); + } + + /* + * Build the problem. + * + * But define a problem-builder first. + */ + VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance(); + + /* + * A solomonReader reads solomon-instance files, and stores the required information in the builder. + */ + new VrpXMLReader(vrpBuilder).read("input/pd_christophides_vrpnc1_vcap50.xml"); + + /* + * Finally, the problem can be built. By default, transportCosts are crowFlyDistances (as usually used for vrp-instances). + */ + vrpBuilder.addProblemConstraint(Constraint.DELIVERIES_FIRST); + VehicleRoutingProblem vrp = vrpBuilder.build(); + + SolutionPlotter.plotVrpAsPNG(vrp, "output/pd_christophides_vrpnc1.png", "pd_vrpnc1"); + + /* + * Define the required vehicle-routing algorithms to solve the above problem. + * + * The algorithm can be defined and configured in an xml-file. + */ +// VehicleRoutingAlgorithm vra = new SchrimpfFactory().createAlgorithm(vrp); + VehicleRoutingAlgorithm vra = VehicleRoutingAlgorithms.readAndCreateAlgorithm(vrp, "input/algorithmConfig_solomon.xml"); + vra.getAlgorithmListeners().addListener(new AlgorithmSearchProgressChartListener("output/sol_progress.png")); + /* + * Solve the problem. + * + * + */ + Collection solutions = vra.searchSolutions(); + + /* + * Retrieve best solution. + */ + VehicleRoutingProblemSolution solution = new SelectBest().selectSolution(solutions); + + /* + * print solution + */ + SolutionPrinter.print(solution, Print.VERBOSE); + + /* + * Plot solution. + */ +// SolutionPlotter.plotSolutionAsPNG(vrp, solution, "output/pd_solomon_r101_solution.png","pd_r101"); + Plotter plotter = new Plotter(vrp, solution); + plotter.setLabel(Label.SIZE); + plotter.setShowFirstActivity(true); + plotter.plot("output/vrpwbh_christophides_vrpnc1.png","vrpwbh_vrpnc1"); + + + + } + +} diff --git a/jsprit-instances/src/main/java/util/Instances.java b/jsprit-instances/src/main/java/util/Instances.java index 57c91364..5526cf84 100644 --- a/jsprit-instances/src/main/java/util/Instances.java +++ b/jsprit-instances/src/main/java/util/Instances.java @@ -1,3 +1,23 @@ +/******************************************************************************* + * 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 util; import java.io.BufferedReader;