1
0
Fork 0
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:
Stefan Schroeder 2013-09-02 19:01:32 +02:00
commit f1bb6c7bd0
96 changed files with 17748 additions and 1121 deletions

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

View file

@ -20,7 +20,9 @@
******************************************************************************/ ******************************************************************************/
package analysis; package analysis;
import java.awt.BasicStroke;
import java.awt.Color; import java.awt.Color;
import java.awt.geom.Ellipse2D;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.Collection; import java.util.Collection;
@ -32,16 +34,22 @@ import java.util.Set;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.jfree.chart.ChartUtilities; import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart; import org.jfree.chart.JFreeChart;
import org.jfree.chart.annotations.XYShapeAnnotation;
import org.jfree.chart.axis.NumberAxis; import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.labels.XYItemLabelGenerator;
import org.jfree.chart.plot.XYPlot; import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYItemRenderer; import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer; 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.XYSeries;
import org.jfree.data.xy.XYSeriesCollection; import org.jfree.data.xy.XYSeriesCollection;
import util.Coordinate; import util.Coordinate;
import util.Locations; import util.Locations;
import basics.Delivery;
import basics.Job; import basics.Job;
import basics.Pickup;
import basics.Service; import basics.Service;
import basics.VehicleRoutingProblem; import basics.VehicleRoutingProblem;
import basics.VehicleRoutingProblemSolution; import basics.VehicleRoutingProblemSolution;
@ -80,13 +88,14 @@ public class SolutionPlotter {
public static void plotVrpAsPNG(VehicleRoutingProblem vrp, String pngFile, String title){ public static void plotVrpAsPNG(VehicleRoutingProblem vrp, String pngFile, String title){
log.info("plot routes to " + pngFile); log.info("plot routes to " + pngFile);
XYSeriesCollection problem; XYSeriesCollection problem;
Map<XYDataItem,String> labels = new HashMap<XYDataItem, String>();
try { try {
problem = makeVrpSeries(vrp); problem = makeVrpSeries(vrp, labels);
} catch (NoLocationFoundException e) { } catch (NoLocationFoundException e) {
log.warn("cannot plot vrp, since coord is missing"); log.warn("cannot plot vrp, since coord is missing");
return; return;
} }
XYPlot plot = createPlot(problem); XYPlot plot = createPlot(problem, labels);
JFreeChart chart = new JFreeChart(title, plot); JFreeChart chart = new JFreeChart(title, plot);
save(chart,pngFile); save(chart,pngFile);
} }
@ -103,14 +112,15 @@ public class SolutionPlotter {
public static void plotRoutesAsPNG(Collection<VehicleRoute> routes, Locations locations, String pngFile, String title) { public static void plotRoutesAsPNG(Collection<VehicleRoute> routes, Locations locations, String pngFile, String title) {
log.info("plot routes to " + pngFile); log.info("plot routes to " + pngFile);
XYSeriesCollection problem; XYSeriesCollection problem;
Map<XYDataItem,String> labels = new HashMap<XYDataItem, String>();
try { try {
problem = makeVrpSeries(routes); problem = makeVrpSeries(routes, labels);
} catch (NoLocationFoundException e) { } catch (NoLocationFoundException e) {
log.warn("cannot plot vrp, since coord is missing"); log.warn("cannot plot vrp, since coord is missing");
return; return;
} }
XYSeriesCollection solutionColl = makeSolutionSeries(routes,locations); XYSeriesCollection solutionColl = makeSolutionSeries(routes,locations);
XYPlot plot = createPlot(problem, solutionColl); XYPlot plot = createPlot(problem, solutionColl, labels);
JFreeChart chart = new JFreeChart(title, plot); JFreeChart chart = new JFreeChart(title, plot);
save(chart,pngFile); save(chart,pngFile);
} }
@ -130,14 +140,15 @@ public class SolutionPlotter {
log.info("plot solution to " + pngFile); log.info("plot solution to " + pngFile);
XYSeriesCollection problem; XYSeriesCollection problem;
XYSeriesCollection solutionColl; XYSeriesCollection solutionColl;
Map<XYDataItem,String> labels = new HashMap<XYDataItem, String>();
try { try {
problem = makeVrpSeries(vrp); problem = makeVrpSeries(vrp, labels);
solutionColl = makeSolutionSeries(vrp, solution); solutionColl = makeSolutionSeries(vrp, solution);
} catch (NoLocationFoundException e) { } catch (NoLocationFoundException e) {
log.warn("cannot plot vrp, since coord is missing"); log.warn("cannot plot vrp, since coord is missing");
return; return;
} }
XYPlot plot = createPlot(problem, solutionColl); XYPlot plot = createPlot(problem, solutionColl, labels);
JFreeChart chart = new JFreeChart(title, plot); JFreeChart chart = new JFreeChart(title, plot);
save(chart,pngFile); 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(); XYPlot plot = new XYPlot();
plot.setBackgroundPaint(Color.LIGHT_GRAY); plot.setBackgroundPaint(Color.LIGHT_GRAY);
plot.setRangeGridlinePaint(Color.WHITE); plot.setRangeGridlinePaint(Color.WHITE);
plot.setDomainGridlinePaint(Color.WHITE); plot.setDomainGridlinePaint(Color.WHITE);
XYItemRenderer problemRenderer = new XYLineAndShapeRenderer(false, true); // Shapes only 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(); NumberAxis xAxis = new NumberAxis();
xAxis.setRangeWithMargins(problem.getDomainBounds(true)); xAxis.setRangeWithMargins(problem.getDomainBounds(true));
@ -167,13 +188,24 @@ public class SolutionPlotter {
return plot; 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(); XYPlot plot = new XYPlot();
plot.setBackgroundPaint(Color.LIGHT_GRAY); plot.setBackgroundPaint(Color.LIGHT_GRAY);
plot.setRangeGridlinePaint(Color.WHITE); plot.setRangeGridlinePaint(Color.WHITE);
plot.setDomainGridlinePaint(Color.WHITE); plot.setDomainGridlinePaint(Color.WHITE);
XYItemRenderer problemRenderer = new XYLineAndShapeRenderer(false, true); // Shapes only 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(); NumberAxis xAxis = new NumberAxis();
xAxis.setRangeWithMargins(problem.getDomainBounds(true)); xAxis.setRangeWithMargins(problem.getDomainBounds(true));
@ -186,7 +218,13 @@ public class SolutionPlotter {
plot.setDomainAxis(0, xAxis); plot.setDomainAxis(0, xAxis);
plot.setRangeAxis(0, yAxis); plot.setRangeAxis(0, yAxis);
XYItemRenderer solutionRenderer = new XYLineAndShapeRenderer(true, false); // Lines only 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.setDataset(1, solutionColl);
plot.setRenderer(1, solutionRenderer); plot.setRenderer(1, solutionRenderer);
plot.setDomainAxis(1, xAxis); plot.setDomainAxis(1, xAxis);
@ -254,7 +292,7 @@ public class SolutionPlotter {
return coll; 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(); XYSeriesCollection coll = new XYSeriesCollection();
XYSeries vehicleSeries = new XYSeries("depot", false, true); XYSeries vehicleSeries = new XYSeries("depot", false, true);
for(Vehicle v : vehicles){ for(Vehicle v : vehicles){
@ -264,28 +302,54 @@ public class SolutionPlotter {
} }
coll.addSeries(vehicleSeries); 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){ for(Job job : services){
Service service = (Service)job; if(job instanceof Pickup){
Coordinate coord = service.getCoord(); Pickup service = (Pickup)job;
jobSeries.add(coord.getX(), coord.getY()); 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; 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<Vehicle> vehicles = new HashSet<Vehicle>();
Set<Job> jobs = new HashSet<Job>(); Set<Job> jobs = new HashSet<Job>();
for(VehicleRoute route : routes){ for(VehicleRoute route : routes){
vehicles.add(route.getVehicle()); vehicles.add(route.getVehicle());
jobs.addAll(route.getTourActivities().getJobs()); jobs.addAll(route.getTourActivities().getJobs());
} }
return makeVrpSeries(vehicles, jobs); return makeVrpSeries(vehicles, jobs, labels);
} }
private static XYSeriesCollection makeVrpSeries(VehicleRoutingProblem vrp) throws NoLocationFoundException{ private static XYSeriesCollection makeVrpSeries(VehicleRoutingProblem vrp, Map<XYDataItem, String> labels) throws NoLocationFoundException{
return makeVrpSeries(vrp.getVehicles(), vrp.getJobs().values()); return makeVrpSeries(vrp.getVehicles(), vrp.getJobs().values(), labels);
} }
private static Locations retrieveLocations(VehicleRoutingProblem vrp) throws NoLocationFoundException { private static Locations retrieveLocations(VehicleRoutingProblem vrp) throws NoLocationFoundException {

View file

@ -52,6 +52,8 @@
<version>2.4.0</version> <version>2.4.0</version>
</dependency> </dependency>
</dependencies> </dependencies>

View 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 algorithms; package algorithms;
import java.util.ArrayList; import java.util.ArrayList;
@ -49,4 +69,8 @@ class BackwardInTimeListeners {
for(BackwardInTimeListener l : listeners){ l.end(start, latestDepartureTime); } for(BackwardInTimeListener l : listeners){ l.end(start, latestDepartureTime); }
} }
public boolean isEmpty() {
return listeners.isEmpty();
}
} }

View file

@ -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; package algorithms;
import basics.route.TourActivity; import basics.route.TourActivity;
class CalcUtils { 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();
} }
} }

View file

@ -25,6 +25,8 @@ import basics.route.End;
import basics.route.ServiceActivity; import basics.route.ServiceActivity;
import basics.route.Start; import basics.route.Start;
import basics.route.TourActivity; import basics.route.TourActivity;
import basics.route.TourActivityFactory;
import basics.route.DefaultTourActivityFactory;
import basics.route.Vehicle; import basics.route.Vehicle;
import basics.route.VehicleImpl.NoVehicle; import basics.route.VehicleImpl.NoVehicle;
import basics.route.VehicleRoute; import basics.route.VehicleRoute;
@ -49,6 +51,8 @@ final class CalculatesServiceInsertion implements JobInsertionCalculator{
private VehicleRoutingTransportCosts transportCosts; private VehicleRoutingTransportCosts transportCosts;
private TourActivityFactory activityFactory;
public void setNeighborhood(Neighborhood neighborhood) { public void setNeighborhood(Neighborhood neighborhood) {
this.neighborhood = neighborhood; this.neighborhood = neighborhood;
logger.info("initialise neighborhood " + neighborhood); logger.info("initialise neighborhood " + neighborhood);
@ -59,6 +63,7 @@ final class CalculatesServiceInsertion implements JobInsertionCalculator{
this.marginalCalculus = marginalsCalculus; this.marginalCalculus = marginalsCalculus;
this.hardRouteLevelConstraint = hardRouteLevelConstraint; this.hardRouteLevelConstraint = hardRouteLevelConstraint;
this.transportCosts = routingCosts; this.transportCosts = routingCosts;
activityFactory = new DefaultTourActivityFactory();
logger.info("initialise " + this); logger.info("initialise " + this);
} }
@ -86,7 +91,8 @@ final class CalculatesServiceInsertion implements JobInsertionCalculator{
Marginals bestMarginals = null; Marginals bestMarginals = null;
Service service = (Service)jobToInsert; Service service = (Service)jobToInsert;
int insertionIndex = InsertionData.NO_INDEX; 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 start = Start.newInstance(newVehicle.getLocationId(), newVehicle.getEarliestDeparture(), newVehicle.getLatestArrival());
start.setEndTime(newVehicleDepartureTime); start.setEndTime(newVehicleDepartureTime);
@ -96,11 +102,9 @@ final class CalculatesServiceInsertion implements JobInsertionCalculator{
TourActivity prevAct = start; TourActivity prevAct = start;
double prevActStartTime = newVehicleDepartureTime; double prevActStartTime = newVehicleDepartureTime;
int actIndex = 0; int actIndex = 0;
// logger.info("start");
for(TourActivity nextAct : currentRoute.getTourActivities().getActivities()){ for(TourActivity nextAct : currentRoute.getTourActivities().getActivities()){
if(deliveryAct2Insert.getTheoreticalLatestOperationStartTime() < prevAct.getTheoreticalEarliestOperationStartTime()){ // logger.info("prevActStartTime="+prevActStartTime);
break;
}
if(neighborhood.areNeighbors(deliveryAct2Insert.getLocationId(), prevAct.getLocationId()) && neighborhood.areNeighbors(deliveryAct2Insert.getLocationId(), nextAct.getLocationId())){ if(neighborhood.areNeighbors(deliveryAct2Insert.getLocationId(), prevAct.getLocationId()) && neighborhood.areNeighbors(deliveryAct2Insert.getLocationId(), nextAct.getLocationId())){
Marginals mc = calculate(insertionContext, prevAct, nextAct, deliveryAct2Insert, prevActStartTime); Marginals mc = calculate(insertionContext, prevAct, nextAct, deliveryAct2Insert, prevActStartTime);
if(mc != null){ 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; prevAct = nextAct;
actIndex++; actIndex++;
} }
// logger.info("prevActStartTime="+prevActStartTime);
End nextAct = end; End nextAct = end;
if(neighborhood.areNeighbors(deliveryAct2Insert.getLocationId(), prevAct.getLocationId()) && neighborhood.areNeighbors(deliveryAct2Insert.getLocationId(), nextAct.getLocationId())){ if(neighborhood.areNeighbors(deliveryAct2Insert.getLocationId(), prevAct.getLocationId()) && neighborhood.areNeighbors(deliveryAct2Insert.getLocationId(), nextAct.getLocationId())){
Marginals mc = calculate(insertionContext, prevAct, nextAct, deliveryAct2Insert, prevActStartTime); Marginals mc = calculate(insertionContext, prevAct, nextAct, deliveryAct2Insert, prevActStartTime);

View file

@ -23,21 +23,21 @@ import java.util.PriorityQueue;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import util.Neighborhood; import util.Neighborhood;
import algorithms.RouteStates.ActivityState;
import basics.Job; import basics.Job;
import basics.Service; import basics.Service;
import basics.costs.VehicleRoutingActivityCosts; import basics.costs.VehicleRoutingActivityCosts;
import basics.costs.VehicleRoutingTransportCosts; import basics.costs.VehicleRoutingTransportCosts;
import basics.route.DefaultTourActivityFactory;
import basics.route.Driver; import basics.route.Driver;
import basics.route.End; import basics.route.End;
import basics.route.ServiceActivity; import basics.route.ServiceActivity;
import basics.route.Start; import basics.route.Start;
import basics.route.TourActivities; import basics.route.TourActivities;
import basics.route.TourActivity; import basics.route.TourActivity;
import basics.route.TourActivityFactory;
import basics.route.Vehicle; import basics.route.Vehicle;
import basics.route.VehicleRoute;
import basics.route.VehicleImpl.NoVehicle; import basics.route.VehicleImpl.NoVehicle;
import basics.route.VehicleRoute;
@ -51,6 +51,8 @@ final class CalculatesServiceInsertionOnRouteLevel implements JobInsertionCalcul
private AuxilliaryCostCalculator auxilliaryPathCostCalculator; private AuxilliaryCostCalculator auxilliaryPathCostCalculator;
private TourActivityFactory tourActivityFactory = new DefaultTourActivityFactory();
private StateManager states; private StateManager states;
private int nuOfActsForwardLooking = 0; 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) { public void setNeighborhood(Neighborhood neighborhood) {
this.neighborhood = neighborhood; this.neighborhood = neighborhood;
@ -142,7 +146,7 @@ final class CalculatesServiceInsertionOnRouteLevel implements JobInsertionCalcul
/** /**
* some inis * some inis
*/ */
TourActivity serviceAct2Insert = ServiceActivity.newInstance(service); TourActivity serviceAct2Insert = tourActivityFactory.createActivity(service);
int best_insertion_index = InsertionData.NO_INDEX; int best_insertion_index = InsertionData.NO_INDEX;
initialiseStartAndEnd(newVehicle, newVehicleDepartureTime); initialiseStartAndEnd(newVehicle, newVehicleDepartureTime);

View file

@ -23,6 +23,7 @@ package algorithms;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import algorithms.HardConstraints.ConstraintManager;
import basics.VehicleRoutingProblem; import basics.VehicleRoutingProblem;
import basics.algo.InsertionListener; import basics.algo.InsertionListener;
import basics.algo.VehicleRoutingAlgorithmListeners.PrioritizedVRAListener; import basics.algo.VehicleRoutingAlgorithmListeners.PrioritizedVRAListener;
@ -81,6 +82,8 @@ class CalculatorBuilder {
private double timeSlice; private double timeSlice;
private int neighbors; private int neighbors;
private ConstraintManager constraintManager;
/** /**
* Constructs the builder. * Constructs the builder.
@ -213,9 +216,11 @@ class CalculatorBuilder {
} }
} }
private CalculatorPlusListeners createStandardLocal(VehicleRoutingProblem vrp, StateManager activityStates2){ private CalculatorPlusListeners createStandardLocal(VehicleRoutingProblem vrp, StateManager statesManager){
MarginalsCalculus defaultCalc = new MarginalsCalculusTriangleInequality(vrp.getTransportCosts(), vrp.getActivityCosts(), new HardConstraints.HardTimeWindowConstraint(activityStates2) ); if(constraintManager == null) throw new IllegalStateException("constraint-manager is null");
JobInsertionCalculator standardServiceInsertion = new CalculatesServiceInsertion(vrp.getTransportCosts(), defaultCalc, new HardConstraints.HardLoadConstraint(activityStates2));
MarginalsCalculus defaultCalc = new MarginalsCalculusTriangleInequality(vrp.getTransportCosts(), vrp.getActivityCosts(), constraintManager);
JobInsertionCalculator standardServiceInsertion = new CalculatesServiceInsertion(vrp.getTransportCosts(), defaultCalc, constraintManager);
((CalculatesServiceInsertion) standardServiceInsertion).setNeighborhood(vrp.getNeighborhood()); ((CalculatesServiceInsertion) standardServiceInsertion).setNeighborhood(vrp.getNeighborhood());
CalculatorPlusListeners calcPlusListeners = new CalculatorPlusListeners(standardServiceInsertion); CalculatorPlusListeners calcPlusListeners = new CalculatorPlusListeners(standardServiceInsertion);
@ -246,6 +251,10 @@ class CalculatorBuilder {
return new CalculatesVehTypeDepServiceInsertion(fleetManager, baseCalc); return new CalculatesVehTypeDepServiceInsertion(fleetManager, baseCalc);
} }
public void setConstraintManager(ConstraintManager constraintManager) {
this.constraintManager = constraintManager;
}
} }

View file

@ -21,17 +21,15 @@
package algorithms; package algorithms;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.List; import java.util.List;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import algorithms.VehicleFleetManager.TypeKey;
import basics.route.TourActivities; import basics.route.TourActivities;
import basics.route.TourActivity; import basics.route.TourActivity;
import basics.route.Vehicle; import basics.route.Vehicle;
import basics.route.VehicleRoute;
import basics.route.VehicleImpl.NoVehicle; import basics.route.VehicleImpl.NoVehicle;
import basics.route.VehicleRoute;
@ -47,13 +45,13 @@ final class FindCheaperVehicleAlgo {
private double weightFixCosts = 1.0; private double weightFixCosts = 1.0;
private RouteStates states; private StateManager states;
public void setWeightFixCosts(double weightFixCosts) { public void setWeightFixCosts(double weightFixCosts) {
this.weightFixCosts = weightFixCosts; this.weightFixCosts = weightFixCosts;
} }
public void setStates(RouteStates states) { public void setStates(StateManager states) {
this.states = states; this.states = states;
} }
@ -85,11 +83,11 @@ final class FindCheaperVehicleAlgo {
if(vehicle.getType().getTypeId().equals(vehicleRoute.getVehicle().getType().getTypeId())){ if(vehicle.getType().getTypeId().equals(vehicleRoute.getVehicle().getType().getTypeId())){
continue; 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 fixCostSaving = vehicleRoute.getVehicle().getType().getVehicleCostParams().fix - vehicle.getType().getVehicleCostParams().fix;
double departureTime = vehicleRoute.getStart().getEndTime(); double departureTime = vehicleRoute.getStart().getEndTime();
double newCost = auxilliaryCostCalculator.costOfPath(path, departureTime, vehicleRoute.getDriver(), vehicle); 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; double totalCostSaving = varCostSaving + weightFixCosts*fixCostSaving;
if(totalCostSaving > bestSaving){ if(totalCostSaving > bestSaving){
bestSaving = totalCostSaving; bestSaving = totalCostSaving;

View 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 algorithms; package algorithms;
import java.util.ArrayList; import java.util.ArrayList;
@ -38,4 +58,8 @@ class ForwardInTimeListeners {
for(ForwardInTimeListener l : listeners){ l.end(end, arrivalTime); } for(ForwardInTimeListener l : listeners){ l.end(end, arrivalTime); }
} }
public boolean isEmpty() {
return listeners.isEmpty();
}
} }

View file

@ -32,9 +32,11 @@ import java.util.Set;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import util.RandomNumberGeneration; import util.RandomNumberGeneration;
import algorithms.RuinStrategy.RuinListener;
import basics.Job; import basics.Job;
import basics.VehicleRoutingProblem; import basics.VehicleRoutingProblem;
import basics.VehicleRoutingProblemSolution; import basics.VehicleRoutingProblemSolution;
import basics.algo.InsertionListener;
import basics.algo.SearchStrategyModule; import basics.algo.SearchStrategyModule;
import basics.algo.SearchStrategyModuleListener; import basics.algo.SearchStrategyModuleListener;
import basics.route.TourActivity; import basics.route.TourActivity;
@ -53,8 +55,6 @@ final class Gendreau implements SearchStrategyModule{
private final InsertionStrategy insertionStrategy; private final InsertionStrategy insertionStrategy;
private final Inserter inserter;
private VehicleFleetManager fleetManager; private VehicleFleetManager fleetManager;
private Random random = RandomNumberGeneration.getRandom(); private Random random = RandomNumberGeneration.getRandom();
@ -71,7 +71,7 @@ final class Gendreau implements SearchStrategyModule{
super(); super();
InsertionListeners insertionListeners = new InsertionListeners(); InsertionListeners insertionListeners = new InsertionListeners();
insertionListeners.addAllListeners(insertionStrategy.getListeners()); insertionListeners.addAllListeners(insertionStrategy.getListeners());
inserter = new Inserter(insertionListeners); new Inserter(insertionListeners);
this.ruin = ruin; this.ruin = ruin;
this.vrp = vrp; this.vrp = vrp;
this.insertionStrategy = insertionStrategy; this.insertionStrategy = insertionStrategy;
@ -205,7 +205,18 @@ final class Gendreau implements SearchStrategyModule{
@Override @Override
public void addModuleListener(SearchStrategyModuleListener moduleListener) { 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);
}
}
} }
} }

View file

@ -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; 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.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; 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 { class HardConstraints {
interface HardRouteLevelConstraint { interface HardRouteLevelConstraint {
@ -13,10 +59,76 @@ class HardConstraints {
interface HardActivityLevelConstraint { 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;
}
}
static class HardLoadConstraint implements HardRouteLevelConstraint{ static class HardLoadConstraint implements HardRouteLevelConstraint{
private StateManager states; private StateManager states;
@ -37,23 +149,163 @@ class HardConstraints {
} }
} }
static class HardTimeWindowConstraint implements HardActivityLevelConstraint { /**
* lsjdfjsdlfjsa
*
* @author stefan
*
*/
static class HardPickupAndDeliveryLoadConstraint implements HardRouteLevelConstraint {
private StateManager states; private StateManager stateManager;
public HardTimeWindowConstraint(StateManager states) { public HardPickupAndDeliveryLoadConstraint(StateManager stateManager) {
super(); super();
this.states = states; this.stateManager = stateManager;
} }
@Override @Override
public boolean fulfilled(InsertionContext iFacts, TourActivity act, double arrTime) { public boolean fulfilled(InsertionContext insertionContext) {
if(arrTime > states.getActivityState(act, StateTypes.LATEST_OPERATION_START_TIME).toDouble()){ if(insertionContext.getJob() instanceof Delivery){
return false; 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; 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;
}
}
} }

View file

@ -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; package algorithms;
import algorithms.InsertionData.NoInsertionFound; import algorithms.InsertionData.NoInsertionFound;
import basics.Job; import basics.Job;
import basics.Service; import basics.Service;
import basics.route.ServiceActivity; import basics.route.ServiceActivity;
import basics.route.TourActivityFactory;
import basics.route.DefaultTourActivityFactory;
import basics.route.VehicleRoute; import basics.route.VehicleRoute;
class Inserter { class Inserter {
private InsertionListeners insertionListeners; private InsertionListeners insertionListeners;
private TourActivityFactory activityFactory;
public Inserter(InsertionListeners insertionListeners) { public Inserter(InsertionListeners insertionListeners) {
this.insertionListeners = insertionListeners; this.insertionListeners = insertionListeners;
activityFactory = new DefaultTourActivityFactory();
} }
public void insertJob(Job job, InsertionData insertionData, VehicleRoute vehicleRoute){ public void insertJob(Job job, InsertionData insertionData, VehicleRoute vehicleRoute){
@ -25,7 +50,7 @@ class Inserter {
} }
// if(vehicleRoute.getDepartureTime() != vehicleRoute.g) // if(vehicleRoute.getDepartureTime() != vehicleRoute.g)
if(job instanceof Service) { 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()); vehicleRoute.setDepartureTime(insertionData.getVehicleDepartureTime());
} }
else throw new IllegalStateException("neither service nor shipment. this is not supported."); else throw new IllegalStateException("neither service nor shipment. this is not supported.");

View 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 algorithms; package algorithms;
import basics.Job; import basics.Job;

View file

@ -25,11 +25,11 @@ import java.util.List;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import org.apache.commons.configuration.HierarchicalConfiguration; import org.apache.commons.configuration.HierarchicalConfiguration;
import org.apache.commons.configuration.XMLConfiguration;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import algorithms.HardConstraints.ConstraintManager;
import algorithms.StateUpdates.UpdateStates;
import basics.VehicleRoutingProblem; import basics.VehicleRoutingProblem;
import basics.VehicleRoutingProblem.FleetComposition;
import basics.algo.InsertionListener; import basics.algo.InsertionListener;
import basics.algo.VehicleRoutingAlgorithmListeners.PrioritizedVRAListener; import basics.algo.VehicleRoutingAlgorithmListeners.PrioritizedVRAListener;
@ -38,7 +38,7 @@ class InsertionFactory {
private static Logger log = Logger.getLogger(InsertionFactory.class); private static Logger log = Logger.getLogger(InsertionFactory.class);
public static InsertionStrategy createInsertion(VehicleRoutingProblem vrp, HierarchicalConfiguration config, 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; boolean concurrentInsertion = false;
if(executorService != null) concurrentInsertion = true; if(executorService != null) concurrentInsertion = true;
if(config.containsKey("[@name]")){ if(config.containsKey("[@name]")){
@ -54,6 +54,7 @@ class InsertionFactory {
calcBuilder.setStates(routeStates); calcBuilder.setStates(routeStates);
calcBuilder.setVehicleRoutingProblem(vrp); calcBuilder.setVehicleRoutingProblem(vrp);
calcBuilder.setVehicleFleetManager(vehicleFleetManager); calcBuilder.setVehicleFleetManager(vehicleFleetManager);
calcBuilder.setConstraintManager(constraintManager);
if(config.containsKey("level")){ if(config.containsKey("level")){
String level = config.getString("level"); String level = config.getString("level");
@ -103,13 +104,13 @@ class InsertionFactory {
// insertionStrategy = RegretInsertion.newInstance(routeAlgorithm); // insertionStrategy = RegretInsertion.newInstance(routeAlgorithm);
// } // }
insertionStrategy.addListener(new RemoveEmptyVehicles(vehicleFleetManager)); // insertionStrategy.addListener(new RemoveEmptyVehicles(vehicleFleetManager));
insertionStrategy.addListener(new ResetAndIniFleetManager(vehicleFleetManager)); // insertionStrategy.addListener(new ResetAndIniFleetManager(vehicleFleetManager));
insertionStrategy.addListener(new VehicleSwitched(vehicleFleetManager)); // insertionStrategy.addListener(new VehicleSwitched(vehicleFleetManager));
// insertionStrategy.addListener(new UpdateLoadAtRouteLevel(routeStates)); // 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); for(InsertionListener l : insertionListeners) insertionStrategy.addListener(l);
// insertionStrategy.addListener(new FindCheaperVehicle( // insertionStrategy.addListener(new FindCheaperVehicle(
// new FindCheaperVehicleAlgoNew(vehicleFleetManager, tourStateCalculator, auxCalculator))); // new FindCheaperVehicleAlgoNew(vehicleFleetManager, tourStateCalculator, auxCalculator)));

View 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 algorithms; package algorithms;
import java.util.ArrayList; import java.util.ArrayList;

View file

@ -46,6 +46,7 @@ class IterateRouteBackwardInTime implements VehicleRouteUpdater{
* *
*/ */
public void iterate(VehicleRoute vehicleRoute) { public void iterate(VehicleRoute vehicleRoute) {
if(listeners.isEmpty()) return;
listeners.start(vehicleRoute, vehicleRoute.getEnd(), vehicleRoute.getEnd().getTheoreticalLatestOperationStartTime()); listeners.start(vehicleRoute, vehicleRoute.getEnd(), vehicleRoute.getEnd().getTheoreticalLatestOperationStartTime());
Iterator<TourActivity> reverseActIter = vehicleRoute.getTourActivities().reverseActivityIterator(); Iterator<TourActivity> reverseActIter = vehicleRoute.getTourActivities().reverseActivityIterator();

View file

@ -48,6 +48,7 @@ class IterateRouteForwardInTime implements VehicleRouteUpdater{
* *
*/ */
public void iterate(VehicleRoute vehicleRoute) { public void iterate(VehicleRoute vehicleRoute) {
if(listeners.isEmpty()) return;
listeners.start(vehicleRoute, vehicleRoute.getStart(), vehicleRoute.getStart().getEndTime()); listeners.start(vehicleRoute, vehicleRoute.getStart(), vehicleRoute.getStart().getEndTime());
Vehicle vehicle = vehicleRoute.getVehicle(); Vehicle vehicle = vehicleRoute.getVehicle();

View file

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

View 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 algorithms; package algorithms;
import basics.route.TourActivity; import basics.route.TourActivity;

View 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 algorithms; package algorithms;
import algorithms.HardConstraints.HardActivityLevelConstraint; import algorithms.HardConstraints.HardActivityLevelConstraint;
@ -21,16 +41,16 @@ class MarginalsCalculusTriangleInequality implements MarginalsCalculus{
@Override @Override
public Marginals calculate(InsertionContext iFacts, TourActivity prevAct, TourActivity nextAct, TourActivity newAct, double depTimeAtPrevAct) { 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_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 tp_time_prevAct_newAct = routingCosts.getTransportTime(prevAct.getLocationId(), newAct.getLocationId(), depTimeAtPrevAct, iFacts.getNewDriver(), iFacts.getNewVehicle());
double newAct_arrTime = depTimeAtPrevAct + tp_time_prevAct_newAct; double newAct_arrTime = depTimeAtPrevAct + tp_time_prevAct_newAct;
if(!hardConstraint.fulfilled(iFacts, newAct, newAct_arrTime)){ double newAct_endTime = CalcUtils.getActivityEndTime(newAct_arrTime, newAct);
return null;
}
double newAct_endTime = CalcUtils.getStartTimeAtAct(newAct_arrTime, newAct);
double act_costs_newAct = activityCosts.getActivityCost(newAct, newAct_arrTime, iFacts.getNewDriver(), iFacts.getNewVehicle()); double act_costs_newAct = activityCosts.getActivityCost(newAct, newAct_arrTime, iFacts.getNewDriver(), iFacts.getNewVehicle());
@ -38,11 +58,7 @@ class MarginalsCalculusTriangleInequality implements MarginalsCalculus{
double tp_time_newAct_nextAct = routingCosts.getTransportTime(newAct.getLocationId(), nextAct.getLocationId(), newAct_endTime, iFacts.getNewDriver(), iFacts.getNewVehicle()); double tp_time_newAct_nextAct = routingCosts.getTransportTime(newAct.getLocationId(), nextAct.getLocationId(), newAct_endTime, iFacts.getNewDriver(), iFacts.getNewVehicle());
double nextAct_arrTime = newAct_endTime + tp_time_newAct_nextAct; 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 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; double totalCosts = tp_costs_prevAct_newAct + tp_costs_newAct_nextAct + act_costs_newAct + act_costs_nextAct;

View 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
******************************************************************************/
///******************************************************************************* ///*******************************************************************************
// * Copyright (c) 2011 Stefan Schroeder. // * Copyright (c) 2011 Stefan Schroeder.
// * eMail: stefan.schroeder@kit.edu // * eMail: stefan.schroeder@kit.edu

View file

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

View 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 algorithms; package algorithms;
import java.util.Collection; import java.util.Collection;

View 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 algorithms; package algorithms;
import java.util.ArrayList; import java.util.ArrayList;

View 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 algorithms; package algorithms;
import basics.route.TourActivity; import basics.route.TourActivity;

View file

@ -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; package algorithms;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -28,30 +47,6 @@ class StateManagerImpl implements StateManager{
private Map<TourActivity,States> activityStates = new HashMap<TourActivity, StateManager.States>(); 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(){ public void clear(){
vehicleRouteStates.clear(); vehicleRouteStates.clear();
activityStates.clear(); activityStates.clear();
@ -85,11 +80,14 @@ class StateManagerImpl implements StateManager{
if(stateType.equals(StateTypes.DURATION)) return new StateImpl(0); 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.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.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; return null;
} }
private State getDefaultRouteState(String stateType, VehicleRoute route){ private State getDefaultRouteState(String stateType, VehicleRoute route){
if(stateType.equals(StateTypes.LOAD)) return new StateImpl(0); 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.COSTS)) return new StateImpl(0);
if(stateType.equals(StateTypes.DURATION)) return new StateImpl(0); if(stateType.equals(StateTypes.DURATION)) return new StateImpl(0);
return null; return null;

View file

@ -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; package algorithms;
class StateTypes { class StateTypes {
final static String LOAD = "load"; final static String LOAD = "load";
final static String LOAD_AT_DEPOT = "loadAtDepot";
final static String DURATION = "duration"; final static String DURATION = "duration";
final static String LATEST_OPERATION_START_TIME = "latestOST"; final static String LATEST_OPERATION_START_TIME = "latestOST";
final static String EARLIEST_OPERATION_START_TIME = "earliestOST"; 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";
} }

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -35,11 +35,16 @@ import org.apache.commons.configuration.HierarchicalConfiguration;
import org.apache.commons.configuration.XMLConfiguration; import org.apache.commons.configuration.XMLConfiguration;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import util.RouteUtils; import algorithms.HardConstraints.ConstraintManager;
import algorithms.RuinStrategy.RuinListener; import algorithms.HardConstraints.HardTimeWindowActivityLevelConstraint;
import algorithms.VehicleRoutingAlgorithms.TypedMap.InsertionStrategyKey; 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.AbstractKey;
import algorithms.VehicleRoutingAlgorithms.TypedMap.AcceptorKey; import algorithms.VehicleRoutingAlgorithms.TypedMap.AcceptorKey;
import algorithms.VehicleRoutingAlgorithms.TypedMap.InsertionStrategyKey;
import algorithms.VehicleRoutingAlgorithms.TypedMap.RuinStrategyKey; import algorithms.VehicleRoutingAlgorithms.TypedMap.RuinStrategyKey;
import algorithms.VehicleRoutingAlgorithms.TypedMap.SelectorKey; import algorithms.VehicleRoutingAlgorithms.TypedMap.SelectorKey;
import algorithms.VehicleRoutingAlgorithms.TypedMap.StrategyModuleKey; import algorithms.VehicleRoutingAlgorithms.TypedMap.StrategyModuleKey;
@ -50,28 +55,25 @@ import algorithms.acceptors.SolutionAcceptor;
import algorithms.selectors.SelectBest; import algorithms.selectors.SelectBest;
import algorithms.selectors.SelectRandomly; import algorithms.selectors.SelectRandomly;
import algorithms.selectors.SolutionSelector; import algorithms.selectors.SolutionSelector;
import basics.Job;
import basics.VehicleRoutingAlgorithm; import basics.VehicleRoutingAlgorithm;
import basics.VehicleRoutingProblem; import basics.VehicleRoutingProblem;
import basics.VehicleRoutingProblem.Constraint;
import basics.VehicleRoutingProblem.FleetSize; import basics.VehicleRoutingProblem.FleetSize;
import basics.VehicleRoutingProblemSolution; import basics.VehicleRoutingProblemSolution;
import basics.algo.AlgorithmStartsListener; import basics.algo.AlgorithmStartsListener;
import basics.algo.InsertionListener; import basics.algo.InsertionListener;
import basics.algo.IterationStartsListener;
import basics.algo.IterationWithoutImprovementBreaker; import basics.algo.IterationWithoutImprovementBreaker;
import basics.algo.PrematureAlgorithmBreaker; import basics.algo.PrematureAlgorithmBreaker;
import basics.algo.SearchStrategy; import basics.algo.SearchStrategy;
import basics.algo.SearchStrategy.DiscoveredSolution; import basics.algo.SearchStrategy.DiscoveredSolution;
import basics.algo.SearchStrategyManager; import basics.algo.SearchStrategyManager;
import basics.algo.SearchStrategyModule; import basics.algo.SearchStrategyModule;
import basics.algo.SearchStrategyModuleListener;
import basics.algo.TimeBreaker; import basics.algo.TimeBreaker;
import basics.algo.VariationCoefficientBreaker; import basics.algo.VariationCoefficientBreaker;
import basics.algo.VehicleRoutingAlgorithmListeners.PrioritizedVRAListener; import basics.algo.VehicleRoutingAlgorithmListeners.PrioritizedVRAListener;
import basics.algo.VehicleRoutingAlgorithmListeners.Priority; import basics.algo.VehicleRoutingAlgorithmListeners.Priority;
import basics.io.AlgorithmConfig; import basics.io.AlgorithmConfig;
import basics.io.AlgorithmConfigXmlReader; import basics.io.AlgorithmConfigXmlReader;
import basics.route.VehicleRoute;
@ -428,50 +430,43 @@ public class VehicleRoutingAlgorithms {
} }
private static VehicleRoutingAlgorithm createAlgo(final VehicleRoutingProblem vrp, XMLConfiguration config, ExecutorService executorService, int nuOfThreads){ private static VehicleRoutingAlgorithm createAlgo(final VehicleRoutingProblem vrp, XMLConfiguration config, ExecutorService executorService, int nuOfThreads){
//fleetmanager // map to store constructed modules
final VehicleFleetManager vehicleFleetManager; TypedMap definedClasses = new TypedMap();
if(vrp.getFleetSize().equals(FleetSize.INFINITE)){
vehicleFleetManager = new InfiniteVehicles(vrp.getVehicles()); // algorithm listeners
}
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>(); Set<PrioritizedVRAListener> algorithmListeners = new HashSet<PrioritizedVRAListener>();
// insertion listeners
List<InsertionListener> insertionListeners = new ArrayList<InsertionListener>(); List<InsertionListener> insertionListeners = new ArrayList<InsertionListener>();
algorithmListeners.add(new PrioritizedVRAListener(Priority.LOW, new SolutionVerifier())); //create fleetmanager
final VehicleFleetManager vehicleFleetManager = createFleetManager(vrp);
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())); //create state-manager
final StateManagerImpl stateManager = new StateManagerImpl();
// RouteStates routeStates = new RouteStates();
// routeStates.initialiseStateOfJobs(vrp.getJobs().values());
// algorithmListeners.add(new PrioritizedVRAListener(Priority.LOW, routeStates));
TypedMap definedClasses = new TypedMap();
/* /*
* initial solution - construction * define constraints
*/ */
AlgorithmStartsListener createInitialSolution = createInitialSolution(config,vrp,vehicleFleetManager,routeStates,algorithmListeners,definedClasses,executorService,nuOfThreads); //constraint manager
ConstraintManager constraintManager = new ConstraintManager();
constraintManager.addConstraint(new HardConstraints.HardTimeWindowActivityLevelConstraint(stateManager, vrp.getTransportCosts()));
if(vrp.getProblemConstraints().contains(Constraint.DELIVERIES_FIRST)){
constraintManager.addConstraint(new HardConstraints.HardPickupAndDeliveryBackhaulActivityLevelConstraint(stateManager));
}
else{
constraintManager.addConstraint(new HardConstraints.HardPickupAndDeliveryActivityLevelConstraint(stateManager));
}
constraintManager.addConstraint(new HardConstraints.HardPickupAndDeliveryLoadConstraint(stateManager));
//construct initial solution creator
AlgorithmStartsListener createInitialSolution = createInitialSolution(config,vrp,vehicleFleetManager,stateManager,algorithmListeners,definedClasses,executorService,nuOfThreads,constraintManager);
if(createInitialSolution != null) algorithmListeners.add(new PrioritizedVRAListener(Priority.MEDIUM, createInitialSolution)); 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"); int solutionMemory = config.getInt("strategy.memory");
SearchStrategyManager searchStratManager = new SearchStrategyManager(); SearchStrategyManager searchStratManager = new SearchStrategyManager();
List<HierarchicalConfiguration> strategyConfigs = config.configurationsAt("strategy.searchStrategies.searchStrategy"); List<HierarchicalConfiguration> strategyConfigs = config.configurationsAt("strategy.searchStrategies.searchStrategy");
@ -483,26 +478,72 @@ public class VehicleRoutingAlgorithms {
strategy.setName(name); strategy.setName(name);
List<HierarchicalConfiguration> modulesConfig = strategyConfig.configurationsAt("modules.module"); List<HierarchicalConfiguration> modulesConfig = strategyConfig.configurationsAt("modules.module");
for(HierarchicalConfiguration moduleConfig : modulesConfig){ 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); strategy.addModule(module);
} }
searchStratManager.addStrategy(strategy, strategyConfig.getDouble("probability")); searchStratManager.addStrategy(strategy, strategyConfig.getDouble("probability"));
} }
//construct algorithm
VehicleRoutingAlgorithm metaAlgorithm = new VehicleRoutingAlgorithm(vrp, searchStratManager); VehicleRoutingAlgorithm metaAlgorithm = new VehicleRoutingAlgorithm(vrp, searchStratManager);
if(config.containsKey("iterations")){ if(config.containsKey("iterations")){
int iter = config.getInt("iterations"); int iter = config.getInt("iterations");
metaAlgorithm.setNuOfIterations(iter); metaAlgorithm.setNuOfIterations(iter);
log.info("set nuOfIterations to " + 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); PrematureAlgorithmBreaker prematureAlgoBreaker = getPrematureBreaker(config,algorithmListeners);
metaAlgorithm.setPrematureAlgorithmBreaker(prematureAlgoBreaker); metaAlgorithm.setPrematureAlgorithmBreaker(prematureAlgoBreaker);
//misc
algorithmListeners.add(new PrioritizedVRAListener(Priority.LOW, new SolutionVerifier()));
//register listeners
registerListeners(metaAlgorithm,algorithmListeners); registerListeners(metaAlgorithm,algorithmListeners);
registerInsertionListeners(definedClasses,insertionListeners); registerInsertionListeners(definedClasses,insertionListeners);
return metaAlgorithm; 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) { private static PrematureAlgorithmBreaker getPrematureBreaker(XMLConfiguration config, Set<PrioritizedVRAListener> algorithmListeners) {
String basedOn = config.getString("prematureBreak[@basedOn]"); String basedOn = config.getString("prematureBreak[@basedOn]");
if(basedOn == null){ if(basedOn == null){
@ -570,7 +611,7 @@ public class VehicleRoutingAlgorithms {
metaAlgorithm.getAlgorithmListeners().addAll(algorithmListeners); 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"); List<HierarchicalConfiguration> modConfigs = config.configurationsAt("construction.insertion");
if(modConfigs == null) return null; if(modConfigs == null) return null;
if(modConfigs.isEmpty()) return null; if(modConfigs.isEmpty()) return null;
@ -585,7 +626,7 @@ public class VehicleRoutingAlgorithms {
InsertionStrategy insertionStrategy = definedClasses.get(insertionStrategyKey); InsertionStrategy insertionStrategy = definedClasses.get(insertionStrategyKey);
if(insertionStrategy == null){ if(insertionStrategy == null){
List<PrioritizedVRAListener> prioListeners = new ArrayList<PrioritizedVRAListener>(); 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); algorithmListeners.addAll(prioListeners);
definedClasses.put(insertionStrategyKey,insertionStrategy); definedClasses.put(insertionStrategyKey,insertionStrategy);
} }
@ -667,7 +708,7 @@ public class VehicleRoutingAlgorithms {
} }
private static SearchStrategyModule buildModule(HierarchicalConfiguration moduleConfig, final VehicleRoutingProblem vrp, VehicleFleetManager vehicleFleetManager, 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]"); String moduleName = moduleConfig.getString("[@name]");
if(moduleName == null) throw new IllegalStateException("module(-name) is missing."); if(moduleName == null) throw new IllegalStateException("module(-name) is missing.");
String moduleId = moduleConfig.getString("[@id]"); String moduleId = moduleConfig.getString("[@id]");
@ -716,49 +757,14 @@ public class VehicleRoutingAlgorithms {
List<HierarchicalConfiguration> insertionConfigs = moduleConfig.configurationsAt("insertion"); List<HierarchicalConfiguration> insertionConfigs = moduleConfig.configurationsAt("insertion");
if(insertionConfigs.size() != 1) throw new IllegalStateException("this should be 1"); if(insertionConfigs.size() != 1) throw new IllegalStateException("this should be 1");
List<PrioritizedVRAListener> prioListeners = new ArrayList<PrioritizedVRAListener>(); 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); algorithmListeners.addAll(prioListeners);
} }
final InsertionStrategy final_insertion = insertion; final InsertionStrategy final_insertion = insertion;
SearchStrategyModule module = new SearchStrategyModule() {
RuinAndRecreateModule rrModule = new RuinAndRecreateModule("ruin_and_recreate", final_insertion, ruin);
private Logger logger = Logger.getLogger(SearchStrategyModule.class); return rrModule;
@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;
} }
if(moduleName.equals("gendreau")){ if(moduleName.equals("gendreau")){
int iterations = moduleConfig.getInt("iterations"); int iterations = moduleConfig.getInt("iterations");
double share = moduleConfig.getDouble("share"); double share = moduleConfig.getDouble("share");
@ -771,7 +777,6 @@ public class VehicleRoutingAlgorithms {
RuinStrategy ruin = definedClasses.get(stratKey); RuinStrategy ruin = definedClasses.get(stratKey);
if(ruin == null){ if(ruin == null){
ruin = new RuinRadial(vrp, 0.3, new JobDistanceAvgCosts(vrp.getTransportCosts())); ruin = new RuinRadial(vrp, 0.3, new JobDistanceAvgCosts(vrp.getTransportCosts()));
ruin.addListener(new UpdateStates(routeStates, vrp.getTransportCosts(), vrp.getActivityCosts()));
definedClasses.put(stratKey, ruin); definedClasses.put(stratKey, ruin);
} }
@ -786,7 +791,7 @@ public class VehicleRoutingAlgorithms {
List<HierarchicalConfiguration> insertionConfigs = moduleConfig.configurationsAt("insertion"); List<HierarchicalConfiguration> insertionConfigs = moduleConfig.configurationsAt("insertion");
if(insertionConfigs.size() != 1) throw new IllegalStateException("this should be 1"); if(insertionConfigs.size() != 1) throw new IllegalStateException("this should be 1");
List<PrioritizedVRAListener> prioListeners = new ArrayList<PrioritizedVRAListener>(); 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); algorithmListeners.addAll(prioListeners);
} }
Gendreau gendreau = new Gendreau(vrp, ruin, insertion); Gendreau gendreau = new Gendreau(vrp, ruin, insertion);
@ -810,7 +815,6 @@ public class VehicleRoutingAlgorithms {
RuinStrategy ruin = definedClasses.get(stratKey); RuinStrategy ruin = definedClasses.get(stratKey);
if(ruin == null){ if(ruin == null){
ruin = new RuinRadial(vrp, shareToRuin, jobDistance); ruin = new RuinRadial(vrp, shareToRuin, jobDistance);
ruin.addListener(new UpdateStates(routeStates, vrp.getTransportCosts(), vrp.getActivityCosts()));
definedClasses.put(stratKey, ruin); definedClasses.put(stratKey, ruin);
} }
return ruin; return ruin;
@ -821,14 +825,13 @@ public class VehicleRoutingAlgorithms {
RuinStrategy ruin = definedClasses.get(stratKey); RuinStrategy ruin = definedClasses.get(stratKey);
if(ruin == null){ if(ruin == null){
ruin = new RuinRandom(vrp, shareToRuin); ruin = new RuinRandom(vrp, shareToRuin);
ruin.addListener(new UpdateStates(routeStates, vrp.getTransportCosts(), vrp.getActivityCosts()));
definedClasses.put(stratKey, ruin); definedClasses.put(stratKey, ruin);
} }
return ruin; return ruin;
} }
private static InsertionStrategy createInsertionStrategy(HierarchicalConfiguration moduleConfig, VehicleRoutingProblem vrp,VehicleFleetManager vehicleFleetManager, StateManagerImpl routeStates, List<PrioritizedVRAListener> algorithmListeners, ExecutorService executorService, int 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); InsertionStrategy insertion = InsertionFactory.createInsertion(vrp, moduleConfig, vehicleFleetManager, routeStates, algorithmListeners, executorService, nuOfThreads, constraintManager);
return insertion; return insertion;
} }

View 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 algorithms; package algorithms;
import basics.algo.InsertionListener; import basics.algo.InsertionListener;

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

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

View file

@ -26,8 +26,6 @@ import util.Coordinate;
public class Service implements Job { public class Service implements Job {
public static class Builder { public static class Builder {
public static Builder newInstance(String id, int size){ public static Builder newInstance(String id, int size){
@ -35,21 +33,21 @@ public class Service implements Job {
} }
private String id; private String id;
private String locationId; protected String locationId;
private String name = "service"; private String type = "service";
private Coordinate coord; protected Coordinate coord;
private double serviceTime; protected double serviceTime;
private TimeWindow timeWindow = TimeWindow.newInstance(0.0, Double.MAX_VALUE); protected TimeWindow timeWindow = TimeWindow.newInstance(0.0, Double.MAX_VALUE);
private int demand; protected int demand;
private Builder(String id, int size) { Builder(String id, int size) {
super(); if(size < 0) throw new IllegalArgumentException("size must be greater than or equal to zero");
this.id = id; this.id = id;
this.demand = size; this.demand = size;
} }
public Builder setName(String name){ protected Builder setType(String name){
this.name = name; this.type = name;
return this; return this;
} }
@ -64,6 +62,7 @@ public class Service implements Job {
} }
public Builder setServiceTime(double serviceTime){ public Builder setServiceTime(double serviceTime){
if(serviceTime < 0) throw new IllegalArgumentException("serviceTime must be greate than or equal to zero");
this.serviceTime = serviceTime; this.serviceTime = serviceTime;
return this; 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."); if(coord == null) throw new IllegalStateException("either locationId or a coordinate must be given. But is not.");
locationId = coord.toString(); locationId = coord.toString();
} }
this.setType("service");
return new Service(this); return new Service(this);
} }
@ -89,7 +88,7 @@ public class Service implements Job {
private final String locationId; private final String locationId;
private final String name; private final String type;
private final Coordinate coord; private final Coordinate coord;
@ -99,14 +98,14 @@ public class Service implements Job {
private final int demand; private final int demand;
private Service(Builder builder){ Service(Builder builder){
id = builder.id; id = builder.id;
locationId = builder.locationId; locationId = builder.locationId;
coord = builder.coord; coord = builder.coord;
serviceTime = builder.serviceTime; serviceTime = builder.serviceTime;
timeWindow = builder.timeWindow; timeWindow = builder.timeWindow;
demand = builder.demand; demand = builder.demand;
name = builder.name; type = builder.type;
} }
@Override @Override
@ -139,7 +138,7 @@ public class Service implements Job {
* @return the name * @return the name
*/ */
public String getType() { public String getType() {
return name; return type;
} }
@Override @Override

View file

@ -49,6 +49,18 @@ import basics.route.VehicleTypeImpl;
*/ */
public class VehicleRoutingProblem { 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. * Builder to build the routing-problem.
* *
@ -81,6 +93,8 @@ public class VehicleRoutingProblem {
private FleetComposition fleetComposition = FleetComposition.HOMOGENEOUS; private FleetComposition fleetComposition = FleetComposition.HOMOGENEOUS;
private Collection<VehicleType> vehicleTypes; private Collection<VehicleType> vehicleTypes;
private Collection<Constraint> problemConstraints;
/** /**
* by default all locations are neighbors * by default all locations are neighbors
@ -99,6 +113,7 @@ public class VehicleRoutingProblem {
coordinates = new HashMap<String, Coordinate>(); coordinates = new HashMap<String, Coordinate>();
vehicleTypes = new ArrayList<VehicleType>(); vehicleTypes = new ArrayList<VehicleType>();
services = new ArrayList<Service>(); services = new ArrayList<Service>();
problemConstraints = new ArrayList<VehicleRoutingProblem.Constraint>();
} }
/** /**
@ -117,6 +132,7 @@ public class VehicleRoutingProblem {
} }
return id; return id;
} }
/** /**
* Returns the unmodifiable map of locations (mapped by their 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. * Sets routing costs.
* *
@ -387,6 +409,8 @@ public class VehicleRoutingProblem {
private FleetComposition fleetComposition; private FleetComposition fleetComposition;
private Collection<Constraint> problemConstraints;
private VehicleRoutingProblem(Builder builder) { private VehicleRoutingProblem(Builder builder) {
this.jobs = builder.jobs; this.jobs = builder.jobs;
this.fleetComposition = builder.fleetComposition; this.fleetComposition = builder.fleetComposition;
@ -396,6 +420,7 @@ public class VehicleRoutingProblem {
this.transportCosts = builder.transportCosts; this.transportCosts = builder.transportCosts;
this.activityCosts = builder.activityCosts; this.activityCosts = builder.activityCosts;
this.neighborhood = builder.neighborhood; this.neighborhood = builder.neighborhood;
this.problemConstraints = builder.problemConstraints;
log.info("initialise " + this); log.info("initialise " + this);
} }
@ -441,6 +466,14 @@ public class VehicleRoutingProblem {
return Collections.unmodifiableMap(jobs); 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. * Returns the entire, unmodifiable collection of types.

View file

@ -20,6 +20,6 @@
******************************************************************************/ ******************************************************************************/
package basics.algo; package basics.algo;
public class SearchStrategyListener { public interface SearchStrategyListener extends VehicleRoutingAlgorithmListener{
} }

View file

@ -20,6 +20,6 @@
******************************************************************************/ ******************************************************************************/
package basics.algo; package basics.algo;
public interface SearchStrategyModuleListener { public interface SearchStrategyModuleListener extends VehicleRoutingAlgorithmListener{
} }

View file

@ -38,25 +38,52 @@ import org.xml.sax.SAXException;
import util.Coordinate; import util.Coordinate;
import util.Resource; import util.Resource;
import basics.Delivery;
import basics.Pickup;
import basics.Service; import basics.Service;
import basics.VehicleRoutingProblem; import basics.VehicleRoutingProblem;
import basics.VehicleRoutingProblem.FleetComposition; import basics.VehicleRoutingProblem.FleetComposition;
import basics.VehicleRoutingProblem.FleetSize; import basics.VehicleRoutingProblem.FleetSize;
import basics.VehicleRoutingProblemSolution; import basics.VehicleRoutingProblemSolution;
import basics.route.DefaultTourActivityFactory;
import basics.route.DeliveryActivity;
import basics.route.Driver; import basics.route.Driver;
import basics.route.DriverImpl; import basics.route.DriverImpl;
import basics.route.End; import basics.route.End;
import basics.route.PickupActivity;
import basics.route.ServiceActivity; import basics.route.ServiceActivity;
import basics.route.Start; import basics.route.Start;
import basics.route.TimeWindow; import basics.route.TimeWindow;
import basics.route.TourActivity;
import basics.route.TourActivityFactory;
import basics.route.Vehicle; import basics.route.Vehicle;
import basics.route.VehicleImpl; import basics.route.VehicleImpl;
import basics.route.VehicleImpl.Builder; import basics.route.VehicleImpl.Builder;
import basics.route.VehicleRoute; import basics.route.VehicleRoute;
import basics.route.VehicleType;
import basics.route.VehicleTypeImpl; import basics.route.VehicleTypeImpl;
public class VrpXMLReader{ 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 static Logger logger = Logger.getLogger(VrpXMLReader.class);
@ -70,6 +97,18 @@ public class VrpXMLReader{
private Collection<VehicleRoutingProblemSolution> solutions; 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 * @param schemaValidation the schemaValidation to set
*/ */
@ -170,10 +209,10 @@ public class VrpXMLReader{
if(arrTime == null) throw new IllegalStateException("act.arrTime is missing."); if(arrTime == null) throw new IllegalStateException("act.arrTime is missing.");
String endTime = actConfig.getString("endTime"); String endTime = actConfig.getString("endTime");
if(endTime == null) throw new IllegalStateException("act.endTime is missing."); if(endTime == null) throw new IllegalStateException("act.endTime is missing.");
ServiceActivity serviceActivity = ServiceActivity.newInstance(service); TourActivity tourActivity = tourActivityFactory.createActivity(service);
serviceActivity.setArrTime(Double.parseDouble(arrTime)); tourActivity.setArrTime(Double.parseDouble(arrTime));
serviceActivity.setEndTime(Double.parseDouble(endTime)); tourActivity.setEndTime(Double.parseDouble(endTime));
routeBuilder.addActivity(serviceActivity); routeBuilder.addActivity(tourActivity);
} }
routes.add(routeBuilder.build()); routes.add(routeBuilder.build());
} }
@ -210,13 +249,12 @@ public class VrpXMLReader{
for(HierarchicalConfiguration serviceConfig : serviceConfigs){ for(HierarchicalConfiguration serviceConfig : serviceConfigs){
String id = serviceConfig.getString("[@id]"); String id = serviceConfig.getString("[@id]");
if(id == null) throw new IllegalStateException("service[@id] is missing."); if(id == null) throw new IllegalStateException("service[@id] is missing.");
String name = serviceConfig.getString("[@type]"); String type = serviceConfig.getString("[@type]");
if(name == null) name = "service"; if(type == null) type = "service";
String capacityDemand = serviceConfig.getString("capacity-demand"); String capacityDemand = serviceConfig.getString("capacity-demand");
int cap = 0; int cap = 0;
if(capacityDemand != null) cap = Integer.parseInt(capacityDemand); if(capacityDemand != null) cap = Integer.parseInt(capacityDemand);
Service.Builder builder = Service.Builder.newInstance(id, cap); Service.Builder builder = serviceBuilderFactory.createBuilder(type, id, cap);
builder.setName(name);
String serviceLocationId = serviceConfig.getString("locationId"); String serviceLocationId = serviceConfig.getString("locationId");
builder.setLocationId(serviceLocationId); builder.setLocationId(serviceLocationId);
Coordinate serviceCoord = null; Coordinate serviceCoord = null;
@ -235,8 +273,6 @@ public class VrpXMLReader{
builder.setLocationId(serviceCoord.toString()); builder.setLocationId(serviceCoord.toString());
} }
} }
if(serviceConfig.containsKey("duration")){ if(serviceConfig.containsKey("duration")){
builder.setServiceTime(serviceConfig.getDouble("duration")); builder.setServiceTime(serviceConfig.getDouble("duration"));
} }
@ -264,15 +300,12 @@ public class VrpXMLReader{
Double fix = typeConfig.getDouble("costs.fixed"); Double fix = typeConfig.getDouble("costs.fixed");
Double timeC = typeConfig.getDouble("costs.time"); Double timeC = typeConfig.getDouble("costs.time");
Double distC = typeConfig.getDouble("costs.distance"); 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(typeId == null) throw new IllegalStateException("typeId is missing.");
if(capacity == null) throw new IllegalStateException("capacity is missing."); if(capacity == null) throw new IllegalStateException("capacity is missing.");
VehicleTypeImpl.Builder typeBuilder = VehicleTypeImpl.Builder.newInstance(typeId, capacity); VehicleTypeImpl.Builder typeBuilder = VehicleTypeImpl.Builder.newInstance(typeId, capacity);
if(fix != null) typeBuilder.setFixedCost(fix); if(fix != null) typeBuilder.setFixedCost(fix);
if(timeC != null) typeBuilder.setCostPerTime(timeC); if(timeC != null) typeBuilder.setCostPerTime(timeC);
if(distC != null) typeBuilder.setCostPerDistance(distC); if(distC != null) typeBuilder.setCostPerDistance(distC);
// if(start != null && end != null) typeBuilder.setTimeSchedule(new TimeSchedule(start, end));
VehicleTypeImpl type = typeBuilder.build(); VehicleTypeImpl type = typeBuilder.build();
types.put(type.getTypeId(), type); types.put(type.getTypeId(), type);
vrpBuilder.addVehicleType(type); vrpBuilder.addVehicleType(type);
@ -310,7 +343,6 @@ public class VrpXMLReader{
if(start != null) builder.setEarliestStart(Double.parseDouble(start)); if(start != null) builder.setEarliestStart(Double.parseDouble(start));
if(end != null) builder.setLatestArrival(Double.parseDouble(end)); if(end != null) builder.setLatestArrival(Double.parseDouble(end));
VehicleImpl vehicle = builder.build(); VehicleImpl vehicle = builder.build();
// vehicleMap.put(vehicle.getId(), vehicle);
vrpBuilder.addVehicle(vehicle); vrpBuilder.addVehicle(vehicle);
vehicleMap.put(vehicleId, vehicle); vehicleMap.put(vehicleId, vehicle);
} }

View file

@ -39,6 +39,7 @@ import basics.VehicleRoutingProblem;
import basics.VehicleRoutingProblemSolution; import basics.VehicleRoutingProblemSolution;
import basics.route.ServiceActivity; import basics.route.ServiceActivity;
import basics.route.TourActivity; import basics.route.TourActivity;
import basics.route.TourActivity.JobActivity;
import basics.route.Vehicle; import basics.route.Vehicle;
import basics.route.VehicleRoute; import basics.route.VehicleRoute;
import basics.route.VehicleType; import basics.route.VehicleType;
@ -84,7 +85,6 @@ public class VrpXMLWriter {
writeProblemType(xmlConfig); writeProblemType(xmlConfig);
writeVehiclesAndTheirTypes(xmlConfig); writeVehiclesAndTheirTypes(xmlConfig);
writerServices(xmlConfig); writerServices(xmlConfig);
// writeShipments(xmlConfig);
writeSolutions(xmlConfig); writeSolutions(xmlConfig);
OutputFormat format = new OutputFormat(); OutputFormat format = new OutputFormat();
@ -133,8 +133,8 @@ public class VrpXMLWriter {
int actCounter = 0; int actCounter = 0;
for(TourActivity act : route.getTourActivities().getActivities()){ for(TourActivity act : route.getTourActivities().getActivities()){
xmlConfig.setProperty(solutionPath + "(" + counter + ").routes.route(" + routeCounter + ").act("+actCounter+")[@type]", act.getName()); xmlConfig.setProperty(solutionPath + "(" + counter + ").routes.route(" + routeCounter + ").act("+actCounter+")[@type]", act.getName());
if(act instanceof ServiceActivity){ if(act instanceof JobActivity){
xmlConfig.setProperty(solutionPath + "(" + counter + ").routes.route(" + routeCounter + ").act("+actCounter+").serviceId", ((ServiceActivity) act).getJob().getId()); 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+").arrTime", act.getArrTime());
xmlConfig.setProperty(solutionPath + "(" + counter + ").routes.route(" + routeCounter + ").act("+actCounter+").endTime", act.getEndTime()); xmlConfig.setProperty(solutionPath + "(" + counter + ").routes.route(" + routeCounter + ").act("+actCounter+").endTime", act.getEndTime());
@ -169,36 +169,6 @@ public class VrpXMLWriter {
} }
// private void writeShipments(XMLConf xmlConfig) {
// String shipmentPathString = "shipments.shipment";
// int counter = 0;
// for(Job j : vrp.getJobs().values()){
// Shipment shipment = (Shipment) j;
// xmlConfig.setProperty(shipmentPathString + "("+counter+")[@id]", shipment.getId());
// if(shipment.getFromId() != null) xmlConfig.setProperty(shipmentPathString + "("+counter+").pickup.locationId", shipment.getFromId());
// if(shipment.getFromCoord() != null) {
// xmlConfig.setProperty(shipmentPathString + "("+counter+").pickup.coord[@x]", shipment.getFromCoord().getX());
// xmlConfig.setProperty(shipmentPathString + "("+counter+").pickup.coord[@y]", shipment.getFromCoord().getY());
// }
// if(shipment.getToId() != null) xmlConfig.setProperty(shipmentPathString + "("+counter+").delivery.locationId", shipment.getToId());
// if(shipment.getFromCoord() != null) {
// xmlConfig.setProperty(shipmentPathString + "("+counter+").delivery.coord[@x]", shipment.getToCoord().getX());
// xmlConfig.setProperty(shipmentPathString + "("+counter+").delivery.coord[@y]", shipment.getToCoord().getY());
// }
// xmlConfig.setProperty(shipmentPathString + "("+counter+").size", shipment.getSize());
// xmlConfig.setProperty(shipmentPathString + "("+counter+").pickup.serviceTime", shipment.getPickupServiceTime());
// xmlConfig.setProperty(shipmentPathString + "("+counter+").pickup.timeWindows.timeWindow(0).start", shipment.getPickupTW().getStart());
// xmlConfig.setProperty(shipmentPathString + "("+counter+").pickup.timeWindows.timeWindow(0).end", shipment.getPickupTW().getEnd());
//
// xmlConfig.setProperty(shipmentPathString + "("+counter+").delivery.serviceTime", shipment.getDeliveryServiceTime());
// xmlConfig.setProperty(shipmentPathString + "("+counter+").delivery.timeWindows.timeWindow(0).start", shipment.getDeliveryTW().getStart());
// xmlConfig.setProperty(shipmentPathString + "("+counter+").delivery.timeWindows.timeWindow(0).end", shipment.getDeliveryTW().getEnd());
//
// counter++;
// }
//
// }
private void writeProblemType(XMLConfiguration xmlConfig){ private void writeProblemType(XMLConfiguration xmlConfig){
xmlConfig.setProperty("problemType.fleetSize", vrp.getFleetSize()); xmlConfig.setProperty("problemType.fleetSize", vrp.getFleetSize());
@ -206,19 +176,6 @@ public class VrpXMLWriter {
} }
private void writeVehiclesAndTheirTypes(XMLConfiguration xmlConfig) { 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 //vehicles
String vehiclePathString = new StringBuilder().append(Schema.VEHICLES).append("."). String vehiclePathString = new StringBuilder().append(Schema.VEHICLES).append(".").
@ -234,13 +191,7 @@ public class VrpXMLWriter {
} }
xmlConfig.setProperty(vehiclePathString + "("+counter+").timeSchedule.start", vehicle.getEarliestDeparture()); xmlConfig.setProperty(vehiclePathString + "("+counter+").timeSchedule.start", vehicle.getEarliestDeparture());
xmlConfig.setProperty(vehiclePathString + "("+counter+").timeSchedule.end", vehicle.getLatestArrival()); 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++; counter++;
} }
@ -250,44 +201,13 @@ public class VrpXMLWriter {
for(VehicleType type : vrp.getTypes()){ for(VehicleType type : vrp.getTypes()){
xmlConfig.setProperty(typePathString + "("+typeCounter+").id", type.getTypeId()); xmlConfig.setProperty(typePathString + "("+typeCounter+").id", type.getTypeId());
xmlConfig.setProperty(typePathString + "("+typeCounter+").capacity", type.getCapacity()); 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.fixed", type.getVehicleCostParams().fix);
xmlConfig.setProperty(typePathString + "("+typeCounter+").costs.distance", type.getVehicleCostParams().perDistanceUnit); xmlConfig.setProperty(typePathString + "("+typeCounter+").costs.distance", type.getVehicleCostParams().perDistanceUnit);
xmlConfig.setProperty(typePathString + "("+typeCounter+").costs.time", type.getVehicleCostParams().perTimeUnit); xmlConfig.setProperty(typePathString + "("+typeCounter+").costs.time", type.getVehicleCostParams().perTimeUnit);
typeCounter++; typeCounter++;
} }
// //type2depot assignments
// int assignmentCounter = 0;
// boolean first = true;
// for(Depot depot : vrp.getDepotToVehicleTypeAssignments().keySet()){
// if(first){
// xmlConfig.setProperty("assignments[@type]", "vehicleType2depot");
// }
// for(VehicleType type : vrp.getDepotToVehicleTypeAssignments().get(depot)){
// xmlConfig.setProperty("assignments.assignment" + "("+assignmentCounter+").depotId", depot2id.get(depot));
// xmlConfig.setProperty("assignments.assignment" + "("+assignmentCounter+").vehicleTypeId", type.getTypeId());
// assignmentCounter++;
// }
// }
//
// //vehicle2depot assignments
// int vehicleAssignmentCounter = 0;
// boolean first_ = true;
// for(Depot depot : vrp.getDepotToVehicleAssignments().keySet()){
// if(first_){
// xmlConfig.setProperty("assignments[@type]", "vehicle2depot");
// }
// for(Vehicle vehicle : vrp.getDepotToVehicleAssignments().get(depot)){
// xmlConfig.setProperty("assignments.assignment" + "("+vehicleAssignmentCounter+").depotId", depot2id.get(depot));
// xmlConfig.setProperty("assignments.assignment" + "("+vehicleAssignmentCounter+").vehicleId", vehicle.getId());
// vehicleAssignmentCounter++;
// }
// }
//
} }

View file

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

View 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;
}
}

View 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 basics.route; package basics.route;
import basics.route.VehicleTypeImpl.VehicleCostParams; import basics.route.VehicleTypeImpl.VehicleCostParams;

View 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();
}
}

View file

@ -31,6 +31,8 @@ public class ServiceActivity implements JobActivity<Service>{
public double endTime; public double endTime;
public int capacityDemand;
/** /**
* @return the arrTime * @return the arrTime
*/ */
@ -67,18 +69,31 @@ public class ServiceActivity implements JobActivity<Service>{
return new ServiceActivity(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 final Service service;
private ServiceActivity(Service service) { protected ServiceActivity(Service service) {
counter++; counter++;
this.service = service; this.service = service;
this.capacityDemand = service.getCapacityDemand();
} }
private ServiceActivity(ServiceActivity serviceActivity) { protected ServiceActivity(ServiceActivity serviceActivity) {
counter++; counter++;
this.service = serviceActivity.getJob(); this.service = serviceActivity.getJob();
this.arrTime = serviceActivity.getArrTime(); this.arrTime = serviceActivity.getArrTime();
this.endTime = serviceActivity.getEndTime(); this.endTime = serviceActivity.getEndTime();
this.capacityDemand = serviceActivity.getCapacityDemand();
} }
@ -123,7 +138,7 @@ public class ServiceActivity implements JobActivity<Service>{
@Override @Override
public int getCapacityDemand() { public int getCapacityDemand() {
return service.getCapacityDemand(); return this.capacityDemand;
} }
@Override @Override

View file

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

View 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 basics.route; package basics.route;
import basics.route.VehicleTypeImpl.VehicleCostParams; import basics.route.VehicleTypeImpl.VehicleCostParams;
@ -13,4 +33,4 @@ public interface VehicleType {
public VehicleCostParams getVehicleCostParams(); public VehicleCostParams getVehicleCostParams();
} }

View 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 basics.route; package basics.route;
@ -148,4 +168,4 @@ public class VehicleTypeImpl implements VehicleType {
public double getMaxVelocity() { public double getMaxVelocity() {
return maxVelocity; return maxVelocity;
} }
} }

View 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 util; package util;
import basics.VehicleRoutingProblem; import basics.VehicleRoutingProblem;
@ -14,4 +34,4 @@ public class BenchmarkInstance {
this.bestKnownResult = bestKnownResult; this.bestKnownResult = bestKnownResult;
this.bestKnownVehicles = bestKnowVehicles; this.bestKnownVehicles = bestKnowVehicles;
} }
} }

View 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 util; package util;
import org.apache.commons.math.stat.descriptive.DescriptiveStatistics; import org.apache.commons.math.stat.descriptive.DescriptiveStatistics;
@ -53,4 +73,4 @@ public class BenchmarkResult {
return statsTimes; return statsTimes;
} }
} }

View 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 util; package util;
import java.util.HashMap; import java.util.HashMap;

View file

@ -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; package algorithms;
import static org.junit.Assert.*; import static org.junit.Assert.assertEquals;
import java.util.Collection; import java.util.Collection;
@ -9,6 +29,8 @@ import org.junit.Test;
import util.Solutions; import util.Solutions;
import algorithms.HardConstraints.HardActivityLevelConstraint; import algorithms.HardConstraints.HardActivityLevelConstraint;
import algorithms.StateUpdates.UpdateCostsAtRouteLevel;
import algorithms.StateUpdates.UpdateLoadAtRouteLevel;
import algorithms.acceptors.AcceptNewIfBetterThanWorst; import algorithms.acceptors.AcceptNewIfBetterThanWorst;
import algorithms.selectors.SelectBest; import algorithms.selectors.SelectBest;
import basics.VehicleRoutingAlgorithm; import basics.VehicleRoutingAlgorithm;
@ -36,7 +58,7 @@ public class BuildCVRPAlgoFromScratchTest {
HardActivityLevelConstraint hardActLevelConstraint = new HardActivityLevelConstraint() { HardActivityLevelConstraint hardActLevelConstraint = new HardActivityLevelConstraint() {
@Override @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; return true;
} }
}; };
@ -76,7 +98,7 @@ public class BuildCVRPAlgoFromScratchTest {
vra.getAlgorithmListeners().addListener(clearStateManager); vra.getAlgorithmListeners().addListener(clearStateManager);
vra.getSearchStrategyManager().addSearchStrategyModuleListener(new RemoveEmptyVehicles(fleetManager)); 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)); vra.getSearchStrategyManager().addSearchStrategyModuleListener(new UpdateLoadAtRouteLevel(stateManager));
VehicleRoutingProblemSolution iniSolution = new CreateInitialSolution(bestInsertion).createInitialSolution(vrp); VehicleRoutingProblemSolution iniSolution = new CreateInitialSolution(bestInsertion).createInitialSolution(vrp);

View file

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

View file

@ -33,6 +33,7 @@ import org.junit.Test;
import util.Coordinate; import util.Coordinate;
import util.ManhattanDistanceCalculator; import util.ManhattanDistanceCalculator;
import util.RouteUtils; import util.RouteUtils;
import algorithms.StateUpdates.UpdateStates;
import basics.Job; import basics.Job;
import basics.Service; import basics.Service;
import basics.VehicleRoutingProblem; import basics.VehicleRoutingProblem;
@ -151,7 +152,7 @@ public class GendreauPostOptTest {
activityCosts = new ExampleActivityCostFunction(); 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); CalculatesServiceInsertionConsideringFixCost withFixCost = new CalculatesServiceInsertionConsideringFixCost(standardServiceInsertion, states);
withFixCost.setWeightOfFixCost(1.2); withFixCost.setWeightOfFixCost(1.2);

View 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 algorithms; package algorithms;
import static org.junit.Assert.*; import static org.junit.Assert.*;

View file

@ -32,17 +32,18 @@ import org.apache.log4j.Logger;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import algorithms.StateUpdates.UpdateStates;
import basics.Job; import basics.Job;
import basics.Service; import basics.Service;
import basics.costs.VehicleRoutingTransportCosts; import basics.costs.VehicleRoutingTransportCosts;
import basics.route.DriverImpl; import basics.route.DriverImpl;
import basics.route.DriverImpl.NoDriver;
import basics.route.ServiceActivity; import basics.route.ServiceActivity;
import basics.route.TimeWindow; import basics.route.TimeWindow;
import basics.route.TourActivities; import basics.route.TourActivities;
import basics.route.TourActivity; import basics.route.TourActivity;
import basics.route.Vehicle; import basics.route.Vehicle;
import basics.route.VehicleRoute; import basics.route.VehicleRoute;
import basics.route.DriverImpl.NoDriver;
@ -156,7 +157,7 @@ public class TestCalculatesServiceInsertion {
ExampleActivityCostFunction activityCosts = new ExampleActivityCostFunction(); 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); stateUpdater = new UpdateStates(states, costs, activityCosts);

View file

@ -34,18 +34,19 @@ import org.junit.Test;
import util.Coordinate; import util.Coordinate;
import util.ManhattanDistanceCalculator; import util.ManhattanDistanceCalculator;
import algorithms.StateUpdates.UpdateStates;
import basics.Job; import basics.Job;
import basics.Service; import basics.Service;
import basics.costs.VehicleRoutingTransportCosts; import basics.costs.VehicleRoutingTransportCosts;
import basics.route.Driver; import basics.route.Driver;
import basics.route.DriverImpl; import basics.route.DriverImpl;
import basics.route.DriverImpl.NoDriver;
import basics.route.ServiceActivity; import basics.route.ServiceActivity;
import basics.route.TimeWindow; import basics.route.TimeWindow;
import basics.route.TourActivities; import basics.route.TourActivities;
import basics.route.TourActivity; import basics.route.TourActivity;
import basics.route.Vehicle; import basics.route.Vehicle;
import basics.route.VehicleRoute; import basics.route.VehicleRoute;
import basics.route.DriverImpl.NoDriver;

View 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 algorithms; package algorithms;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
@ -10,6 +30,10 @@ import org.junit.Test;
import util.Coordinate; import util.Coordinate;
import util.ManhattanDistanceCalculator; import util.ManhattanDistanceCalculator;
import algorithms.StateUpdates.UpdateActivityTimes;
import algorithms.StateUpdates.UpdateCostsAtAllLevels;
import algorithms.StateUpdates.UpdateEarliestStartTimeWindowAtActLocations;
import algorithms.StateUpdates.UpdateLoadAtAllLevels;
import basics.Job; import basics.Job;
import basics.Service; import basics.Service;
import basics.costs.DefaultVehicleRoutingActivityCosts; import basics.costs.DefaultVehicleRoutingActivityCosts;
@ -34,10 +58,6 @@ public class TestIterateRouteForwardInTime {
TourActivities anotherTour; TourActivities anotherTour;
RouteStates states;
private VehicleRoute vehicleRoute; private VehicleRoute vehicleRoute;
private VehicleRoutingTransportCosts cost; private VehicleRoutingTransportCosts cost;
@ -46,6 +66,8 @@ public class TestIterateRouteForwardInTime {
ServiceActivity secondAct; ServiceActivity secondAct;
StateManagerImpl stateManager;
@Before @Before
public void setUp(){ public void setUp(){
cost = new VehicleRoutingTransportCosts() { cost = new VehicleRoutingTransportCosts() {
@ -99,6 +121,8 @@ public class TestIterateRouteForwardInTime {
tour.addActivity(secondAct); tour.addActivity(secondAct);
vehicleRoute = VehicleRoute.newInstance(tour,DriverImpl.noDriver(),vehicle); vehicleRoute = VehicleRoute.newInstance(tour,DriverImpl.noDriver(),vehicle);
stateManager = new StateManagerImpl();
} }
@Test @Test
@ -129,12 +153,11 @@ public class TestIterateRouteForwardInTime {
@Test @Test
public void whenIteratingWithLoadUpdateAtActLocations_itShouldUpdateLoad() { public void whenIteratingWithLoadUpdateAtActLocations_itShouldUpdateLoad() {
IterateRouteForwardInTime forwardInTime = new IterateRouteForwardInTime(cost); IterateRouteForwardInTime forwardInTime = new IterateRouteForwardInTime(cost);
StateManagerImpl states = new StateManagerImpl(); forwardInTime.addListener(new UpdateLoadAtAllLevels(stateManager));
forwardInTime.addListener(new UpdateLoadAtAllLevels(states));
forwardInTime.iterate(vehicleRoute); forwardInTime.iterate(vehicleRoute);
assertEquals(5.0, states.getActivityStates(firstAct).getState(StateTypes.LOAD).toDouble(), 0.01); assertEquals(5.0, stateManager.getActivityState(firstAct,StateTypes.LOAD).toDouble(), 0.01);
assertEquals(10.0, states.getActivityStates(secondAct).getState(StateTypes.LOAD).toDouble(), 0.01); assertEquals(10.0, stateManager.getActivityState(secondAct,StateTypes.LOAD).toDouble(), 0.01);
} }
@ -153,42 +176,41 @@ public class TestIterateRouteForwardInTime {
@Test @Test
public void testStatesOfAct1(){ public void testStatesOfAct1(){
IterateRouteForwardInTime forwardInTime = new IterateRouteForwardInTime(cost); IterateRouteForwardInTime forwardInTime = new IterateRouteForwardInTime(cost);
StateManagerImpl states = new StateManagerImpl(); forwardInTime.addListener(new UpdateLoadAtAllLevels(stateManager));
forwardInTime.addListener(new UpdateLoadAtAllLevels(states)); forwardInTime.addListener(new UpdateEarliestStartTimeWindowAtActLocations(stateManager));
forwardInTime.addListener(new UpdateEarliestStartTimeWindowAtActLocations(states)); forwardInTime.addListener(new UpdateCostsAtAllLevels(new DefaultVehicleRoutingActivityCosts(), cost, stateManager));
forwardInTime.addListener(new UpdateCostsAtAllLevels(new DefaultVehicleRoutingActivityCosts(), cost, states));
forwardInTime.iterate(vehicleRoute); forwardInTime.iterate(vehicleRoute);
assertEquals(10.0, states.getActivityStates(firstAct).getState(StateTypes.COSTS).toDouble(),0.05); assertEquals(10.0, stateManager.getActivityState(firstAct, StateTypes.COSTS).toDouble(),0.05);
assertEquals(5.0, states.getActivityStates(firstAct).getState(StateTypes.LOAD).toDouble(),0.05); assertEquals(5.0, stateManager.getActivityState(firstAct, 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.EARLIEST_OPERATION_START_TIME).toDouble(),0.05);
// assertEquals(20.0, states.getState(tour.getActivities().get(0)).getLatestOperationStart(),0.05); // assertEquals(20.0, states.getState(tour.getActivities().get(0)).getLatestOperationStart(),0.05);
} }
@Test @Test
public void testStatesOfAct2(){ public void testStatesOfAct2(){
IterateRouteForwardInTime forwardInTime = new IterateRouteForwardInTime(cost); IterateRouteForwardInTime forwardInTime = new IterateRouteForwardInTime(cost);
StateManagerImpl states = new StateManagerImpl();
forwardInTime.addListener(new UpdateLoadAtAllLevels(states)); forwardInTime.addListener(new UpdateLoadAtAllLevels(stateManager));
forwardInTime.addListener(new UpdateEarliestStartTimeWindowAtActLocations(states)); forwardInTime.addListener(new UpdateEarliestStartTimeWindowAtActLocations(stateManager));
forwardInTime.addListener(new UpdateCostsAtAllLevels(new DefaultVehicleRoutingActivityCosts(), cost, states)); forwardInTime.addListener(new UpdateCostsAtAllLevels(new DefaultVehicleRoutingActivityCosts(), cost, stateManager));
forwardInTime.iterate(vehicleRoute); forwardInTime.iterate(vehicleRoute);
assertEquals(30.0, states.getActivityStates(secondAct).getState(StateTypes.COSTS).toDouble(),0.05); assertEquals(30.0, stateManager.getActivityState(secondAct, StateTypes.COSTS).toDouble(),0.05);
assertEquals(10.0, states.getActivityStates(secondAct).getState(StateTypes.LOAD).toDouble(),0.05); assertEquals(10.0, stateManager.getActivityState(secondAct, 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.EARLIEST_OPERATION_START_TIME).toDouble(),0.05);
// assertEquals(40.0, states.getState(tour.getActivities().get(1)).getLatestOperationStart(),0.05); // assertEquals(40.0, states.getState(tour.getActivities().get(1)).getLatestOperationStart(),0.05);
} }
@Test @Test
public void testStatesOfAct3(){ public void testStatesOfAct3(){
IterateRouteForwardInTime forwardInTime = new IterateRouteForwardInTime(cost); IterateRouteForwardInTime forwardInTime = new IterateRouteForwardInTime(cost);
StateManagerImpl states = new StateManagerImpl();
forwardInTime.addListener(new UpdateActivityTimes()); forwardInTime.addListener(new UpdateActivityTimes());
forwardInTime.addListener(new UpdateCostsAtAllLevels(new DefaultVehicleRoutingActivityCosts(), cost, states)); forwardInTime.addListener(new UpdateCostsAtAllLevels(new DefaultVehicleRoutingActivityCosts(), cost, stateManager));
forwardInTime.iterate(vehicleRoute); 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(40.0, vehicleRoute.getEnd().getArrTime(),0.05);
assertEquals(50.0, vehicleRoute.getEnd().getTheoreticalLatestOperationStartTime(),0.05); assertEquals(50.0, vehicleRoute.getEnd().getTheoreticalLatestOperationStartTime(),0.05);
} }

View 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 algorithms; package algorithms;
import org.junit.Test; import org.junit.Test;

View file

@ -27,6 +27,7 @@ import org.junit.Test;
import util.Coordinate; import util.Coordinate;
import util.ManhattanDistanceCalculator; import util.ManhattanDistanceCalculator;
import algorithms.StateUpdates.UpdateStates;
import basics.Job; import basics.Job;
import basics.Service; import basics.Service;
import basics.costs.VehicleRoutingTransportCosts; import basics.costs.VehicleRoutingTransportCosts;
@ -38,7 +39,6 @@ import basics.route.TourActivities;
import basics.route.Vehicle; import basics.route.Vehicle;
import basics.route.VehicleImpl; import basics.route.VehicleImpl;
import basics.route.VehicleRoute; import basics.route.VehicleRoute;
import basics.route.VehicleType;
import basics.route.VehicleTypeImpl; import basics.route.VehicleTypeImpl;

View file

@ -125,7 +125,7 @@ public class VrpReaderV2Test {
new VrpXMLReader(builder, null).read(inFileName); new VrpXMLReader(builder, null).read(inFileName);
VehicleRoutingProblem vrp = builder.build(); VehicleRoutingProblem vrp = builder.build();
Service s1 = (Service) vrp.getJobs().get("1"); Service s1 = (Service) vrp.getJobs().get("1");
assertEquals("delivery",s1.getType()); assertEquals("service",s1.getType());
assertEquals(1,s1.getCapacityDemand()); assertEquals(1,s1.getCapacityDemand());
assertEquals(0.0,s1.getServiceDuration(),0.01); assertEquals(0.0,s1.getServiceDuration(),0.01);
assertEquals(2, vrp.getJobs().size()); assertEquals(2, vrp.getJobs().size());

View file

@ -130,8 +130,8 @@ public class VrpWriterV2Test {
builder.addVehicle(v1); builder.addVehicle(v1);
builder.addVehicle(v2); builder.addVehicle(v2);
Service s1 = Service.Builder.newInstance("1", 1).setLocationId("loc").setName("delivery").setServiceTime(2.0).build(); Service s1 = Service.Builder.newInstance("1", 1).setLocationId("loc").setServiceTime(2.0).build();
Service s2 = Service.Builder.newInstance("2", 1).setLocationId("loc2").setName("delivery").setServiceTime(4.0).build(); Service s2 = Service.Builder.newInstance("2", 1).setLocationId("loc2").setServiceTime(4.0).build();
VehicleRoutingProblem vrp = builder.addService(s1).addService(s2).build(); VehicleRoutingProblem vrp = builder.addService(s1).addService(s2).build();
new VrpXMLWriter(vrp, null).write(infileName); new VrpXMLWriter(vrp, null).write(infileName);
@ -144,7 +144,7 @@ public class VrpWriterV2Test {
Service s1_read = (Service) vrp.getJobs().get("1"); Service s1_read = (Service) vrp.getJobs().get("1");
assertEquals("1", s1_read.getId()); assertEquals("1", s1_read.getId());
assertEquals("loc", s1_read.getLocationId()); assertEquals("loc", s1_read.getLocationId());
assertEquals("delivery", s1_read.getType()); assertEquals("service", s1_read.getType());
assertEquals(2.0,s1_read.getServiceDuration(),0.01); assertEquals(2.0,s1_read.getServiceDuration(),0.01);
} }
@ -162,8 +162,8 @@ public class VrpWriterV2Test {
builder.addVehicle(v1); builder.addVehicle(v1);
builder.addVehicle(v2); builder.addVehicle(v2);
Service s1 = Service.Builder.newInstance("1", 1).setLocationId("loc").setName("delivery").setServiceTime(2.0).build(); Service s1 = Service.Builder.newInstance("1", 1).setLocationId("loc").setServiceTime(2.0).build();
Service s2 = Service.Builder.newInstance("2", 1).setLocationId("loc2").setName("delivery").setServiceTime(4.0).build(); Service s2 = Service.Builder.newInstance("2", 1).setLocationId("loc2").setServiceTime(4.0).build();
builder.addService(s1).addService(s2); builder.addService(s1).addService(s2);
VehicleRoutingProblem vrp = builder.build(); VehicleRoutingProblem vrp = builder.build();

View file

@ -20,8 +20,6 @@
******************************************************************************/ ******************************************************************************/
package basics.io; package basics.io;
import static org.junit.Assert.assertEquals;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
@ -31,19 +29,15 @@ import org.junit.Test;
import basics.Service; import basics.Service;
import basics.VehicleRoutingProblem; import basics.VehicleRoutingProblem;
import basics.VehicleRoutingProblemSolution;
import basics.Service.Builder;
import basics.VehicleRoutingProblem.FleetComposition; import basics.VehicleRoutingProblem.FleetComposition;
import basics.VehicleRoutingProblem.FleetSize; import basics.VehicleRoutingProblem.FleetSize;
import basics.io.VrpXMLReader; import basics.VehicleRoutingProblemSolution;
import basics.io.VrpXMLWriter;
import basics.route.End; import basics.route.End;
import basics.route.ServiceActivity; import basics.route.ServiceActivity;
import basics.route.Start; import basics.route.Start;
import basics.route.Vehicle; import basics.route.Vehicle;
import basics.route.VehicleImpl; import basics.route.VehicleImpl;
import basics.route.VehicleRoute; import basics.route.VehicleRoute;
import basics.route.VehicleType;
import basics.route.VehicleTypeImpl; import basics.route.VehicleTypeImpl;
public class VrpWriterV3Test { public class VrpWriterV3Test {
@ -69,8 +63,8 @@ public class VrpWriterV3Test {
builder.addVehicle(v1); builder.addVehicle(v1);
builder.addVehicle(v2); builder.addVehicle(v2);
Service s1 = Service.Builder.newInstance("1", 1).setLocationId("loc").setName("delivery").setServiceTime(2.0).build(); Service s1 = Service.Builder.newInstance("1", 1).setLocationId("loc").setServiceTime(2.0).build();
Service s2 = Service.Builder.newInstance("2", 1).setLocationId("loc2").setName("delivery").setServiceTime(4.0).build(); Service s2 = Service.Builder.newInstance("2", 1).setLocationId("loc2").setServiceTime(4.0).build();
builder.addService(s1).addService(s2); builder.addService(s1).addService(s2);
VehicleRoutingProblem vrp = builder.build(); VehicleRoutingProblem vrp = builder.build();

View file

@ -75,7 +75,7 @@
</vehicleTypes> </vehicleTypes>
<services> <services>
<service id="1" type="delivery"> <service id="1" type="service">
<locationId>j(1,5)</locationId> <locationId>j(1,5)</locationId>
<coord x="10.0" y="10.0"/> <coord x="10.0" y="10.0"/>
<capacity-demand>1</capacity-demand> <capacity-demand>1</capacity-demand>
@ -88,7 +88,7 @@
</timeWindows> </timeWindows>
</service> </service>
<service id="2" type="delivery"> <service id="2" type="service">
<locationId>i(3,9)</locationId> <locationId>i(3,9)</locationId>
<coord x="10.0" y="10.0"/> <coord x="10.0" y="10.0"/>
<capacity-demand>1</capacity-demand> <capacity-demand>1</capacity-demand>

View file

@ -50,7 +50,7 @@
</type> </type>
</vehicleTypes> </vehicleTypes>
<services> <services>
<service id="2" type="delivery"> <service id="2" type="service">
<locationId>loc2</locationId> <locationId>loc2</locationId>
<capacity-demand>1</capacity-demand> <capacity-demand>1</capacity-demand>
<duration>4.0</duration> <duration>4.0</duration>
@ -61,7 +61,7 @@
</timeWindow> </timeWindow>
</timeWindows> </timeWindows>
</service> </service>
<service id="1" type="delivery"> <service id="1" type="service">
<locationId>loc</locationId> <locationId>loc</locationId>
<capacity-demand>1</capacity-demand> <capacity-demand>1</capacity-demand>
<duration>2.0</duration> <duration>2.0</duration>
@ -82,12 +82,12 @@
<driverId>noDriver</driverId> <driverId>noDriver</driverId>
<vehicleId>v1</vehicleId> <vehicleId>v1</vehicleId>
<start>10.0</start> <start>10.0</start>
<act type="delivery"> <act type="service">
<serviceId>1</serviceId> <serviceId>1</serviceId>
<arrTime>20.0</arrTime> <arrTime>20.0</arrTime>
<endTime>30.0</endTime> <endTime>30.0</endTime>
</act> </act>
<act type="delivery"> <act type="service">
<serviceId>2</serviceId> <serviceId>2</serviceId>
<arrTime>40.0</arrTime> <arrTime>40.0</arrTime>
<endTime>80.0</endTime> <endTime>80.0</endTime>

View 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>

File diff suppressed because it is too large Load diff

View 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

View 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>

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View 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>

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View 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; package examples;
import readers.ChristofidesReader; import readers.ChristofidesReader;

View 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; package examples;
import java.io.File; import java.io.File;

View 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; package examples;
import java.io.File; import java.io.File;

View 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; package examples;
import java.io.File; import java.io.File;

View 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");
}
}

View 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 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");
}
}

View file

@ -201,7 +201,7 @@ public class RefuseCollectionExample {
VehicleRoutingProblem vrp = vrpBuilder.build(); VehicleRoutingProblem vrp = vrpBuilder.build();
VehicleRoutingAlgorithm vra = new GreedySchrimpfFactory().createAlgorithm(vrp); VehicleRoutingAlgorithm vra = new GreedySchrimpfFactory().createAlgorithm(vrp);
vra.setPrematureBreak(10); vra.setPrematureBreak(100);
Collection<VehicleRoutingProblemSolution> solutions = vra.searchSolutions(); Collection<VehicleRoutingProblemSolution> solutions = vra.searchSolutions();
SolutionPrinter.print(Solutions.getBest(solutions),Print.VERBOSE); SolutionPrinter.print(Solutions.getBest(solutions),Print.VERBOSE);

View file

@ -26,7 +26,6 @@ import java.util.Collection;
import readers.SolomonReader; import readers.SolomonReader;
import algorithms.VehicleRoutingAlgorithms; import algorithms.VehicleRoutingAlgorithms;
import algorithms.selectors.SelectBest; import algorithms.selectors.SelectBest;
import analysis.AlgorithmSearchProgressChartListener;
import analysis.SolutionPlotter; import analysis.SolutionPlotter;
import analysis.SolutionPrinter; import analysis.SolutionPrinter;
import analysis.SolutionPrinter.Print; import analysis.SolutionPrinter.Print;

View 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");
}
}

View file

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

View 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 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");
}
}

View 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 util; package util;
import java.io.BufferedReader; import java.io.BufferedReader;