mirror of
https://github.com/graphhopper/jsprit.git
synced 2020-01-24 07:45:05 +01:00
io of multiple cap constraints
This commit is contained in:
parent
a6726537e9
commit
cec4e4235e
3 changed files with 133 additions and 25 deletions
|
|
@ -35,7 +35,6 @@ import jsprit.core.problem.job.Service;
|
||||||
import jsprit.core.problem.job.Shipment;
|
import jsprit.core.problem.job.Shipment;
|
||||||
import jsprit.core.problem.solution.VehicleRoutingProblemSolution;
|
import jsprit.core.problem.solution.VehicleRoutingProblemSolution;
|
||||||
import jsprit.core.problem.solution.route.VehicleRoute;
|
import jsprit.core.problem.solution.route.VehicleRoute;
|
||||||
import jsprit.core.problem.solution.route.activity.End;
|
|
||||||
import jsprit.core.problem.solution.route.activity.TimeWindow;
|
import jsprit.core.problem.solution.route.activity.TimeWindow;
|
||||||
import jsprit.core.problem.solution.route.activity.TourActivityFactory;
|
import jsprit.core.problem.solution.route.activity.TourActivityFactory;
|
||||||
import jsprit.core.problem.vehicle.PenaltyVehicleType;
|
import jsprit.core.problem.vehicle.PenaltyVehicleType;
|
||||||
|
|
@ -60,21 +59,25 @@ import org.xml.sax.SAXException;
|
||||||
public class VrpXMLReader{
|
public class VrpXMLReader{
|
||||||
|
|
||||||
public interface ServiceBuilderFactory {
|
public interface ServiceBuilderFactory {
|
||||||
Service.Builder createBuilder(String serviceType, String id, int size);
|
Service.Builder createBuilder(String serviceType, String id, Integer size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static class DefaultServiceBuilderFactory implements ServiceBuilderFactory{
|
static class DefaultServiceBuilderFactory implements ServiceBuilderFactory{
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public jsprit.core.problem.job.Service.Builder createBuilder(String serviceType, String id, int size) {
|
public jsprit.core.problem.job.Service.Builder createBuilder(String serviceType, String id, Integer size) {
|
||||||
if(serviceType.equals("pickup")){
|
if(serviceType.equals("pickup")){
|
||||||
return Pickup.Builder.newInstance(id, size);
|
if(size != null) return Pickup.Builder.newInstance(id, size);
|
||||||
|
else return Pickup.Builder.newInstance(id);
|
||||||
}
|
}
|
||||||
else if(serviceType.equals("delivery")){
|
else if(serviceType.equals("delivery")){
|
||||||
return Delivery.Builder.newInstance(id, size);
|
if(size != null) return Delivery.Builder.newInstance(id, size);
|
||||||
|
else return Delivery.Builder.newInstance(id);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
return Service.Builder.newInstance(id, size);
|
if(size != null) return Service.Builder.newInstance(id, size);
|
||||||
|
else return Service.Builder.newInstance(id);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -238,8 +241,8 @@ public class VrpXMLReader{
|
||||||
|
|
||||||
// Start startAct = Start.newInstance(vehicle.getLocationId(), vehicle.getEarliestDeparture(), vehicle.getLatestArrival());
|
// Start startAct = Start.newInstance(vehicle.getLocationId(), vehicle.getEarliestDeparture(), vehicle.getLatestArrival());
|
||||||
// startAct.setEndTime(Double.parseDouble(start));
|
// 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.setDepartureTime(departureTime);
|
||||||
|
|
@ -313,8 +316,29 @@ public class VrpXMLReader{
|
||||||
for(HierarchicalConfiguration shipmentConfig : shipmentConfigs){
|
for(HierarchicalConfiguration shipmentConfig : shipmentConfigs){
|
||||||
String id = shipmentConfig.getString("[@id]");
|
String id = shipmentConfig.getString("[@id]");
|
||||||
if(id == null) throw new IllegalStateException("shipment[@id] is missing.");
|
if(id == null) throw new IllegalStateException("shipment[@id] is missing.");
|
||||||
int cap = getCap(shipmentConfig);
|
|
||||||
Shipment.Builder builder = Shipment.Builder.newInstance(id, cap);
|
String capacityString = shipmentConfig.getString("capacity-demand");
|
||||||
|
boolean capacityDimensionsExist = shipmentConfig.containsKey("capacity-dimensions.dimension(0)");
|
||||||
|
if(capacityString == null && !capacityDimensionsExist){
|
||||||
|
throw new IllegalStateException("capacity of shipment is not set. use 'capacity-dimensions'");
|
||||||
|
}
|
||||||
|
if(capacityString != null && capacityDimensionsExist){
|
||||||
|
throw new IllegalStateException("either use capacity or capacity-dimension, not both. prefer the use of 'capacity-dimensions' over 'capacity'.");
|
||||||
|
}
|
||||||
|
|
||||||
|
Shipment.Builder builder;
|
||||||
|
if(capacityString != null){
|
||||||
|
builder = Shipment.Builder.newInstance(id, Integer.parseInt(capacityString));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
builder = Shipment.Builder.newInstance(id);
|
||||||
|
List<HierarchicalConfiguration> dimensionConfigs = shipmentConfig.configurationsAt("capacity-dimensions");
|
||||||
|
for(HierarchicalConfiguration dimension : dimensionConfigs){
|
||||||
|
Integer index = dimension.getInt("dimension[@index]");
|
||||||
|
Integer value = dimension.getInt("dimension");
|
||||||
|
builder.addCapacityDimension(index, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//pickup-locationId
|
//pickup-locationId
|
||||||
String pickupLocationId = shipmentConfig.getString("pickup.locationId");
|
String pickupLocationId = shipmentConfig.getString("pickup.locationId");
|
||||||
|
|
@ -394,13 +418,6 @@ public class VrpXMLReader{
|
||||||
return pickupCoord;
|
return pickupCoord;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int getCap(HierarchicalConfiguration serviceConfig) {
|
|
||||||
String capacityDemand = serviceConfig.getString("capacity-demand");
|
|
||||||
int cap = 0;
|
|
||||||
if(capacityDemand != null) cap = Integer.parseInt(capacityDemand);
|
|
||||||
return cap;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void readServices(XMLConfiguration vrpProblem) {
|
private void readServices(XMLConfiguration vrpProblem) {
|
||||||
List<HierarchicalConfiguration> serviceConfigs = vrpProblem.configurationsAt("services.service");
|
List<HierarchicalConfiguration> serviceConfigs = vrpProblem.configurationsAt("services.service");
|
||||||
for(HierarchicalConfiguration serviceConfig : serviceConfigs){
|
for(HierarchicalConfiguration serviceConfig : serviceConfigs){
|
||||||
|
|
@ -408,8 +425,29 @@ public class VrpXMLReader{
|
||||||
if(id == null) throw new IllegalStateException("service[@id] is missing.");
|
if(id == null) throw new IllegalStateException("service[@id] is missing.");
|
||||||
String type = serviceConfig.getString("[@type]");
|
String type = serviceConfig.getString("[@type]");
|
||||||
if(type == null) type = "service";
|
if(type == null) type = "service";
|
||||||
int cap = getCap(serviceConfig);
|
|
||||||
Service.Builder builder = serviceBuilderFactory.createBuilder(type, id, cap);
|
String capacityString = serviceConfig.getString("capacity-demand");
|
||||||
|
boolean capacityDimensionsExist = serviceConfig.containsKey("capacity-dimensions.dimension(0)");
|
||||||
|
if(capacityString == null && !capacityDimensionsExist){
|
||||||
|
throw new IllegalStateException("capacity of service is not set. use 'capacity-dimensions'");
|
||||||
|
}
|
||||||
|
if(capacityString != null && capacityDimensionsExist){
|
||||||
|
throw new IllegalStateException("either use capacity or capacity-dimension, not both. prefer the use of 'capacity-dimensions' over 'capacity'.");
|
||||||
|
}
|
||||||
|
|
||||||
|
Service.Builder builder;
|
||||||
|
if(capacityString != null){
|
||||||
|
builder = serviceBuilderFactory.createBuilder(type, id, Integer.parseInt(capacityString));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
builder = serviceBuilderFactory.createBuilder(type, id, null);
|
||||||
|
List<HierarchicalConfiguration> dimensionConfigs = serviceConfig.configurationsAt("capacity-dimensions");
|
||||||
|
for(HierarchicalConfiguration dimension : dimensionConfigs){
|
||||||
|
Integer index = dimension.getInt("dimension[@index]");
|
||||||
|
Integer value = dimension.getInt("dimension");
|
||||||
|
builder.addCapacityDimension(index, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
String serviceLocationId = serviceConfig.getString("locationId");
|
String serviceLocationId = serviceConfig.getString("locationId");
|
||||||
if(serviceLocationId != null) builder.setLocationId(serviceLocationId);
|
if(serviceLocationId != null) builder.setLocationId(serviceLocationId);
|
||||||
Coordinate serviceCoord = getCoord(serviceConfig,"");
|
Coordinate serviceCoord = getCoord(serviceConfig,"");
|
||||||
|
|
@ -446,13 +484,34 @@ public class VrpXMLReader{
|
||||||
List<HierarchicalConfiguration> typeConfigs = vrpProblem.configurationsAt("vehicleTypes.type");
|
List<HierarchicalConfiguration> typeConfigs = vrpProblem.configurationsAt("vehicleTypes.type");
|
||||||
for(HierarchicalConfiguration typeConfig : typeConfigs){
|
for(HierarchicalConfiguration typeConfig : typeConfigs){
|
||||||
String typeId = typeConfig.getString("id");
|
String typeId = typeConfig.getString("id");
|
||||||
Integer capacity = typeConfig.getInt("capacity");
|
if(typeId == null) throw new IllegalStateException("typeId is missing.");
|
||||||
|
|
||||||
|
String capacityString = typeConfig.getString("capacity");
|
||||||
|
boolean capacityDimensionsExist = typeConfig.containsKey("capacity-dimensions.dimension(0)");
|
||||||
|
if(capacityString == null && !capacityDimensionsExist){
|
||||||
|
throw new IllegalStateException("capacity of type is not set. use 'capacity-dimensions'");
|
||||||
|
}
|
||||||
|
if(capacityString != null && capacityDimensionsExist){
|
||||||
|
throw new IllegalStateException("either use capacity or capacity-dimension, not both. prefer the use of 'capacity-dimensions' over 'capacity'.");
|
||||||
|
}
|
||||||
|
|
||||||
|
VehicleTypeImpl.Builder typeBuilder;
|
||||||
|
if(capacityString != null){
|
||||||
|
typeBuilder = VehicleTypeImpl.Builder.newInstance(typeId, Integer.parseInt(capacityString));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
typeBuilder = VehicleTypeImpl.Builder.newInstance(typeId);
|
||||||
|
List<HierarchicalConfiguration> dimensionConfigs = typeConfig.configurationsAt("capacity-dimensions");
|
||||||
|
for(HierarchicalConfiguration dimension : dimensionConfigs){
|
||||||
|
Integer index = dimension.getInt("dimension[@index]");
|
||||||
|
Integer value = dimension.getInt("dimension");
|
||||||
|
typeBuilder.addCapacityDimension(index, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
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");
|
||||||
if(typeId == null) throw new IllegalStateException("typeId is missing.");
|
|
||||||
if(capacity == null) throw new IllegalStateException("capacity is missing.");
|
|
||||||
VehicleTypeImpl.Builder typeBuilder = VehicleTypeImpl.Builder.newInstance(typeId, capacity);
|
|
||||||
if(fix != null) typeBuilder.setFixedCost(fix);
|
if(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);
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,21 @@
|
||||||
<xs:all>
|
<xs:all>
|
||||||
<xs:element name="id" type="xs:string" minOccurs="1" maxOccurs="1"/>
|
<xs:element name="id" type="xs:string" minOccurs="1" maxOccurs="1"/>
|
||||||
<xs:element name="capacity" type="xs:integer" minOccurs="0" maxOccurs="1" default="0"/>
|
<xs:element name="capacity" type="xs:integer" minOccurs="0" maxOccurs="1" default="0"/>
|
||||||
|
<xs:element name="capacity-dimensions" minOccurs="0" maxOccurs="1">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:all>
|
||||||
|
<xs:element name="dimension" minOccurs="1">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:simpleContent>
|
||||||
|
<xs:extension base="xs:integer">
|
||||||
|
<xs:attribute name="index" type="xs:integer" use="required"/>
|
||||||
|
</xs:extension>
|
||||||
|
</xs:simpleContent>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
</xs:all>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
<xs:element name="costs">
|
<xs:element name="costs">
|
||||||
<xs:complexType>
|
<xs:complexType>
|
||||||
<xs:all>
|
<xs:all>
|
||||||
|
|
@ -109,6 +124,21 @@
|
||||||
<xs:element name="locationId" type="xs:string" minOccurs="0" maxOccurs="1"/>
|
<xs:element name="locationId" type="xs:string" minOccurs="0" maxOccurs="1"/>
|
||||||
<xs:element name="coord" type="coordType" minOccurs="0" maxOccurs="1"/>
|
<xs:element name="coord" type="coordType" minOccurs="0" maxOccurs="1"/>
|
||||||
<xs:element name="capacity-demand" type="xs:integer" minOccurs="0" maxOccurs="1" default="0"/>
|
<xs:element name="capacity-demand" type="xs:integer" minOccurs="0" maxOccurs="1" default="0"/>
|
||||||
|
<xs:element name="capacity-dimensions" minOccurs="0" maxOccurs="1">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:all>
|
||||||
|
<xs:element name="dimension" minOccurs="1">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:simpleContent>
|
||||||
|
<xs:extension base="xs:integer">
|
||||||
|
<xs:attribute name="index" type="xs:integer" use="required"/>
|
||||||
|
</xs:extension>
|
||||||
|
</xs:simpleContent>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
</xs:all>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
<xs:element name="duration" type="xs:decimal" minOccurs="0" maxOccurs="1" default="0.0"/>
|
<xs:element name="duration" type="xs:decimal" minOccurs="0" maxOccurs="1" default="0.0"/>
|
||||||
<xs:element name="timeWindows" minOccurs="0" maxOccurs="1">
|
<xs:element name="timeWindows" minOccurs="0" maxOccurs="1">
|
||||||
<xs:complexType>
|
<xs:complexType>
|
||||||
|
|
@ -166,6 +196,21 @@
|
||||||
</xs:complexType>
|
</xs:complexType>
|
||||||
</xs:element>
|
</xs:element>
|
||||||
<xs:element name="capacity-demand" type="xs:integer" minOccurs="1" maxOccurs="1"/>
|
<xs:element name="capacity-demand" type="xs:integer" minOccurs="1" maxOccurs="1"/>
|
||||||
|
<xs:element name="capacity-dimensions" minOccurs="0" maxOccurs="1">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:all>
|
||||||
|
<xs:element name="dimension" minOccurs="1">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:simpleContent>
|
||||||
|
<xs:extension base="xs:integer">
|
||||||
|
<xs:attribute name="index" type="xs:integer" use="required"/>
|
||||||
|
</xs:extension>
|
||||||
|
</xs:simpleContent>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
</xs:all>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
</xs:sequence>
|
</xs:sequence>
|
||||||
<xs:attribute name="id" type="xs:string" use="required" />
|
<xs:attribute name="id" type="xs:string" use="required" />
|
||||||
</xs:complexType>
|
</xs:complexType>
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,9 @@
|
||||||
<vehicleTypes>
|
<vehicleTypes>
|
||||||
<type>
|
<type>
|
||||||
<id>vehType</id>
|
<id>vehType</id>
|
||||||
<capacity>20</capacity>
|
<capacity-dimensions>
|
||||||
|
<dimension index="1">20</dimension>
|
||||||
|
</capacity-dimensions>
|
||||||
<costs>
|
<costs>
|
||||||
<fixed>0.0</fixed>
|
<fixed>0.0</fixed>
|
||||||
<distance>0.0</distance>
|
<distance>0.0</distance>
|
||||||
|
|
@ -111,7 +113,9 @@
|
||||||
<service id="1" type="service">
|
<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-dimensions>
|
||||||
|
<dimension index="1">1</dimension>
|
||||||
|
</capacity-dimensions>
|
||||||
<duration>10.0</duration>
|
<duration>10.0</duration>
|
||||||
<timeWindows>
|
<timeWindows>
|
||||||
<timeWindow>
|
<timeWindow>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue