mirror of
https://github.com/graphhopper/jsprit.git
synced 2020-01-24 07:45:05 +01:00
Merge remote-tracking branch 'choose_remote_name/vrpWithBackhauls'
Conflicts: jsprit-core/src/main/java/algorithms/CalculatesServiceInsertion.java
This commit is contained in:
commit
f1bb6c7bd0
96 changed files with 17748 additions and 1121 deletions
387
jsprit-analysis/src/main/java/analysis/Plotter.java
Normal file
387
jsprit-analysis/src/main/java/analysis/Plotter.java
Normal file
|
|
@ -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<XYDataItem,String> labels = new HashMap<XYDataItem, String>();
|
||||
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<XYDataItem,String> labels = new HashMap<XYDataItem, String>();
|
||||
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<XYDataItem, String> 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<XYDataItem, String> 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<solutionColl.getSeriesCount();i++){
|
||||
XYSeries s = solutionColl.getSeries(i);
|
||||
XYDataItem firstCustomer = s.getDataItem(1);
|
||||
solutionRenderer.addAnnotation(new XYShapeAnnotation( new Ellipse2D.Double(firstCustomer.getXValue()-0.7, firstCustomer.getYValue()-0.7, 1.5, 1.5), new BasicStroke(1.0f), Color.RED));
|
||||
}
|
||||
}
|
||||
plot.setDataset(1, solutionColl);
|
||||
plot.setRenderer(1, solutionRenderer);
|
||||
plot.setDomainAxis(1, xAxis);
|
||||
plot.setRangeAxis(1, yAxis);
|
||||
|
||||
return plot;
|
||||
}
|
||||
|
||||
private void save(JFreeChart chart, String pngFile) {
|
||||
try {
|
||||
ChartUtilities.saveChartAsPNG(new File(pngFile), chart, 1000, 600);
|
||||
} catch (IOException e) {
|
||||
log.error("cannot plot");
|
||||
log.error(e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private XYSeriesCollection makeSolutionSeries(VehicleRoutingProblem vrp, VehicleRoutingProblemSolution solution) throws NoLocationFoundException{
|
||||
Locations locations = retrieveLocations(vrp);
|
||||
XYSeriesCollection coll = new XYSeriesCollection();
|
||||
int counter = 1;
|
||||
for(VehicleRoute route : solution.getRoutes()){
|
||||
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 makeSolutionSeries(Collection<VehicleRoute> 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<Vehicle> vehicles, Collection<Job> services, Map<XYDataItem, String> 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<XYDataItem, String> 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<VehicleRoute> routes, Map<XYDataItem, String> labels) throws NoLocationFoundException{
|
||||
Set<Vehicle> vehicles = new HashSet<Vehicle>();
|
||||
Set<Job> jobs = new HashSet<Job>();
|
||||
for(VehicleRoute route : routes){
|
||||
vehicles.add(route.getVehicle());
|
||||
jobs.addAll(route.getTourActivities().getJobs());
|
||||
}
|
||||
return makeVrpSeries(vehicles, jobs, labels);
|
||||
}
|
||||
|
||||
private XYSeriesCollection makeVrpSeries(VehicleRoutingProblem vrp, Map<XYDataItem, String> labels) throws NoLocationFoundException{
|
||||
return makeVrpSeries(vrp.getVehicles(), vrp.getJobs().values(), labels);
|
||||
}
|
||||
|
||||
private Locations retrieveLocations(VehicleRoutingProblem vrp) throws NoLocationFoundException {
|
||||
final Map<String, Coordinate> locs = new HashMap<String, Coordinate>();
|
||||
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);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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<XYDataItem,String> labels = new HashMap<XYDataItem, String>();
|
||||
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<VehicleRoute> routes, Locations locations, String pngFile, String title) {
|
||||
log.info("plot routes to " + pngFile);
|
||||
XYSeriesCollection problem;
|
||||
Map<XYDataItem,String> labels = new HashMap<XYDataItem, String>();
|
||||
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<XYDataItem,String> labels = new HashMap<XYDataItem, String>();
|
||||
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<XYDataItem, String> 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<XYDataItem, String> 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<solutionColl.getSeriesCount();i++){
|
||||
// XYSeries s = solutionColl.getSeries(i);
|
||||
// XYDataItem firstCustomer = s.getDataItem(1);
|
||||
// solutionRenderer.addAnnotation(new XYShapeAnnotation( new Ellipse2D.Double(firstCustomer.getXValue()-0.7, firstCustomer.getYValue()-0.7, 1.5, 1.5), new BasicStroke(1.0f), Color.RED));
|
||||
// }
|
||||
plot.setDataset(1, solutionColl);
|
||||
plot.setRenderer(1, solutionRenderer);
|
||||
plot.setDomainAxis(1, xAxis);
|
||||
|
|
@ -254,7 +292,7 @@ public class SolutionPlotter {
|
|||
return coll;
|
||||
}
|
||||
|
||||
private static XYSeriesCollection makeVrpSeries(Collection<Vehicle> vehicles, Collection<Job> services) throws NoLocationFoundException{
|
||||
private static XYSeriesCollection makeVrpSeries(Collection<Vehicle> vehicles, Collection<Job> services, Map<XYDataItem, String> 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<VehicleRoute> routes) throws NoLocationFoundException{
|
||||
private static XYSeriesCollection makeVrpSeries(Collection<VehicleRoute> routes, Map<XYDataItem, String> labels) throws NoLocationFoundException{
|
||||
Set<Vehicle> vehicles = new HashSet<Vehicle>();
|
||||
Set<Job> jobs = new HashSet<Job>();
|
||||
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<XYDataItem, String> labels) throws NoLocationFoundException{
|
||||
return makeVrpSeries(vrp.getVehicles(), vrp.getJobs().values(), labels);
|
||||
}
|
||||
|
||||
private static Locations retrieveLocations(VehicleRoutingProblem vrp) throws NoLocationFoundException {
|
||||
|
|
|
|||
|
|
@ -52,6 +52,8 @@
|
|||
<version>2.4.0</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -82,6 +83,8 @@ class CalculatorBuilder {
|
|||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
* <p>HardPickupAndDeliveryLoadConstraint requires LOAD_AT_DEPOT and LOAD (i.e. load at end) at route-level
|
||||
*
|
||||
* <p>HardTimeWindowConstraint requires LATEST_OPERATION_START_TIME
|
||||
*
|
||||
* <p>HardPickupAndDeliveryConstraint requires LOAD_AT_DEPOT and LOAD at route-level and FUTURE_PICKS and PAST_DELIVIERS on activity-level
|
||||
*
|
||||
* <p>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,7 +59,73 @@ 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<HardRouteLevelConstraint> hardConstraints = new ArrayList<HardRouteLevelConstraint>();
|
||||
|
||||
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<HardActivityLevelConstraint> hardConstraints = new ArrayList<HardActivityLevelConstraint>();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.");
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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<PrioritizedVRAListener> algorithmListeners, ExecutorService executorService, int nuOfThreads){
|
||||
VehicleFleetManager vehicleFleetManager, StateManagerImpl routeStates, List<PrioritizedVRAListener> 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)));
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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<TourActivity> reverseActIter = vehicleRoute.getTourActivities().reverseActivityIterator();
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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<Info> infos = new ArrayList<Info>();
|
||||
|
||||
@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<VehicleRoutingProblemSolution> 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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
||||
|
|
@ -39,10 +59,6 @@ class MarginalsCalculusTriangleInequality implements MarginalsCalculus{
|
|||
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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<TourActivity, ActivityState> activityStates;
|
||||
|
||||
private Map<Service, TourActivity> tourActivities;
|
||||
|
||||
private Map<VehicleRoute, RouteState> routeStates;
|
||||
|
||||
public RouteStates() {
|
||||
activityStates = new HashMap<TourActivity, RouteStates.ActivityState>();
|
||||
tourActivities = new HashMap<Service,TourActivity>();
|
||||
routeStates = new HashMap<VehicleRoute, RouteStates.RouteState>();
|
||||
}
|
||||
|
||||
ActivityState getState(TourActivity act){
|
||||
if(!activityStates.containsKey(act)) return null;
|
||||
return activityStates.get(act);
|
||||
}
|
||||
|
||||
public void clearStates(){
|
||||
activityStates.clear();
|
||||
}
|
||||
|
||||
public Map<TourActivity, ActivityState> 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<Job> 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<VehicleRoutingProblemSolution> solutions) {
|
||||
resetRouteStates();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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<TourActivity,States> activityStates = new HashMap<TourActivity, StateManager.States>();
|
||||
|
||||
public Map<VehicleRoute, States> 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<TourActivity, States> 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;
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
}
|
||||
|
|
|
|||
678
jsprit-core/src/main/java/algorithms/StateUpdates.java
Normal file
678
jsprit-core/src/main/java/algorithms/StateUpdates.java
Normal file
|
|
@ -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<Class<? extends VehicleRoutingAlgorithmListener>,Collection<VehicleRoutingAlgorithmListener>> listeners = new HashMap<Class<? extends VehicleRoutingAlgorithmListener>,Collection<VehicleRoutingAlgorithmListener>>();
|
||||
|
||||
public void addListener(VehicleRoutingAlgorithmListener vraListener){
|
||||
if(!listeners.containsKey(vraListener.getClass())){
|
||||
listeners.put(vraListener.getClass(), new ArrayList<VehicleRoutingAlgorithmListener>());
|
||||
}
|
||||
listeners.get(vraListener.getClass()).add(vraListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ruinStarts(Collection<VehicleRoute> routes) {
|
||||
if(listeners.containsKey(RuinListener.class)){
|
||||
for(VehicleRoutingAlgorithmListener l : listeners.get(RuinListener.class)){
|
||||
((RuinListener)l).ruinStarts(routes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ruinEnds(Collection<VehicleRoute> routes,Collection<Job> 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<VehicleRoute> 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<VehicleRoute> vehicleRoutes,Collection<Job> unassignedJobs) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void informIterationEnds(int i, VehicleRoutingProblem problem,Collection<VehicleRoutingProblemSolution> solutions) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void informIterationStarts(int i, VehicleRoutingProblem problem,Collection<VehicleRoutingProblemSolution> 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<VehicleRoute> vehicleRoutes, Collection<Job> 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<VehicleRoute> 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<VehicleRoute> vehicleRoutes, Collection<Job> 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<VehicleRoute> routes) {}
|
||||
|
||||
@Override
|
||||
public void ruinEnds(Collection<VehicleRoute> routes,Collection<Job> 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<VehicleRoutingProblemSolution> 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<InsertionStarts> insertionStartsListeners;
|
||||
|
||||
private Collection<JobInsertedListener> jobInsertionListeners;
|
||||
|
||||
public UpdateRouteStatesOnceTheRouteHasBeenChanged(VehicleRoutingTransportCosts routingCosts) {
|
||||
forwardInTimeIterator = new IterateRouteForwardInTime(routingCosts);
|
||||
backwardInTimeIterator = new IterateRouteBackwardInTime(routingCosts);
|
||||
insertionStartsListeners = new ArrayList<InsertionStarts>();
|
||||
jobInsertionListeners = new ArrayList<JobInsertedListener>();
|
||||
}
|
||||
|
||||
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<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs) {
|
||||
for(VehicleRoute route : vehicleRoutes){
|
||||
for(InsertionStarts insertionsStartsHandler : insertionStartsListeners){
|
||||
insertionsStartsHandler.insertionStarts(route);
|
||||
}
|
||||
forwardInTimeIterator.iterate(route);
|
||||
backwardInTimeIterator.iterate(route);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -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<VehicleRoute> vehicleRoutes, Collection<Job> 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<VehicleRoute> 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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) {}
|
||||
|
||||
}
|
||||
|
|
@ -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) {}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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<VehicleRoute> vehicleRoutes, Collection<Job> 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));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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<VehicleRoute> routes) {}
|
||||
|
||||
@Override
|
||||
public void ruinEnds(Collection<VehicleRoute> routes,Collection<Job> unassignedJobs) {
|
||||
for(VehicleRoute route : routes) {
|
||||
iterateForward.iterate(route);
|
||||
iterateBackward.iterate(route);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removed(Job job, VehicleRoute fromRoute) {}
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
||||
|
||||
|
||||
|
|
@ -429,49 +431,42 @@ 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");
|
||||
}
|
||||
|
||||
Set<PrioritizedVRAListener> algorithmListeners = new HashSet<PrioritizedVRAListener>();
|
||||
List<InsertionListener> insertionListeners = new ArrayList<InsertionListener>();
|
||||
|
||||
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<VehicleRoutingProblemSolution> solutions) {
|
||||
routeStates.clear();
|
||||
}
|
||||
};
|
||||
algorithmListeners.add(new PrioritizedVRAListener(Priority.LOW, resetStates));
|
||||
|
||||
// insertionListeners.add(new UdateCostsAtRouteLevel(routeStates,vrp.getTransportCosts(),vrp.getActivityCosts()));
|
||||
|
||||
// RouteStates routeStates = new RouteStates();
|
||||
// routeStates.initialiseStateOfJobs(vrp.getJobs().values());
|
||||
// algorithmListeners.add(new PrioritizedVRAListener(Priority.LOW, routeStates));
|
||||
|
||||
// map to store constructed modules
|
||||
TypedMap definedClasses = new TypedMap();
|
||||
|
||||
// algorithm listeners
|
||||
Set<PrioritizedVRAListener> algorithmListeners = new HashSet<PrioritizedVRAListener>();
|
||||
|
||||
// insertion listeners
|
||||
List<InsertionListener> insertionListeners = new ArrayList<InsertionListener>();
|
||||
|
||||
//create fleetmanager
|
||||
final VehicleFleetManager vehicleFleetManager = createFleetManager(vrp);
|
||||
|
||||
//create state-manager
|
||||
final StateManagerImpl stateManager = new StateManagerImpl();
|
||||
|
||||
/*
|
||||
* 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<HierarchicalConfiguration> strategyConfigs = config.configurationsAt("strategy.searchStrategies.searchStrategy");
|
||||
|
|
@ -483,26 +478,72 @@ public class VehicleRoutingAlgorithms {
|
|||
strategy.setName(name);
|
||||
List<HierarchicalConfiguration> 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<PrioritizedVRAListener> 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<PrioritizedVRAListener> algorithmListeners, TypedMap definedClasses, ExecutorService executorService, int nuOfThreads) {
|
||||
private static AlgorithmStartsListener createInitialSolution(XMLConfiguration config, final VehicleRoutingProblem vrp, VehicleFleetManager vehicleFleetManager, StateManagerImpl routeStates, Set<PrioritizedVRAListener> algorithmListeners, TypedMap definedClasses, ExecutorService executorService, int nuOfThreads, ConstraintManager constraintManager) {
|
||||
List<HierarchicalConfiguration> 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<PrioritizedVRAListener> prioListeners = new ArrayList<PrioritizedVRAListener>();
|
||||
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<PrioritizedVRAListener> algorithmListeners, TypedMap definedClasses, ExecutorService executorService, int nuOfThreads) {
|
||||
final StateManagerImpl routeStates, Set<PrioritizedVRAListener> 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<HierarchicalConfiguration> insertionConfigs = moduleConfig.configurationsAt("insertion");
|
||||
if(insertionConfigs.size() != 1) throw new IllegalStateException("this should be 1");
|
||||
List<PrioritizedVRAListener> prioListeners = new ArrayList<PrioritizedVRAListener>();
|
||||
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<Job> 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<HierarchicalConfiguration> insertionConfigs = moduleConfig.configurationsAt("insertion");
|
||||
if(insertionConfigs.size() != 1) throw new IllegalStateException("this should be 1");
|
||||
List<PrioritizedVRAListener> prioListeners = new ArrayList<PrioritizedVRAListener>();
|
||||
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<PrioritizedVRAListener> 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<PrioritizedVRAListener> algorithmListeners, ExecutorService executorService, int nuOfThreads, ConstraintManager constraintManager) {
|
||||
InsertionStrategy insertion = InsertionFactory.createInsertion(vrp, moduleConfig, vehicleFleetManager, routeStates, algorithmListeners, executorService, nuOfThreads, constraintManager);
|
||||
return insertion;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
52
jsprit-core/src/main/java/basics/Delivery.java
Normal file
52
jsprit-core/src/main/java/basics/Delivery.java
Normal file
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
50
jsprit-core/src/main/java/basics/Pickup.java
Normal file
50
jsprit-core/src/main/java/basics/Pickup.java
Normal file
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -49,6 +49,18 @@ import basics.route.VehicleTypeImpl;
|
|||
*/
|
||||
public class VehicleRoutingProblem {
|
||||
|
||||
/**
|
||||
* Overall problem constraints.
|
||||
*
|
||||
* <p>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.
|
||||
*
|
||||
|
|
@ -82,6 +94,8 @@ public class VehicleRoutingProblem {
|
|||
|
||||
private Collection<VehicleType> vehicleTypes;
|
||||
|
||||
private Collection<Constraint> problemConstraints;
|
||||
|
||||
/**
|
||||
* by default all locations are neighbors
|
||||
*/
|
||||
|
|
@ -99,6 +113,7 @@ public class VehicleRoutingProblem {
|
|||
coordinates = new HashMap<String, Coordinate>();
|
||||
vehicleTypes = new ArrayList<VehicleType>();
|
||||
services = new ArrayList<Service>();
|
||||
problemConstraints = new ArrayList<VehicleRoutingProblem.Constraint>();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -118,6 +133,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<Constraint> 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<Constraint> getProblemConstraints(){
|
||||
return Collections.unmodifiableCollection(problemConstraints);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the entire, unmodifiable collection of types.
|
||||
|
|
|
|||
|
|
@ -20,6 +20,6 @@
|
|||
******************************************************************************/
|
||||
package basics.algo;
|
||||
|
||||
public class SearchStrategyListener {
|
||||
public interface SearchStrategyListener extends VehicleRoutingAlgorithmListener{
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,6 @@
|
|||
******************************************************************************/
|
||||
package basics.algo;
|
||||
|
||||
public interface SearchStrategyModuleListener {
|
||||
public interface SearchStrategyModuleListener extends VehicleRoutingAlgorithmListener{
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,26 +38,53 @@ 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);
|
||||
|
||||
private VehicleRoutingProblem.Builder vrpBuilder;
|
||||
|
|
@ -70,6 +97,18 @@ public class VrpXMLReader{
|
|||
|
||||
private Collection<VehicleRoutingProblemSolution> 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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
@ -170,36 +170,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());
|
||||
xmlConfig.setProperty("problemType.fleetComposition", vrp.getFleetComposition());
|
||||
|
|
@ -207,19 +177,6 @@ public class VrpXMLWriter {
|
|||
|
||||
private void writeVehiclesAndTheirTypes(XMLConfiguration xmlConfig) {
|
||||
|
||||
// //depots
|
||||
// Map<Depot,Integer> depot2id = new HashMap<Depot, Integer>();
|
||||
// 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(".").
|
||||
append(Schema.VEHICLE).toString();
|
||||
|
|
@ -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,8 +201,6 @@ 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);
|
||||
|
|
@ -259,35 +208,6 @@ public class VrpXMLWriter {
|
|||
}
|
||||
|
||||
|
||||
// //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++;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
105
jsprit-core/src/main/java/basics/route/DeliveryActivity.java
Normal file
105
jsprit-core/src/main/java/basics/route/DeliveryActivity.java
Normal file
|
|
@ -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<Delivery>{
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
106
jsprit-core/src/main/java/basics/route/PickupActivity.java
Normal file
106
jsprit-core/src/main/java/basics/route/PickupActivity.java
Normal file
|
|
@ -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<Pickup>{
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -31,6 +31,8 @@ public class ServiceActivity implements JobActivity<Service>{
|
|||
|
||||
public double endTime;
|
||||
|
||||
public int capacityDemand;
|
||||
|
||||
/**
|
||||
* @return the arrTime
|
||||
*/
|
||||
|
|
@ -67,18 +69,31 @@ public class ServiceActivity implements JobActivity<Service>{
|
|||
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<Service>{
|
|||
|
||||
@Override
|
||||
public int getCapacityDemand() {
|
||||
return service.getCapacityDemand();
|
||||
return this.capacityDemand;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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<VehicleRoute> vehicleRoutes, Collection<Job> 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<VehicleRoutingProblemSolution> solutions = vra.searchSolutions();
|
||||
// System.out.println(Solutions.getBest(solutions).getCost());
|
||||
// new VrpXMLWriter(vrp, solutions).write("output/pd_solomon_r101.xml");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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.*;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@
|
|||
</vehicleTypes>
|
||||
|
||||
<services>
|
||||
<service id="1" type="delivery">
|
||||
<service id="1" type="service">
|
||||
<locationId>j(1,5)</locationId>
|
||||
<coord x="10.0" y="10.0"/>
|
||||
<capacity-demand>1</capacity-demand>
|
||||
|
|
@ -88,7 +88,7 @@
|
|||
</timeWindows>
|
||||
</service>
|
||||
|
||||
<service id="2" type="delivery">
|
||||
<service id="2" type="service">
|
||||
<locationId>i(3,9)</locationId>
|
||||
<coord x="10.0" y="10.0"/>
|
||||
<capacity-demand>1</capacity-demand>
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@
|
|||
</type>
|
||||
</vehicleTypes>
|
||||
<services>
|
||||
<service id="2" type="delivery">
|
||||
<service id="2" type="service">
|
||||
<locationId>loc2</locationId>
|
||||
<capacity-demand>1</capacity-demand>
|
||||
<duration>4.0</duration>
|
||||
|
|
@ -61,7 +61,7 @@
|
|||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="1" type="delivery">
|
||||
<service id="1" type="service">
|
||||
<locationId>loc</locationId>
|
||||
<capacity-demand>1</capacity-demand>
|
||||
<duration>2.0</duration>
|
||||
|
|
@ -82,12 +82,12 @@
|
|||
<driverId>noDriver</driverId>
|
||||
<vehicleId>v1</vehicleId>
|
||||
<start>10.0</start>
|
||||
<act type="delivery">
|
||||
<act type="service">
|
||||
<serviceId>1</serviceId>
|
||||
<arrTime>20.0</arrTime>
|
||||
<endTime>30.0</endTime>
|
||||
</act>
|
||||
<act type="delivery">
|
||||
<act type="service">
|
||||
<serviceId>2</serviceId>
|
||||
<arrTime>40.0</arrTime>
|
||||
<endTime>80.0</endTime>
|
||||
|
|
|
|||
635
jsprit-core/src/test/resources/pdVRP_vrpnc1_jsprit.xml
Normal file
635
jsprit-core/src/test/resources/pdVRP_vrpnc1_jsprit.xml
Normal file
|
|
@ -0,0 +1,635 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<problem xmlns="http://www.w3schools.com"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3schools.com vrp_xml_schema.xsd">
|
||||
<problemType>
|
||||
<fleetSize>INFINITE</fleetSize>
|
||||
<fleetComposition>HOMOGENEOUS</fleetComposition>
|
||||
</problemType>
|
||||
<vehicles>
|
||||
<vehicle>
|
||||
<id>christophidesVehicle</id>
|
||||
<typeId>christophidesType</typeId>
|
||||
<location>
|
||||
<id>[x=30.0][y=40.0]</id>
|
||||
<coord x="30.0" y="40.0"/>
|
||||
</location>
|
||||
<timeSchedule>
|
||||
<start>0.0</start>
|
||||
<end>999999.0</end>
|
||||
</timeSchedule>
|
||||
</vehicle>
|
||||
</vehicles>
|
||||
<vehicleTypes>
|
||||
<type>
|
||||
<id>christophidesType</id>
|
||||
<capacity>50</capacity>
|
||||
<costs>
|
||||
<fixed>0.0</fixed>
|
||||
<distance>1.0</distance>
|
||||
<time>0.0</time>
|
||||
</costs>
|
||||
</type>
|
||||
</vehicleTypes>
|
||||
<services>
|
||||
<service id="35" type="delivery">
|
||||
<locationId>[x=62.0][y=63.0]</locationId>
|
||||
<coord x="62.0" y="63.0"/>
|
||||
<capacity-demand>17</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="36" type="pickup">
|
||||
<locationId>[x=63.0][y=69.0]</locationId>
|
||||
<coord x="63.0" y="69.0"/>
|
||||
<capacity-demand>6</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="33" type="pickup">
|
||||
<locationId>[x=46.0][y=10.0]</locationId>
|
||||
<coord x="46.0" y="10.0"/>
|
||||
<capacity-demand>23</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="34" type="pickup">
|
||||
<locationId>[x=61.0][y=33.0]</locationId>
|
||||
<coord x="61.0" y="33.0"/>
|
||||
<capacity-demand>26</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="39" type="pickup">
|
||||
<locationId>[x=59.0][y=15.0]</locationId>
|
||||
<coord x="59.0" y="15.0"/>
|
||||
<capacity-demand>14</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="37" type="delivery">
|
||||
<locationId>[x=32.0][y=22.0]</locationId>
|
||||
<coord x="32.0" y="22.0"/>
|
||||
<capacity-demand>9</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="38" type="delivery">
|
||||
<locationId>[x=45.0][y=35.0]</locationId>
|
||||
<coord x="45.0" y="35.0"/>
|
||||
<capacity-demand>15</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="43" type="delivery">
|
||||
<locationId>[x=5.0][y=64.0]</locationId>
|
||||
<coord x="5.0" y="64.0"/>
|
||||
<capacity-demand>11</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="42" type="delivery">
|
||||
<locationId>[x=21.0][y=10.0]</locationId>
|
||||
<coord x="21.0" y="10.0"/>
|
||||
<capacity-demand>13</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="41" type="delivery">
|
||||
<locationId>[x=10.0][y=17.0]</locationId>
|
||||
<coord x="10.0" y="17.0"/>
|
||||
<capacity-demand>27</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="40" type="delivery">
|
||||
<locationId>[x=5.0][y=6.0]</locationId>
|
||||
<coord x="5.0" y="6.0"/>
|
||||
<capacity-demand>7</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="22" type="pickup">
|
||||
<locationId>[x=42.0][y=57.0]</locationId>
|
||||
<coord x="42.0" y="57.0"/>
|
||||
<capacity-demand>8</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="23" type="delivery">
|
||||
<locationId>[x=16.0][y=57.0]</locationId>
|
||||
<coord x="16.0" y="57.0"/>
|
||||
<capacity-demand>16</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="24" type="delivery">
|
||||
<locationId>[x=8.0][y=52.0]</locationId>
|
||||
<coord x="8.0" y="52.0"/>
|
||||
<capacity-demand>10</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="25" type="pickup">
|
||||
<locationId>[x=7.0][y=38.0]</locationId>
|
||||
<coord x="7.0" y="38.0"/>
|
||||
<capacity-demand>28</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="26" type="delivery">
|
||||
<locationId>[x=27.0][y=68.0]</locationId>
|
||||
<coord x="27.0" y="68.0"/>
|
||||
<capacity-demand>7</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="27" type="pickup">
|
||||
<locationId>[x=30.0][y=48.0]</locationId>
|
||||
<coord x="30.0" y="48.0"/>
|
||||
<capacity-demand>15</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="28" type="pickup">
|
||||
<locationId>[x=43.0][y=67.0]</locationId>
|
||||
<coord x="43.0" y="67.0"/>
|
||||
<capacity-demand>14</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="29" type="delivery">
|
||||
<locationId>[x=58.0][y=48.0]</locationId>
|
||||
<coord x="58.0" y="48.0"/>
|
||||
<capacity-demand>6</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="3" type="delivery">
|
||||
<locationId>[x=52.0][y=64.0]</locationId>
|
||||
<coord x="52.0" y="64.0"/>
|
||||
<capacity-demand>16</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="2" type="delivery">
|
||||
<locationId>[x=49.0][y=49.0]</locationId>
|
||||
<coord x="49.0" y="49.0"/>
|
||||
<capacity-demand>30</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="1" type="delivery">
|
||||
<locationId>[x=37.0][y=52.0]</locationId>
|
||||
<coord x="37.0" y="52.0"/>
|
||||
<capacity-demand>7</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="7" type="pickup">
|
||||
<locationId>[x=17.0][y=63.0]</locationId>
|
||||
<coord x="17.0" y="63.0"/>
|
||||
<capacity-demand>19</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="30" type="delivery">
|
||||
<locationId>[x=58.0][y=27.0]</locationId>
|
||||
<coord x="58.0" y="27.0"/>
|
||||
<capacity-demand>19</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="6" type="pickup">
|
||||
<locationId>[x=21.0][y=47.0]</locationId>
|
||||
<coord x="21.0" y="47.0"/>
|
||||
<capacity-demand>15</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="5" type="delivery">
|
||||
<locationId>[x=40.0][y=30.0]</locationId>
|
||||
<coord x="40.0" y="30.0"/>
|
||||
<capacity-demand>21</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="32" type="pickup">
|
||||
<locationId>[x=38.0][y=46.0]</locationId>
|
||||
<coord x="38.0" y="46.0"/>
|
||||
<capacity-demand>12</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="4" type="delivery">
|
||||
<locationId>[x=20.0][y=26.0]</locationId>
|
||||
<coord x="20.0" y="26.0"/>
|
||||
<capacity-demand>9</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="31" type="delivery">
|
||||
<locationId>[x=37.0][y=69.0]</locationId>
|
||||
<coord x="37.0" y="69.0"/>
|
||||
<capacity-demand>11</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="9" type="pickup">
|
||||
<locationId>[x=52.0][y=33.0]</locationId>
|
||||
<coord x="52.0" y="33.0"/>
|
||||
<capacity-demand>11</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="8" type="pickup">
|
||||
<locationId>[x=31.0][y=62.0]</locationId>
|
||||
<coord x="31.0" y="62.0"/>
|
||||
<capacity-demand>23</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="19" type="delivery">
|
||||
<locationId>[x=13.0][y=13.0]</locationId>
|
||||
<coord x="13.0" y="13.0"/>
|
||||
<capacity-demand>9</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="17" type="pickup">
|
||||
<locationId>[x=27.0][y=23.0]</locationId>
|
||||
<coord x="27.0" y="23.0"/>
|
||||
<capacity-demand>3</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="18" type="delivery">
|
||||
<locationId>[x=17.0][y=33.0]</locationId>
|
||||
<coord x="17.0" y="33.0"/>
|
||||
<capacity-demand>41</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="15" type="pickup">
|
||||
<locationId>[x=36.0][y=16.0]</locationId>
|
||||
<coord x="36.0" y="16.0"/>
|
||||
<capacity-demand>10</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="16" type="delivery">
|
||||
<locationId>[x=52.0][y=41.0]</locationId>
|
||||
<coord x="52.0" y="41.0"/>
|
||||
<capacity-demand>15</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="13" type="delivery">
|
||||
<locationId>[x=5.0][y=25.0]</locationId>
|
||||
<coord x="5.0" y="25.0"/>
|
||||
<capacity-demand>23</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="14" type="pickup">
|
||||
<locationId>[x=12.0][y=42.0]</locationId>
|
||||
<coord x="12.0" y="42.0"/>
|
||||
<capacity-demand>21</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="11" type="delivery">
|
||||
<locationId>[x=42.0][y=41.0]</locationId>
|
||||
<coord x="42.0" y="41.0"/>
|
||||
<capacity-demand>19</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="12" type="pickup">
|
||||
<locationId>[x=31.0][y=32.0]</locationId>
|
||||
<coord x="31.0" y="32.0"/>
|
||||
<capacity-demand>29</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="21" type="delivery">
|
||||
<locationId>[x=62.0][y=42.0]</locationId>
|
||||
<coord x="62.0" y="42.0"/>
|
||||
<capacity-demand>8</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="20" type="delivery">
|
||||
<locationId>[x=57.0][y=58.0]</locationId>
|
||||
<coord x="57.0" y="58.0"/>
|
||||
<capacity-demand>28</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="49" type="pickup">
|
||||
<locationId>[x=48.0][y=28.0]</locationId>
|
||||
<coord x="48.0" y="28.0"/>
|
||||
<capacity-demand>18</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="48" type="pickup">
|
||||
<locationId>[x=25.0][y=55.0]</locationId>
|
||||
<coord x="25.0" y="55.0"/>
|
||||
<capacity-demand>17</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="45" type="pickup">
|
||||
<locationId>[x=39.0][y=10.0]</locationId>
|
||||
<coord x="39.0" y="10.0"/>
|
||||
<capacity-demand>10</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="44" type="pickup">
|
||||
<locationId>[x=30.0][y=15.0]</locationId>
|
||||
<coord x="30.0" y="15.0"/>
|
||||
<capacity-demand>16</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="47" type="pickup">
|
||||
<locationId>[x=25.0][y=32.0]</locationId>
|
||||
<coord x="25.0" y="32.0"/>
|
||||
<capacity-demand>25</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="46" type="pickup">
|
||||
<locationId>[x=32.0][y=39.0]</locationId>
|
||||
<coord x="32.0" y="39.0"/>
|
||||
<capacity-demand>5</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="10" type="delivery">
|
||||
<locationId>[x=51.0][y=21.0]</locationId>
|
||||
<coord x="51.0" y="21.0"/>
|
||||
<capacity-demand>5</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="50" type="pickup">
|
||||
<locationId>[x=56.0][y=37.0]</locationId>
|
||||
<coord x="56.0" y="37.0"/>
|
||||
<capacity-demand>10</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
</services>
|
||||
</problem>
|
||||
1235
jsprit-core/src/test/resources/pd_solomon_r101.xml
Normal file
1235
jsprit-core/src/test/resources/pd_solomon_r101.xml
Normal file
File diff suppressed because it is too large
Load diff
110
jsprit-examples/input/R101.txt
Normal file
110
jsprit-examples/input/R101.txt
Normal file
|
|
@ -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
|
||||
842
jsprit-examples/input/cordeau_p01.xml
Normal file
842
jsprit-examples/input/cordeau_p01.xml
Normal file
|
|
@ -0,0 +1,842 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<problem xmlns="http://www.w3schools.com"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3schools.com vrp_xml_schema.xsd">
|
||||
<problemType>
|
||||
<fleetSize>INFINITE</fleetSize>
|
||||
<fleetComposition>HOMOGENEOUS</fleetComposition>
|
||||
</problemType>
|
||||
<vehicles>
|
||||
<vehicle>
|
||||
<id>1_1_cordeauVehicle</id>
|
||||
<typeId>1_cordeauType</typeId>
|
||||
<location>
|
||||
<id>[x=20.0][y=20.0]</id>
|
||||
<coord x="20.0" y="20.0"/>
|
||||
</location>
|
||||
<timeSchedule>
|
||||
<start>0.0</start>
|
||||
<end>999999.0</end>
|
||||
</timeSchedule>
|
||||
</vehicle>
|
||||
<vehicle>
|
||||
<id>1_2_cordeauVehicle</id>
|
||||
<typeId>1_cordeauType</typeId>
|
||||
<location>
|
||||
<id>[x=20.0][y=20.0]</id>
|
||||
<coord x="20.0" y="20.0"/>
|
||||
</location>
|
||||
<timeSchedule>
|
||||
<start>0.0</start>
|
||||
<end>999999.0</end>
|
||||
</timeSchedule>
|
||||
</vehicle>
|
||||
<vehicle>
|
||||
<id>1_3_cordeauVehicle</id>
|
||||
<typeId>1_cordeauType</typeId>
|
||||
<location>
|
||||
<id>[x=20.0][y=20.0]</id>
|
||||
<coord x="20.0" y="20.0"/>
|
||||
</location>
|
||||
<timeSchedule>
|
||||
<start>0.0</start>
|
||||
<end>999999.0</end>
|
||||
</timeSchedule>
|
||||
</vehicle>
|
||||
<vehicle>
|
||||
<id>1_4_cordeauVehicle</id>
|
||||
<typeId>1_cordeauType</typeId>
|
||||
<location>
|
||||
<id>[x=20.0][y=20.0]</id>
|
||||
<coord x="20.0" y="20.0"/>
|
||||
</location>
|
||||
<timeSchedule>
|
||||
<start>0.0</start>
|
||||
<end>999999.0</end>
|
||||
</timeSchedule>
|
||||
</vehicle>
|
||||
<vehicle>
|
||||
<id>2_1_cordeauVehicle</id>
|
||||
<typeId>2_cordeauType</typeId>
|
||||
<location>
|
||||
<id>[x=30.0][y=40.0]</id>
|
||||
<coord x="30.0" y="40.0"/>
|
||||
</location>
|
||||
<timeSchedule>
|
||||
<start>0.0</start>
|
||||
<end>999999.0</end>
|
||||
</timeSchedule>
|
||||
</vehicle>
|
||||
<vehicle>
|
||||
<id>2_2_cordeauVehicle</id>
|
||||
<typeId>2_cordeauType</typeId>
|
||||
<location>
|
||||
<id>[x=30.0][y=40.0]</id>
|
||||
<coord x="30.0" y="40.0"/>
|
||||
</location>
|
||||
<timeSchedule>
|
||||
<start>0.0</start>
|
||||
<end>999999.0</end>
|
||||
</timeSchedule>
|
||||
</vehicle>
|
||||
<vehicle>
|
||||
<id>2_3_cordeauVehicle</id>
|
||||
<typeId>2_cordeauType</typeId>
|
||||
<location>
|
||||
<id>[x=30.0][y=40.0]</id>
|
||||
<coord x="30.0" y="40.0"/>
|
||||
</location>
|
||||
<timeSchedule>
|
||||
<start>0.0</start>
|
||||
<end>999999.0</end>
|
||||
</timeSchedule>
|
||||
</vehicle>
|
||||
<vehicle>
|
||||
<id>2_4_cordeauVehicle</id>
|
||||
<typeId>2_cordeauType</typeId>
|
||||
<location>
|
||||
<id>[x=30.0][y=40.0]</id>
|
||||
<coord x="30.0" y="40.0"/>
|
||||
</location>
|
||||
<timeSchedule>
|
||||
<start>0.0</start>
|
||||
<end>999999.0</end>
|
||||
</timeSchedule>
|
||||
</vehicle>
|
||||
<vehicle>
|
||||
<id>3_1_cordeauVehicle</id>
|
||||
<typeId>3_cordeauType</typeId>
|
||||
<location>
|
||||
<id>[x=50.0][y=30.0]</id>
|
||||
<coord x="50.0" y="30.0"/>
|
||||
</location>
|
||||
<timeSchedule>
|
||||
<start>0.0</start>
|
||||
<end>999999.0</end>
|
||||
</timeSchedule>
|
||||
</vehicle>
|
||||
<vehicle>
|
||||
<id>3_2_cordeauVehicle</id>
|
||||
<typeId>3_cordeauType</typeId>
|
||||
<location>
|
||||
<id>[x=50.0][y=30.0]</id>
|
||||
<coord x="50.0" y="30.0"/>
|
||||
</location>
|
||||
<timeSchedule>
|
||||
<start>0.0</start>
|
||||
<end>999999.0</end>
|
||||
</timeSchedule>
|
||||
</vehicle>
|
||||
<vehicle>
|
||||
<id>3_3_cordeauVehicle</id>
|
||||
<typeId>3_cordeauType</typeId>
|
||||
<location>
|
||||
<id>[x=50.0][y=30.0]</id>
|
||||
<coord x="50.0" y="30.0"/>
|
||||
</location>
|
||||
<timeSchedule>
|
||||
<start>0.0</start>
|
||||
<end>999999.0</end>
|
||||
</timeSchedule>
|
||||
</vehicle>
|
||||
<vehicle>
|
||||
<id>3_4_cordeauVehicle</id>
|
||||
<typeId>3_cordeauType</typeId>
|
||||
<location>
|
||||
<id>[x=50.0][y=30.0]</id>
|
||||
<coord x="50.0" y="30.0"/>
|
||||
</location>
|
||||
<timeSchedule>
|
||||
<start>0.0</start>
|
||||
<end>999999.0</end>
|
||||
</timeSchedule>
|
||||
</vehicle>
|
||||
<vehicle>
|
||||
<id>4_1_cordeauVehicle</id>
|
||||
<typeId>4_cordeauType</typeId>
|
||||
<location>
|
||||
<id>[x=60.0][y=50.0]</id>
|
||||
<coord x="60.0" y="50.0"/>
|
||||
</location>
|
||||
<timeSchedule>
|
||||
<start>0.0</start>
|
||||
<end>999999.0</end>
|
||||
</timeSchedule>
|
||||
</vehicle>
|
||||
<vehicle>
|
||||
<id>4_2_cordeauVehicle</id>
|
||||
<typeId>4_cordeauType</typeId>
|
||||
<location>
|
||||
<id>[x=60.0][y=50.0]</id>
|
||||
<coord x="60.0" y="50.0"/>
|
||||
</location>
|
||||
<timeSchedule>
|
||||
<start>0.0</start>
|
||||
<end>999999.0</end>
|
||||
</timeSchedule>
|
||||
</vehicle>
|
||||
<vehicle>
|
||||
<id>4_3_cordeauVehicle</id>
|
||||
<typeId>4_cordeauType</typeId>
|
||||
<location>
|
||||
<id>[x=60.0][y=50.0]</id>
|
||||
<coord x="60.0" y="50.0"/>
|
||||
</location>
|
||||
<timeSchedule>
|
||||
<start>0.0</start>
|
||||
<end>999999.0</end>
|
||||
</timeSchedule>
|
||||
</vehicle>
|
||||
<vehicle>
|
||||
<id>4_4_cordeauVehicle</id>
|
||||
<typeId>4_cordeauType</typeId>
|
||||
<location>
|
||||
<id>[x=60.0][y=50.0]</id>
|
||||
<coord x="60.0" y="50.0"/>
|
||||
</location>
|
||||
<timeSchedule>
|
||||
<start>0.0</start>
|
||||
<end>999999.0</end>
|
||||
</timeSchedule>
|
||||
</vehicle>
|
||||
</vehicles>
|
||||
<vehicleTypes>
|
||||
<type>
|
||||
<id>1_cordeauType</id>
|
||||
<capacity>80</capacity>
|
||||
<costs>
|
||||
<fixed>0.0</fixed>
|
||||
<distance>1.0</distance>
|
||||
<time>0.0</time>
|
||||
</costs>
|
||||
</type>
|
||||
<type>
|
||||
<id>2_cordeauType</id>
|
||||
<capacity>80</capacity>
|
||||
<costs>
|
||||
<fixed>0.0</fixed>
|
||||
<distance>1.0</distance>
|
||||
<time>0.0</time>
|
||||
</costs>
|
||||
</type>
|
||||
<type>
|
||||
<id>3_cordeauType</id>
|
||||
<capacity>80</capacity>
|
||||
<costs>
|
||||
<fixed>0.0</fixed>
|
||||
<distance>1.0</distance>
|
||||
<time>0.0</time>
|
||||
</costs>
|
||||
</type>
|
||||
<type>
|
||||
<id>4_cordeauType</id>
|
||||
<capacity>80</capacity>
|
||||
<costs>
|
||||
<fixed>0.0</fixed>
|
||||
<distance>1.0</distance>
|
||||
<time>0.0</time>
|
||||
</costs>
|
||||
</type>
|
||||
</vehicleTypes>
|
||||
<services>
|
||||
<service id="35" type="delivery">
|
||||
<locationId>[x=62.0][y=63.0]</locationId>
|
||||
<coord x="62.0" y="63.0"/>
|
||||
<capacity-demand>17</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="36" type="delivery">
|
||||
<locationId>[x=63.0][y=69.0]</locationId>
|
||||
<coord x="63.0" y="69.0"/>
|
||||
<capacity-demand>6</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="33" type="delivery">
|
||||
<locationId>[x=46.0][y=10.0]</locationId>
|
||||
<coord x="46.0" y="10.0"/>
|
||||
<capacity-demand>23</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="34" type="pickup">
|
||||
<locationId>[x=61.0][y=33.0]</locationId>
|
||||
<coord x="61.0" y="33.0"/>
|
||||
<capacity-demand>26</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="39" type="pickup">
|
||||
<locationId>[x=59.0][y=15.0]</locationId>
|
||||
<coord x="59.0" y="15.0"/>
|
||||
<capacity-demand>14</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="37" type="pickup">
|
||||
<locationId>[x=32.0][y=22.0]</locationId>
|
||||
<coord x="32.0" y="22.0"/>
|
||||
<capacity-demand>9</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="38" type="pickup">
|
||||
<locationId>[x=45.0][y=35.0]</locationId>
|
||||
<coord x="45.0" y="35.0"/>
|
||||
<capacity-demand>15</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="43" type="delivery">
|
||||
<locationId>[x=5.0][y=64.0]</locationId>
|
||||
<coord x="5.0" y="64.0"/>
|
||||
<capacity-demand>11</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="42" type="delivery">
|
||||
<locationId>[x=21.0][y=10.0]</locationId>
|
||||
<coord x="21.0" y="10.0"/>
|
||||
<capacity-demand>13</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="41" type="delivery">
|
||||
<locationId>[x=10.0][y=17.0]</locationId>
|
||||
<coord x="10.0" y="17.0"/>
|
||||
<capacity-demand>27</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="40" type="pickup">
|
||||
<locationId>[x=5.0][y=6.0]</locationId>
|
||||
<coord x="5.0" y="6.0"/>
|
||||
<capacity-demand>7</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="22" type="pickup">
|
||||
<locationId>[x=42.0][y=57.0]</locationId>
|
||||
<coord x="42.0" y="57.0"/>
|
||||
<capacity-demand>8</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="23" type="pickup">
|
||||
<locationId>[x=16.0][y=57.0]</locationId>
|
||||
<coord x="16.0" y="57.0"/>
|
||||
<capacity-demand>16</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="24" type="delivery">
|
||||
<locationId>[x=8.0][y=52.0]</locationId>
|
||||
<coord x="8.0" y="52.0"/>
|
||||
<capacity-demand>10</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="25" type="delivery">
|
||||
<locationId>[x=7.0][y=38.0]</locationId>
|
||||
<coord x="7.0" y="38.0"/>
|
||||
<capacity-demand>28</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="26" type="pickup">
|
||||
<locationId>[x=27.0][y=68.0]</locationId>
|
||||
<coord x="27.0" y="68.0"/>
|
||||
<capacity-demand>7</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="27" type="pickup">
|
||||
<locationId>[x=30.0][y=48.0]</locationId>
|
||||
<coord x="30.0" y="48.0"/>
|
||||
<capacity-demand>15</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="28" type="pickup">
|
||||
<locationId>[x=43.0][y=67.0]</locationId>
|
||||
<coord x="43.0" y="67.0"/>
|
||||
<capacity-demand>14</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="29" type="delivery">
|
||||
<locationId>[x=58.0][y=48.0]</locationId>
|
||||
<coord x="58.0" y="48.0"/>
|
||||
<capacity-demand>6</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="3" type="delivery">
|
||||
<locationId>[x=52.0][y=64.0]</locationId>
|
||||
<coord x="52.0" y="64.0"/>
|
||||
<capacity-demand>16</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="2" type="pickup">
|
||||
<locationId>[x=49.0][y=49.0]</locationId>
|
||||
<coord x="49.0" y="49.0"/>
|
||||
<capacity-demand>30</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="1" type="delivery">
|
||||
<locationId>[x=37.0][y=52.0]</locationId>
|
||||
<coord x="37.0" y="52.0"/>
|
||||
<capacity-demand>7</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="30" type="pickup">
|
||||
<locationId>[x=58.0][y=27.0]</locationId>
|
||||
<coord x="58.0" y="27.0"/>
|
||||
<capacity-demand>19</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="7" type="delivery">
|
||||
<locationId>[x=17.0][y=63.0]</locationId>
|
||||
<coord x="17.0" y="63.0"/>
|
||||
<capacity-demand>19</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="6" type="pickup">
|
||||
<locationId>[x=21.0][y=47.0]</locationId>
|
||||
<coord x="21.0" y="47.0"/>
|
||||
<capacity-demand>15</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="5" type="delivery">
|
||||
<locationId>[x=40.0][y=30.0]</locationId>
|
||||
<coord x="40.0" y="30.0"/>
|
||||
<capacity-demand>21</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="32" type="delivery">
|
||||
<locationId>[x=38.0][y=46.0]</locationId>
|
||||
<coord x="38.0" y="46.0"/>
|
||||
<capacity-demand>12</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="4" type="pickup">
|
||||
<locationId>[x=20.0][y=26.0]</locationId>
|
||||
<coord x="20.0" y="26.0"/>
|
||||
<capacity-demand>9</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="31" type="pickup">
|
||||
<locationId>[x=37.0][y=69.0]</locationId>
|
||||
<coord x="37.0" y="69.0"/>
|
||||
<capacity-demand>11</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="9" type="delivery">
|
||||
<locationId>[x=52.0][y=33.0]</locationId>
|
||||
<coord x="52.0" y="33.0"/>
|
||||
<capacity-demand>11</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="8" type="pickup">
|
||||
<locationId>[x=31.0][y=62.0]</locationId>
|
||||
<coord x="31.0" y="62.0"/>
|
||||
<capacity-demand>23</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="19" type="delivery">
|
||||
<locationId>[x=13.0][y=13.0]</locationId>
|
||||
<coord x="13.0" y="13.0"/>
|
||||
<capacity-demand>9</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="17" type="pickup">
|
||||
<locationId>[x=27.0][y=23.0]</locationId>
|
||||
<coord x="27.0" y="23.0"/>
|
||||
<capacity-demand>3</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="18" type="pickup">
|
||||
<locationId>[x=17.0][y=33.0]</locationId>
|
||||
<coord x="17.0" y="33.0"/>
|
||||
<capacity-demand>41</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="15" type="delivery">
|
||||
<locationId>[x=36.0][y=16.0]</locationId>
|
||||
<coord x="36.0" y="16.0"/>
|
||||
<capacity-demand>10</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="16" type="pickup">
|
||||
<locationId>[x=52.0][y=41.0]</locationId>
|
||||
<coord x="52.0" y="41.0"/>
|
||||
<capacity-demand>15</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="13" type="delivery">
|
||||
<locationId>[x=5.0][y=25.0]</locationId>
|
||||
<coord x="5.0" y="25.0"/>
|
||||
<capacity-demand>23</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="14" type="pickup">
|
||||
<locationId>[x=12.0][y=42.0]</locationId>
|
||||
<coord x="12.0" y="42.0"/>
|
||||
<capacity-demand>21</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="11" type="delivery">
|
||||
<locationId>[x=42.0][y=41.0]</locationId>
|
||||
<coord x="42.0" y="41.0"/>
|
||||
<capacity-demand>19</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="12" type="delivery">
|
||||
<locationId>[x=31.0][y=32.0]</locationId>
|
||||
<coord x="31.0" y="32.0"/>
|
||||
<capacity-demand>29</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="21" type="pickup">
|
||||
<locationId>[x=62.0][y=42.0]</locationId>
|
||||
<coord x="62.0" y="42.0"/>
|
||||
<capacity-demand>8</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="20" type="pickup">
|
||||
<locationId>[x=57.0][y=58.0]</locationId>
|
||||
<coord x="57.0" y="58.0"/>
|
||||
<capacity-demand>28</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="49" type="delivery">
|
||||
<locationId>[x=48.0][y=28.0]</locationId>
|
||||
<coord x="48.0" y="28.0"/>
|
||||
<capacity-demand>18</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="48" type="pickup">
|
||||
<locationId>[x=25.0][y=55.0]</locationId>
|
||||
<coord x="25.0" y="55.0"/>
|
||||
<capacity-demand>17</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="45" type="delivery">
|
||||
<locationId>[x=39.0][y=10.0]</locationId>
|
||||
<coord x="39.0" y="10.0"/>
|
||||
<capacity-demand>10</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="44" type="delivery">
|
||||
<locationId>[x=30.0][y=15.0]</locationId>
|
||||
<coord x="30.0" y="15.0"/>
|
||||
<capacity-demand>16</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="47" type="pickup">
|
||||
<locationId>[x=25.0][y=32.0]</locationId>
|
||||
<coord x="25.0" y="32.0"/>
|
||||
<capacity-demand>25</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="46" type="pickup">
|
||||
<locationId>[x=32.0][y=39.0]</locationId>
|
||||
<coord x="32.0" y="39.0"/>
|
||||
<capacity-demand>5</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="10" type="delivery">
|
||||
<locationId>[x=51.0][y=21.0]</locationId>
|
||||
<coord x="51.0" y="21.0"/>
|
||||
<capacity-demand>5</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="50" type="pickup">
|
||||
<locationId>[x=56.0][y=37.0]</locationId>
|
||||
<coord x="56.0" y="37.0"/>
|
||||
<capacity-demand>10</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
</services>
|
||||
</problem>
|
||||
3356
jsprit-examples/input/cordeau_p08.xml
Normal file
3356
jsprit-examples/input/cordeau_p08.xml
Normal file
File diff suppressed because it is too large
Load diff
1235
jsprit-examples/input/deliveries_solomon_c101.xml
Normal file
1235
jsprit-examples/input/deliveries_solomon_c101.xml
Normal file
File diff suppressed because it is too large
Load diff
635
jsprit-examples/input/pd_christophides_vrpnc1_vcap50.xml
Normal file
635
jsprit-examples/input/pd_christophides_vrpnc1_vcap50.xml
Normal file
|
|
@ -0,0 +1,635 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<problem xmlns="http://www.w3schools.com"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3schools.com vrp_xml_schema.xsd">
|
||||
<problemType>
|
||||
<fleetSize>INFINITE</fleetSize>
|
||||
<fleetComposition>HOMOGENEOUS</fleetComposition>
|
||||
</problemType>
|
||||
<vehicles>
|
||||
<vehicle>
|
||||
<id>christophidesVehicle</id>
|
||||
<typeId>christophidesType</typeId>
|
||||
<location>
|
||||
<id>[x=30.0][y=40.0]</id>
|
||||
<coord x="30.0" y="40.0"/>
|
||||
</location>
|
||||
<timeSchedule>
|
||||
<start>0.0</start>
|
||||
<end>999999.0</end>
|
||||
</timeSchedule>
|
||||
</vehicle>
|
||||
</vehicles>
|
||||
<vehicleTypes>
|
||||
<type>
|
||||
<id>christophidesType</id>
|
||||
<capacity>50</capacity>
|
||||
<costs>
|
||||
<fixed>0.0</fixed>
|
||||
<distance>1.0</distance>
|
||||
<time>0.0</time>
|
||||
</costs>
|
||||
</type>
|
||||
</vehicleTypes>
|
||||
<services>
|
||||
<service id="35" type="delivery">
|
||||
<locationId>[x=62.0][y=63.0]</locationId>
|
||||
<coord x="62.0" y="63.0"/>
|
||||
<capacity-demand>17</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="36" type="pickup">
|
||||
<locationId>[x=63.0][y=69.0]</locationId>
|
||||
<coord x="63.0" y="69.0"/>
|
||||
<capacity-demand>6</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="33" type="pickup">
|
||||
<locationId>[x=46.0][y=10.0]</locationId>
|
||||
<coord x="46.0" y="10.0"/>
|
||||
<capacity-demand>23</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="34" type="pickup">
|
||||
<locationId>[x=61.0][y=33.0]</locationId>
|
||||
<coord x="61.0" y="33.0"/>
|
||||
<capacity-demand>26</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="39" type="pickup">
|
||||
<locationId>[x=59.0][y=15.0]</locationId>
|
||||
<coord x="59.0" y="15.0"/>
|
||||
<capacity-demand>14</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="37" type="delivery">
|
||||
<locationId>[x=32.0][y=22.0]</locationId>
|
||||
<coord x="32.0" y="22.0"/>
|
||||
<capacity-demand>9</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="38" type="delivery">
|
||||
<locationId>[x=45.0][y=35.0]</locationId>
|
||||
<coord x="45.0" y="35.0"/>
|
||||
<capacity-demand>15</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="43" type="delivery">
|
||||
<locationId>[x=5.0][y=64.0]</locationId>
|
||||
<coord x="5.0" y="64.0"/>
|
||||
<capacity-demand>11</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="42" type="delivery">
|
||||
<locationId>[x=21.0][y=10.0]</locationId>
|
||||
<coord x="21.0" y="10.0"/>
|
||||
<capacity-demand>13</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="41" type="delivery">
|
||||
<locationId>[x=10.0][y=17.0]</locationId>
|
||||
<coord x="10.0" y="17.0"/>
|
||||
<capacity-demand>27</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="40" type="delivery">
|
||||
<locationId>[x=5.0][y=6.0]</locationId>
|
||||
<coord x="5.0" y="6.0"/>
|
||||
<capacity-demand>7</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="22" type="pickup">
|
||||
<locationId>[x=42.0][y=57.0]</locationId>
|
||||
<coord x="42.0" y="57.0"/>
|
||||
<capacity-demand>8</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="23" type="delivery">
|
||||
<locationId>[x=16.0][y=57.0]</locationId>
|
||||
<coord x="16.0" y="57.0"/>
|
||||
<capacity-demand>16</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="24" type="delivery">
|
||||
<locationId>[x=8.0][y=52.0]</locationId>
|
||||
<coord x="8.0" y="52.0"/>
|
||||
<capacity-demand>10</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="25" type="pickup">
|
||||
<locationId>[x=7.0][y=38.0]</locationId>
|
||||
<coord x="7.0" y="38.0"/>
|
||||
<capacity-demand>28</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="26" type="delivery">
|
||||
<locationId>[x=27.0][y=68.0]</locationId>
|
||||
<coord x="27.0" y="68.0"/>
|
||||
<capacity-demand>7</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="27" type="pickup">
|
||||
<locationId>[x=30.0][y=48.0]</locationId>
|
||||
<coord x="30.0" y="48.0"/>
|
||||
<capacity-demand>15</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="28" type="pickup">
|
||||
<locationId>[x=43.0][y=67.0]</locationId>
|
||||
<coord x="43.0" y="67.0"/>
|
||||
<capacity-demand>14</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="29" type="delivery">
|
||||
<locationId>[x=58.0][y=48.0]</locationId>
|
||||
<coord x="58.0" y="48.0"/>
|
||||
<capacity-demand>6</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="3" type="delivery">
|
||||
<locationId>[x=52.0][y=64.0]</locationId>
|
||||
<coord x="52.0" y="64.0"/>
|
||||
<capacity-demand>16</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="2" type="delivery">
|
||||
<locationId>[x=49.0][y=49.0]</locationId>
|
||||
<coord x="49.0" y="49.0"/>
|
||||
<capacity-demand>30</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="1" type="delivery">
|
||||
<locationId>[x=37.0][y=52.0]</locationId>
|
||||
<coord x="37.0" y="52.0"/>
|
||||
<capacity-demand>7</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="7" type="pickup">
|
||||
<locationId>[x=17.0][y=63.0]</locationId>
|
||||
<coord x="17.0" y="63.0"/>
|
||||
<capacity-demand>19</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="30" type="delivery">
|
||||
<locationId>[x=58.0][y=27.0]</locationId>
|
||||
<coord x="58.0" y="27.0"/>
|
||||
<capacity-demand>19</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="6" type="pickup">
|
||||
<locationId>[x=21.0][y=47.0]</locationId>
|
||||
<coord x="21.0" y="47.0"/>
|
||||
<capacity-demand>15</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="5" type="delivery">
|
||||
<locationId>[x=40.0][y=30.0]</locationId>
|
||||
<coord x="40.0" y="30.0"/>
|
||||
<capacity-demand>21</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="32" type="pickup">
|
||||
<locationId>[x=38.0][y=46.0]</locationId>
|
||||
<coord x="38.0" y="46.0"/>
|
||||
<capacity-demand>12</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="4" type="delivery">
|
||||
<locationId>[x=20.0][y=26.0]</locationId>
|
||||
<coord x="20.0" y="26.0"/>
|
||||
<capacity-demand>9</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="31" type="delivery">
|
||||
<locationId>[x=37.0][y=69.0]</locationId>
|
||||
<coord x="37.0" y="69.0"/>
|
||||
<capacity-demand>11</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="9" type="pickup">
|
||||
<locationId>[x=52.0][y=33.0]</locationId>
|
||||
<coord x="52.0" y="33.0"/>
|
||||
<capacity-demand>11</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="8" type="pickup">
|
||||
<locationId>[x=31.0][y=62.0]</locationId>
|
||||
<coord x="31.0" y="62.0"/>
|
||||
<capacity-demand>23</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="19" type="delivery">
|
||||
<locationId>[x=13.0][y=13.0]</locationId>
|
||||
<coord x="13.0" y="13.0"/>
|
||||
<capacity-demand>9</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="17" type="pickup">
|
||||
<locationId>[x=27.0][y=23.0]</locationId>
|
||||
<coord x="27.0" y="23.0"/>
|
||||
<capacity-demand>3</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="18" type="delivery">
|
||||
<locationId>[x=17.0][y=33.0]</locationId>
|
||||
<coord x="17.0" y="33.0"/>
|
||||
<capacity-demand>41</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="15" type="pickup">
|
||||
<locationId>[x=36.0][y=16.0]</locationId>
|
||||
<coord x="36.0" y="16.0"/>
|
||||
<capacity-demand>10</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="16" type="delivery">
|
||||
<locationId>[x=52.0][y=41.0]</locationId>
|
||||
<coord x="52.0" y="41.0"/>
|
||||
<capacity-demand>15</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="13" type="delivery">
|
||||
<locationId>[x=5.0][y=25.0]</locationId>
|
||||
<coord x="5.0" y="25.0"/>
|
||||
<capacity-demand>23</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="14" type="pickup">
|
||||
<locationId>[x=12.0][y=42.0]</locationId>
|
||||
<coord x="12.0" y="42.0"/>
|
||||
<capacity-demand>21</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="11" type="delivery">
|
||||
<locationId>[x=42.0][y=41.0]</locationId>
|
||||
<coord x="42.0" y="41.0"/>
|
||||
<capacity-demand>19</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="12" type="pickup">
|
||||
<locationId>[x=31.0][y=32.0]</locationId>
|
||||
<coord x="31.0" y="32.0"/>
|
||||
<capacity-demand>29</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="21" type="delivery">
|
||||
<locationId>[x=62.0][y=42.0]</locationId>
|
||||
<coord x="62.0" y="42.0"/>
|
||||
<capacity-demand>8</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="20" type="delivery">
|
||||
<locationId>[x=57.0][y=58.0]</locationId>
|
||||
<coord x="57.0" y="58.0"/>
|
||||
<capacity-demand>28</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="49" type="pickup">
|
||||
<locationId>[x=48.0][y=28.0]</locationId>
|
||||
<coord x="48.0" y="28.0"/>
|
||||
<capacity-demand>18</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="48" type="pickup">
|
||||
<locationId>[x=25.0][y=55.0]</locationId>
|
||||
<coord x="25.0" y="55.0"/>
|
||||
<capacity-demand>17</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="45" type="pickup">
|
||||
<locationId>[x=39.0][y=10.0]</locationId>
|
||||
<coord x="39.0" y="10.0"/>
|
||||
<capacity-demand>10</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="44" type="pickup">
|
||||
<locationId>[x=30.0][y=15.0]</locationId>
|
||||
<coord x="30.0" y="15.0"/>
|
||||
<capacity-demand>16</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="47" type="pickup">
|
||||
<locationId>[x=25.0][y=32.0]</locationId>
|
||||
<coord x="25.0" y="32.0"/>
|
||||
<capacity-demand>25</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="46" type="pickup">
|
||||
<locationId>[x=32.0][y=39.0]</locationId>
|
||||
<coord x="32.0" y="39.0"/>
|
||||
<capacity-demand>5</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="10" type="delivery">
|
||||
<locationId>[x=51.0][y=21.0]</locationId>
|
||||
<coord x="51.0" y="21.0"/>
|
||||
<capacity-demand>5</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
<service id="50" type="pickup">
|
||||
<locationId>[x=56.0][y=37.0]</locationId>
|
||||
<coord x="56.0" y="37.0"/>
|
||||
<capacity-demand>10</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>1.7976931348623157E308</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
</services>
|
||||
</problem>
|
||||
1235
jsprit-examples/input/pickups_and_deliveries_solomon_c101.xml
Normal file
1235
jsprit-examples/input/pickups_and_deliveries_solomon_c101.xml
Normal file
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
1235
jsprit-examples/input/pickups_and_deliveries_solomon_r101.xml
Normal file
1235
jsprit-examples/input/pickups_and_deliveries_solomon_r101.xml
Normal file
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
1235
jsprit-examples/input/pickups_solomon_c101.xml
Normal file
1235
jsprit-examples/input/pickups_solomon_c101.xml
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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<VehicleRoutingProblemSolution> 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");
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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<VehicleRoutingProblemSolution> 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");
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -201,7 +201,7 @@ public class RefuseCollectionExample {
|
|||
VehicleRoutingProblem vrp = vrpBuilder.build();
|
||||
|
||||
VehicleRoutingAlgorithm vra = new GreedySchrimpfFactory().createAlgorithm(vrp);
|
||||
vra.setPrematureBreak(10);
|
||||
vra.setPrematureBreak(100);
|
||||
Collection<VehicleRoutingProblemSolution> solutions = vra.searchSolutions();
|
||||
|
||||
SolutionPrinter.print(Solutions.getBest(solutions),Print.VERBOSE);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
104
jsprit-examples/src/main/java/examples/SolomonR101Example.java
Normal file
104
jsprit-examples/src/main/java/examples/SolomonR101Example.java
Normal file
|
|
@ -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<VehicleRoutingProblemSolution> 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");
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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<VehicleRoutingProblemSolution> 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");
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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<VehicleRoutingProblemSolution> 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");
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue