1
0
Fork 0
mirror of https://github.com/graphhopper/jsprit.git synced 2020-01-24 07:45:05 +01:00

modify reader/writer to deal with open routes and add examples

This commit is contained in:
oblonski 2013-11-29 08:27:30 +01:00
parent 4e25d894b6
commit f662e5a469
9 changed files with 1434 additions and 18 deletions

View file

@ -60,13 +60,13 @@ class Inserter {
@Override @Override
public void handleJobInsertion(Job job, InsertionData iData, VehicleRoute route) { public void handleJobInsertion(Job job, InsertionData iData, VehicleRoute route) {
if(job instanceof Service){ if(job instanceof Service){
route.getTourActivities().addActivity(iData.getDeliveryInsertionIndex(), this.activityFactory.createActivity((Service)job));
route.setDepartureTime(iData.getVehicleDepartureTime());
if(!iData.getSelectedVehicle().isReturnToDepot()){ if(!iData.getSelectedVehicle().isReturnToDepot()){
if(iData.getDeliveryInsertionIndex()>=route.getTourActivities().getActivities().size()){ if(iData.getDeliveryInsertionIndex()>=route.getTourActivities().getActivities().size()){
setEndLocation(route,(Service)job); setEndLocation(route,(Service)job);
} }
} }
route.getTourActivities().addActivity(iData.getDeliveryInsertionIndex(), this.activityFactory.createActivity((Service)job));
route.setDepartureTime(iData.getVehicleDepartureTime());
} }
else delegator.handleJobInsertion(job, iData, route); else delegator.handleJobInsertion(job, iData, route);
} }
@ -93,14 +93,14 @@ class Inserter {
if(job instanceof Shipment){ if(job instanceof Shipment){
TourActivity pickupShipment = this.activityFactory.createPickup((Shipment)job); TourActivity pickupShipment = this.activityFactory.createPickup((Shipment)job);
TourActivity deliverShipment = this.activityFactory.createDelivery((Shipment)job); TourActivity deliverShipment = this.activityFactory.createDelivery((Shipment)job);
route.getTourActivities().addActivity(iData.getDeliveryInsertionIndex(), deliverShipment);
route.getTourActivities().addActivity(iData.getPickupInsertionIndex(), pickupShipment);
route.setDepartureTime(iData.getVehicleDepartureTime());
if(!iData.getSelectedVehicle().isReturnToDepot()){ if(!iData.getSelectedVehicle().isReturnToDepot()){
if(iData.getDeliveryInsertionIndex()>=route.getTourActivities().getActivities().size()){ if(iData.getDeliveryInsertionIndex()>=route.getTourActivities().getActivities().size()){
setEndLocation(route,(Shipment)job); setEndLocation(route,(Shipment)job);
} }
} }
route.getTourActivities().addActivity(iData.getDeliveryInsertionIndex(), deliverShipment);
route.getTourActivities().addActivity(iData.getPickupInsertionIndex(), pickupShipment);
route.setDepartureTime(iData.getVehicleDepartureTime());
} }
else delegator.handleJobInsertion(job, iData, route); else delegator.handleJobInsertion(job, iData, route);
} }

View file

@ -230,14 +230,19 @@ public class VrpXMLReader{
if(vehicle == null) throw new IllegalStateException("vehicle is missing."); if(vehicle == null) throw new IllegalStateException("vehicle is missing.");
String start = routeConfig.getString("start"); String start = routeConfig.getString("start");
if(start == null) throw new IllegalStateException("route start-time is missing."); if(start == null) throw new IllegalStateException("route start-time is missing.");
double departureTime = Double.parseDouble(start);
String end = routeConfig.getString("end"); String end = routeConfig.getString("end");
if(end == null) throw new IllegalStateException("route end-time is missing."); if(end == null) throw new IllegalStateException("route end-time is missing.");
Start startAct = Start.newInstance(vehicle.getLocationId(), vehicle.getEarliestDeparture(), vehicle.getLatestArrival());
startAct.setEndTime(Double.parseDouble(start)); // Start startAct = Start.newInstance(vehicle.getLocationId(), vehicle.getEarliestDeparture(), vehicle.getLatestArrival());
// startAct.setEndTime(Double.parseDouble(start));
End endAct = End.newInstance(vehicle.getLocationId(), vehicle.getEarliestDeparture(), vehicle.getLatestArrival()); End endAct = End.newInstance(vehicle.getLocationId(), vehicle.getEarliestDeparture(), vehicle.getLatestArrival());
endAct.setArrTime(Double.parseDouble(end)); endAct.setArrTime(Double.parseDouble(end));
VehicleRoute.Builder routeBuilder = VehicleRoute.Builder.newInstance(vehicle, driver); VehicleRoute.Builder routeBuilder = VehicleRoute.Builder.newInstance(vehicle, driver);
routeBuilder.setDepartureTime(departureTime);
routeBuilder.setRouteEndArrivalTime(Double.parseDouble(end));
List<HierarchicalConfiguration> actConfigs = routeConfig.configurationsAt("act"); List<HierarchicalConfiguration> actConfigs = routeConfig.configurationsAt("act");
for(HierarchicalConfiguration actConfig : actConfigs){ for(HierarchicalConfiguration actConfig : actConfigs){
String type = actConfig.getString("[@type]"); String type = actConfig.getString("[@type]");
@ -466,6 +471,10 @@ public class VrpXMLReader{
String end = vehicleConfig.getString("timeSchedule.end"); String end = vehicleConfig.getString("timeSchedule.end");
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));
String returnToDepot = vehicleConfig.getString("returnToDepot");
if(returnToDepot != null){
builder.setReturnToDepot(vehicleConfig.getBoolean("returnToDepot"));
}
VehicleImpl vehicle = builder.build(); VehicleImpl vehicle = builder.build();
vrpBuilder.addVehicle(vehicle); vrpBuilder.addVehicle(vehicle);
vehicleMap.put(vehicleId, vehicle); vehicleMap.put(vehicleId, vehicle);

View file

@ -234,6 +234,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());
xmlConfig.setProperty(vehiclePathString + "("+counter+").returnToDepot", vehicle.isReturnToDepot());
counter++; counter++;
} }

View file

