diff --git a/CHANGELOG.md b/CHANGELOG.md
index 28122e2a..574c7ed2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,46 @@
Change-log
==========
+**v1.1.1** @ 2014-01-31
+
+jsprit-core:
+- fixed bug: [#80](https://github.com/jsprit/jsprit/issues/80)
+- added new package reporting with basic reporting
+
+**v1.1.0** @ 2014-01-27
+
+- [detailed changelog](https://github.com/jsprit/misc-rep/raw/master/changelog_1.0.0_to_1.1.0.txt)
+
+jsprit-core:
+- added javadocs (VehicleRoutingProblem and classes in package vehicle. and job.)
+- added unit-tests (for classes in package vehicle., job. and io.)
+- deprecated methods in VehicleRoutingProblem, VehicleTypeImpl, VehicleImpl
+- added func in VehicleRoutingProblem.Builder (.addPenaltyVehicle(...) methods)
+- added feature: open-routes ([#54](https://github.com/jsprit/jsprit/issues/54))
+- added func in VehicleImpl and VehicleImpl.Builder (.setReturnToDepot(...), isReturnToDepot())
+- added feature: prohibit vehicles to take over entire route ([#70](https://github.com/jsprit/jsprit/issues/70))
+- fixed bug: [#58](https://github.com/jsprit/jsprit/issues/58),[#76](https://github.com/jsprit/jsprit/issues/76)-[#79](https://github.com/jsprit/jsprit/issues/79)
+- added abstract class AbstractForwardVehicleRoutingCosts
+- inspected and removed all warnings
+- visibility of methods activity.Start.get/setCoordinate(...) decreased from public to package [potential Break Change]
+- visibility of methods activity.End.get/setCoordinate(...) decreased from public to package [potential Break Change]
+- method isReturnToDepot() has been added to interface Vehicle [potential Break Change]
+- visibility of constructor VehicleImpl.Builder decreased from public to private [potential Break Change]
+
+jsprit-analysis:
+- added GraphStreamViewer
+- inspected and removed all warnings
+
+jsprit-example:
+- added BicycleMessenger
+- enriched examples with GraphStreamViewer
+- inspected and removed all warnings
+
+jsprit-instance:
+- added VrphGoldenReader (plus instances to bechmark VRPH)
+- inspected and removed all warnings
+
+
+
**v1.0.0** @ 2013-11-26 (break change)
- re-organized API
diff --git a/README.md b/README.md
index 8eb7797e..22d84746 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
jsprit
======
jsprit is a java based, open source toolkit for solving rich traveling salesman (TSP) and vehicle routing problems (VRP).
-It is lightweight, flexible and easy-to-use, and based on a single all-purpose meta-heuristic currently solving
+It is lightweight, flexible and easy-to-use, and based on a single all-purpose meta-heuristic currently solving
- Capacitated VRP
- Multiple Depot VRP
- VRP with Time Windows
@@ -16,10 +16,6 @@ It is lightweight, flexible and easy-to-use, and based on a single all-purpose <
Setting up the problem, defining additional constraints, modifying the algorithms and visualising the discovered solutions is as easy and handy as
reading classical VRP instances to benchmark your algorithm. It is fit for change and extension due to a modular design and a comprehensive set of unit and integration-tests.
-Additionally, jsprit can be used along with MATSim
-to solve the above problem-types in real networks (i.e. without preprocessing transport times and costs). A variety of least cost path algorithms such as Dijkstra and A*
-can be used, and a dynamic and interactive visualiser greatly enhances the analysis.
-
##In Development
- continues improvement of code, handling and performance
- soft constraints
@@ -41,6 +37,8 @@ This software is released under [LGPL](http://opensource.org/licenses/LGPL-3.0).
[Add the latest release to your pom](https://github.com/jsprit/jsprit/wiki/Add-latest-release-to-your-pom).
+If you do not want Maven to manage your dependencies, go to [snapshot-jars](https://github.com/jsprit/mvn-rep/tree/master/snapshots/jsprit) or [realease-jars](https://github.com/jsprit/mvn-rep/tree/master/releases/jsprit) to download jsprit-binaries directly. Just click on the jar-file you want to download and use the 'Raw'-button to actually download it. Put the jars into your classpath. Note that you then need to put all [dependencies](https://github.com/jsprit/jsprit/wiki/Modules-and-Dependencies) jsprit relies on manually to your classpath as well.
+
####If not
The following documentation is recommended:
diff --git a/jsprit-analysis/pom.xml b/jsprit-analysis/pom.xml
index 9beae624..08b33b45 100644
--- a/jsprit-analysis/pom.xml
+++ b/jsprit-analysis/pom.xml
@@ -22,7 +22,7 @@
It determines how much capacity this job consumes of vehicle/transport unit. + * + * @deprecated use getCapacity() instead + * @return + */ @Deprecated public int getCapacityDemand(); 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..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 @@ -16,18 +16,47 @@ ******************************************************************************/ 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 + * @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) { super(id, size); } + /** + * Builds Pickup. + * + *
Pickup type is "pickup" + * + * @return pickup + * @throw 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 +68,11 @@ public class Pickup extends Service { } + /** + * Constructs the Pickup + * + * @param builder + */ Pickup(Builder builder) { super(builder); } 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 b4124b46..6b97bd3a 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 @@ -20,11 +20,35 @@ import jsprit.core.problem.Capacity; 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 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. + * + * @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 + * @throws IllegalArgumentException if size < 0 or id is null + */ public static Builder newInstance(String id, int size){ Builder builder = new Builder(id,size); builder.addCapacityDimension(0, size); @@ -36,17 +60,31 @@ public class Service implements Job { } 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; protected Capacity.Builder capacityBuilder = Capacity.Builder.newInstance(); protected Capacity capacity; + /** + * 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; } @@ -55,37 +93,84 @@ public class Service implements Job { this.id = id; } + /** + * 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 + * @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; } + public Builder addCapacityDimension(int dimensionIndex, int dimensionValue){ capacityBuilder.addDimension(dimensionIndex, dimensionValue); 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 + * @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; } + /** + * 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."); @@ -131,18 +216,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; } @@ -159,14 +264,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; @@ -175,8 +283,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) { 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 467121df..005d0ba2 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 @@ -4,8 +4,31 @@ import jsprit.core.problem.Capacity; 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; @@ -32,6 +55,14 @@ public class Shipment implements Job{ private Capacity capacity; + /** + * 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){ Builder builder = new Builder(id,size); builder.addCapacityDimension(0, size); @@ -42,8 +73,16 @@ public class Shipment implements Job{ return new Builder(id); } + /** + * 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; } @@ -52,51 +91,140 @@ public class Shipment implements Job{ this.id = id; } + /** + * 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; } + /** + * Adds capacity dimension. + * + * @param dimIndex + * @param dimVal + * @return + */ public Builder addCapacityDimension(int dimIndex, int dimVal) { capacityBuilder.addDimension(dimIndex, dimVal); 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."); @@ -134,7 +262,13 @@ public class Shipment implements Job{ private final TimeWindow pickupTimeWindow; private final Capacity capacity; + + /** + * Constructs the shipment. + * + * @param builder + */ Shipment(Builder builder){ this.id = builder.id; this.demand = builder.demand; @@ -159,34 +293,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; } @@ -199,6 +375,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/main/java/jsprit/core/problem/solution/route/VehicleRoute.java b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/VehicleRoute.java index 08b17991..e1c3083f 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/solution/route/VehicleRoute.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/solution/route/VehicleRoute.java @@ -37,22 +37,65 @@ import jsprit.core.problem.vehicle.Vehicle; import jsprit.core.problem.vehicle.VehicleImpl; import jsprit.core.problem.vehicle.VehicleImpl.NoVehicle; +/** + * Contains the tour, i.e. a number of activities, a vehicle servicing the tour and a driver. + * + * + * @author stefan + * + */ public class VehicleRoute { - + + /** + * Returns a deep copy of this vehicleRoute. + * + * @param route + * @return copied route + * @throws IllegalArgumentException if route is null + */ public static VehicleRoute copyOf(VehicleRoute route) { + if(route == null) throw new IllegalArgumentException("route must not be null"); return new VehicleRoute(route); } + /** + * Returns a newInstance of {@link VehicleRoute}. + * + * @param tour + * @param driver + * @param vehicle + * @return + */ public static VehicleRoute newInstance(TourActivities tour, Driver driver, Vehicle vehicle) { return new VehicleRoute(tour,driver,vehicle); } + /** + * Returns an empty route. + * + *
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;
}
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)
diff --git a/jsprit-core/src/main/java/jsprit/core/reporting/SolutionPrinter.java b/jsprit-core/src/main/java/jsprit/core/reporting/SolutionPrinter.java
new file mode 100644
index 00000000..ef7eabe3
--- /dev/null
+++ b/jsprit-core/src/main/java/jsprit/core/reporting/SolutionPrinter.java
@@ -0,0 +1,178 @@
+/*******************************************************************************
+ * 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 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++;
+// }
+// }
+//
+//
+// }
+
+}
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 @@
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");
}
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();
}
}
diff --git a/pom.xml b/pom.xml
index b7bf6563..8de7c695 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
+ * if start and end are null, new start and end activities are created.
+ *
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
*
diff --git a/jsprit-instances/instances/vrph/c20_3mix.txt b/jsprit-instances/instances/vrph/c20_3mix.txt
deleted file mode 100644
index 9003a6d2..00000000
--- a/jsprit-instances/instances/vrph/c20_3mix.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-20
- 0 30 40 0
- 1 37 52 7
- 2 49 49 30
- 3 52 64 16
- 4 20 26 9
- 5 40 30 21
- 6 21 47 15
- 7 17 63 19
- 8 31 62 23
- 9 52 33 11
- 10 51 21 5
- 11 42 41 19
- 12 31 32 29
- 13 5 25 23
- 14 12 42 21
- 15 36 16 10
- 16 52 41 15
- 17 27 23 3
- 18 17 33 41
- 19 13 13 9
- 20 57 58 28
-//Vehicles characteristics: type, volume, fixed cost
-5
-v 1 20 20
-v 2 30 35
-v 3 40 50
-v 4 70 120
-v 5 120 225
diff --git a/jsprit-instances/instances/vrph/c20_4mix.txt b/jsprit-instances/instances/vrph/c20_4mix.txt
deleted file mode 100644
index f7dd9eaa..00000000
--- a/jsprit-instances/instances/vrph/c20_4mix.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-20
- 0 30 40 0
- 1 37 52 7
- 2 49 49 30
- 3 52 64 16
- 4 20 26 9
- 5 40 30 21
- 6 21 47 15
- 7 17 63 19
- 8 31 62 23
- 9 52 33 11
- 10 51 21 5
- 11 42 41 19
- 12 31 32 29
- 13 5 25 23
- 14 12 42 21
- 15 36 16 10
- 16 52 41 15
- 17 27 23 3
- 18 17 33 41
- 19 13 13 9
- 20 57 58 28
-//Vehicles characteristics: type, volume, fixed cost
-3
-v 1 60 1000
-v 2 80 1500
-v 3 150 3000
diff --git a/jsprit-instances/instances/vrph/c20_5mix.txt b/jsprit-instances/instances/vrph/c20_5mix.txt
deleted file mode 100644
index 5a9c33e7..00000000
--- a/jsprit-instances/instances/vrph/c20_5mix.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-20
- 0 30 40 0
- 1 37 52 7
- 2 49 49 30
- 3 52 64 16
- 4 20 26 9
- 5 40 30 21
- 6 21 47 15
- 7 17 63 19
- 8 31 62 23
- 9 52 33 11
- 10 51 21 5
- 11 42 41 19
- 12 31 32 29
- 13 5 25 23
- 14 12 42 21
- 15 36 16 10
- 16 52 41 15
- 17 27 23 3
- 18 17 33 41
- 19 13 13 9
- 20 57 58 28
-//Vehicles characteristics: type, volume, fixed cost
-5
-v 1 20 20
-v 2 30 35
-v 3 40 50
-v 4 70 120
-v 5 120 225
\ No newline at end of file
diff --git a/jsprit-instances/instances/vrph/c20_6mix.txt b/jsprit-instances/instances/vrph/c20_6mix.txt
deleted file mode 100644
index f7dd9eaa..00000000
--- a/jsprit-instances/instances/vrph/c20_6mix.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-20
- 0 30 40 0
- 1 37 52 7
- 2 49 49 30
- 3 52 64 16
- 4 20 26 9
- 5 40 30 21
- 6 21 47 15
- 7 17 63 19
- 8 31 62 23
- 9 52 33 11
- 10 51 21 5
- 11 42 41 19
- 12 31 32 29
- 13 5 25 23
- 14 12 42 21
- 15 36 16 10
- 16 52 41 15
- 17 27 23 3
- 18 17 33 41
- 19 13 13 9
- 20 57 58 28
-//Vehicles characteristics: type, volume, fixed cost
-3
-v 1 60 1000
-v 2 80 1500
-v 3 150 3000
diff --git a/jsprit-instances/instances/vrph/cn_17mix.txt b/jsprit-instances/instances/vrph/cn_17mix.txt
index c137802e..fe1cff90 100644
--- a/jsprit-instances/instances/vrph/cn_17mix.txt
+++ b/jsprit-instances/instances/vrph/cn_17mix.txt
@@ -78,10 +78,11 @@
//Vehicles characteristics: volume, fixed cost, variable cost, number available
//See E. D. Taillard, "A heuristic column generation method for the heterogeneous fleet vrp"
//RAIRO Rech. Op�r. 33 (1) 1999, pp 1-14)
-//see http://ina2.eivd.ch/collaborateurs/etd/articles.dir/vrphen.pdf50 25 1.0 4
-v 1 120 80 1.2 4
-v 2 200 150 1.5 2
-v 3 350 320 1.8 1
+//see http://ina2.eivd.ch/collaborateurs/etd/articles.dir/vrphen.pdf
+v 1 50 25 1.0 4
+v 2 120 80 1.2 4
+v 3 200 150 1.5 2
+v 4 350 320 1.8 1
7 350 0 1000000 703.124497 + 7 * 150 = 1753.12
14 27 57 15 37 20 70 60 71 69 36 47 5 29 45 2685412
diff --git a/jsprit-instances/pom.xml b/jsprit-instances/pom.xml
index 5a46de9d..d22eec74 100644
--- a/jsprit-instances/pom.xml
+++ b/jsprit-instances/pom.xml
@@ -3,7 +3,7 @@