From 88b15fd448dbfa745ee7842d6d34ce7f27b13cde Mon Sep 17 00:00:00 2001 From: oblonski <4sschroeder@gmail.com> Date: Thu, 16 Jan 2014 15:38:59 -0500 Subject: [PATCH 01/57] add javadoc --- .../java/jsprit/core/problem/job/Job.java | 18 +++ .../java/jsprit/core/problem/job/Service.java | 114 +++++++++++++++++- 2 files changed, 126 insertions(+), 6 deletions(-) diff --git a/jsprit-core/src/main/java/jsprit/core/problem/job/Job.java b/jsprit-core/src/main/java/jsprit/core/problem/job/Job.java index 50aec2bb..261591dc 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/job/Job.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/job/Job.java @@ -16,10 +16,28 @@ ******************************************************************************/ package jsprit.core.problem.job; +/** + * Basic interface for all jobs. + * + * @author schroeder + * + */ public interface Job { + /** + * Returns the unique identifier (id) of a job. + * + * @return id + */ public String getId(); + /** + * Returns capacity (demand) of job. + * + *
It determines how much capacity this job consumes of vehicle/transport unit. + * + * @return + */ public int getCapacityDemand(); diff --git a/jsprit-core/src/main/java/jsprit/core/problem/job/Service.java b/jsprit-core/src/main/java/jsprit/core/problem/job/Service.java index 69e2e6c0..235e5c43 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/job/Service.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/job/Service.java @@ -19,55 +19,133 @@ package jsprit.core.problem.job; import jsprit.core.problem.solution.route.activity.TimeWindow; import jsprit.core.util.Coordinate; - +/** + * Service implementation of a job. + * + *
A service distinguishes itself from a shipment such that it has only one locations. Thus a service + * is a single point in space (where a service-activity occurs). + * + *
Note that two services are equal if they have the same id. + * + * @author schroeder + * + */ public class Service implements Job { + /** + * Builder that builds a service. + * + * @author schroeder + * + */ public static class Builder { + /** + * Returns a new instance of service-builder. + * + * @param id of service + * @param size of capacity-demand + * @return builder + */ public static Builder newInstance(String id, int size){ return new Builder(id,size); } private String id; + protected String locationId; + private String type = "service"; + protected Coordinate coord; + protected double serviceTime; + protected TimeWindow timeWindow = TimeWindow.newInstance(0.0, Double.MAX_VALUE); + protected int demand; + /** + * Constructs the builder. + * + * @param id + * @param size + */ Builder(String id, int size) { if(size < 0) throw new IllegalArgumentException("size must be greater than or equal to zero"); this.id = id; this.demand = size; } + /** + * Protected method to set the type-name of the service. + * + *
Currently there are {@link Service}, {@link Pickup} and {@link Delivery}. + * + * @param name + * @return the builder + */ protected Builder setType(String name){ this.type = name; return this; } + /** + * Sets the location-id of this service. + * + * @param locationId + * @return builder + */ public Builder setLocationId(String locationId){ this.locationId = locationId; return this; } + /** + * Sets the coordinate of this service. + * + * @param coord + * @return builder + */ public Builder setCoord(Coordinate coord){ this.coord = coord; return this; } + /** + * Sets the serviceTime of this service. + * + *
It is understood as time that a service or its implied activity takes at the service-location, for instance + * to unload goods. + * + * @param serviceTime + * @return builder + */ public Builder setServiceTime(double serviceTime){ if(serviceTime < 0) throw new IllegalArgumentException("serviceTime must be greate than or equal to zero"); this.serviceTime = serviceTime; return this; } + /** + * Sets the time-window of this service. + * + *
The time-window indicates the time period a service/activity/operation is allowed to start. + * + * @param tw + * @return builder + */ public Builder setTimeWindow(TimeWindow tw){ this.timeWindow = tw; return this; } + /** + * Builds the service. + * + * @return {@link Service} + * @throws IllegalStateException if neither locationId nor coordinate is set. + */ public Service build(){ if(locationId == null) { if(coord == null) throw new IllegalStateException("either locationId or a coordinate must be given. But is not."); @@ -109,18 +187,38 @@ public class Service implements Job { return id; } + /** + * Returns the location-id of this service. + * + * @return String that indicates the location + */ public String getLocationId() { return locationId; } + /** + * Returns the coordinate of this service. + * + * @return {@link Coordinate} + */ public Coordinate getCoord(){ return coord; } + /** + * Returns the service-time/duration a service takes at service-location. + * + * @return service duration + */ public double getServiceDuration() { return serviceTime; } + /** + * Returns the time-window a service(-operation) is allowed to start. + * + * @return time window + */ public TimeWindow getTimeWindow(){ return timeWindow; } @@ -137,14 +235,17 @@ public class Service implements Job { return type; } + /** + * Returns a string with the service's attributes. + * + *
String is built as follows: [attr1=val1][attr2=val2]... + */ @Override public String toString() { return "[id=" + id + "][type="+type+"][locationId=" + locationId + "][coord="+coord+"][size=" + demand + "][serviceTime=" + serviceTime + "][timeWindow=" + timeWindow + "]"; } - /* (non-Javadoc) - * @see java.lang.Object#hashCode() - */ + @Override public int hashCode() { final int prime = 31; @@ -153,8 +254,9 @@ public class Service implements Job { return result; } - /* (non-Javadoc) - * @see java.lang.Object#equals(java.lang.Object) + /** + * Two services are equal if they have the same id. + * */ @Override public boolean equals(Object obj) { From 7b1a2bd9b0def52e641b46fa213d2ebadd76170e Mon Sep 17 00:00:00 2001 From: oblonski <4sschroeder@gmail.com> Date: Thu, 16 Jan 2014 16:55:05 -0500 Subject: [PATCH 02/57] add javadoc and tests --- .../java/jsprit/core/problem/job/Service.java | 7 ++- .../jsprit/core/problem/job/ServiceTest.java | 62 ++++++++++++++++++- 2 files changed, 66 insertions(+), 3 deletions(-) diff --git a/jsprit-core/src/main/java/jsprit/core/problem/job/Service.java b/jsprit-core/src/main/java/jsprit/core/problem/job/Service.java index 235e5c43..439db4ca 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/job/Service.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/job/Service.java @@ -22,7 +22,7 @@ import jsprit.core.util.Coordinate; /** * Service implementation of a job. * - *
A service distinguishes itself from a shipment such that it has only one locations. Thus a service + *
A service distinguishes itself from a shipment such that it has only one location. Thus a service * is a single point in space (where a service-activity occurs). * *
Note that two services are equal if they have the same id. @@ -120,9 +120,10 @@ public class Service implements Job { * * @param serviceTime * @return builder + * @throws IllegalArgumentException if serviceTime < 0 */ public Builder setServiceTime(double serviceTime){ - if(serviceTime < 0) throw new IllegalArgumentException("serviceTime must be greate than or equal to zero"); + if(serviceTime < 0) throw new IllegalArgumentException("serviceTime must be greater than or equal to zero"); this.serviceTime = serviceTime; return this; } @@ -134,8 +135,10 @@ public class Service implements Job { * * @param tw * @return builder + * @throw IllegalArgumentException if timeWindow is null */ public Builder setTimeWindow(TimeWindow tw){ + if(tw == null) throw new IllegalArgumentException("time-window arg must not be null"); this.timeWindow = tw; return this; } diff --git a/jsprit-core/src/test/java/jsprit/core/problem/job/ServiceTest.java b/jsprit-core/src/test/java/jsprit/core/problem/job/ServiceTest.java index 0c68453c..3a1c82f0 100644 --- a/jsprit-core/src/test/java/jsprit/core/problem/job/ServiceTest.java +++ b/jsprit-core/src/test/java/jsprit/core/problem/job/ServiceTest.java @@ -16,12 +16,15 @@ ******************************************************************************/ package jsprit.core.problem.job; +import static org.junit.Assert.*; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import java.util.HashSet; import java.util.Set; -import jsprit.core.problem.job.Service; +import jsprit.core.problem.solution.route.activity.TimeWindow; +import jsprit.core.util.Coordinate; import org.junit.Test; @@ -55,4 +58,61 @@ public class ServiceTest { assertTrue(serviceSet.isEmpty()); } + + @Test + public void whenCallingForNewInstanceOfBuilder_itShouldReturnBuilderCorrectly(){ + Service.Builder builder = Service.Builder.newInstance("s", 0); + assertNotNull(builder); + assertTrue(builder instanceof Service.Builder); + } + + @Test + public void whenSettingNoType_itShouldReturn_service(){ + Service s = Service.Builder.newInstance("s", 0).setLocationId("loc").build(); + assertEquals("service",s.getType()); + } + + @Test + public void whenSettingLocation_itShouldBeSetCorrectly(){ + Service s = Service.Builder.newInstance("s", 0).setLocationId("loc").build(); + assertEquals("loc",s.getLocationId()); + } + + @Test + public void whenSettingLocationCoord_itShouldBeSetCorrectly(){ + Service s = Service.Builder.newInstance("s", 0).setCoord(Coordinate.newInstance(1, 2)).build(); + assertEquals(1.0,s.getCoord().getX(),0.01); + assertEquals(2.0,s.getCoord().getY(),0.01); + } + + @Test(expected=IllegalStateException.class) + public void whenSettingNeitherLocationIdNorCoord_throwsException(){ + @SuppressWarnings("unused") + Service s = Service.Builder.newInstance("s", 0).build(); + } + + @Test(expected=IllegalArgumentException.class) + public void whenServiceTimeSmallerZero_throwIllegalStateException(){ + @SuppressWarnings("unused") + Service s = Service.Builder.newInstance("s", 0).setLocationId("loc").setServiceTime(-1).build(); + } + + @Test + public void whenSettingServiceTime_itShouldBeSetCorrectly(){ + Service s = Service.Builder.newInstance("s", 0).setLocationId("loc").setServiceTime(1).build(); + assertEquals(1.0,s.getServiceDuration(),0.01); + } + + @Test(expected=IllegalArgumentException.class) + public void whenTimeWindowIsNull_throwException(){ + @SuppressWarnings("unused") + Service s = Service.Builder.newInstance("s", 0).setLocationId("loc").setTimeWindow(null).build(); + } + + @Test + public void whenSettingTimeWindow_itShouldBeSetCorrectly(){ + Service s = Service.Builder.newInstance("s", 0).setLocationId("loc").setTimeWindow(TimeWindow.newInstance(1.0, 2.0)).build(); + assertEquals(1.0,s.getTimeWindow().getStart(),0.01); + assertEquals(2.0,s.getTimeWindow().getEnd(),0.01); + } } From ca0caf450c01a7ac6ba85b959bddcc20975dabc6 Mon Sep 17 00:00:00 2001 From: oblonski <4sschroeder@gmail.com> Date: Thu, 16 Jan 2014 16:55:26 -0500 Subject: [PATCH 03/57] add boundaries --- .../solution/route/activity/TimeWindow.java | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/TimeWindow.java b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/TimeWindow.java index a78a3a60..138414f3 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/TimeWindow.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/activity/TimeWindow.java @@ -17,6 +17,7 @@ package jsprit.core.problem.solution.route.activity; /** + * TimeWindow consists of a startTime and endTime. * * @author stefan schroeder * @@ -24,6 +25,14 @@ package jsprit.core.problem.solution.route.activity; public class TimeWindow { + /** + * Returns new instance of TimeWindow. + * + * @param start + * @param end + * @return TimeWindow + * @throw IllegalArgumentException either if start or end < 0.0 or end < start + */ public static TimeWindow newInstance(double start, double end){ return new TimeWindow(start,end); } @@ -31,16 +40,35 @@ public class TimeWindow { private final double start; private final double end; + /** + * Constructs the timeWindow + * + * @param start + * @param end + * @throw IllegalArgumentException either if start or end < 0.0 or end < start + */ public TimeWindow(double start, double end) { super(); + if(start < 0.0 || end < 0.0) throw new IllegalArgumentException("neither start nor end must be < 0.0"); + if(end < start) throw new IllegalArgumentException("end cannot be smaller than start"); this.start = start; this.end = end; } + /** + * Returns startTime of TimeWindow. + * + * @return startTime + */ public double getStart() { return start; } + /** + * Returns endTime of TimeWindow. + * + * @return endTime + */ public double getEnd() { return end; } @@ -62,6 +90,9 @@ public class TimeWindow { return result; } + /** + * Two timeWindows are equal if they have the same start AND endTime. + */ @Override public boolean equals(Object obj) { if (this == obj) From 6b4656afff5a6677bd609f120114ad85dd0d31d0 Mon Sep 17 00:00:00 2001 From: oblonski <4sschroeder@gmail.com> Date: Thu, 16 Jan 2014 17:07:38 -0500 Subject: [PATCH 04/57] add javadocs and tests --- .../jsprit/core/problem/job/Delivery.java | 32 +++++++++++++++-- .../java/jsprit/core/problem/job/Pickup.java | 34 ++++++++++++++++++- .../jsprit/core/problem/job/DeliveryTest.java | 12 +++++++ .../jsprit/core/problem/job/PickupTest.java | 12 +++++++ 4 files changed, 87 insertions(+), 3 deletions(-) create mode 100644 jsprit-core/src/test/java/jsprit/core/problem/job/DeliveryTest.java create mode 100644 jsprit-core/src/test/java/jsprit/core/problem/job/PickupTest.java diff --git a/jsprit-core/src/main/java/jsprit/core/problem/job/Delivery.java b/jsprit-core/src/main/java/jsprit/core/problem/job/Delivery.java index 79532708..f3c29a2a 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/job/Delivery.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/job/Delivery.java @@ -16,19 +16,42 @@ ******************************************************************************/ package jsprit.core.problem.job; - +/** + * Delivery extends Service and is intended to model a Service where smth is UNLOADED (i.e. delivered) from a transport unit. + * + * @author schroeder + * + */ public class Delivery extends Service{ public static class Builder extends Service.Builder { + /** + * Returns a new instance of Delivery.Builder + * + * @param id + * @param size + * @return builder + */ public static Builder newInstance(String id, int size){ return new Builder(id,size); } + /** + * Constructs the builder + * + * @param id + * @param size + */ Builder(String id, int size) { super(id, size); } - + /** + * Builds Delivery. + * + * @return delivery + * @throw {@link IllegalStateException} if neither locationId nor coord is set + */ public Delivery build(){ if(locationId == null) { if(coord == null) throw new IllegalStateException("either locationId or a coordinate must be given. But is not."); @@ -40,6 +63,11 @@ public class Delivery extends Service{ } + /** + * Constructs Delivery. + * + * @param builder + */ Delivery(Builder builder) { super(builder); diff --git a/jsprit-core/src/main/java/jsprit/core/problem/job/Pickup.java b/jsprit-core/src/main/java/jsprit/core/problem/job/Pickup.java index e706d27f..f14ec34d 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/job/Pickup.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/job/Pickup.java @@ -16,18 +16,45 @@ ******************************************************************************/ package jsprit.core.problem.job; +/** + * Pickup extends Service and is intended to model a Service where smth is LOADED (i.e. picked up) to a transport unit. + * + * @author schroeder + * + */ public class Pickup extends Service { public static class Builder extends Service.Builder { - + + /** + * Returns a new instance of Pickup.Builder + * + * @param id + * @param size + * @return builder + */ public static Builder newInstance(String id, int size){ return new Builder(id,size); } + /** + * Constructs the builder. + * + * @param id + * @param size + */ Builder(String id, int size) { super(id, size); } + /** + * Builds Pickup. + * + *
Pickup type is "pickup" + * + * @return pickup + * @throw {@link IllegalStateException} if neither locationId nor coordinate has been set + */ public Pickup build(){ if(locationId == null) { if(coord == null) throw new IllegalStateException("either locationId or a coordinate must be given. But is not."); @@ -39,6 +66,11 @@ public class Pickup extends Service { } + /** + * Constructs the Pickup + * + * @param builder + */ Pickup(Builder builder) { super(builder); } diff --git a/jsprit-core/src/test/java/jsprit/core/problem/job/DeliveryTest.java b/jsprit-core/src/test/java/jsprit/core/problem/job/DeliveryTest.java new file mode 100644 index 00000000..1ca82c45 --- /dev/null +++ b/jsprit-core/src/test/java/jsprit/core/problem/job/DeliveryTest.java @@ -0,0 +1,12 @@ +package jsprit.core.problem.job; + +import org.junit.Test; + +public class DeliveryTest { + + @Test(expected=IllegalStateException.class) + public void whenNeitherLocationIdNorCoordIsSet_itThrowsException(){ + Delivery.Builder.newInstance("p", 0).build(); + } + +} diff --git a/jsprit-core/src/test/java/jsprit/core/problem/job/PickupTest.java b/jsprit-core/src/test/java/jsprit/core/problem/job/PickupTest.java new file mode 100644 index 00000000..73b60ed5 --- /dev/null +++ b/jsprit-core/src/test/java/jsprit/core/problem/job/PickupTest.java @@ -0,0 +1,12 @@ +package jsprit.core.problem.job; + +import org.junit.Test; + +public class PickupTest { + + @Test(expected=IllegalStateException.class) + public void whenNeitherLocationIdNorCoordIsSet_itThrowsException(){ + Pickup.Builder.newInstance("p", 0).build(); + } + +} From 597619716778f0378b1790218eb319043559919a Mon Sep 17 00:00:00 2001 From: oblonski <4sschroeder@gmail.com> Date: Thu, 16 Jan 2014 19:28:40 -0500 Subject: [PATCH 05/57] add javadoc and tests --- .../jsprit/core/problem/job/Delivery.java | 4 +- .../java/jsprit/core/problem/job/Pickup.java | 4 +- .../java/jsprit/core/problem/job/Service.java | 3 + .../jsprit/core/problem/job/Shipment.java | 192 +++++++++++++++++- .../jsprit/core/problem/job/ServiceTest.java | 2 +- .../jsprit/core/problem/job/ShipmentTest.java | 169 +++++++++++++-- 6 files changed, 346 insertions(+), 28 deletions(-) diff --git a/jsprit-core/src/main/java/jsprit/core/problem/job/Delivery.java b/jsprit-core/src/main/java/jsprit/core/problem/job/Delivery.java index f3c29a2a..187952df 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/job/Delivery.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/job/Delivery.java @@ -32,6 +32,7 @@ public class Delivery extends Service{ * @param id * @param size * @return builder + * @throws IllegalArgumentException if size < 0 or id is null */ public static Builder newInstance(String id, int size){ return new Builder(id,size); @@ -42,6 +43,7 @@ public class Delivery extends Service{ * * @param id * @param size + * @throws IllegalArgumentException if size < 0 or id is null */ Builder(String id, int size) { super(id, size); @@ -50,7 +52,7 @@ public class Delivery extends Service{ * Builds Delivery. * * @return delivery - * @throw {@link IllegalStateException} if neither locationId nor coord is set + * @throw IllegalStateException if neither locationId nor coord is set */ public Delivery build(){ if(locationId == null) { diff --git a/jsprit-core/src/main/java/jsprit/core/problem/job/Pickup.java b/jsprit-core/src/main/java/jsprit/core/problem/job/Pickup.java index f14ec34d..4fbed1a3 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/job/Pickup.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/job/Pickup.java @@ -32,6 +32,7 @@ public class Pickup extends Service { * @param id * @param size * @return builder + * @throws IllegalArgumentException if size < 0 or id is null */ public static Builder newInstance(String id, int size){ return new Builder(id,size); @@ -42,6 +43,7 @@ public class Pickup extends Service { * * @param id * @param size + * @throws IllegalArgumentException if size < 0 or id is null */ Builder(String id, int size) { super(id, size); @@ -53,7 +55,7 @@ public class Pickup extends Service { *
Pickup type is "pickup" * * @return pickup - * @throw {@link IllegalStateException} if neither locationId nor coordinate has been set + * @throw IllegalStateException if neither locationId nor coordinate has been set */ public Pickup build(){ if(locationId == null) { diff --git a/jsprit-core/src/main/java/jsprit/core/problem/job/Service.java b/jsprit-core/src/main/java/jsprit/core/problem/job/Service.java index 439db4ca..a29fa874 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/job/Service.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/job/Service.java @@ -46,6 +46,7 @@ public class Service implements Job { * @param id of service * @param size of capacity-demand * @return builder + * @throws IllegalArgumentException if size < 0 or id is null */ public static Builder newInstance(String id, int size){ return new Builder(id,size); @@ -70,9 +71,11 @@ public class Service implements Job { * * @param id * @param size + * @throws IllegalArgumentException if size < 0 or id is null */ Builder(String id, int size) { if(size < 0) throw new IllegalArgumentException("size must be greater than or equal to zero"); + if(id == null) throw new IllegalArgumentException("id must not be null"); this.id = id; this.demand = size; } diff --git a/jsprit-core/src/main/java/jsprit/core/problem/job/Shipment.java b/jsprit-core/src/main/java/jsprit/core/problem/job/Shipment.java index 6168aa98..79f2de82 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/job/Shipment.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/job/Shipment.java @@ -3,8 +3,31 @@ package jsprit.core.problem.job; import jsprit.core.problem.solution.route.activity.TimeWindow; import jsprit.core.util.Coordinate; +/** + * Shipment is an implementation of Job and consists of a pickup and a delivery of something. + * + *
It distinguishes itself from {@link Service} as two locations are involved a pickup where usually + * something is loaded to the transport unit and a delivery where something is unloaded. + * + *
By default serviceTimes of both pickup and delivery is 0.0 and timeWindows of both is [0.0, Double.MAX_VALUE], + * + *
A shipment can be built with a builder. You can get an instance of the builder by coding Shipment.Builder.newInstance(...).
+ * This way you can specify the shipment. Once you build the shipment, it is immutable, i.e. fields/attributes cannot be changed anymore and
+ * you can only 'get' the specified values.
+ *
+ *
Note that two shipments are equal if they have the same id. + * + * @author schroeder + * + */ public class Shipment implements Job{ + /** + * Builder that builds the shipment. + * + * @author schroeder + * + */ public static class Builder { private int demand; @@ -27,56 +50,153 @@ public class Shipment implements Job{ private TimeWindow pickupTimeWindow = TimeWindow.newInstance(0.0, Double.MAX_VALUE);; + /** + * Returns a new instance of this builder. + * + * @param id + * @param size + * @return builder + * @throws IllegalArgumentException if size < 0 or id is null + */ public static Builder newInstance(String id, int size){ return new Builder(id,size); } + /** + * Constructs the builder + * + * @param id + * @param size + * @throws IllegalArgumentException if size < 0 or id is null + */ Builder(String id, int size) { if(size < 0) throw new IllegalArgumentException("size must be greater than or equal to zero"); + if(id == null) throw new IllegalArgumentException("id must not be null"); this.id = id; this.demand = size; } + /** + * Sets pickup-location. + * + * @param pickupLocation + * @return builder + * @throws IllegalArgumentException if location is null + */ public Builder setPickupLocation(String pickupLocation){ + if(pickupLocation == null) throw new IllegalArgumentException("location must not be null"); this.pickupLocation = pickupLocation; return this; } + /** + * Sets pickup-coordinate. + * + * @param pickupCoord + * @return builder + * @throws IllegalArgumentException if pickupCoord is null + */ public Builder setPickupCoord(Coordinate pickupCoord){ + if(pickupCoord == null) throw new IllegalArgumentException("coord must not be null"); this.pickupCoord = pickupCoord; return this; } + /** + * Sets pickupServiceTime. + * + *
ServiceTime is intended to be the time the implied activity takes at the pickup-location. + * + * @param serviceTime + * @return builder + * @throws IllegalArgumentException if servicTime < 0.0 + */ public Builder setPickupServiceTime(double serviceTime){ + if(serviceTime < 0.0) throw new IllegalArgumentException("serviceTime must not be < 0.0"); this.pickupServiceTime = serviceTime; return this; } + /** + * Sets the timeWindow for the pickup, i.e. the time-period in which a pickup operation is + * allowed to start. + * + *
By default timeWindow is [0.0, Double.MAX_VALUE} + * + * @param timeWindow + * @return builder + * @throws IllegalArgumentException if timeWindow is null + */ public Builder setPickupTimeWindow(TimeWindow timeWindow){ + if(timeWindow == null) throw new IllegalArgumentException("timeWindow cannot be null"); this.pickupTimeWindow = timeWindow; return this; } + /** + * Sets the delivery-location. + * + * @param deliveryLocation + * @return builder + * @throws IllegalArgumentException if location is null + */ public Builder setDeliveryLocation(String deliveryLocation){ + if(deliveryLocation == null) throw new IllegalArgumentException("delivery location must not be null"); this.deliveryLocation = deliveryLocation; return this; } + /** + * Sets delivery-coord. + * + * @param deliveryCoord + * @return builder + * @throws IllegalArgumentException if coord is null; + */ public Builder setDeliveryCoord(Coordinate deliveryCoord){ + if(deliveryCoord == null) throw new IllegalArgumentException("coord must not be null"); this.deliveryCoord = deliveryCoord; return this; } + /** + * Sets the delivery service-time. + * + *
ServiceTime is intended to be the time the implied activity takes at the delivery-location. + * + * @param deliveryServiceTime + * @return builder + * @throws IllegalArgumentException if serviceTime < 0.0 + */ public Builder setDeliveryServiceTime(double deliveryServiceTime){ + if(deliveryServiceTime < 0.0) throw new IllegalArgumentException("deliveryServiceTime must not be < 0.0"); this.deliveryServiceTime = deliveryServiceTime; return this; } + /** + * Sets the timeWindow for the delivery, i.e. the time-period in which a delivery operation is + * allowed to start. + * + *
By default timeWindow is [0.0, Double.MAX_VALUE} + * + * @param timeWindow + * @return builder + * @throws IllegalArgumentException if timeWindow is null + */ public Builder setDeliveryTimeWindow(TimeWindow timeWindow){ + if(timeWindow == null) throw new IllegalArgumentException("delivery time-window must not be null"); this.deliveryTimeWindow = timeWindow; return this; } + /** + * Builds the shipment. + * + * @return shipment + * @throws IllegalStateException if neither pickup-location nor pickup-coord is set or if neither delivery-location nor delivery-coord + * is set + */ public Shipment build(){ if(pickupLocation == null) { if(pickupCoord == null) throw new IllegalStateException("either locationId or a coordinate must be given. But is not."); @@ -90,26 +210,31 @@ public class Shipment implements Job{ } } - private int demand; + private final int demand; - private String id; + private final String id; - private String pickupLocation; + private final String pickupLocation; - private Coordinate pickupCoord; + private final Coordinate pickupCoord; - private double pickupServiceTime; + private final double pickupServiceTime; - private String deliveryLocation; + private final String deliveryLocation; - private Coordinate deliveryCoord; + private final Coordinate deliveryCoord; - private double deliveryServiceTime; + private final double deliveryServiceTime; - private TimeWindow deliveryTimeWindow; + private final TimeWindow deliveryTimeWindow; - private TimeWindow pickupTimeWindow; + private final TimeWindow pickupTimeWindow; + /** + * Constructs the shipment. + * + * @param builder + */ Shipment(Builder builder){ this.id = builder.id; this.demand = builder.demand; @@ -133,34 +258,76 @@ public class Shipment implements Job{ return demand; } + /** + * Returns the pickup-location. + * + * @return pickup-location + */ public String getPickupLocation() { return pickupLocation; } + /** + * Returns the pickup-coordinate. + * + * @return coordinate of the pickup + */ public Coordinate getPickupCoord() { return pickupCoord; } + /** + * Returns the pickup service-time. + * + *
By default service-time is 0.0.
+ *
+ * @return service-time
+ */
public double getPickupServiceTime() {
return pickupServiceTime;
}
+ /**
+ * Returns delivery-location.
+ *
+ * @return delivery-location
+ */
public String getDeliveryLocation() {
return deliveryLocation;
}
+ /**
+ * Returns coordinate of the delivery.
+ *
+ * @return coordinate of delivery
+ */
public Coordinate getDeliveryCoord() {
return deliveryCoord;
}
+ /**
+ * Returns service-time of delivery.
+ *
+ * @return service-time of delivery
+ */
public double getDeliveryServiceTime() {
return deliveryServiceTime;
}
+ /**
+ * Returns the time-window of delivery.
+ *
+ * @return time-window of delivery
+ */
public TimeWindow getDeliveryTimeWindow() {
return deliveryTimeWindow;
}
+ /**
+ * Returns the time-window of pickup.
+ *
+ * @return time-window of pickup
+ */
public TimeWindow getPickupTimeWindow() {
return pickupTimeWindow;
}
@@ -173,6 +340,11 @@ public class Shipment implements Job{
return result;
}
+ /**
+ * Two shipments are equal if they have the same id.
+ *
+ * @return true if shipments are equal (have the same id)
+ */
@Override
public boolean equals(Object obj) {
if (this == obj)
diff --git a/jsprit-core/src/test/java/jsprit/core/problem/job/ServiceTest.java b/jsprit-core/src/test/java/jsprit/core/problem/job/ServiceTest.java
index 3a1c82f0..05c5d753 100644
--- a/jsprit-core/src/test/java/jsprit/core/problem/job/ServiceTest.java
+++ b/jsprit-core/src/test/java/jsprit/core/problem/job/ServiceTest.java
@@ -16,7 +16,7 @@
******************************************************************************/
package jsprit.core.problem.job;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
diff --git a/jsprit-core/src/test/java/jsprit/core/problem/job/ShipmentTest.java b/jsprit-core/src/test/java/jsprit/core/problem/job/ShipmentTest.java
index 9fff73b9..1ff658c9 100644
--- a/jsprit-core/src/test/java/jsprit/core/problem/job/ShipmentTest.java
+++ b/jsprit-core/src/test/java/jsprit/core/problem/job/ShipmentTest.java
@@ -1,8 +1,8 @@
package jsprit.core.problem.job;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
-import jsprit.core.problem.job.Shipment;
import jsprit.core.problem.solution.route.activity.TimeWindow;
import jsprit.core.util.Coordinate;
@@ -38,20 +38,159 @@ public class ShipmentTest {
assertEquals(10,one.getCapacityDemand());
}
+ @Test(expected=IllegalArgumentException.class)
+ public void whenShipmentIsBuiltWithNegativeDemand_itShouldThrowException(){
+ @SuppressWarnings("unused")
+ Shipment one = Shipment.Builder.newInstance("s", -10).setPickupLocation("foo").setDeliveryLocation("foofoo").build();
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void whenIdIsNull_itShouldThrowException(){
+ @SuppressWarnings("unused")
+ Shipment one = Shipment.Builder.newInstance(null, 10).setPickupLocation("foo").setDeliveryLocation("foofoo").build();
+ }
+
@Test
- public void whenShipmentIsDefined_itsFieldsShouldBeDefinedCorrectly(){
- Shipment one = Shipment.Builder.newInstance("s", 10).setPickupLocation("foo").setPickupCoord(Coordinate.newInstance(0, 0)).setPickupServiceTime(1.0)
- .setPickupTimeWindow(TimeWindow.newInstance(0.0, 1.0))
- .setDeliveryLocation("foofoo").setDeliveryServiceTime(20).setDeliveryCoord(Coordinate.newInstance(1, 1)).
- setDeliveryTimeWindow(TimeWindow.newInstance(1.0, 2.0)).build();
- assertEquals("s",one.getId());
- assertEquals(10,one.getCapacityDemand());
- assertEquals("foo",one.getPickupLocation());
- assertEquals(0,one.getPickupCoord().getX(),0.01);
- assertEquals(1.0,one.getPickupServiceTime(),0.01);
- assertEquals("foofoo",one.getDeliveryLocation());
- assertEquals(20.0,one.getDeliveryServiceTime(),0.01);
- assertEquals(1.0,one.getDeliveryCoord().getX(),0.01);
- assertEquals(1.0,one.getDeliveryTimeWindow().getStart(),0.01);
+ public void whenCallingForANewBuilderInstance_itShouldReturnBuilderCorrectly(){
+ Shipment.Builder builder = Shipment.Builder.newInstance("s", 0);
+ assertNotNull(builder);
+ }
+
+ @Test(expected=IllegalStateException.class)
+ public void whenNeitherPickupLocationIdNorPickupCoord_itThrowsException(){
+ @SuppressWarnings("unused")
+ Shipment s = Shipment.Builder.newInstance("s", 0).setDeliveryLocation("delLoc").build();
+ }
+
+ @Test(expected=IllegalStateException.class)
+ public void whenNeitherDeliveryLocationIdNorDeliveryCoord_itThrowsException(){
+ @SuppressWarnings("unused")
+ Shipment s = Shipment.Builder.newInstance("s", 0).setPickupLocation("pickLoc").build();
+ }
+
+ @Test
+ public void whenPickupLocationIdIsSet_itShouldBeDoneCorrectly(){
+ Shipment s = Shipment.Builder.newInstance("s", 0).setDeliveryLocation("delLoc").setPickupLocation("pickLoc").build();
+ assertEquals("pickLoc",s.getPickupLocation());
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void whenPickupLocationIsNull_itThrowsException(){
+ @SuppressWarnings("unused")
+ Shipment.Builder builder = Shipment.Builder.newInstance("s", 0).setPickupLocation(null);
+ }
+
+ @Test
+ public void whenPickupCoordIsSet_itShouldBeDoneCorrectly(){
+ Shipment s = Shipment.Builder.newInstance("s", 0).setDeliveryLocation("delLoc").setPickupLocation("pickLoc").setPickupCoord(Coordinate.newInstance(1, 2)).build();
+ assertEquals(1.0,s.getPickupCoord().getX(),0.01);
+ assertEquals(2.0,s.getPickupCoord().getY(),0.01);
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void whenPickupCoordIsNull_itThrowsException(){
+ @SuppressWarnings("unused")
+ Shipment.Builder builder = Shipment.Builder.newInstance("s", 0).setPickupCoord(null);
+ }
+
+ @Test
+ public void whenDeliveryLocationIdIsSet_itShouldBeDoneCorrectly(){
+ Shipment s = Shipment.Builder.newInstance("s", 0).setDeliveryLocation("delLoc").setPickupLocation("pickLoc").build();
+ assertEquals("delLoc",s.getDeliveryLocation());
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void whenDeliveryLocationIsNull_itThrowsException(){
+ @SuppressWarnings("unused")
+ Shipment.Builder builder = Shipment.Builder.newInstance("s", 0).setDeliveryLocation(null);
+ }
+
+ @Test
+ public void whenDeliveryCoordIsSet_itShouldBeDoneCorrectly(){
+ Shipment s = Shipment.Builder.newInstance("s", 0).setDeliveryLocation("delLoc").setPickupLocation("pickLoc").setDeliveryCoord(Coordinate.newInstance(1, 2)).build();
+ assertEquals(1.0,s.getDeliveryCoord().getX(),0.01);
+ assertEquals(2.0,s.getDeliveryCoord().getY(),0.01);
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void whenDeliveryCoordIsNull_itThrowsException(){
+ @SuppressWarnings("unused")
+ Shipment.Builder builder = Shipment.Builder.newInstance("s", 0).setDeliveryCoord(null);
+ }
+
+ @Test
+ public void whenPickupServiceTimeIsNotSet_itShouldBeZero(){
+ Shipment s = Shipment.Builder.newInstance("s", 0).setDeliveryLocation("delLoc").setPickupLocation("pickLoc").build();
+ assertEquals(0.0,s.getPickupServiceTime(),0.01);
+ }
+
+ @Test
+ public void whenDeliveryServiceTimeIsNotSet_itShouldBeZero(){
+ Shipment s = Shipment.Builder.newInstance("s", 0).setDeliveryLocation("delLoc").setPickupLocation("pickLoc").build();
+ assertEquals(0.0,s.getDeliveryServiceTime(),0.01);
+ }
+
+ @Test
+ public void whenPickupServiceTimeIsSet_itShouldBeDoneCorrectly(){
+ Shipment s = Shipment.Builder.newInstance("s", 0).setPickupServiceTime(2.0).setDeliveryLocation("delLoc").setPickupLocation("pickLoc").build();
+ assertEquals(2.0,s.getPickupServiceTime(),0.01);
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void whenPickupServiceIsSmallerThanZero_itShouldThrowException(){
+ @SuppressWarnings("unused")
+ Shipment s = Shipment.Builder.newInstance("s", 0).setPickupServiceTime(-2.0).setDeliveryLocation("delLoc").setPickupLocation("pickLoc").build();
+ }
+
+ @Test
+ public void whenDeliveryServiceTimeIsSet_itShouldBeDoneCorrectly(){
+ Shipment s = Shipment.Builder.newInstance("s", 0).setDeliveryServiceTime(2.0).setDeliveryLocation("delLoc").setPickupLocation("pickLoc").build();
+ assertEquals(2.0,s.getDeliveryServiceTime(),0.01);
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void whenDeliveryServiceIsSmallerThanZero_itShouldThrowException(){
+ @SuppressWarnings("unused")
+ Shipment s = Shipment.Builder.newInstance("s", 0).setDeliveryServiceTime(-2.0).setDeliveryLocation("delLoc").setPickupLocation("pickLoc").build();
+ }
+
+ @Test
+ public void whenPickupTimeWindowIsNotSet_itShouldBeTheDefaultOne(){
+ Shipment s = Shipment.Builder.newInstance("s", 0).setDeliveryLocation("delLoc").setPickupLocation("pickLoc").build();
+ assertEquals(0.0,s.getPickupTimeWindow().getStart(),0.01);
+ assertEquals(Double.MAX_VALUE,s.getPickupTimeWindow().getEnd(),0.01);
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void whenPickupTimeWindowIsNull_itShouldThrowException(){
+ @SuppressWarnings("unused")
+ Shipment s = Shipment.Builder.newInstance("s", 0).setPickupTimeWindow(null).setDeliveryLocation("delLoc").setPickupLocation("pickLoc").build();
+ }
+
+ @Test
+ public void whenPickupTimeWindowIsSet_itShouldBeDoneCorrectly(){
+ Shipment s = Shipment.Builder.newInstance("s", 0).setPickupTimeWindow(TimeWindow.newInstance(1, 2)).setDeliveryLocation("delLoc").setPickupLocation("pickLoc").build();
+ assertEquals(1.0,s.getPickupTimeWindow().getStart(),0.01);
+ assertEquals(2.0,s.getPickupTimeWindow().getEnd(),0.01);
+ }
+
+ @Test
+ public void whenDeliveryTimeWindowIsNotSet_itShouldBeTheDefaultOne(){
+ Shipment s = Shipment.Builder.newInstance("s", 0).setDeliveryLocation("delLoc").setPickupLocation("pickLoc").build();
+ assertEquals(0.0,s.getDeliveryTimeWindow().getStart(),0.01);
+ assertEquals(Double.MAX_VALUE,s.getDeliveryTimeWindow().getEnd(),0.01);
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void whenDeliveryTimeWindowIsNull_itShouldThrowException(){
+ @SuppressWarnings("unused")
+ Shipment s = Shipment.Builder.newInstance("s", 0).setDeliveryTimeWindow(null).setDeliveryLocation("delLoc").setPickupLocation("pickLoc").build();
+ }
+
+ @Test
+ public void whenDeliveryTimeWindowIsSet_itShouldBeDoneCorrectly(){
+ Shipment s = Shipment.Builder.newInstance("s", 0).setDeliveryTimeWindow(TimeWindow.newInstance(1, 2)).setDeliveryLocation("delLoc").setPickupLocation("pickLoc").build();
+ assertEquals(1.0,s.getDeliveryTimeWindow().getStart(),0.01);
+ assertEquals(2.0,s.getDeliveryTimeWindow().getEnd(),0.01);
}
}
From 7c020ab67b69750576ea3e4cb74e4ac271ce941e Mon Sep 17 00:00:00 2001
From: jsprit You can find best results of different problems, instances and authors here:
+ * See {@link VrphType} what kind of problems can be generated
*
- * Note that c20_3-c20_6 do not have variable costs and a limited nuVehicle, thus they can only be used for FSMF.
- *
* @author schroeder
*
*/
@@ -110,6 +108,7 @@ public class VrphGoldenReader {
typeBuilder.setCostPerDistance(Double.parseDouble(tokens[4]));
nuOfVehicles = Integer.parseInt(tokens[5]);
vrpBuilder.setFleetSize(FleetSize.FINITE);
+ vrpBuilder.addPenaltyVehicles(5.0, 5000);
}
else throw new IllegalStateException("option " + vrphType + " cannot be applied with this instance");
}
@@ -119,6 +118,7 @@ public class VrphGoldenReader {
typeBuilder.setCostPerDistance(Double.parseDouble(tokens[4]));
nuOfVehicles = Integer.parseInt(tokens[5]);
vrpBuilder.setFleetSize(FleetSize.FINITE);
+ vrpBuilder.addPenaltyVehicles(5.0, 5000);
}
else throw new IllegalStateException("option " + vrphType + " cannot be applied with this instance");
}
From 844f2e1e1b6c2364c90f5e0e92b9290544e43103 Mon Sep 17 00:00:00 2001
From: Stefan Schroeder <4sschroeder@gmail.com>
Date: Mon, 20 Jan 2014 18:11:38 +0100
Subject: [PATCH 19/57] mod test
---
.../instance/reader/GoldenReaderTest.java | 33 +++++++++++--------
1 file changed, 20 insertions(+), 13 deletions(-)
diff --git a/jsprit-instances/src/test/java/jsprit/instance/reader/GoldenReaderTest.java b/jsprit-instances/src/test/java/jsprit/instance/reader/GoldenReaderTest.java
index bd482aab..787dbe5b 100644
--- a/jsprit-instances/src/test/java/jsprit/instance/reader/GoldenReaderTest.java
+++ b/jsprit-instances/src/test/java/jsprit/instance/reader/GoldenReaderTest.java
@@ -6,6 +6,7 @@ import static org.junit.Assert.assertTrue;
import jsprit.core.problem.VehicleRoutingProblem;
import jsprit.core.problem.job.Job;
import jsprit.core.problem.job.Service;
+import jsprit.core.problem.vehicle.PenaltyVehicleType;
import jsprit.core.problem.vehicle.Vehicle;
import jsprit.core.util.Coordinate;
import jsprit.instance.reader.VrphGoldenReader.VrphType;
@@ -20,7 +21,13 @@ public class GoldenReaderTest {
new VrphGoldenReader(vrpBuilder, VrphType.HVRPD)
.read(this.getClass().getClassLoader().getResource("cn_13mix.txt").getPath());
VehicleRoutingProblem vrp = vrpBuilder.build();
- assertEquals(17,vrp.getVehicles().size());
+ int nuOfVehicles = 0;
+ for(Vehicle v : vrp.getVehicles()){
+ if(!(v.getType() instanceof PenaltyVehicleType)){
+ nuOfVehicles++;
+ }
+ }
+ assertEquals(17,nuOfVehicles);
}
@Test
@@ -31,7 +38,7 @@ public class GoldenReaderTest {
VehicleRoutingProblem vrp = vrpBuilder.build();
int nuOfType1Vehicles = 0;
for(Vehicle v : vrp.getVehicles()){
- if(v.getType().getTypeId().equals("type_1")){
+ if(v.getType().getTypeId().equals("type_1") && !(v.getType() instanceof PenaltyVehicleType) ){
nuOfType1Vehicles++;
}
}
@@ -46,7 +53,7 @@ public class GoldenReaderTest {
VehicleRoutingProblem vrp = vrpBuilder.build();
int sumOfType1Cap = 0;
for(Vehicle v : vrp.getVehicles()){
- if(v.getType().getTypeId().equals("type_1")){
+ if(v.getType().getTypeId().equals("type_1") && !(v.getType() instanceof PenaltyVehicleType) ){
sumOfType1Cap+=v.getCapacity();
}
}
@@ -61,7 +68,7 @@ public class GoldenReaderTest {
VehicleRoutingProblem vrp = vrpBuilder.build();
int nuOfType1Vehicles = 0;
for(Vehicle v : vrp.getVehicles()){
- if(v.getType().getTypeId().equals("type_2")){
+ if(v.getType().getTypeId().equals("type_2") && !(v.getType() instanceof PenaltyVehicleType) ){
nuOfType1Vehicles++;
}
}
@@ -76,7 +83,7 @@ public class GoldenReaderTest {
VehicleRoutingProblem vrp = vrpBuilder.build();
int sumOfType1Cap = 0;
for(Vehicle v : vrp.getVehicles()){
- if(v.getType().getTypeId().equals("type_2")){
+ if(v.getType().getTypeId().equals("type_2") && !(v.getType() instanceof PenaltyVehicleType) ){
sumOfType1Cap+=v.getCapacity();
}
}
@@ -91,7 +98,7 @@ public class GoldenReaderTest {
VehicleRoutingProblem vrp = vrpBuilder.build();
int nuOfType1Vehicles = 0;
for(Vehicle v : vrp.getVehicles()){
- if(v.getType().getTypeId().equals("type_3")){
+ if(v.getType().getTypeId().equals("type_3") && !(v.getType() instanceof PenaltyVehicleType) ){
nuOfType1Vehicles++;
}
}
@@ -106,7 +113,7 @@ public class GoldenReaderTest {
VehicleRoutingProblem vrp = vrpBuilder.build();
int sumOfType1Cap = 0;
for(Vehicle v : vrp.getVehicles()){
- if(v.getType().getTypeId().equals("type_3")){
+ if(v.getType().getTypeId().equals("type_3") && !(v.getType() instanceof PenaltyVehicleType) ){
sumOfType1Cap+=v.getCapacity();
}
}
@@ -121,7 +128,7 @@ public class GoldenReaderTest {
VehicleRoutingProblem vrp = vrpBuilder.build();
int nuOfType1Vehicles = 0;
for(Vehicle v : vrp.getVehicles()){
- if(v.getType().getTypeId().equals("type_4")){
+ if(v.getType().getTypeId().equals("type_4") && !(v.getType() instanceof PenaltyVehicleType) ){
nuOfType1Vehicles++;
}
}
@@ -136,7 +143,7 @@ public class GoldenReaderTest {
VehicleRoutingProblem vrp = vrpBuilder.build();
int sumOfType1Cap = 0;
for(Vehicle v : vrp.getVehicles()){
- if(v.getType().getTypeId().equals("type_4")){
+ if(v.getType().getTypeId().equals("type_4") && !(v.getType() instanceof PenaltyVehicleType) ){
sumOfType1Cap+=v.getCapacity();
}
}
@@ -151,7 +158,7 @@ public class GoldenReaderTest {
VehicleRoutingProblem vrp = vrpBuilder.build();
int nuOfType1Vehicles = 0;
for(Vehicle v : vrp.getVehicles()){
- if(v.getType().getTypeId().equals("type_5")){
+ if(v.getType().getTypeId().equals("type_5") && !(v.getType() instanceof PenaltyVehicleType) ){
nuOfType1Vehicles++;
}
}
@@ -166,7 +173,7 @@ public class GoldenReaderTest {
VehicleRoutingProblem vrp = vrpBuilder.build();
int sumOfType1Cap = 0;
for(Vehicle v : vrp.getVehicles()){
- if(v.getType().getTypeId().equals("type_5")){
+ if(v.getType().getTypeId().equals("type_5") && !(v.getType() instanceof PenaltyVehicleType) ){
sumOfType1Cap+=v.getCapacity();
}
}
@@ -181,7 +188,7 @@ public class GoldenReaderTest {
VehicleRoutingProblem vrp = vrpBuilder.build();
int nuOfType1Vehicles = 0;
for(Vehicle v : vrp.getVehicles()){
- if(v.getType().getTypeId().equals("type_6")){
+ if(v.getType().getTypeId().equals("type_6") && !(v.getType() instanceof PenaltyVehicleType) ){
nuOfType1Vehicles++;
}
}
@@ -196,7 +203,7 @@ public class GoldenReaderTest {
VehicleRoutingProblem vrp = vrpBuilder.build();
int sumOfType1Cap = 0;
for(Vehicle v : vrp.getVehicles()){
- if(v.getType().getTypeId().equals("type_6")){
+ if(v.getType().getTypeId().equals("type_6") && !(v.getType() instanceof PenaltyVehicleType) ){
sumOfType1Cap+=v.getCapacity();
}
}
From 153899748b1cd62d1930662f443b4b152b0cf59e Mon Sep 17 00:00:00 2001
From: Stefan Schroeder <4sschroeder@gmail.com>
Date: Thu, 23 Jan 2014 11:10:06 +0100
Subject: [PATCH 20/57] does not allow VrpReader to set null coord
---
.../src/main/java/jsprit/core/problem/io/VrpXMLReader.java | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/jsprit-core/src/main/java/jsprit/core/problem/io/VrpXMLReader.java b/jsprit-core/src/main/java/jsprit/core/problem/io/VrpXMLReader.java
index 4b8dfe2f..71b54d3f 100644
--- a/jsprit-core/src/main/java/jsprit/core/problem/io/VrpXMLReader.java
+++ b/jsprit-core/src/main/java/jsprit/core/problem/io/VrpXMLReader.java
@@ -320,9 +320,9 @@ public class VrpXMLReader{
builder.setPickupLocation(pickupLocationId);
Coordinate pickupCoord = getCoord(shipmentConfig,"pickup.");
- builder.setPickupCoord(pickupCoord);
-
+
if(pickupCoord != null){
+ builder.setPickupCoord(pickupCoord);
if(pickupLocationId != null){
vrpBuilder.addLocation(pickupLocationId,pickupCoord);
}
@@ -341,9 +341,9 @@ public class VrpXMLReader{
builder.setDeliveryLocation(deliveryLocationId);
Coordinate deliveryCoord = getCoord(shipmentConfig,"delivery.");
- builder.setDeliveryCoord(deliveryCoord);
if(deliveryCoord != null){
+ builder.setDeliveryCoord(deliveryCoord);
if(deliveryLocationId != null){
vrpBuilder.addLocation(deliveryLocationId,deliveryCoord);
}
From aacece58c50906218ad39253dc200a6e2e261038 Mon Sep 17 00:00:00 2001
From: Stefan Schroeder <4sschroeder@gmail.com>
Date: Thu, 23 Jan 2014 11:13:03 +0100
Subject: [PATCH 21/57] does not allow reader to set null coord
---
.../src/main/java/jsprit/core/problem/io/VrpXMLReader.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/jsprit-core/src/main/java/jsprit/core/problem/io/VrpXMLReader.java b/jsprit-core/src/main/java/jsprit/core/problem/io/VrpXMLReader.java
index 71b54d3f..db8dffba 100644
--- a/jsprit-core/src/main/java/jsprit/core/problem/io/VrpXMLReader.java
+++ b/jsprit-core/src/main/java/jsprit/core/problem/io/VrpXMLReader.java
@@ -393,8 +393,8 @@ public class VrpXMLReader{
String serviceLocationId = serviceConfig.getString("locationId");
builder.setLocationId(serviceLocationId);
Coordinate serviceCoord = getCoord(serviceConfig,"");
- builder.setCoord(serviceCoord);
if(serviceCoord != null){
+ builder.setCoord(serviceCoord);
if(serviceLocationId != null){
vrpBuilder.addLocation(serviceLocationId,serviceCoord);
}
From cef0453c9064b7c9c0a8a223a325a17488f01630 Mon Sep 17 00:00:00 2001
From: Stefan Schroeder <4sschroeder@gmail.com>
Date: Thu, 23 Jan 2014 11:23:27 +0100
Subject: [PATCH 22/57] bugfix issue #77
---
.../main/java/jsprit/core/problem/io/VrpXMLReader.java | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/jsprit-core/src/main/java/jsprit/core/problem/io/VrpXMLReader.java b/jsprit-core/src/main/java/jsprit/core/problem/io/VrpXMLReader.java
index db8dffba..e29e9cc8 100644
--- a/jsprit-core/src/main/java/jsprit/core/problem/io/VrpXMLReader.java
+++ b/jsprit-core/src/main/java/jsprit/core/problem/io/VrpXMLReader.java
@@ -332,10 +332,10 @@ public class VrpXMLReader{
}
}
-// String pickupTWStart = shipmentConfig.getString("pickup.timeWindows.timeWindow(0).start");
-// String pickupTWEnd = shipmentConfig.getString("pickup.timeWindows.timeWindow(0).end");
-// TimeWindow pickupTW = TimeWindow.newInstance(Double.parseDouble(pickupTWStart), Double.parseDouble(pickupTWEnd));
-// builder.setPickupTimeWindow(pickupTW);
+ String pickupTWStart = shipmentConfig.getString("pickup.timeWindows.timeWindow(0).start");
+ String pickupTWEnd = shipmentConfig.getString("pickup.timeWindows.timeWindow(0).end");
+ TimeWindow pickupTW = TimeWindow.newInstance(Double.parseDouble(pickupTWStart), Double.parseDouble(pickupTWEnd));
+ builder.setPickupTimeWindow(pickupTW);
String deliveryLocationId = shipmentConfig.getString("delivery.locationId");
builder.setDeliveryLocation(deliveryLocationId);
From 8f749c9fdfcba146660132624414c333fc3a19e8 Mon Sep 17 00:00:00 2001
From: Stefan Schroeder <4sschroeder@gmail.com>
Date: Thu, 23 Jan 2014 12:07:19 +0100
Subject: [PATCH 23/57] bugfix issue #78
---
.../jsprit/core/problem/io/VrpXMLReader.java | 34 ++--
.../src/main/resources/vrp_xml_schema.xsd | 8 +-
.../core/problem/io/VrpReaderV2Test.java | 151 +++++++++++++++++-
.../resources/finiteVrpForReaderV2Test.xml | 39 ++++-
4 files changed, 203 insertions(+), 29 deletions(-)
diff --git a/jsprit-core/src/main/java/jsprit/core/problem/io/VrpXMLReader.java b/jsprit-core/src/main/java/jsprit/core/problem/io/VrpXMLReader.java
index e29e9cc8..ab4628da 100644
--- a/jsprit-core/src/main/java/jsprit/core/problem/io/VrpXMLReader.java
+++ b/jsprit-core/src/main/java/jsprit/core/problem/io/VrpXMLReader.java
@@ -316,11 +316,14 @@ public class VrpXMLReader{
int cap = getCap(shipmentConfig);
Shipment.Builder builder = Shipment.Builder.newInstance(id, cap);
+ //pickup-locationId
String pickupLocationId = shipmentConfig.getString("pickup.locationId");
- builder.setPickupLocation(pickupLocationId);
+ if(pickupLocationId != null){
+ builder.setPickupLocation(pickupLocationId);
+ }
+ //pickup-coord
Coordinate pickupCoord = getCoord(shipmentConfig,"pickup.");
-
if(pickupCoord != null){
builder.setPickupCoord(pickupCoord);
if(pickupLocationId != null){
@@ -331,17 +334,23 @@ public class VrpXMLReader{
builder.setPickupLocation(pickupCoord.toString());
}
}
-
+ //pickup-tw
String pickupTWStart = shipmentConfig.getString("pickup.timeWindows.timeWindow(0).start");
String pickupTWEnd = shipmentConfig.getString("pickup.timeWindows.timeWindow(0).end");
- TimeWindow pickupTW = TimeWindow.newInstance(Double.parseDouble(pickupTWStart), Double.parseDouble(pickupTWEnd));
- builder.setPickupTimeWindow(pickupTW);
+ if(pickupTWStart != null && pickupTWEnd != null){
+ TimeWindow pickupTW = TimeWindow.newInstance(Double.parseDouble(pickupTWStart), Double.parseDouble(pickupTWEnd));
+ builder.setPickupTimeWindow(pickupTW);
+ }
+
+ //delivery-locaitonId
String deliveryLocationId = shipmentConfig.getString("delivery.locationId");
- builder.setDeliveryLocation(deliveryLocationId);
+ if(deliveryLocationId != null){
+ builder.setDeliveryLocation(deliveryLocationId);
+ }
+ //delivery-coord
Coordinate deliveryCoord = getCoord(shipmentConfig,"delivery.");
-
if(deliveryCoord != null){
builder.setDeliveryCoord(deliveryCoord);
if(deliveryLocationId != null){
@@ -349,14 +358,17 @@ public class VrpXMLReader{
}
else{
vrpBuilder.addLocation(deliveryCoord.toString(),deliveryCoord);
- builder.setPickupLocation(deliveryCoord.toString());
+ builder.setDeliveryLocation(deliveryCoord.toString());
}
}
String delTWStart = shipmentConfig.getString("delivery.timeWindows.timeWindow(0).start");
String delTWEnd = shipmentConfig.getString("delivery.timeWindows.timeWindow(0).end");
- TimeWindow delTW = TimeWindow.newInstance(Double.parseDouble(delTWStart), Double.parseDouble(delTWEnd));
- builder.setDeliveryTimeWindow(delTW);
+ if(delTWStart != null && delTWEnd != null){
+ TimeWindow delTW = TimeWindow.newInstance(Double.parseDouble(delTWStart), Double.parseDouble(delTWEnd));
+ builder.setDeliveryTimeWindow(delTW);
+ }
+
Shipment shipment = builder.build();
vrpBuilder.addJob(shipment);
@@ -391,7 +403,7 @@ public class VrpXMLReader{
int cap = getCap(serviceConfig);
Service.Builder builder = serviceBuilderFactory.createBuilder(type, id, cap);
String serviceLocationId = serviceConfig.getString("locationId");
- builder.setLocationId(serviceLocationId);
+ if(serviceLocationId != null) builder.setLocationId(serviceLocationId);
Coordinate serviceCoord = getCoord(serviceConfig,"");
if(serviceCoord != null){
builder.setCoord(serviceCoord);
diff --git a/jsprit-core/src/main/resources/vrp_xml_schema.xsd b/jsprit-core/src/main/resources/vrp_xml_schema.xsd
index 0b64fe56..421e9574 100644
--- a/jsprit-core/src/main/resources/vrp_xml_schema.xsd
+++ b/jsprit-core/src/main/resources/vrp_xml_schema.xsd
@@ -40,7 +40,7 @@
An empty route has an empty list of tour-activities, no driver (DriverImpl.noDriver()) and no vehicle (VehicleImpl.createNoVehicle()).
+ *
+ * @return
+ */
public static VehicleRoute emptyRoute() {
return new VehicleRoute(TourActivities.emptyTour(), DriverImpl.noDriver(), VehicleImpl.createNoVehicle());
}
+ /**
+ * Builder that builds the vehicle route.
+ *
+ * @author stefan
+ *
+ */
public static class Builder {
+ /**
+ * Returns new instance of this builder.
+ *
+ * @param vehicle
+ * @param driver
+ * @return this builder
+ */
public static Builder newInstance(Vehicle vehicle, Driver driver){
return new Builder(vehicle,driver);
}
@@ -73,10 +116,24 @@ public class VehicleRoute {
private Set By default {@link DefaultTourActivityFactory} is used.
+ *
+ * @param serviceActivityFactory
+ */
public void setServiceActivityFactory(TourActivityFactory serviceActivityFactory) {
this.serviceActivityFactory = serviceActivityFactory;
}
+ /**
+ * Sets the shipmentActivityFactory to create shipmentActivities.
+ *
+ * By default {@link DefaultShipmentActivityFactory} is used.
+ *
+ * @param shipmentActivityFactory
+ */
public void setShipmentActivityFactory(TourShipmentActivityFactory shipmentActivityFactory) {
this.shipmentActivityFactory = shipmentActivityFactory;
}
@@ -100,7 +157,7 @@ public class VehicleRoute {
}
/**
- * Sets the departure-time of the route.
+ * Sets the departure-time of the route, i.e. which is the time the vehicle departs from start-location.
*
* @param departureTime
* @return
@@ -110,16 +167,46 @@ public class VehicleRoute {
return this;
}
+ /**
+ * Sets the end-time of the route, i.e. which is the time the vehicle has to be at its end-location at latest.
+ *
+ * @param endTime
+ * @return this builder
+ */
public Builder setRouteEndArrivalTime(double endTime){
end.setArrTime(endTime);
return this;
}
+ /**
+ * Adds a service to this route.
+ *
+ * This implies that for this service a serviceActivity is created with {@link TourActivityFactory} and added to the sequence of tourActivities.
+ *
+ * The resulting activity occurs in the activity-sequence in the order adding/inserting.
+ *
+ * @param service
+ * @return this builder
+ * @throws IllegalArgumentException if service is null
+ */
public Builder addService(Service service){
+ if(service == null) throw new IllegalArgumentException("service must not be null");
addService(service,0.0,0.0);
return this;
}
+ /**
+ * Adds a service with specified activity arrival- and endTime.
+ *
+ * This implies that for this service a serviceActivity is created with {@link TourActivityFactory} and added to the sequence of tourActivities.
+ *
+ * Basically this activity is then scheduled with an activity arrival and activity endTime.
+ *
+ * @param service
+ * @param arrTime
+ * @param endTime
+ * @return builder
+ */
public Builder addService(Service service, double arrTime, double endTime){
TourActivity act = serviceActivityFactory.createActivity(service);
act.setArrTime(arrTime);
@@ -266,15 +353,38 @@ public class VehicleRoute {
return tourActivities;
}
-
+ /**
+ * Returns the vehicle operating this route.
+ *
+ * @return Vehicle
+ */
public Vehicle getVehicle() {
return vehicle;
}
+ /**
+ * Returns the driver operating this route.
+ *
+ * @return Driver
+ */
public Driver getDriver() {
return driver;
}
+ /**
+ * Sets the vehicle and its departureTime.
+ *
+ * This implies the following: startActivity is initialized with the location of the specified vehicle. the time-window of this activity is initialized
+ * as follows: [time-window.start = vehicle.getEarliestDeparture()][time-window.end = vehicle.getLatestArrival()]
+ * endActivity is initialized with the location of the specified vehicle as well. time-window of this activity:[time-window.start = vehicle.getEarliestDeparture()][time-window.end = vehicle.getLatestArrival()]
+ * start.endTime is set to the specified departureTime
+ * Note that start end end-locations are always initialized with the location of the specified vehicle. (this will change soon, then there will be start and end location of vehicle which can be different, 23.01.14)
+ *
+ * @param vehicle
+ * @param vehicleDepTime
+ */
public void setVehicle(Vehicle vehicle, double vehicleDepTime){
this.vehicle = vehicle;
setStartAndEnd(vehicle, vehicleDepTime);
@@ -297,24 +407,50 @@ public class VehicleRoute {
}
+ /**
+ * Sets departureTime of this route, i.e. the time the vehicle departs from its start-location.
+ *
+ * @param vehicleDepTime
+ */
public void setDepartureTime(double vehicleDepTime){
if(start == null) throw new IllegalStateException("cannot set departureTime without having a vehicle on this route. use setVehicle(vehicle,departureTime) instead.");
start.setEndTime(vehicleDepTime);
}
+ /**
+ * Returns the departureTime of this vehicle.
+ *
+ * @return departureTime
+ * @throws IllegalStateException if start is null
+ */
public double getDepartureTime(){
if(start == null) throw new IllegalStateException("cannot get departureTime without having a vehicle on this route. use setVehicle(vehicle,departureTime) instead.");
return start.getEndTime();
}
+ /**
+ * Returns tour if tour-activity-sequence is empty, i.e. to activity on the tour yet.
+ *
+ * @return
+ */
public boolean isEmpty() {
return tourActivities.isEmpty();
}
+ /**
+ * Returns start-activity of this route.
+ *
+ * @return start
+ */
public Start getStart() {
return start;
}
+ /**
+ * Returns end-activity of this route.
+ *
+ * @return end
+ */
public End getEnd() {
return end;
}
From a05a342a67a95741464b6f4dda1235ef57da68ad Mon Sep 17 00:00:00 2001
From: jsprit Print.CONCISE and Print.VERBOSE are available.
+ *
+ * @author stefan schroeder
+ *
+ */
+ public enum Print {
+
+ CONCISE,VERBOSE
+ }
+
+ /**
+ * Prints costs and #vehicles to stdout (System.out.println).
+ *
+ * @param solution
+ */
+ public static void print(VehicleRoutingProblemSolution solution){
+ System.out.println("[costs="+solution.getCost() + "]");
+ System.out.println("[#vehicles="+solution.getRoutes().size() + "]");
+
+ }
+
+ private static class Jobs {
+ int nServices;
+ int nShipments;
+ public Jobs(int nServices, int nShipments) {
+ super();
+ this.nServices = nServices;
+ this.nShipments = nShipments;
+ }
+ }
+
+ public static void print(VehicleRoutingProblem problem, VehicleRoutingProblemSolution solution, Print print){
+ String leftAlign = "| %-13s | %-8s | %n";
+
+ System.out.format("+--------------------------+%n");
+ System.out.printf("| problem |%n");
+ System.out.format("+---------------+----------+%n");
+ System.out.printf("| indicator | value |%n");
+ System.out.format("+---------------+----------+%n");
+
+ System.out.format(leftAlign, "nJobs", problem.getJobs().values().size());
+ Jobs jobs = getNuOfJobs(problem);
+ System.out.format(leftAlign, "nServices",jobs.nServices);
+ System.out.format(leftAlign, "nShipments",jobs.nShipments);
+ System.out.format(leftAlign, "fleetsize",problem.getFleetSize().toString());
+ System.out.format("+--------------------------+%n");
+
+
+ String leftAlignSolution = "| %-13s | %-40s | %n";
+ System.out.format("+----------------------------------------------------------+%n");
+ System.out.printf("| solution |%n");
+ System.out.format("+---------------+------------------------------------------+%n");
+ System.out.printf("| indicator | value |%n");
+ System.out.format("+---------------+------------------------------------------+%n");
+ System.out.format(leftAlignSolution, "costs",solution.getCost());
+ System.out.format(leftAlignSolution, "nVehicles",solution.getRoutes().size());
+ System.out.format("+----------------------------------------------------------+%n");
+
+ if(print.equals(Print.VERBOSE)){
+ printVerbose(problem,solution);
+ }
+ }
+
+ private static void printVerbose(VehicleRoutingProblem problem, VehicleRoutingProblemSolution solution) {
+ String leftAlgin = "| %-7s | %-20s | %-21s | %-15s | %-15s | %-15s | %-15s |%n";
+ System.out.format("+--------------------------------------------------------------------------------------------------------------------------------+%n");
+ System.out.printf("| detailed solution |%n");
+ System.out.format("+---------+----------------------+-----------------------+-----------------+-----------------+-----------------+-----------------+%n");
+ System.out.printf("| route | vehicle | activity | job | arrTime | endTime | costs |%n");
+ int routeNu = 1;
+ for(VehicleRoute route : solution.getRoutes()){
+ System.out.format("+---------+----------------------+-----------------------+-----------------+-----------------+-----------------+-----------------+%n");
+ double costs = 0;
+ System.out.format(leftAlgin, routeNu, route.getVehicle().getId(), route.getStart().getName(), "-", "undef", Math.round(route.getStart().getEndTime()),Math.round(costs));
+ TourActivity prevAct = route.getStart();
+ for(TourActivity act : route.getActivities()){
+ String jobId;
+ if(act instanceof JobActivity) jobId = ((JobActivity)act).getJob().getId();
+ else jobId = "-";
+ double c = problem.getTransportCosts().getTransportCost(prevAct.getLocationId(), act.getLocationId(), prevAct.getEndTime(), route.getDriver(), route.getVehicle());
+ c+= problem.getActivityCosts().getActivityCost(act, act.getArrTime(), route.getDriver(), route.getVehicle());
+ costs+=c;
+ System.out.format(leftAlgin, routeNu, route.getVehicle().getId(), act.getName(), jobId, Math.round(act.getArrTime()), Math.round(act.getEndTime()),Math.round(costs));
+ prevAct=act;
+ }
+ double c = problem.getTransportCosts().getTransportCost(prevAct.getLocationId(), route.getEnd().getLocationId(), prevAct.getEndTime(), route.getDriver(), route.getVehicle());
+ c+= problem.getActivityCosts().getActivityCost(route.getEnd(), route.getEnd().getArrTime(), route.getDriver(), route.getVehicle());
+ costs+=c;
+ System.out.format(leftAlgin, routeNu, route.getVehicle().getId(), route.getEnd().getName(), "-", Math.round(route.getEnd().getArrTime()), "undef", Math.round(costs));
+ routeNu++;
+ }
+ System.out.format("+--------------------------------------------------------------------------------------------------------------------------------+%n");
+ }
+
+ private static Jobs getNuOfJobs(VehicleRoutingProblem problem) {
+ int nShipments = 0;
+ int nServices = 0;
+ for(Job j : problem.getJobs().values()){
+ if(j instanceof Shipment) nShipments++;
+ if(j instanceof Service) nServices++;
+ }
+ return new Jobs(nServices,nShipments);
+ }
+
+// /**
+// * Prints the details of the solution according to a print-level, i.e. Print.CONCISE or PRINT.VERBOSE.
+// *
+// * CONCISE prints total-costs and #vehicles.
+// * VERBOSE prints the route-details additionally. If the DefaultVehicleRouteCostCalculator (which is the standard-calculator)
+// * is used in VehicleRoute, then route-costs are differentiated further between transport, activity, vehicle, driver and other-costs.
+// *
+// * @param solution
+// * @param level
+// *
+// * @deprecated is not going to work anymore
+// */
+// @Deprecated
+// public static void print(VehicleRoutingProblemSolution solution, Print level){
+// if(level.equals(Print.CONCISE)){
+// print(solution);
+// }
+// else{
+// print(solution);
+// System.out.println("routes");
+// int routeCount = 1;
+// for(VehicleRoute route : solution.getRoutes()){
+// System.out.println("[route="+routeCount+"][departureTime="+route.getStart().getEndTime()+"[total=" + route.getCost() + "]");
+// if(route.getVehicleRouteCostCalculator() instanceof DefaultVehicleRouteCostCalculator){
+// DefaultVehicleRouteCostCalculator defaultCalc = (DefaultVehicleRouteCostCalculator) route.getVehicleRouteCostCalculator();
+// System.out.println("[transport=" + defaultCalc.getTpCosts() + "][activity=" + defaultCalc.getActCosts() +
+// "][vehicle=" + defaultCalc.getVehicleCosts() + "][driver=" + defaultCalc.getDriverCosts() + "][other=" + defaultCalc.getOther() + "]");
+// }
+// routeCount++;
+// }
+// }
+//
+//
+// }
+
+}
From 7aa8189cabbfb0bff79f5a0e96cdf80a6b39c1af Mon Sep 17 00:00:00 2001
From: Stefan Schroeder <4sschroeder@gmail.com>
Date: Fri, 31 Jan 2014 14:36:13 +0100
Subject: [PATCH 52/57] misc
---
.../test/java/jsprit/core/algorithm/RefuseCollection_IT.java | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/jsprit-core/src/test/java/jsprit/core/algorithm/RefuseCollection_IT.java b/jsprit-core/src/test/java/jsprit/core/algorithm/RefuseCollection_IT.java
index ccf9ffbf..abd5e244 100644
--- a/jsprit-core/src/test/java/jsprit/core/algorithm/RefuseCollection_IT.java
+++ b/jsprit-core/src/test/java/jsprit/core/algorithm/RefuseCollection_IT.java
@@ -37,6 +37,8 @@ import jsprit.core.problem.solution.VehicleRoutingProblemSolution;
import jsprit.core.problem.vehicle.Vehicle;
import jsprit.core.problem.vehicle.VehicleImpl;
import jsprit.core.problem.vehicle.VehicleTypeImpl;
+import jsprit.core.reporting.SolutionPrinter;
+import jsprit.core.reporting.SolutionPrinter.Print;
import jsprit.core.util.Solutions;
import jsprit.core.util.VehicleRoutingTransportCostsMatrix;
import jsprit.core.util.VehicleRoutingTransportCostsMatrix.Builder;
@@ -188,6 +190,8 @@ public class RefuseCollection_IT {
vra.setPrematureAlgorithmTermination(new IterationWithoutImprovementTermination(100));
Collection
http://link.springer.com/article/10.1007%2Fs10732-011-9186-y
*
http://www2.ic.uff.br/~satoru/conteudo/artigos/PAPER%20PUCA-JHeuristics-2011.pdf
*
http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.100.2331&rep=rep1&type=pdf
*
From 95441ac8e6ede1e65a11d7f166d8639743915989 Mon Sep 17 00:00:00 2001
From: jsprit
+ * if start and end are null, new start and end activities are created.
+ *