@ -61,6 +61,8 @@ public class VehicleRoute {
private Start start; private Start start;
private End end;
private TourActivities tourActivities = new TourActivities(); private TourActivities tourActivities = new TourActivities();
private TourActivityFactory serviceActivityFactory = new DefaultTourActivityFactory(); private TourActivityFactory serviceActivityFactory = new DefaultTourActivityFactory();
@ -79,6 +81,10 @@ public class VehicleRoute {
/** /**
* Constructs the route-builder. * Constructs the route-builder.
*
* <p>Default startLocation is vehicle.getLocationId()<br>
* Default departureTime is vehicle.getEarliestDeparture()<br>
* Default endLocation is either vehicle.getLocationId() or (if !vehicle.isReturnToDepot()) last specified activityLocation
* @param vehicle * @param vehicle
* @param driver * @param driver
*/ */
@ -88,7 +94,7 @@ public class VehicleRoute {
this.driver = driver; this.driver = driver;
start = Start.newInstance(vehicle.getLocationId(), vehicle.getEarliestDeparture(), vehicle.getLatestArrival()); start = Start.newInstance(vehicle.getLocationId(), vehicle.getEarliestDeparture(), vehicle.getLatestArrival());
start.setEndTime(vehicle.getEarliestDeparture()); start.setEndTime(vehicle.getEarliestDeparture());
End.newInstance(vehicle.getLocationId(), vehicle.getEarliestDeparture(), vehicle.getLatestArrival()); end = End.newInstance(vehicle.getLocationId(), vehicle.getEarliestDeparture(), vehicle.getLatestArrival());
} }
/** /**
@ -102,6 +108,11 @@ public class VehicleRoute {
return this; return this;
} }
public Builder setRouteEndArrivalTime(double endTime){
end.setArrTime(endTime);
return this;
}
public Builder addService(Service service){ public Builder addService(Service service){
addService(service,0.0,0.0); addService(service,0.0,0.0);
return this; return this;
@ -185,7 +196,12 @@ public class VehicleRoute {
if(!openShipments.isEmpty()){ if(!openShipments.isEmpty()){
throw new IllegalStateException("there are still shipments that have not been delivered yet."); throw new IllegalStateException("there are still shipments that have not been delivered yet.");
} }
VehicleRoute route = VehicleRoute.newInstance(tourActivities, driver, vehicle); if(!vehicle.isReturnToDepot()){
if(!tourActivities.isEmpty()){
end.setLocationId(tourActivities.getActivities().get(tourActivities.getActivities().size()-1).getLocationId());
}
}
VehicleRoute route = new VehicleRoute(this);
return route; return route;
} }
@ -218,13 +234,14 @@ public class VehicleRoute {
setStartAndEnd(vehicle, vehicle.getEarliestDeparture()); setStartAndEnd(vehicle, vehicle.getEarliestDeparture());
} }
// private VehicleRoute(Builder builder){
// this.tourActivities = builder.tour; private VehicleRoute(Builder builder){
// this.vehicle = builder.vehicle; this.tourActivities = builder.tourActivities;
// this.driver = builder.driver; this.vehicle = builder.vehicle;
// this.start = builder.start; this.driver = builder.driver;
// this.end = builder.end; this.start = builder.start;
// } this.end = builder.end;
}
private void verify(TourActivities tour, Driver driver, Vehicle vehicle) { private void verify(TourActivities tour, Driver driver, Vehicle vehicle) {
if(tour == null || driver == null || vehicle == null) throw new IllegalStateException("null is not allowed for tour, driver or vehicle. use emptyRoute. use Tour.emptyTour, DriverImpl.noDriver() and VehicleImpl.noVehicle() instead." + if(tour == null || driver == null || vehicle == null) throw new IllegalStateException("null is not allowed for tour, driver or vehicle. use emptyRoute. use Tour.emptyTour, DriverImpl.noDriver() and VehicleImpl.noVehicle() instead." +

View file

@ -53,7 +53,7 @@
</xs:element> </xs:element>
<xs:element name="typeId" type="xs:string" minOccurs="1" maxOccurs="1"/> <xs:element name="typeId" type="xs:string" minOccurs="1" maxOccurs="1"/>
<xs:element name="timeSchedule" type="timeWindowType"/> <xs:element name="timeSchedule" type="timeWindowType"/>
<xs:element name="returnToDepot" type="xs:boolean" minOccurs="0" maxOccurs="1"/>
</xs:all> </xs:all>
</xs:complexType> </xs:complexType>
</xs:element> </xs:element>

View file

@ -0,0 +1,49 @@
<?xml version="1.0" ?>
<algorithm xmlns="http://www.w3schools.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3schools.com algorithm_schema.xsd">
<iterations>2000</iterations>
<construction>
<insertion name="bestInsertion">
<considerFixedCosts>1.0</considerFixedCosts>
</insertion>
</construction>
<strategy>
<memory>1</memory>
<searchStrategies>
<searchStrategy name="randomRuinAndRecreate">
<selector name="selectBest"/>
<acceptor name="acceptNewRemoveWorst"/>
<modules>
<module name="ruin_and_recreate">
<ruin name="randomRuin">
<share>0.5</share>
</ruin>
<insertion name="bestInsertion"/>
</module>
</modules>
<probability>0.5</probability>
</searchStrategy>
<searchStrategy name="radialRuinAndRecreate">
<selector name="selectBest"/>
<acceptor name="acceptNewRemoveWorst"/>
<modules>
<module name="ruin_and_recreate">
<ruin name="radialRuin">
<share>0.3</share>
</ruin>
<insertion name="bestInsertion"/>
</module>
</modules>
<probability>0.5</probability>
</searchStrategy>
</searchStrategies>
</strategy>
</algorithm>

File diff suppressed because it is too large Load diff

View file

@ -23,6 +23,7 @@ import jsprit.analysis.toolbox.SolutionPlotter;
import jsprit.analysis.toolbox.SolutionPrinter; import jsprit.analysis.toolbox.SolutionPrinter;
import jsprit.core.algorithm.VehicleRoutingAlgorithm; import jsprit.core.algorithm.VehicleRoutingAlgorithm;
import jsprit.core.algorithm.box.SchrimpfFactory; import jsprit.core.algorithm.box.SchrimpfFactory;
import jsprit.core.algorithm.io.VehicleRoutingAlgorithms;
import jsprit.core.problem.VehicleRoutingProblem; import jsprit.core.problem.VehicleRoutingProblem;
import jsprit.core.problem.io.VrpXMLWriter; import jsprit.core.problem.io.VrpXMLWriter;
import jsprit.core.problem.job.Service; import jsprit.core.problem.job.Service;
@ -54,6 +55,7 @@ public class SimpleExampleOpenRoutes {
* get a vehicle type-builder and build a type with the typeId "vehicleType" and a capacity of 2 * get a vehicle type-builder and build a type with the typeId "vehicleType" and a capacity of 2
*/ */
VehicleTypeImpl.Builder vehicleTypeBuilder = VehicleTypeImpl.Builder.newInstance("vehicleType", 2); VehicleTypeImpl.Builder vehicleTypeBuilder = VehicleTypeImpl.Builder.newInstance("vehicleType", 2);
vehicleTypeBuilder.setFixedCost(100);
VehicleType vehicleType = vehicleTypeBuilder.build(); VehicleType vehicleType = vehicleTypeBuilder.build();
/* /*
@ -63,6 +65,7 @@ public class SimpleExampleOpenRoutes {
vehicleBuilder.setLocationCoord(Coordinate.newInstance(10, 10)); vehicleBuilder.setLocationCoord(Coordinate.newInstance(10, 10));
vehicleBuilder.setType(vehicleType); vehicleBuilder.setType(vehicleType);
vehicleBuilder.setReturnToDepot(false); vehicleBuilder.setReturnToDepot(false);
Vehicle vehicle = vehicleBuilder.build(); Vehicle vehicle = vehicleBuilder.build();
/* /*
@ -84,7 +87,7 @@ public class SimpleExampleOpenRoutes {
/* /*
* get the algorithm out-of-the-box. * get the algorithm out-of-the-box.
*/ */
VehicleRoutingAlgorithm algorithm = new SchrimpfFactory().createAlgorithm(problem); VehicleRoutingAlgorithm algorithm = VehicleRoutingAlgorithms.readAndCreateAlgorithm(problem, "input/algorithmConfig_fix.xml");
/* /*
* and search a solution * and search a solution

View file

@ -0,0 +1,101 @@
/*******************************************************************************
* Copyright (C) 2013 Stefan Schroeder
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
package jsprit.examples;
import java.io.File;
import java.util.Collection;
import jsprit.analysis.toolbox.SolutionPlotter;
import jsprit.analysis.toolbox.SolutionPrinter;
import jsprit.core.algorithm.VehicleRoutingAlgorithm;
import jsprit.core.algorithm.io.VehicleRoutingAlgorithms;
import jsprit.core.algorithm.selector.SelectBest;
import jsprit.core.problem.VehicleRoutingProblem;
import jsprit.core.problem.io.VrpXMLReader;
import jsprit.core.problem.solution.VehicleRoutingProblemSolution;
import jsprit.instance.reader.SolomonReader;
public class SolomonOpenExample {
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/deliveries_solomon_open_c101.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/solomon_C101_open.png", "C101");
/*
* 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_fix.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);
/*
* Plot solution.
*/
SolutionPlotter.plotSolutionAsPNG(vrp, solution, "output/solomon_C101_open_solution.png","C101");
}
}