mirror of
https://github.com/graphhopper/jsprit.git
synced 2020-01-24 07:45:05 +01:00
modify io to read and write shipments, add tests to test reader/writer
This commit is contained in:
parent
d06f6ddc4b
commit
3740225058
14 changed files with 514 additions and 62 deletions
|
|
@ -228,11 +228,14 @@ public class VehicleRoutingProblem {
|
|||
/**
|
||||
* Adds a job which is either a service or a shipment.
|
||||
*
|
||||
* <p>Note that job.getId() must be unique, i.e. no job (either it is a shipment or a service) is allowed to have an already allocated id.
|
||||
*
|
||||
* @param job
|
||||
* @return
|
||||
* @throws IllegalStateException if job is neither a shipment or a service.
|
||||
* @throws IllegalStateException if job is neither a shipment or a service, or jobId has already been added.
|
||||
*/
|
||||
public Builder addJob(Job job) {
|
||||
if(jobs.containsKey(job.getId())) throw new IllegalStateException("jobList already contains a job with id " + job.getId() + ". make sure you use unique ids for your jobs (i.e. service and shipments)");
|
||||
if(job instanceof Service) {
|
||||
addService((Service) job);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,18 +42,17 @@ import basics.VehicleRoutingProblem;
|
|||
import basics.VehicleRoutingProblem.FleetComposition;
|
||||
import basics.VehicleRoutingProblem.FleetSize;
|
||||
import basics.VehicleRoutingProblemSolution;
|
||||
import basics.route.DefaultTourActivityFactory;
|
||||
import basics.route.Driver;
|
||||
import basics.route.DriverImpl;
|
||||
import basics.route.End;
|
||||
import basics.route.Start;
|
||||
import basics.route.TimeWindow;
|
||||
import basics.route.TourActivity;
|
||||
import basics.route.TourActivityFactory;
|
||||
import basics.route.Vehicle;
|
||||
import basics.route.VehicleImpl;
|
||||
import basics.route.VehicleImpl.Builder;
|
||||
import basics.route.VehicleRoute;
|
||||
import basics.route.VehicleRouteBuilder;
|
||||
import basics.route.VehicleTypeImpl;
|
||||
|
||||
public class VrpXMLReader{
|
||||
|
|
@ -125,21 +124,21 @@ public class VrpXMLReader{
|
|||
|
||||
private Map<String, Service> serviceMap;
|
||||
|
||||
private Map<String, Shipment> shipmentMap;
|
||||
|
||||
private boolean schemaValidation = true;
|
||||
|
||||
private Collection<VehicleRoutingProblemSolution> solutions;
|
||||
|
||||
private ServiceBuilderFactory serviceBuilderFactory = new DefaultServiceBuilderFactory();
|
||||
|
||||
private TourActivityFactory tourActivityFactory = new DefaultTourActivityFactory();
|
||||
|
||||
private Collection<JobConfigReader> jobConfigReaders = new ArrayList<VrpXMLReader.JobConfigReader>();
|
||||
|
||||
|
||||
public void addJobConfigReader(JobConfigReader reader){
|
||||
jobConfigReaders.add(reader);
|
||||
}
|
||||
public void setTourActivityFactory(TourActivityFactory tourActivityFactory){
|
||||
this.tourActivityFactory = tourActivityFactory;
|
||||
}
|
||||
|
||||
public void setServiceBuilderFactory(ServiceBuilderFactory serviceBuilderFactory){
|
||||
|
|
@ -157,6 +156,7 @@ public class VrpXMLReader{
|
|||
this.vrpBuilder = vrpBuilder;
|
||||
this.vehicleMap = new HashMap<String, Vehicle>();
|
||||
this.serviceMap = new HashMap<String, Service>();
|
||||
this.shipmentMap = new HashMap<String, Shipment>();
|
||||
this.solutions = solutions;
|
||||
}
|
||||
|
||||
|
|
@ -164,6 +164,7 @@ public class VrpXMLReader{
|
|||
this.vrpBuilder = vrpBuilder;
|
||||
this.vehicleMap = new HashMap<String, Vehicle>();
|
||||
this.serviceMap = new HashMap<String, Service>();
|
||||
this.shipmentMap = new HashMap<String, Shipment>();
|
||||
this.solutions = null;
|
||||
}
|
||||
|
||||
|
|
@ -207,6 +208,7 @@ public class VrpXMLReader{
|
|||
|
||||
readShipments(xmlConfig);
|
||||
readServices(xmlConfig);
|
||||
|
||||
readSolutions(xmlConfig);
|
||||
}
|
||||
|
||||
|
|
@ -234,28 +236,36 @@ public class VrpXMLReader{
|
|||
startAct.setEndTime(Double.parseDouble(start));
|
||||
End endAct = End.newInstance(vehicle.getLocationId(), vehicle.getEarliestDeparture(), vehicle.getLatestArrival());
|
||||
endAct.setArrTime(Double.parseDouble(end));
|
||||
VehicleRoute.Builder routeBuilder = VehicleRoute.Builder.newInstance(startAct, endAct);
|
||||
routeBuilder.setDriver(driver);
|
||||
routeBuilder.setVehicle(vehicle);
|
||||
|
||||
VehicleRouteBuilder routeBuilder = new VehicleRouteBuilder(vehicle, driver);
|
||||
List<HierarchicalConfiguration> actConfigs = routeConfig.configurationsAt("act");
|
||||
for(HierarchicalConfiguration actConfig : actConfigs){
|
||||
String type = actConfig.getString("[@type]");
|
||||
if(type == null) throw new IllegalStateException("act[@type] is missing.");
|
||||
|
||||
String arrTimeS = actConfig.getString("arrTime");
|
||||
if(arrTimeS == null) throw new IllegalStateException("act.arrTime is missing.");
|
||||
String endTimeS = actConfig.getString("endTime");
|
||||
if(endTimeS == null) throw new IllegalStateException("act.endTime is missing.");
|
||||
double arrTime = Double.parseDouble(arrTimeS);
|
||||
double endTime = Double.parseDouble(endTimeS);
|
||||
String serviceId = actConfig.getString("serviceId");
|
||||
if(serviceId != null) {
|
||||
Service service = getService(serviceId);
|
||||
String arrTime = actConfig.getString("arrTime");
|
||||
if(arrTime == null) throw new IllegalStateException("act.arrTime is missing.");
|
||||
String endTime = actConfig.getString("endTime");
|
||||
if(endTime == null) throw new IllegalStateException("act.endTime is missing.");
|
||||
TourActivity tourActivity = tourActivityFactory.createActivity(service);
|
||||
tourActivity.setArrTime(Double.parseDouble(arrTime));
|
||||
tourActivity.setEndTime(Double.parseDouble(endTime));
|
||||
routeBuilder.addActivity(tourActivity);
|
||||
routeBuilder.addService(service, arrTime, endTime);
|
||||
}
|
||||
else{
|
||||
String shipmentId = actConfig.getString("shipmentId");
|
||||
if(shipmentId == null) throw new IllegalStateException("either serviceId or shipmentId is missing");
|
||||
Shipment shipment = getShipment(shipmentId);
|
||||
if(shipment == null) throw new IllegalStateException("shipment with id " + shipmentId + " does not exist.");
|
||||
if(type.equals("pickupShipment")){
|
||||
routeBuilder.addPickup(shipment, arrTime, endTime);
|
||||
}
|
||||
else if(type.equals("deliverShipment")){
|
||||
routeBuilder.addDelivery(shipment, arrTime, endTime);
|
||||
}
|
||||
else throw new IllegalStateException("type " + type + " is not supported. Use 'pickupShipment' or 'deliverShipment' here");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -266,6 +276,9 @@ public class VrpXMLReader{
|
|||
}
|
||||
}
|
||||
|
||||
private Shipment getShipment(String shipmentId) {
|
||||
return shipmentMap.get(shipmentId);
|
||||
}
|
||||
private Service getService(String serviceId) {
|
||||
return serviceMap.get(serviceId);
|
||||
}
|
||||
|
|
@ -328,6 +341,9 @@ public class VrpXMLReader{
|
|||
builder.setPickupLocation(deliveryCoord.toString());
|
||||
}
|
||||
}
|
||||
Shipment shipment = builder.build();
|
||||
vrpBuilder.addJob(shipment);
|
||||
shipmentMap .put(shipment.getId(),shipment);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ import org.w3c.dom.Element;
|
|||
|
||||
import basics.Job;
|
||||
import basics.Service;
|
||||
import basics.Shipment;
|
||||
import basics.VehicleRoutingProblem;
|
||||
import basics.VehicleRoutingProblemSolution;
|
||||
import basics.route.TourActivity;
|
||||
|
|
@ -79,7 +80,8 @@ public class VrpXMLWriter {
|
|||
|
||||
writeProblemType(xmlConfig);
|
||||
writeVehiclesAndTheirTypes(xmlConfig);
|
||||
writerServices(xmlConfig);
|
||||
writeServices(xmlConfig);
|
||||
writeShipments(xmlConfig);
|
||||
writeSolutions(xmlConfig);
|
||||
|
||||
OutputFormat format = new OutputFormat();
|
||||
|
|
@ -129,7 +131,16 @@ public class VrpXMLWriter {
|
|||
for(TourActivity act : route.getTourActivities().getActivities()){
|
||||
xmlConfig.setProperty(solutionPath + "(" + counter + ").routes.route(" + routeCounter + ").act("+actCounter+")[@type]", act.getName());
|
||||
if(act instanceof JobActivity){
|
||||
xmlConfig.setProperty(solutionPath + "(" + counter + ").routes.route(" + routeCounter + ").act("+actCounter+").serviceId", ((JobActivity) act).getJob().getId());
|
||||
Job job = ((JobActivity) act).getJob();
|
||||
if(job instanceof Service){
|
||||
xmlConfig.setProperty(solutionPath + "(" + counter + ").routes.route(" + routeCounter + ").act("+actCounter+").serviceId", job.getId());
|
||||
}
|
||||
else if(job instanceof Shipment){
|
||||
xmlConfig.setProperty(solutionPath + "(" + counter + ").routes.route(" + routeCounter + ").act("+actCounter+").shipmentId", job.getId());
|
||||
}
|
||||
else{
|
||||
throw new IllegalStateException("cannot write solution correctly since job-type is not know. make sure you use either service or shipment, or another writer");
|
||||
}
|
||||
}
|
||||
xmlConfig.setProperty(solutionPath + "(" + counter + ").routes.route(" + routeCounter + ").act("+actCounter+").arrTime", act.getArrTime());
|
||||
xmlConfig.setProperty(solutionPath + "(" + counter + ").routes.route(" + routeCounter + ").act("+actCounter+").endTime", act.getEndTime());
|
||||
|
|
@ -142,10 +153,11 @@ public class VrpXMLWriter {
|
|||
}
|
||||
}
|
||||
|
||||
private void writerServices(XMLConf xmlConfig) {
|
||||
private void writeServices(XMLConf xmlConfig) {
|
||||
String shipmentPathString = "services.service";
|
||||
int counter = 0;
|
||||
for(Job j : vrp.getJobs().values()){
|
||||
if(!(j instanceof Service)) continue;
|
||||
Service service = (Service) j;
|
||||
xmlConfig.setProperty(shipmentPathString + "("+counter+")[@id]", service.getId());
|
||||
xmlConfig.setProperty(shipmentPathString + "("+counter+")[@type]", service.getType());
|
||||
|
|
@ -161,8 +173,41 @@ public class VrpXMLWriter {
|
|||
|
||||
counter++;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void writeShipments(XMLConf xmlConfig) {
|
||||
String shipmentPathString = "shipments.shipment";
|
||||
int counter = 0;
|
||||
for(Job j : vrp.getJobs().values()){
|
||||
if(!(j instanceof Shipment)) continue;
|
||||
Shipment shipment = (Shipment) j;
|
||||
xmlConfig.setProperty(shipmentPathString + "("+counter+")[@id]", shipment.getId());
|
||||
// xmlConfig.setProperty(shipmentPathString + "("+counter+")[@type]", service.getType());
|
||||
if(shipment.getPickupLocation() != null) xmlConfig.setProperty(shipmentPathString + "("+counter+").pickup.locationId", shipment.getPickupLocation());
|
||||
if(shipment.getPickupCoord() != null) {
|
||||
xmlConfig.setProperty(shipmentPathString + "("+counter+").pickup.coord[@x]", shipment.getPickupCoord().getX());
|
||||
xmlConfig.setProperty(shipmentPathString + "("+counter+").pickup.coord[@y]", shipment.getPickupCoord().getY());
|
||||
}
|
||||
|
||||
xmlConfig.setProperty(shipmentPathString + "("+counter+").pickup.duration", shipment.getPickupServiceTime());
|
||||
xmlConfig.setProperty(shipmentPathString + "("+counter+").pickup.timeWindows.timeWindow(0).start", shipment.getPickupTimeWindow().getStart());
|
||||
xmlConfig.setProperty(shipmentPathString + "("+counter+").pickup.timeWindows.timeWindow(0).end", shipment.getPickupTimeWindow().getEnd());
|
||||
|
||||
|
||||
if(shipment.getDeliveryLocation() != null) xmlConfig.setProperty(shipmentPathString + "("+counter+").delivery.locationId", shipment.getDeliveryLocation());
|
||||
if(shipment.getDeliveryCoord() != null) {
|
||||
xmlConfig.setProperty(shipmentPathString + "("+counter+").delivery.coord[@x]", shipment.getDeliveryCoord().getX());
|
||||
xmlConfig.setProperty(shipmentPathString + "("+counter+").delivery.coord[@y]", shipment.getDeliveryCoord().getY());
|
||||
}
|
||||
|
||||
xmlConfig.setProperty(shipmentPathString + "("+counter+").delivery.duration", shipment.getDeliveryServiceTime());
|
||||
xmlConfig.setProperty(shipmentPathString + "("+counter+").delivery.timeWindows.timeWindow(0).start", shipment.getDeliveryTimeWindow().getStart());
|
||||
xmlConfig.setProperty(shipmentPathString + "("+counter+").delivery.timeWindows.timeWindow(0).end", shipment.getDeliveryTimeWindow().getEnd());
|
||||
|
||||
|
||||
xmlConfig.setProperty(shipmentPathString + "("+counter+").capacity-demand", shipment.getCapacityDemand());
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
|
||||
private void writeProblemType(XMLConfiguration xmlConfig){
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ public final class DeliverShipment implements DeliveryActivity{
|
|||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "DeliverShipment";
|
||||
return "deliverShipment";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ public final class PickupShipment implements PickupActivity{
|
|||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "PickupShipment";
|
||||
return "pickupShipment";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -62,7 +62,15 @@ public class VehicleRouteBuilder {
|
|||
}
|
||||
|
||||
public VehicleRouteBuilder addService(Service service){
|
||||
tourActivities.addActivity(serviceActivityFactory.createActivity(service));
|
||||
addService(service,0.0,0.0);
|
||||
return this;
|
||||
}
|
||||
|
||||
public VehicleRouteBuilder addService(Service service, double arrTime, double endTime){
|
||||
TourActivity act = serviceActivityFactory.createActivity(service);
|
||||
act.setArrTime(arrTime);
|
||||
act.setEndTime(endTime);
|
||||
tourActivities.addActivity(act);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
@ -74,8 +82,23 @@ public class VehicleRouteBuilder {
|
|||
* @return
|
||||
*/
|
||||
public VehicleRouteBuilder addPickup(Shipment shipment){
|
||||
addPickup(shipment,0.0,0.0);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a the pickup of the specified shipment at specified arrival and end-time.
|
||||
*
|
||||
* @param shipment
|
||||
* @throws IllegalStateException if method has already been called with the specified shipment.
|
||||
* @return
|
||||
*/
|
||||
public VehicleRouteBuilder addPickup(Shipment shipment, double arrTime, double endTime){
|
||||
if(openShipments.contains(shipment)) throw new IllegalStateException("shipment has already been added. cannot add it twice.");
|
||||
tourActivities.addActivity(shipmentActivityFactory.createPickup(shipment));
|
||||
TourActivity act = shipmentActivityFactory.createPickup(shipment);
|
||||
act.setArrTime(arrTime);
|
||||
act.setEndTime(endTime);
|
||||
tourActivities.addActivity(act);
|
||||
openShipments.add(shipment);
|
||||
return this;
|
||||
}
|
||||
|
|
@ -88,8 +111,23 @@ public class VehicleRouteBuilder {
|
|||
* @return
|
||||
*/
|
||||
public VehicleRouteBuilder addDelivery(Shipment shipment){
|
||||
addDelivery(shipment,0.0,0.0);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a the delivery of the specified shipment at a specified arrival and endTime.
|
||||
*
|
||||
* @param shipment
|
||||
* @throws IllegalStateException if specified shipment has not been picked up yet (i.e. method addPickup(shipment) has not been called yet).
|
||||
* @return
|
||||
*/
|
||||
public VehicleRouteBuilder addDelivery(Shipment shipment, double arrTime, double endTime){
|
||||
if(openShipments.contains(shipment)){
|
||||
tourActivities.addActivity(shipmentActivityFactory.createDelivery(shipment));
|
||||
TourActivity act = shipmentActivityFactory.createDelivery(shipment);
|
||||
act.setArrTime(arrTime);
|
||||
act.setEndTime(endTime);
|
||||
tourActivities.addActivity(act);
|
||||
openShipments.remove(shipment);
|
||||
}
|
||||
else{ throw new IllegalStateException("cannot deliver shipment. shipment " + shipment + " needs to be picked up first."); }
|
||||
|
|
|
|||
|
|
@ -1,24 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
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
|
||||
-->
|
||||
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.w3schools.com"
|
||||
xmlns="http://www.w3schools.com" elementFormDefault="qualified">
|
||||
|
||||
|
|
@ -99,16 +80,10 @@
|
|||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:all>
|
||||
|
||||
</xs:complexType>
|
||||
|
||||
</xs:element>
|
||||
|
||||
</xs:sequence>
|
||||
|
||||
</xs:complexType>
|
||||
|
||||
|
||||
</xs:element>
|
||||
|
||||
<xs:element name="services" minOccurs="0" maxOccurs="1">
|
||||
|
|
@ -138,6 +113,53 @@
|
|||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:element name="shipments" minOccurs="0" maxOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="shipment" minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="pickup" minOccurs="1" maxOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:all>
|
||||
<xs:element name="locationId" type="xs:string" minOccurs="1" maxOccurs="1"/>
|
||||
<xs:element name="coord" type="coordType" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element name="duration" type="xs:decimal" minOccurs="0" maxOccurs="1" default="0.0"/>
|
||||
<xs:element name="timeWindows" minOccurs="0" maxOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="timeWindow" type="timeWindowType" minOccurs="1" maxOccurs="unbounded"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:all>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="delivery" minOccurs="1" maxOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:all>
|
||||
<xs:element name="locationId" type="xs:string" minOccurs="1" maxOccurs="1"/>
|
||||
<xs:element name="coord" type="coordType" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element name="duration" type="xs:decimal" minOccurs="0" maxOccurs="1" default="0.0"/>
|
||||
<xs:element name="timeWindows" minOccurs="0" maxOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="timeWindow" type="timeWindowType" minOccurs="1" maxOccurs="unbounded"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:all>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="capacity-demand" type="xs:integer" minOccurs="1" maxOccurs="1"/>
|
||||
</xs:sequence>
|
||||
<xs:attribute name="id" type="xs:string" use="required" />
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:element name="solutions" minOccurs="0" maxOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
|
|
@ -157,11 +179,11 @@
|
|||
<xs:element name="start" type="xs:double" minOccurs="1" maxOccurs="1"/>
|
||||
<xs:element name="act" minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:complexType>
|
||||
<xs:all>
|
||||
<xs:element name="serviceId" type="xs:string" minOccurs="1" maxOccurs="1"/>
|
||||
<xs:element name="arrTime" type="xs:double" minOccurs="1" maxOccurs="1"/>
|
||||
<xs:element name="endTime" type="xs:double" minOccurs="1" maxOccurs="1"/>
|
||||
</xs:all>
|
||||
<xs:choice>
|
||||
<xs:group ref="serviceActGroup"/>
|
||||
<xs:group ref="shipmentActGroup"/>
|
||||
|
||||
</xs:choice>
|
||||
<xs:attribute name="type" type="xs:string" use="required"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
|
@ -188,6 +210,22 @@
|
|||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:group name="serviceActGroup">
|
||||
<xs:sequence>
|
||||
<xs:element name="serviceId" type="xs:string" minOccurs="1" maxOccurs="1"/>
|
||||
<xs:element name="arrTime" type="xs:double" minOccurs="1" maxOccurs="1"/>
|
||||
<xs:element name="endTime" type="xs:double" minOccurs="1" maxOccurs="1"/>
|
||||
</xs:sequence>
|
||||
</xs:group>
|
||||
|
||||
<xs:group name="shipmentActGroup">
|
||||
<xs:sequence>
|
||||
<xs:element name="shipmentId" type="xs:string" minOccurs="1" maxOccurs="1"/>
|
||||
<xs:element name="arrTime" type="xs:double" minOccurs="1" maxOccurs="1"/>
|
||||
<xs:element name="endTime" type="xs:double" minOccurs="1" maxOccurs="1"/>
|
||||
</xs:sequence>
|
||||
</xs:group>
|
||||
|
||||
<xs:complexType name="timeWindowType">
|
||||
<xs:sequence>
|
||||
<xs:element name="start" type="xs:double"/>
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ public class TestAlgorithmReader {
|
|||
config = new XMLConfiguration("src/test/resources/testConfig.xml");
|
||||
VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
|
||||
solutions = new ArrayList<VehicleRoutingProblemSolution>();
|
||||
new VrpXMLReader(vrpBuilder,solutions).read("src/test/resources/finiteVrpForReaderV2Test.xml");
|
||||
new VrpXMLReader(vrpBuilder,solutions).read("src/test/resources/finiteVrp.xml");
|
||||
vrp = vrpBuilder.build();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,12 +16,21 @@
|
|||
******************************************************************************/
|
||||
package basics.io;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import basics.VehicleRoutingProblem;
|
||||
import basics.VehicleRoutingProblem.Builder;
|
||||
import basics.VehicleRoutingProblemSolution;
|
||||
import basics.route.DeliverShipment;
|
||||
import basics.route.PickupService;
|
||||
import basics.route.PickupShipment;
|
||||
import basics.route.TourActivity;
|
||||
|
||||
public class ReaderTest {
|
||||
|
||||
|
|
@ -29,7 +38,24 @@ public class ReaderTest {
|
|||
@Test
|
||||
public void testRead_ifReaderIsCalled_itReadsSuccessfully(){
|
||||
new VrpXMLReader(VehicleRoutingProblem.Builder.newInstance(), new ArrayList<VehicleRoutingProblemSolution>()).read("src/test/resources/lui-shen-solution.xml");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRead_ifReaderIsCalled_itReadsSuccessfullyV2(){
|
||||
Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
|
||||
VehicleRoutingProblem vrp = vrpBuilder.build();
|
||||
ArrayList<VehicleRoutingProblemSolution> solutions = new ArrayList<VehicleRoutingProblemSolution>();
|
||||
new VrpXMLReader(vrpBuilder, solutions).read("src/test/resources/finiteVrpWithShipmentsAndSolution.xml");
|
||||
assertEquals(3,vrp.getJobs().size());
|
||||
assertEquals(1,solutions.size());
|
||||
|
||||
assertEquals(1,solutions.get(0).getRoutes().size());
|
||||
List<TourActivity> activities = solutions.get(0).getRoutes().iterator().next().getTourActivities().getActivities();
|
||||
assertEquals(4,activities.size());
|
||||
assertTrue(activities.get(0) instanceof PickupService);
|
||||
assertTrue(activities.get(1) instanceof PickupService);
|
||||
assertTrue(activities.get(2) instanceof PickupShipment);
|
||||
assertTrue(activities.get(3) instanceof DeliverShipment);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,9 @@ import java.util.List;
|
|||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import basics.Job;
|
||||
import basics.Service;
|
||||
import basics.Shipment;
|
||||
import basics.VehicleRoutingProblem;
|
||||
import basics.VehicleRoutingProblem.FleetComposition;
|
||||
import basics.VehicleRoutingProblem.FleetSize;
|
||||
|
|
@ -110,7 +112,25 @@ public class VrpReaderV2Test {
|
|||
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
|
||||
new VrpXMLReader(builder, null).read(inFileName);
|
||||
VehicleRoutingProblem vrp = builder.build();
|
||||
assertEquals(2, vrp.getJobs().size());
|
||||
assertEquals(3, vrp.getJobs().size());
|
||||
int servCounter = 0;
|
||||
for(Job j : vrp.getJobs().values()){
|
||||
if(j instanceof Service) servCounter++;
|
||||
}
|
||||
assertEquals(2,servCounter);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenReadingShipments_itReadsThemCorrectly(){
|
||||
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
|
||||
new VrpXMLReader(builder, null).read(inFileName);
|
||||
VehicleRoutingProblem vrp = builder.build();
|
||||
assertEquals(3, vrp.getJobs().size());
|
||||
int shipCounter = 0;
|
||||
for(Job j : vrp.getJobs().values()){
|
||||
if(j instanceof Shipment) shipCounter++;
|
||||
}
|
||||
assertEquals(1,shipCounter);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -122,6 +142,6 @@ public class VrpReaderV2Test {
|
|||
assertEquals("service",s1.getType());
|
||||
assertEquals(1,s1.getCapacityDemand());
|
||||
assertEquals(0.0,s1.getServiceDuration(),0.01);
|
||||
assertEquals(2, vrp.getJobs().size());
|
||||
assertEquals(3, vrp.getJobs().size());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ public class VrpWriterV2Test {
|
|||
VehicleRoutingProblem vrp = builder.addService(s1).addService(s2).build();
|
||||
new VrpXMLWriter(vrp, null).write(infileName);
|
||||
|
||||
VehicleRoutingProblem.Builder vrpToReadBuilder = builder;
|
||||
VehicleRoutingProblem.Builder vrpToReadBuilder = VehicleRoutingProblem.Builder.newInstance();
|
||||
new VrpXMLReader(vrpToReadBuilder, null).read(infileName);
|
||||
VehicleRoutingProblem readVrp = vrpToReadBuilder.build();
|
||||
assertEquals(2,readVrp.getJobs().size());
|
||||
|
|
|
|||
89
jsprit-core/src/test/resources/finiteVrp.xml
Normal file
89
jsprit-core/src/test/resources/finiteVrp.xml
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
<?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>FINITE</fleetSize>
|
||||
<fleetComposition>HETEROGENEOUS</fleetComposition>
|
||||
</problemType>
|
||||
|
||||
<vehicles>
|
||||
<vehicle>
|
||||
<id>v1</id>
|
||||
<location>
|
||||
<id>depotLoc2</id>
|
||||
<coord x="100.0" y="100.0"/>
|
||||
</location>
|
||||
<typeId>vehType</typeId>
|
||||
<timeSchedule>
|
||||
<start>0.0</start>
|
||||
<end>1000.0</end>
|
||||
</timeSchedule>
|
||||
</vehicle>
|
||||
<vehicle>
|
||||
<id>v2</id>
|
||||
<location>
|
||||
<id>depotLoc</id>
|
||||
<coord x="10.0" y="100.0"/>
|
||||
</location>
|
||||
<typeId>vehType2</typeId>
|
||||
<timeSchedule>
|
||||
<start>0.0</start>
|
||||
<end>1000.0</end>
|
||||
</timeSchedule>
|
||||
</vehicle>
|
||||
</vehicles>
|
||||
<vehicleTypes>
|
||||
<type>
|
||||
<id>vehType</id>
|
||||
<capacity>20</capacity>
|
||||
<costs>
|
||||
<fixed>0.0</fixed>
|
||||
<distance>0.0</distance>
|
||||
<time>0.0</time>
|
||||
</costs>
|
||||
</type>
|
||||
<type>
|
||||
<id>vehType2</id>
|
||||
<capacity>200</capacity>
|
||||
<costs>
|
||||
<fixed>0.0</fixed>
|
||||
<distance>0.0</distance>
|
||||
<time>0.0</time>
|
||||
</costs>
|
||||
</type>
|
||||
</vehicleTypes>
|
||||
|
||||
<services>
|
||||
<service id="1" type="service">
|
||||
<locationId>j(1,5)</locationId>
|
||||
<coord x="10.0" y="10.0"/>
|
||||
<capacity-demand>1</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>4000.0</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
|
||||
<service id="2" type="service">
|
||||
<locationId>i(3,9)</locationId>
|
||||
<coord x="10.0" y="10.0"/>
|
||||
<capacity-demand>1</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>4000.0</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
|
||||
</services>
|
||||
|
||||
|
||||
|
||||
</problem>
|
||||
|
|
@ -102,5 +102,33 @@
|
|||
</service>
|
||||
|
||||
</services>
|
||||
|
||||
<shipments>
|
||||
<shipment id="3">
|
||||
<pickup>
|
||||
<locationId>i(3,9)</locationId>
|
||||
<coord x="10.0" y="10.0"/>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>4000.0</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</pickup>
|
||||
<delivery>
|
||||
<locationId>i(9,9)</locationId>
|
||||
<coord x="10.0" y="0.0"/>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>4000.0</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</delivery>
|
||||
<capacity-demand>1</capacity-demand>
|
||||
</shipment>
|
||||
</shipments>
|
||||
|
||||
</problem>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,149 @@
|
|||
<?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>FINITE</fleetSize>
|
||||
<fleetComposition>HETEROGENEOUS</fleetComposition>
|
||||
</problemType>
|
||||
|
||||
<vehicles>
|
||||
<vehicle>
|
||||
<id>v1</id>
|
||||
<location>
|
||||
<id>depotLoc2</id>
|
||||
<coord x="100.0" y="100.0"/>
|
||||
</location>
|
||||
<typeId>vehType</typeId>
|
||||
<timeSchedule>
|
||||
<start>0.0</start>
|
||||
<end>1000.0</end>
|
||||
</timeSchedule>
|
||||
</vehicle>
|
||||
<vehicle>
|
||||
<id>v2</id>
|
||||
<location>
|
||||
<id>depotLoc</id>
|
||||
<coord x="10.0" y="100.0"/>
|
||||
</location>
|
||||
<typeId>vehType2</typeId>
|
||||
<timeSchedule>
|
||||
<start>0.0</start>
|
||||
<end>1000.0</end>
|
||||
</timeSchedule>
|
||||
</vehicle>
|
||||
</vehicles>
|
||||
<vehicleTypes>
|
||||
<type>
|
||||
<id>vehType</id>
|
||||
<capacity>20</capacity>
|
||||
<costs>
|
||||
<fixed>0.0</fixed>
|
||||
<distance>0.0</distance>
|
||||
<time>0.0</time>
|
||||
</costs>
|
||||
</type>
|
||||
<type>
|
||||
<id>vehType2</id>
|
||||
<capacity>200</capacity>
|
||||
<costs>
|
||||
<fixed>0.0</fixed>
|
||||
<distance>0.0</distance>
|
||||
<time>0.0</time>
|
||||
</costs>
|
||||
</type>
|
||||
</vehicleTypes>
|
||||
|
||||
<services>
|
||||
<service id="1" type="service">
|
||||
<locationId>j(1,5)</locationId>
|
||||
<coord x="10.0" y="10.0"/>
|
||||
<capacity-demand>1</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>4000.0</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
|
||||
<service id="2" type="service">
|
||||
<locationId>i(3,9)</locationId>
|
||||
<coord x="10.0" y="10.0"/>
|
||||
<capacity-demand>1</capacity-demand>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>4000.0</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</service>
|
||||
</services>
|
||||
|
||||
<shipments>
|
||||
<shipment id="3">
|
||||
<pickup>
|
||||
<locationId>i(3,9)</locationId>
|
||||
<coord x="10.0" y="10.0"/>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>4000.0</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</pickup>
|
||||
<delivery>
|
||||
<locationId>i(9,9)</locationId>
|
||||
<coord x="10.0" y="0.0"/>
|
||||
<duration>0.0</duration>
|
||||
<timeWindows>
|
||||
<timeWindow>
|
||||
<start>0.0</start>
|
||||
<end>4000.0</end>
|
||||
</timeWindow>
|
||||
</timeWindows>
|
||||
</delivery>
|
||||
<capacity-demand>1</capacity-demand>
|
||||
</shipment>
|
||||
</shipments>
|
||||
|
||||
<solutions>
|
||||
<solution>
|
||||
<cost>100.0</cost>
|
||||
<routes>
|
||||
<route>
|
||||
<cost>0.0</cost>
|
||||
<driverId>noDriver</driverId>
|
||||
<vehicleId>v1</vehicleId>
|
||||
<start>10.0</start>
|
||||
<act type="service">
|
||||
<serviceId>1</serviceId>
|
||||
<arrTime>20.0</arrTime>
|
||||
<endTime>30.0</endTime>
|
||||
</act>
|
||||
<act type="service">
|
||||
<serviceId>2</serviceId>
|
||||
<arrTime>40.0</arrTime>
|
||||
<endTime>80.0</endTime>
|
||||
</act>
|
||||
<act type="pickupShipment">
|
||||
<shipmentId>3</shipmentId>
|
||||
<arrTime>40.0</arrTime>
|
||||
<endTime>80.0</endTime>
|
||||
</act>
|
||||
<act type="deliverShipment">
|
||||
<shipmentId>3</shipmentId>
|
||||
<arrTime>40.0</arrTime>
|
||||
<endTime>80.0</endTime>
|
||||
</act>
|
||||
<end>100.0</end>
|
||||
</route>
|
||||
</routes>
|
||||
</solution>
|
||||
</solutions>
|
||||
|
||||
</problem>
|
||||
Loading…
Add table
Add a link
Reference in a new issue