diff --git a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/io/VrpXMLReader.java b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/io/VrpXMLReader.java index 5c881726..57c3d52a 100644 --- a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/io/VrpXMLReader.java +++ b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/io/VrpXMLReader.java @@ -390,11 +390,11 @@ public class VrpXMLReader { if (pickupServiceTime != null) builder.setPickupServiceTime(Double.parseDouble(pickupServiceTime)); //pickup-tw - String pickupTWStart = shipmentConfig.getString("pickup.timeWindows.timeWindow(0).start"); - String pickupTWEnd = shipmentConfig.getString("pickup.timeWindows.timeWindow(0).end"); - if (pickupTWStart != null && pickupTWEnd != null) { - TimeWindow pickupTW = TimeWindow.newInstance(Double.parseDouble(pickupTWStart), Double.parseDouble(pickupTWEnd)); - builder.setPickupTimeWindow(pickupTW); + List pickupTWConfigs = shipmentConfig.configurationsAt("pickup.timeWindows.timeWindow"); + if (!pickupTWConfigs.isEmpty()) { + for (HierarchicalConfiguration pu_twConfig : pickupTWConfigs) { + builder.addPickupTimeWindow(TimeWindow.newInstance(pu_twConfig.getDouble("start"), pu_twConfig.getDouble("end"))); + } } //delivery location @@ -424,11 +424,11 @@ public class VrpXMLReader { if (deliveryServiceTime != null) builder.setDeliveryServiceTime(Double.parseDouble(deliveryServiceTime)); //delivery-tw - String delTWStart = shipmentConfig.getString("delivery.timeWindows.timeWindow(0).start"); - String delTWEnd = shipmentConfig.getString("delivery.timeWindows.timeWindow(0).end"); - if (delTWStart != null && delTWEnd != null) { - TimeWindow delTW = TimeWindow.newInstance(Double.parseDouble(delTWStart), Double.parseDouble(delTWEnd)); - builder.setDeliveryTimeWindow(delTW); + List deliveryTWConfigs = shipmentConfig.configurationsAt("delivery.timeWindows.timeWindow"); + if (!deliveryTWConfigs.isEmpty()) { + for (HierarchicalConfiguration dl_twConfig : deliveryTWConfigs) { + builder.addDeliveryTimeWindow(TimeWindow.newInstance(dl_twConfig.getDouble("start"), dl_twConfig.getDouble("end"))); + } } //read skills @@ -514,7 +514,7 @@ public class VrpXMLReader { List deliveryTWConfigs = serviceConfig.configurationsAt("timeWindows.timeWindow"); if (!deliveryTWConfigs.isEmpty()) { for (HierarchicalConfiguration twConfig : deliveryTWConfigs) { - builder.setTimeWindow(TimeWindow.newInstance(twConfig.getDouble("start"), twConfig.getDouble("end"))); + builder.addTimeWindow(TimeWindow.newInstance(twConfig.getDouble("start"), twConfig.getDouble("end"))); } } @@ -673,13 +673,16 @@ public class VrpXMLReader { } // read break - String breakStartString = vehicleConfig.getString("breaks.timeWindow.start"); - String breakEndString = vehicleConfig.getString("breaks.timeWindow.end"); - String breakDurationString = vehicleConfig.getString("breaks.duration"); - if(breakStartString!=null && breakEndString!=null && breakDurationString!=null ) - builder.setBreak(Break.Builder.newInstance(vehicleId) - .addTimeWindow(Double.parseDouble(breakStartString), Double.parseDouble(breakEndString)) - .setServiceTime(Double.parseDouble(breakDurationString)).build()); + List breakTWConfigs = vehicleConfig.configurationsAt("break.timeWindows.timeWindow"); + if (!breakTWConfigs.isEmpty()) { + String breakDurationString = vehicleConfig.getString("breaks.duration"); + Break.Builder current_break = Break.Builder.newInstance(vehicleId); + current_break.setServiceTime(Double.parseDouble(breakDurationString)); + for (HierarchicalConfiguration twConfig : breakTWConfigs) { + current_break.addTimeWindow(TimeWindow.newInstance(twConfig.getDouble("start"), twConfig.getDouble("end"))); + } + builder.setBreak(current_break.build()); + } //build vehicle diff --git a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/io/VrpXMLWriter.java b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/io/VrpXMLWriter.java index cb58b42c..506122d0 100644 --- a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/io/VrpXMLWriter.java +++ b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/problem/io/VrpXMLWriter.java @@ -25,6 +25,7 @@ import com.graphhopper.jsprit.core.problem.job.Service; import com.graphhopper.jsprit.core.problem.job.Shipment; import com.graphhopper.jsprit.core.problem.solution.VehicleRoutingProblemSolution; import com.graphhopper.jsprit.core.problem.solution.route.VehicleRoute; +import com.graphhopper.jsprit.core.problem.solution.route.activity.TimeWindow; import com.graphhopper.jsprit.core.problem.solution.route.activity.TourActivity; import com.graphhopper.jsprit.core.problem.vehicle.Vehicle; import com.graphhopper.jsprit.core.problem.vehicle.VehicleType; @@ -229,9 +230,15 @@ public class VrpXMLWriter { xmlConfig.setProperty(shipmentPathString + "(" + counter + ").capacity-dimensions.dimension(" + i + ")[@index]", i); xmlConfig.setProperty(shipmentPathString + "(" + counter + ").capacity-dimensions.dimension(" + i + ")", service.getSize().get(i)); } + + Collection tws = service.getTimeWindows(); + int index = 0; xmlConfig.setProperty(shipmentPathString + "(" + counter + ").duration", service.getServiceDuration()); - xmlConfig.setProperty(shipmentPathString + "(" + counter + ").timeWindows.timeWindow(0).start", service.getTimeWindow().getStart()); - xmlConfig.setProperty(shipmentPathString + "(" + counter + ").timeWindows.timeWindow(0).end", service.getTimeWindow().getEnd()); + for(TimeWindow tw : tws) { + xmlConfig.setProperty(shipmentPathString + "(" + counter + ").timeWindows.timeWindow(" + index + ").start", tw.getStart()); + xmlConfig.setProperty(shipmentPathString + "(" + counter + ").timeWindows.timeWindow(" + index + ").end", tw.getEnd()); + ++index; + } //skills String skillString = getSkillString(service); @@ -265,10 +272,14 @@ public class VrpXMLWriter { xmlConfig.setProperty(shipmentPathString + "(" + counter + ").pickup.location.index", shipment.getPickupLocation().getIndex()); } + Collection pu_tws = shipment.getPickupTimeWindows(); + int index = 0; 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()); - + for(TimeWindow tw : pu_tws) { + xmlConfig.setProperty(shipmentPathString + "(" + counter + ").pickup.timeWindows.timeWindow(" + index + ").start", tw.getStart()); + xmlConfig.setProperty(shipmentPathString + "(" + counter + ").pickup.timeWindows.timeWindow(" + index + ").end", tw.getEnd()); + ++index; + } if (shipment.getDeliveryLocation().getId() != null) xmlConfig.setProperty(shipmentPathString + "(" + counter + ").delivery.location.id", shipment.getDeliveryLocation().getId()); @@ -280,9 +291,14 @@ public class VrpXMLWriter { xmlConfig.setProperty(shipmentPathString + "(" + counter + ").delivery.location.index", shipment.getDeliveryLocation().getIndex()); } - 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()); + Collection del_tws = shipment.getDeliveryTimeWindows(); + xmlConfig.setProperty(shipmentPathString + "(" + counter + ").delivery.duration", shipment.getDeliveryServiceTime()); + index = 0; + for(TimeWindow tw : del_tws) { + xmlConfig.setProperty(shipmentPathString + "(" + counter + ").delivery.timeWindows.timeWindow(" + index + ").start", tw.getStart()); + xmlConfig.setProperty(shipmentPathString + "(" + counter + ").delivery.timeWindows.timeWindow(" + index + ").end", tw.getEnd()); + ++index; + } for (int i = 0; i < shipment.getSize().getNuOfDimensions(); i++) { xmlConfig.setProperty(shipmentPathString + "(" + counter + ").capacity-dimensions.dimension(" + i + ")[@index]", i); @@ -336,9 +352,14 @@ public class VrpXMLWriter { xmlConfig.setProperty(vehiclePathString + "(" + counter + ").timeSchedule.end", vehicle.getLatestArrival()); if (vehicle.getBreak() != null) { - xmlConfig.setProperty(vehiclePathString + "(" + counter + ").break.timeWindow.start", vehicle.getBreak().getTimeWindow().getStart()); - xmlConfig.setProperty(vehiclePathString + "(" + counter + ").break.timeWindow.end", vehicle.getBreak().getTimeWindow().getEnd()); + Collection tws = vehicle.getBreak().getTimeWindows(); + int index = 0; xmlConfig.setProperty(vehiclePathString + "(" + counter + ").break.duration", vehicle.getBreak().getServiceDuration()); + for(TimeWindow tw : tws) { + xmlConfig.setProperty(vehiclePathString + "(" + counter + ").break.timeWindows.timeWindow(" + index + ").start", tw.getStart()); + xmlConfig.setProperty(vehiclePathString + "(" + counter + ").break.timeWindows.timeWindow(" + index + ").end", tw.getEnd()); + ++index; + } } xmlConfig.setProperty(vehiclePathString + "(" + counter + ").returnToDepot", vehicle.isReturnToDepot()); diff --git a/jsprit-core/src/main/resources/vrp_xml_schema.xsd b/jsprit-core/src/main/resources/vrp_xml_schema.xsd index 52b8f8cf..a621bcc9 100644 --- a/jsprit-core/src/main/resources/vrp_xml_schema.xsd +++ b/jsprit-core/src/main/resources/vrp_xml_schema.xsd @@ -371,7 +371,14 @@ - + + + + + + +