1
0
Fork 0
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:
oblonski 2013-10-30 08:43:01 +01:00
parent d06f6ddc4b
commit 3740225058
14 changed files with 514 additions and 62 deletions

View file

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

View file

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

View file

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

View file

@ -32,7 +32,7 @@ public final class DeliverShipment implements DeliveryActivity{
@Override
public String getName() {
return "DeliverShipment";
return "deliverShipment";
}
@Override

View file

@ -32,7 +32,7 @@ public final class PickupShipment implements PickupActivity{
@Override
public String getName() {
return "PickupShipment";
return "pickupShipment";
}
@Override

View file

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

View file

@ -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"/>

View file

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

View file

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

View file

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

View file

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

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

View file

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

View file

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