mirror of
https://github.com/graphhopper/jsprit.git
synced 2020-01-24 07:45:05 +01:00
Merge branch 'merge-exp-time-scheduling'
This commit is contained in:
commit
98a682077d
8 changed files with 209 additions and 125 deletions
|
|
@ -117,9 +117,11 @@ final class BestInsertion implements InsertionStrategy{
|
||||||
}
|
}
|
||||||
VehicleRoute newRoute = VehicleRoute.emptyRoute();
|
VehicleRoute newRoute = VehicleRoute.emptyRoute();
|
||||||
InsertionData newIData = bestInsertionCostCalculator.getInsertionData(newRoute, unassignedJob, NO_NEW_VEHICLE_YET, NO_NEW_DEPARTURE_TIME_YET, NO_NEW_DRIVER_YET, bestInsertionCost);
|
InsertionData newIData = bestInsertionCostCalculator.getInsertionData(newRoute, unassignedJob, NO_NEW_VEHICLE_YET, NO_NEW_DEPARTURE_TIME_YET, NO_NEW_DRIVER_YET, bestInsertionCost);
|
||||||
if(newIData.getInsertionCost() < bestInsertionCost){
|
if(!(newIData instanceof NoInsertionFound)){
|
||||||
bestInsertion = new Insertion(newRoute,newIData);
|
if(newIData.getInsertionCost() < bestInsertionCost){
|
||||||
vehicleRoutes.add(newRoute);
|
bestInsertion = new Insertion(newRoute,newIData);
|
||||||
|
vehicleRoutes.add(newRoute);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(bestInsertion == null) badJobs.add(unassignedJob);
|
if(bestInsertion == null) badJobs.add(unassignedJob);
|
||||||
else inserter.insertJob(unassignedJob, bestInsertion.getInsertionData(), bestInsertion.getRoute());
|
else inserter.insertJob(unassignedJob, bestInsertion.getInsertionData(), bestInsertion.getRoute());
|
||||||
|
|
|
||||||
|
|
@ -1,93 +1,78 @@
|
||||||
/*******************************************************************************
|
|
||||||
* 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.core.algorithm.recreate;
|
package jsprit.core.algorithm.recreate;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import jsprit.core.algorithm.recreate.InsertionData.NoInsertionFound;
|
||||||
|
import jsprit.core.algorithm.recreate.listener.InsertionStartsListener;
|
||||||
import jsprit.core.problem.driver.Driver;
|
import jsprit.core.problem.driver.Driver;
|
||||||
import jsprit.core.problem.job.Job;
|
import jsprit.core.problem.job.Job;
|
||||||
import jsprit.core.problem.solution.route.VehicleRoute;
|
import jsprit.core.problem.solution.route.VehicleRoute;
|
||||||
import jsprit.core.problem.vehicle.Vehicle;
|
import jsprit.core.problem.vehicle.Vehicle;
|
||||||
|
import jsprit.core.util.RandomNumberGeneration;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
|
|
||||||
class CalculatesServiceInsertionWithTimeScheduling implements JobInsertionCostsCalculator{
|
class CalculatesServiceInsertionWithTimeScheduling implements JobInsertionCostsCalculator{
|
||||||
|
|
||||||
|
|
||||||
private static Logger log = LogManager.getLogger(CalculatesServiceInsertionWithTimeScheduling.class);
|
public static class KnowledgeInjection implements InsertionStartsListener {
|
||||||
|
private CalculatesServiceInsertionWithTimeScheduling c;
|
||||||
private JobInsertionCostsCalculator jic;
|
public KnowledgeInjection(CalculatesServiceInsertionWithTimeScheduling c) {
|
||||||
|
super();
|
||||||
// private Random random = new Random();
|
this.c = c;
|
||||||
|
}
|
||||||
private int nOfDepartureTimes = 3;
|
@Override
|
||||||
|
public void informInsertionStarts(Collection<VehicleRoute> vehicleRoutes,Collection<Job> unassignedJobs) {
|
||||||
private double timeSlice = 900.0;
|
List<Double> knowledge = new ArrayList<Double>();
|
||||||
|
if(vehicleRoutes.isEmpty()){
|
||||||
public CalculatesServiceInsertionWithTimeScheduling(JobInsertionCostsCalculator jic, double timeSlice, int neighbors) {
|
// System.out.println("hmm");
|
||||||
super();
|
}
|
||||||
this.jic = jic;
|
for(VehicleRoute route : vehicleRoutes){
|
||||||
this.timeSlice = timeSlice;
|
// if(route.getDepartureTime() == 21600.){
|
||||||
this.nOfDepartureTimes = neighbors;
|
// System.out.println("hu");
|
||||||
log.info("initialise " + this);
|
// }
|
||||||
}
|
knowledge.add(route.getDepartureTime());
|
||||||
|
}
|
||||||
@Override
|
c.setDepartureTimeKnowledge(knowledge);
|
||||||
public String toString() {
|
}
|
||||||
return "[name=calculatesServiceInsertionWithTimeScheduling][timeSlice="+timeSlice+"][#timeSlice="+nOfDepartureTimes+"]";
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
private static Logger log = LogManager.getLogger(CalculatesServiceInsertionWithTimeScheduling.class);
|
||||||
public InsertionData getInsertionData(VehicleRoute currentRoute, Job jobToInsert, Vehicle newVehicle, double newVehicleDepartureTime, Driver newDriver, double bestKnownScore) {
|
|
||||||
List<Double> vehicleDepartureTimes = new ArrayList<Double>();
|
|
||||||
double currentStart;
|
|
||||||
if(currentRoute.getStart() == null){
|
|
||||||
currentStart = newVehicleDepartureTime;
|
|
||||||
}
|
|
||||||
else currentStart = currentRoute.getStart().getEndTime();
|
|
||||||
|
|
||||||
vehicleDepartureTimes.add(currentStart);
|
|
||||||
// double earliestDeparture = newVehicle.getEarliestDeparture();
|
|
||||||
// double latestEnd = newVehicle.getLatestArrival();
|
|
||||||
|
|
||||||
for(int i=0;i<nOfDepartureTimes;i++){
|
|
||||||
double neighborStartTime_earlier = currentStart - (i+1)*timeSlice;
|
|
||||||
// if(neighborStartTime_earlier > earliestDeparture) {
|
|
||||||
vehicleDepartureTimes.add(neighborStartTime_earlier);
|
|
||||||
// }
|
|
||||||
double neighborStartTime_later = currentStart + (i+1)*timeSlice;
|
|
||||||
// if(neighborStartTime_later < latestEnd) {
|
|
||||||
vehicleDepartureTimes.add(neighborStartTime_later);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
InsertionData bestIData = null;
|
|
||||||
for(Double departureTime : vehicleDepartureTimes){
|
|
||||||
InsertionData iData = jic.getInsertionData(currentRoute, jobToInsert, newVehicle, departureTime, newDriver, bestKnownScore);
|
|
||||||
if(bestIData == null) bestIData = iData;
|
|
||||||
else if(iData.getInsertionCost() < bestIData.getInsertionCost()){
|
|
||||||
iData.setVehicleDepartureTime(departureTime);
|
|
||||||
bestIData = iData;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// log.info(bestIData);
|
|
||||||
return bestIData;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
private JobInsertionCostsCalculator jic;
|
||||||
|
|
||||||
|
private List<Double> departureTimeKnowledge = new ArrayList<Double>();
|
||||||
|
|
||||||
|
CalculatesServiceInsertionWithTimeScheduling(JobInsertionCostsCalculator jic, double t, double f) {
|
||||||
|
super();
|
||||||
|
this.jic = jic;
|
||||||
|
log.info("initialise " + this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "[name="+this.getClass().toString()+"]";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InsertionData getInsertionData(VehicleRoute currentRoute, Job jobToInsert, Vehicle newVehicle, double newVehicleDepartureTime, Driver newDriver, double bestKnownScore) {
|
||||||
|
double departureTime = newVehicleDepartureTime;
|
||||||
|
if(currentRoute.isEmpty()){
|
||||||
|
if(!departureTimeKnowledge.isEmpty()){
|
||||||
|
departureTime = departureTimeKnowledge.get(RandomNumberGeneration.getRandom().nextInt(departureTimeKnowledge.size()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
InsertionData insertionData = jic.getInsertionData(currentRoute, jobToInsert, newVehicle, departureTime, newDriver, bestKnownScore);
|
||||||
|
// if(!(insertionData instanceof NoInsertionFound) && insertionData.getVehicleDepartureTime() < 28000){
|
||||||
|
// System.out.println("hmm");
|
||||||
|
// }
|
||||||
|
return insertionData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDepartureTimeKnowledge(List<Double> departureTimes){
|
||||||
|
departureTimeKnowledge=departureTimes;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,91 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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.core.algorithm.recreate;
|
||||||
|
|
||||||
|
import jsprit.core.problem.driver.Driver;
|
||||||
|
import jsprit.core.problem.job.Job;
|
||||||
|
import jsprit.core.problem.solution.route.VehicleRoute;
|
||||||
|
import jsprit.core.problem.vehicle.Vehicle;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
class CalculatesServiceInsertionWithTimeSchedulingInSlices implements JobInsertionCostsCalculator{
|
||||||
|
|
||||||
|
|
||||||
|
private static Logger log = LogManager.getLogger(CalculatesServiceInsertionWithTimeSchedulingInSlices.class);
|
||||||
|
|
||||||
|
private JobInsertionCostsCalculator jic;
|
||||||
|
|
||||||
|
private int nOfDepartureTimes = 3;
|
||||||
|
|
||||||
|
private double timeSlice = 900.0;
|
||||||
|
|
||||||
|
public CalculatesServiceInsertionWithTimeSchedulingInSlices(JobInsertionCostsCalculator jic, double timeSlice, int neighbors) {
|
||||||
|
super();
|
||||||
|
this.jic = jic;
|
||||||
|
this.timeSlice = timeSlice;
|
||||||
|
this.nOfDepartureTimes = neighbors;
|
||||||
|
log.info("initialise " + this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "[name="+this.getClass().toString()+"][timeSlice="+timeSlice+"][#timeSlice="+nOfDepartureTimes+"]";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InsertionData getInsertionData(VehicleRoute currentRoute, Job jobToInsert, Vehicle newVehicle, double newVehicleDepartureTime, Driver newDriver, double bestKnownScore) {
|
||||||
|
List<Double> vehicleDepartureTimes = new ArrayList<Double>();
|
||||||
|
double currentStart;
|
||||||
|
if(currentRoute.getStart() == null){
|
||||||
|
currentStart = newVehicleDepartureTime;
|
||||||
|
}
|
||||||
|
else currentStart = currentRoute.getStart().getEndTime();
|
||||||
|
|
||||||
|
vehicleDepartureTimes.add(currentStart);
|
||||||
|
// double earliestDeparture = newVehicle.getEarliestDeparture();
|
||||||
|
// double latestEnd = newVehicle.getLatestArrival();
|
||||||
|
|
||||||
|
for(int i=0;i<nOfDepartureTimes;i++){
|
||||||
|
double neighborStartTime_earlier = currentStart - (i+1)*timeSlice;
|
||||||
|
// if(neighborStartTime_earlier > earliestDeparture) {
|
||||||
|
vehicleDepartureTimes.add(neighborStartTime_earlier);
|
||||||
|
// }
|
||||||
|
double neighborStartTime_later = currentStart + (i+1)*timeSlice;
|
||||||
|
// if(neighborStartTime_later < latestEnd) {
|
||||||
|
vehicleDepartureTimes.add(neighborStartTime_later);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
InsertionData bestIData = null;
|
||||||
|
for(Double departureTime : vehicleDepartureTimes){
|
||||||
|
InsertionData iData = jic.getInsertionData(currentRoute, jobToInsert, newVehicle, departureTime, newDriver, bestKnownScore);
|
||||||
|
if(bestIData == null) bestIData = iData;
|
||||||
|
else if(iData.getInsertionCost() < bestIData.getInsertionCost()){
|
||||||
|
iData.setVehicleDepartureTime(departureTime);
|
||||||
|
bestIData = iData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// log.info(bestIData);
|
||||||
|
return bestIData;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -217,7 +217,12 @@ class CalculatorBuilder {
|
||||||
addInsertionListeners(withFixed.getInsertionListener());
|
addInsertionListeners(withFixed.getInsertionListener());
|
||||||
}
|
}
|
||||||
if(timeScheduling){
|
if(timeScheduling){
|
||||||
baseCalculator = new CalculatesServiceInsertionWithTimeScheduling(baseCalculator,timeSlice,neighbors);
|
// baseCalculator = new CalculatesServiceInsertionWithTimeSchedulingInSlices(baseCalculator,timeSlice,neighbors);
|
||||||
|
CalculatesServiceInsertionWithTimeScheduling wts = new CalculatesServiceInsertionWithTimeScheduling(baseCalculator,timeSlice,neighbors);
|
||||||
|
CalculatorPlusListeners calcPlusListeners = new CalculatorPlusListeners(wts);
|
||||||
|
calcPlusListeners.getInsertionListener().add(new CalculatesServiceInsertionWithTimeScheduling.KnowledgeInjection(wts));
|
||||||
|
addInsertionListeners(calcPlusListeners.getInsertionListener());
|
||||||
|
baseCalculator = calcPlusListeners.getCalculator();
|
||||||
}
|
}
|
||||||
return createFinalInsertion(fleetManager, baseCalculator, states);
|
return createFinalInsertion(fleetManager, baseCalculator, states);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -114,8 +114,7 @@ final class VehicleTypeDependentJobInsertionCalculator implements JobInsertionCo
|
||||||
else depTime = v.getEarliestDeparture();
|
else depTime = v.getEarliestDeparture();
|
||||||
InsertionData iData = insertionCalculator.getInsertionData(currentRoute, jobToInsert, v, depTime, selectedDriver, bestKnownCost_);
|
InsertionData iData = insertionCalculator.getInsertionData(currentRoute, jobToInsert, v, depTime, selectedDriver, bestKnownCost_);
|
||||||
if(iData instanceof NoInsertionFound) {
|
if(iData instanceof NoInsertionFound) {
|
||||||
if(bestIData instanceof NoInsertionFound) bestIData = iData;
|
continue;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
if(iData.getInsertionCost() < bestKnownCost_){
|
if(iData.getInsertionCost() < bestKnownCost_){
|
||||||
bestIData = iData;
|
bestIData = iData;
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
|
|
||||||
import jsprit.core.algorithm.VehicleRoutingAlgorithm;
|
import jsprit.core.algorithm.VehicleRoutingAlgorithm;
|
||||||
import jsprit.core.algorithm.io.VehicleRoutingAlgorithms;
|
import jsprit.core.algorithm.io.VehicleRoutingAlgorithms;
|
||||||
import jsprit.core.problem.VehicleRoutingProblem;
|
import jsprit.core.problem.VehicleRoutingProblem;
|
||||||
|
|
@ -36,9 +37,10 @@ import jsprit.core.problem.vehicle.VehicleTypeImpl;
|
||||||
import jsprit.core.util.Coordinate;
|
import jsprit.core.util.Coordinate;
|
||||||
import jsprit.core.util.Solutions;
|
import jsprit.core.util.Solutions;
|
||||||
|
|
||||||
|
import org.junit.Ignore;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
@Ignore
|
||||||
public class TestDepartureTimeOpt {
|
public class TestDepartureTimeOpt {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
||||||
|
|
@ -5,23 +5,6 @@
|
||||||
<fleetSize>FINITE</fleetSize>
|
<fleetSize>FINITE</fleetSize>
|
||||||
</problemType>
|
</problemType>
|
||||||
<vehicles>
|
<vehicles>
|
||||||
<vehicle>
|
|
||||||
<id>v2</id>
|
|
||||||
<typeId>vehType2</typeId>
|
|
||||||
<startLocation>
|
|
||||||
<id>depotLoc</id>
|
|
||||||
<coord x="10.0" y="100.0"/>
|
|
||||||
</startLocation>
|
|
||||||
<endLocation>
|
|
||||||
<id>depotLoc</id>
|
|
||||||
<coord x="10.0" y="100.0"/>
|
|
||||||
</endLocation>
|
|
||||||
<timeSchedule>
|
|
||||||
<start>0.0</start>
|
|
||||||
<end>1000.0</end>
|
|
||||||
</timeSchedule>
|
|
||||||
<returnToDepot>false</returnToDepot>
|
|
||||||
</vehicle>
|
|
||||||
<vehicle>
|
<vehicle>
|
||||||
<id>v3</id>
|
<id>v3</id>
|
||||||
<typeId>vehType2</typeId>
|
<typeId>vehType2</typeId>
|
||||||
|
|
@ -40,8 +23,25 @@
|
||||||
<returnToDepot>true</returnToDepot>
|
<returnToDepot>true</returnToDepot>
|
||||||
</vehicle>
|
</vehicle>
|
||||||
<vehicle>
|
<vehicle>
|
||||||
<id>v5</id>
|
<id>v2</id>
|
||||||
<typeId>vehType3</typeId>
|
<typeId>vehType2</typeId>
|
||||||
|
<startLocation>
|
||||||
|
<id>depotLoc</id>
|
||||||
|
<coord x="10.0" y="100.0"/>
|
||||||
|
</startLocation>
|
||||||
|
<endLocation>
|
||||||
|
<id>depotLoc</id>
|
||||||
|
<coord x="10.0" y="100.0"/>
|
||||||
|
</endLocation>
|
||||||
|
<timeSchedule>
|
||||||
|
<start>0.0</start>
|
||||||
|
<end>1000.0</end>
|
||||||
|
</timeSchedule>
|
||||||
|
<returnToDepot>false</returnToDepot>
|
||||||
|
</vehicle>
|
||||||
|
<vehicle>
|
||||||
|
<id>v4</id>
|
||||||
|
<typeId>vehType2</typeId>
|
||||||
<startLocation>
|
<startLocation>
|
||||||
<id>startLoc</id>
|
<id>startLoc</id>
|
||||||
<coord x="10.0" y="100.0"/>
|
<coord x="10.0" y="100.0"/>
|
||||||
|
|
@ -57,8 +57,8 @@
|
||||||
<returnToDepot>true</returnToDepot>
|
<returnToDepot>true</returnToDepot>
|
||||||
</vehicle>
|
</vehicle>
|
||||||
<vehicle>
|
<vehicle>
|
||||||
<id>v4</id>
|
<id>v5</id>
|
||||||
<typeId>vehType2</typeId>
|
<typeId>vehType3</typeId>
|
||||||
<startLocation>
|
<startLocation>
|
||||||
<id>startLoc</id>
|
<id>startLoc</id>
|
||||||
<coord x="10.0" y="100.0"/>
|
<coord x="10.0" y="100.0"/>
|
||||||
|
|
@ -137,20 +137,6 @@
|
||||||
</type>
|
</type>
|
||||||
</vehicleTypes>
|
</vehicleTypes>
|
||||||
<services>
|
<services>
|
||||||
<service id="2" type="service">
|
|
||||||
<locationId>i(3,9)</locationId>
|
|
||||||
<coord x="10.0" y="10.0"/>
|
|
||||||
<capacity-dimensions>
|
|
||||||
<dimension index="0">1</dimension>
|
|
||||||
</capacity-dimensions>
|
|
||||||
<duration>0.0</duration>
|
|
||||||
<timeWindows>
|
|
||||||
<timeWindow>
|
|
||||||
<start>0.0</start>
|
|
||||||
<end>4000.0</end>
|
|
||||||
</timeWindow>
|
|
||||||
</timeWindows>
|
|
||||||
</service>
|
|
||||||
<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"/>
|
||||||
|
|
@ -165,6 +151,20 @@
|
||||||
</timeWindow>
|
</timeWindow>
|
||||||
</timeWindows>
|
</timeWindows>
|
||||||
</service>
|
</service>
|
||||||
|
<service id="2" type="service">
|
||||||
|
<locationId>i(3,9)</locationId>
|
||||||
|
<coord x="10.0" y="10.0"/>
|
||||||
|
<capacity-dimensions>
|
||||||
|
<dimension index="0">1</dimension>
|
||||||
|
</capacity-dimensions>
|
||||||
|
<duration>0.0</duration>
|
||||||
|
<timeWindows>
|
||||||
|
<timeWindow>
|
||||||
|
<start>0.0</start>
|
||||||
|
<end>4000.0</end>
|
||||||
|
</timeWindow>
|
||||||
|
</timeWindows>
|
||||||
|
</service>
|
||||||
</services>
|
</services>
|
||||||
<shipments>
|
<shipments>
|
||||||
<shipment id="3">
|
<shipment id="3">
|
||||||
|
|
|
||||||
|
|
@ -35,12 +35,12 @@
|
||||||
</type>
|
</type>
|
||||||
</vehicleTypes>
|
</vehicleTypes>
|
||||||
<services>
|
<services>
|
||||||
<service id="2" type="service">
|
<service id="1" type="service">
|
||||||
<locationId>loc2</locationId>
|
<locationId>loc</locationId>
|
||||||
<capacity-dimensions>
|
<capacity-dimensions>
|
||||||
<dimension index="0">1</dimension>
|
<dimension index="0">1</dimension>
|
||||||
</capacity-dimensions>
|
</capacity-dimensions>
|
||||||
<duration>4.0</duration>
|
<duration>2.0</duration>
|
||||||
<timeWindows>
|
<timeWindows>
|
||||||
<timeWindow>
|
<timeWindow>
|
||||||
<start>0.0</start>
|
<start>0.0</start>
|
||||||
|
|
@ -48,12 +48,12 @@
|
||||||
</timeWindow>
|
</timeWindow>
|
||||||
</timeWindows>
|
</timeWindows>
|
||||||
</service>
|
</service>
|
||||||
<service id="1" type="service">
|
<service id="2" type="service">
|
||||||
<locationId>loc</locationId>
|
<locationId>loc2</locationId>
|
||||||
<capacity-dimensions>
|
<capacity-dimensions>
|
||||||
<dimension index="0">1</dimension>
|
<dimension index="0">1</dimension>
|
||||||
</capacity-dimensions>
|
</capacity-dimensions>
|
||||||
<duration>2.0</duration>
|
<duration>4.0</duration>
|
||||||
<timeWindows>
|
<timeWindows>
|
||||||
<timeWindow>
|
<timeWindow>
|
||||||
<start>0.0</start>
|
<start>0.0</start>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue