1
0
Fork 0
mirror of https://github.com/graphhopper/jsprit.git synced 2020-01-24 07:45:05 +01:00

Merge branch 'master' into multiple-cap-constraints

Conflicts:
	jsprit-core/src/main/java/jsprit/core/problem/job/Job.java
	jsprit-core/src/main/java/jsprit/core/problem/job/Service.java
	jsprit-core/src/main/java/jsprit/core/problem/job/Shipment.java
	jsprit-core/src/test/java/jsprit/core/problem/job/ServiceTest.java
This commit is contained in:
oblonski 2014-02-04 21:47:15 +01:00
commit ef2723d801
34 changed files with 1517 additions and 203 deletions

View file

@ -1,5 +1,46 @@
Change-log
==========
**v1.1.1** @ 2014-01-31
<em>jsprit-core:</em>
- 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)
<em>jsprit-core:</em>
- 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 <b>[potential Break Change]</b>
- visibility of methods activity.End.get/setCoordinate(...) decreased from public to package <b>[potential Break Change]</b>
- method isReturnToDepot() has been added to interface Vehicle <b>[potential Break Change]</b>
- visibility of constructor VehicleImpl.Builder decreased from public to private <b>[potential Break Change]</b>
<em>jsprit-analysis:</em>
- added GraphStreamViewer
- inspected and removed all warnings
<em>jsprit-example:</em>
- added BicycleMessenger
- enriched examples with GraphStreamViewer
- inspected and removed all warnings
<em>jsprit-instance:</em>
- added VrphGoldenReader (plus instances to bechmark VRPH)
- inspected and removed all warnings
**v1.0.0** @ 2013-11-26 (break change)
- re-organized API

View file

@ -1,7 +1,7 @@
jsprit
======
jsprit is a java based, open source toolkit for solving rich <a href="http://en.wikipedia.org/wiki/Travelling_salesman_problem" target="_blank">traveling salesman</a> (TSP) and <a href="http://neo.lcc.uma.es/vrp/vehicle-routing-problem/" target="_blank">vehicle routing problems</a> (VRP).
It is lightweight, flexible and easy-to-use, and based on a single all-purpose <a href="http://www.sciencedirect.com/science/article/pii/S0021999199964136" target="_blank">meta-heuristic</a> currently solving
It is lightweight, flexible and easy-to-use, and based on a single all-purpose <a href="https://github.com/jsprit/jsprit/wiki/Meta-Heuristic-and-Configuration" target="_blank">meta-heuristic</a> 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 <a href="http://www.matsim.org" target="blank_">MATSim</a>
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:

View file

@ -22,7 +22,7 @@
<parent>
<groupId>jsprit</groupId>
<artifactId>jsprit</artifactId>
<version>1.0.1-SNAPSHOT</version>
<version>1.1.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jsprit-analysis</artifactId>

View file

@ -3,7 +3,7 @@
<parent>
<groupId>jsprit</groupId>
<artifactId>jsprit</artifactId>
<version>1.0.1-SNAPSHOT</version>
<version>1.1.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jsprit-core</artifactId>

View file

@ -47,7 +47,7 @@ import jsprit.core.util.CalculationUtils;
if(arrTimeAtNextAct > latestArrTimeAtNextAct){
return ConstraintsStatus.NOT_FULFILLED;
}
double arrTimeAtNextOnDirectRouteWithNewVehicle = prevActDepTime + routingCosts.getTransportCost(prevAct.getLocationId(), nextAct.getLocationId(), prevActDepTime, iFacts.getNewDriver(), iFacts.getNewVehicle());
double arrTimeAtNextOnDirectRouteWithNewVehicle = prevActDepTime + routingCosts.getTransportTime(prevAct.getLocationId(), nextAct.getLocationId(), prevActDepTime, iFacts.getNewDriver(), iFacts.getNewVehicle());
//if vehicle cannot even manage direct-route - break
if(arrTimeAtNextOnDirectRouteWithNewVehicle > latestArrTimeAtNextAct){
return ConstraintsStatus.NOT_FULFILLED_BREAK;

View file

@ -316,13 +316,16 @@ 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.");
builder.setPickupCoord(pickupCoord);
if(pickupCoord != null){
builder.setPickupCoord(pickupCoord);
if(pickupLocationId != null){
vrpBuilder.addLocation(pickupLocationId,pickupCoord);
}
@ -331,32 +334,49 @@ public class VrpXMLReader{
builder.setPickupLocation(pickupCoord.toString());
}
}
//pickup-serviceTime
String pickupServiceTime = shipmentConfig.getString("pickup.duration");
if(pickupServiceTime != null) builder.setPickupServiceTime(Double.parseDouble(pickupServiceTime));
// 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);
//pickup-tw
String pickupTWStart = shipmentConfig.getString("pickup.timeWindows.timeWindow(0).start");
String pickupTWEnd = shipmentConfig.getString("pickup.timeWindows.timeWindow(0).end");
if(pickupTWStart != null && pickupTWEnd != null){
TimeWindow pickupTW = TimeWindow.newInstance(Double.parseDouble(pickupTWStart), Double.parseDouble(pickupTWEnd));
builder.setPickupTimeWindow(pickupTW);
}
//delivery-locationId
String deliveryLocationId = shipmentConfig.getString("delivery.locationId");
builder.setDeliveryLocation(deliveryLocationId);
if(deliveryLocationId != null){
builder.setDeliveryLocation(deliveryLocationId);
}
//delivery-coord
Coordinate deliveryCoord = getCoord(shipmentConfig,"delivery.");
builder.setDeliveryCoord(deliveryCoord);
if(deliveryCoord != null){
builder.setDeliveryCoord(deliveryCoord);
if(deliveryLocationId != null){
vrpBuilder.addLocation(deliveryLocationId,deliveryCoord);
}
else{
vrpBuilder.addLocation(deliveryCoord.toString(),deliveryCoord);
builder.setPickupLocation(deliveryCoord.toString());
builder.setDeliveryLocation(deliveryCoord.toString());
}
}
//delivery-serviceTime
String deliveryServiceTime = shipmentConfig.getString("delivery.duration");
if(deliveryServiceTime != null) builder.setDeliveryServiceTime(Double.parseDouble(deliveryServiceTime));
//delivery-tw
String delTWStart = shipmentConfig.getString("delivery.timeWindows.timeWindow(0).start");
String delTWEnd = shipmentConfig.getString("delivery.timeWindows.timeWindow(0).end");
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,10 +411,10 @@ 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,"");
builder.setCoord(serviceCoord);
if(serviceCoord != null){
builder.setCoord(serviceCoord);
if(serviceLocationId != null){
vrpBuilder.addLocation(serviceLocationId,serviceCoord);
}

View file

@ -16,19 +16,44 @@
******************************************************************************/
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
* @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 Delivery.
*
* @return delivery
* @throw 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 +65,11 @@ public class Delivery extends Service{
}
/**
* Constructs Delivery.
*
* @param builder
*/
Delivery(Builder builder) {
super(builder);

View file

@ -16,12 +16,32 @@
******************************************************************************/
package jsprit.core.problem.job;
import jsprit.core.problem.Capacity;
/**
* 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.
*
* <p>It determines how much capacity this job consumes of vehicle/transport unit.
*
* @deprecated use getCapacity() instead
* @return
*/
@Deprecated
public int getCapacityDemand();

View file

@ -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.
*
*<p>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);
}

View file

@ -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.
*
* <p>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).
*
* <p>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.
*
* <p>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.
*
* <p>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.
*
* <p>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.
*
* <p>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) {

View file

@ -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.
*
* <p>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.
*
* <p>By default serviceTimes of both pickup and delivery is 0.0 and timeWindows of both is [0.0, Double.MAX_VALUE],
*
* <p>A shipment can be built with a builder. You can get an instance of the builder by coding <code>Shipment.Builder.newInstance(...)</code>.
* 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.
*
* <p>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.
*
* <p>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.
*
* <p>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.
*
* <p>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.
*
* <p>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.");
@ -135,6 +263,12 @@ public class Shipment implements Job{
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.
*
* <p>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)

View file

@ -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.
*
* <p>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<Shipment> openShipments = new HashSet<Shipment>();
/**
* Sets the serviceActivityFactory to create serviceActivities.
*
* <p>By default {@link DefaultTourActivityFactory} is used.
*
* @param serviceActivityFactory
*/
public void setServiceActivityFactory(TourActivityFactory serviceActivityFactory) {
this.serviceActivityFactory = serviceActivityFactory;
}
/**
* Sets the shipmentActivityFactory to create shipmentActivities.
*
* <p>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.
*
* <p>This implies that for this service a serviceActivity is created with {@link TourActivityFactory} and added to the sequence of tourActivities.
*
* <p>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.
*
* <p>This implies that for this service a serviceActivity is created with {@link TourActivityFactory} and added to the sequence of tourActivities.
*
* <p>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.
*
* <p>This implies the following:<br>
* if start and end are null, new start and end activities are created.<br>
* <p>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()]
* <p>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()]
* <p>start.endTime is set to the specified departureTime
* <p>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;
}

View file

@ -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)

View file

@ -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 <http://www.gnu.org/licenses/>.
******************************************************************************/
package jsprit.core.reporting;
import jsprit.core.problem.VehicleRoutingProblem;
import jsprit.core.problem.job.Job;
import jsprit.core.problem.job.Service;
import jsprit.core.problem.job.Shipment;
import jsprit.core.problem.solution.VehicleRoutingProblemSolution;
import jsprit.core.problem.solution.route.VehicleRoute;
import jsprit.core.problem.solution.route.activity.TourActivity;
import jsprit.core.problem.solution.route.activity.TourActivity.JobActivity;
/**
* Printer to print the details of a vehicle-routing-problem solution.
*
* @author stefan schroeder
*
*/
public class SolutionPrinter {
/**
* Enum to indicate verbose-level.
*
* <p> 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.
// *
// * <p>CONCISE prints total-costs and #vehicles.
// * <p>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++;
// }
// }
//
//
// }
}

View file

@ -40,7 +40,7 @@
<xs:element name="location">
<xs:complexType>
<xs:all>
<xs:element name="id" type="xs:string" minOccurs="1" maxOccurs="1"/>
<xs:element name="id" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="coord" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:attribute name="x" type="xs:decimal" use="required"/>
@ -95,7 +95,7 @@
<xs:element name="service" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:all>
<xs:element name="locationId" type="xs:string" minOccurs="1" maxOccurs="1"/>
<xs:element name="locationId" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="coord" type="coordType" minOccurs="0" maxOccurs="1"/>
<xs:element name="capacity-demand" type="xs:integer" minOccurs="0" maxOccurs="1" default="0"/>
<xs:element name="duration" type="xs:decimal" minOccurs="0" maxOccurs="1" default="0.0"/>
@ -125,7 +125,7 @@
<xs:element name="pickup" minOccurs="1" maxOccurs="1">
<xs:complexType>
<xs:all>
<xs:element name="locationId" type="xs:string" minOccurs="1" maxOccurs="1"/>
<xs:element name="locationId" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="coord" type="coordType" minOccurs="0" maxOccurs="1"/>
<xs:element name="duration" type="xs:decimal" minOccurs="0" maxOccurs="1" default="0.0"/>
<xs:element name="timeWindows" minOccurs="0" maxOccurs="1">
@ -141,7 +141,7 @@
<xs:element name="delivery" minOccurs="1" maxOccurs="1">
<xs:complexType>
<xs:all>
<xs:element name="locationId" type="xs:string" minOccurs="1" maxOccurs="1"/>
<xs:element name="locationId" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="coord" type="coordType" minOccurs="0" maxOccurs="1"/>
<xs:element name="duration" type="xs:decimal" minOccurs="0" maxOccurs="1" default="0.0"/>
<xs:element name="timeWindows" minOccurs="0" maxOccurs="1">

View file

@ -0,0 +1,229 @@
/*******************************************************************************
* Copyright (C) 2013 Stefan Schroeder
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
package jsprit.core.algorithm;
import static org.junit.Assert.assertEquals;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Collection;
import jsprit.core.algorithm.box.GreedySchrimpfFactory;
import jsprit.core.algorithm.termination.IterationWithoutImprovementTermination;
import jsprit.core.problem.VehicleRoutingProblem;
import jsprit.core.problem.VehicleRoutingProblem.FleetSize;
import jsprit.core.problem.job.Service;
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;
import org.junit.Test;
public class RefuseCollectionWithCostsHigherThanTimesAndFiniteFleet_IT {
static class RelationKey {
static RelationKey newKey(String from, String to){
int fromInt = Integer.parseInt(from);
int toInt = Integer.parseInt(to);
if(fromInt < toInt){
return new RelationKey(from, to);
}
else {
return new RelationKey(to, from);
}
}
final String from;
final String to;
public RelationKey(String from, String to) {
super();
this.from = from;
this.to = to;
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((from == null) ? 0 : from.hashCode());
result = prime * result + ((to == null) ? 0 : to.hashCode());
return result;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
RelationKey other = (RelationKey) obj;
if (from == null) {
if (other.from != null)
return false;
} else if (!from.equals(other.from))
return false;
if (to == null) {
if (other.to != null)
return false;
} else if (!to.equals(other.to))
return false;
return true;
}
}
// static class RoutingCosts extends AbstractForwardVehicleRoutingTransportCosts {
//
// private Map<RelationKey,Integer> distances;
//
// public RoutingCosts(Map<RelationKey, Integer> distances) {
// super();
// this.distances = distances;
// }
//
// @Override
// public double getTransportTime(String fromId, String toId, double departureTime, Driver driver, Vehicle vehicle) {
// return getTransportCost(fromId, toId, departureTime, driver, vehicle)/2.;
// }
//
// @Override
// public double getTransportCost(String fromId, String toId,double departureTime, Driver driver, Vehicle vehicle) {
// if(fromId.equals(toId)) return 0.0;
// RelationKey key = RelationKey.newKey(fromId, toId);
// return distances.get(key);
// }
//
// }
@Test
public void testAlgo(){
/*
* create vehicle-type and vehicle
*/
VehicleTypeImpl.Builder typeBuilder = VehicleTypeImpl.Builder.newInstance("vehicle-type", 23);
typeBuilder.setCostPerDistance(1.0);
VehicleTypeImpl bigType = typeBuilder.build();
VehicleImpl.Builder vehicleBuilder = VehicleImpl.Builder.newInstance("vehicle");
vehicleBuilder.setLocationId("1");
vehicleBuilder.setType(bigType);
vehicleBuilder.setLatestArrival(220);
Vehicle bigVehicle = vehicleBuilder.build();
/*
* start building the problem
*/
VehicleRoutingProblem.Builder vrpBuilder = VehicleRoutingProblem.Builder.newInstance();
vrpBuilder.setFleetSize(FleetSize.INFINITE);
vrpBuilder.addVehicle(bigVehicle);
/*
* create cost-matrix
*/
VehicleRoutingTransportCostsMatrix.Builder matrixBuilder = VehicleRoutingTransportCostsMatrix.Builder.newInstance(true);
/*
* read demand quantities
*/
try {
readDemandQuantities(vrpBuilder);
readDistances(matrixBuilder);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
vrpBuilder.setRoutingCost(matrixBuilder.build());
VehicleRoutingProblem vrp = vrpBuilder.build();
VehicleRoutingAlgorithm vra = new GreedySchrimpfFactory().createAlgorithm(vrp);
vra.setPrematureAlgorithmTermination(new IterationWithoutImprovementTermination(100));
Collection<VehicleRoutingProblemSolution> solutions = vra.searchSolutions();
SolutionPrinter.print(vrp, Solutions.bestOf(solutions), Print.VERBOSE);
assertEquals(2.*397.,Solutions.bestOf(solutions).getCost(),0.01);
assertEquals(2,Solutions.bestOf(solutions).getRoutes().size());
}
private static void readDemandQuantities(VehicleRoutingProblem.Builder vrpBuilder) throws FileNotFoundException, IOException {
BufferedReader reader = new BufferedReader(new FileReader(new File("src/test/resources/refuseCollectionExample_Quantities")));
String line = null;
boolean firstLine = true;
while((line = reader.readLine()) != null){
if(firstLine) {
firstLine = false;
continue;
}
String[] lineTokens = line.split(",");
/*
* build service
*/
Service service = Service.Builder.newInstance(lineTokens[0], Integer.parseInt(lineTokens[1])).setLocationId(lineTokens[0]).build();
/*
* and add it to problem
*/
vrpBuilder.addJob(service);
}
reader.close();
}
private static void readDistances(Builder matrixBuilder) throws IOException {
BufferedReader reader = new BufferedReader(new FileReader(new File("src/test/resources/refuseCollectionExample_Distances")));
String line = null;
boolean firstLine = true;
while((line = reader.readLine()) != null){
if(firstLine) {
firstLine = false;
continue;
}
String[] lineTokens = line.split(",");
matrixBuilder.addTransportDistance(lineTokens[0],lineTokens[1], 2.*Integer.parseInt(lineTokens[2]));
matrixBuilder.addTransportTime(lineTokens[0],lineTokens[1], Integer.parseInt(lineTokens[2]));
}
reader.close();
}
}

View file

@ -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<VehicleRoutingProblemSolution> solutions = vra.searchSolutions();
SolutionPrinter.print(vrp, Solutions.bestOf(solutions), Print.VERBOSE);
assertEquals(397.0,Solutions.bestOf(solutions).getCost(),0.01);
assertEquals(2,Solutions.bestOf(solutions).getRoutes().size());
}
@ -227,6 +231,7 @@ public class RefuseCollection_IT {
}
String[] lineTokens = line.split(",");
matrixBuilder.addTransportDistance(lineTokens[0],lineTokens[1], Integer.parseInt(lineTokens[2]));
matrixBuilder.addTransportTime(lineTokens[0],lineTokens[1], Integer.parseInt(lineTokens[2]));
}
reader.close();

View file

@ -106,12 +106,19 @@ public class VrpReaderV2Test {
assertEquals(FleetSize.FINITE,vrp.getFleetSize());
}
@Test
public void whenReadingJobs_nuOfJobsIsReadThemCorrectly(){
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
new VrpXMLReader(builder, null).read(inFileName);
VehicleRoutingProblem vrp = builder.build();
assertEquals(4, vrp.getJobs().size());
}
@Test
public void whenReadingServices_itReadsThemCorrectly(){
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
new VrpXMLReader(builder, null).read(inFileName);
VehicleRoutingProblem vrp = builder.build();
assertEquals(3, vrp.getJobs().size());
int servCounter = 0;
for(Job j : vrp.getJobs().values()){
if(j instanceof Service) servCounter++;
@ -124,23 +131,171 @@ public class VrpReaderV2Test {
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
new VrpXMLReader(builder, null).read(inFileName);
VehicleRoutingProblem vrp = builder.build();
assertEquals(3, vrp.getJobs().size());
int shipCounter = 0;
for(Job j : vrp.getJobs().values()){
if(j instanceof Shipment) shipCounter++;
}
assertEquals(1,shipCounter);
assertEquals(2,shipCounter);
}
@Test
public void whenReadingServices_servicesAreBuiltCorrectly(){
public void whenReadingServices_capOfService1IsReadCorrectly(){
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
new VrpXMLReader(builder, null).read(inFileName);
VehicleRoutingProblem vrp = builder.build();
Service s1 = (Service) vrp.getJobs().get("1");
assertEquals(1,s1.getCapacityDemand());
}
@Test
public void whenReadingServices_durationOfService1IsReadCorrectly(){
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
new VrpXMLReader(builder, null).read(inFileName);
VehicleRoutingProblem vrp = builder.build();
Service s1 = (Service) vrp.getJobs().get("1");
assertEquals(10.0,s1.getServiceDuration(),0.01);
}
@Test
public void whenReadingServices_twOfService1IsReadCorrectly(){
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
new VrpXMLReader(builder, null).read(inFileName);
VehicleRoutingProblem vrp = builder.build();
Service s1 = (Service) vrp.getJobs().get("1");
assertEquals(0.0,s1.getTimeWindow().getStart(),0.01);
assertEquals(4000.0,s1.getTimeWindow().getEnd(),0.01);
}
@Test
public void whenReadingServices_typeOfService1IsReadCorrectly(){
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
new VrpXMLReader(builder, null).read(inFileName);
VehicleRoutingProblem vrp = builder.build();
Service s1 = (Service) vrp.getJobs().get("1");
assertEquals("service",s1.getType());
assertEquals(1,s1.getCapacityDemand());
assertEquals(0.0,s1.getServiceDuration(),0.01);
assertEquals(3, vrp.getJobs().size());
}
@Test
public void whenReadingJobs_capOfShipment3IsReadCorrectly(){
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
new VrpXMLReader(builder, null).read(inFileName);
VehicleRoutingProblem vrp = builder.build();
Shipment s = (Shipment) vrp.getJobs().get("3");
assertEquals(10,s.getCapacityDemand());
}
@Test
public void whenReadingJobs_pickupServiceTimeOfShipment3IsReadCorrectly(){
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
new VrpXMLReader(builder, null).read(inFileName);
VehicleRoutingProblem vrp = builder.build();
Shipment s = (Shipment) vrp.getJobs().get("3");
assertEquals(10.0,s.getPickupServiceTime(),0.01);
}
@Test
public void whenReadingJobs_pickupTimeWindowOfShipment3IsReadCorrectly(){
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
new VrpXMLReader(builder, null).read(inFileName);
VehicleRoutingProblem vrp = builder.build();
Shipment s = (Shipment) vrp.getJobs().get("3");
assertEquals(1000.0,s.getPickupTimeWindow().getStart(),0.01);
assertEquals(4000.0,s.getPickupTimeWindow().getEnd(),0.01);
}
@Test
public void whenReadingJobs_deliveryTimeWindowOfShipment3IsReadCorrectly(){
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
new VrpXMLReader(builder, null).read(inFileName);
VehicleRoutingProblem vrp = builder.build();
Shipment s = (Shipment) vrp.getJobs().get("3");
assertEquals(6000.0,s.getDeliveryTimeWindow().getStart(),0.01);
assertEquals(10000.0,s.getDeliveryTimeWindow().getEnd(),0.01);
}
@Test
public void whenReadingJobs_deliveryServiceTimeOfShipment3IsReadCorrectly(){
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
new VrpXMLReader(builder, null).read(inFileName);
VehicleRoutingProblem vrp = builder.build();
Shipment s = (Shipment) vrp.getJobs().get("3");
assertEquals(100.0,s.getDeliveryServiceTime(),0.01);
}
@Test
public void whenReadingJobs_deliveryCoordShipment3IsReadCorrectly(){
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
new VrpXMLReader(builder, null).read(inFileName);
VehicleRoutingProblem vrp = builder.build();
Shipment s = (Shipment) vrp.getJobs().get("3");
assertEquals(10.0,s.getDeliveryCoord().getX(),0.01);
assertEquals(0.0,s.getDeliveryCoord().getY(),0.01);
}
@Test
public void whenReadingJobs_pickupCoordShipment3IsReadCorrectly(){
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
new VrpXMLReader(builder, null).read(inFileName);
VehicleRoutingProblem vrp = builder.build();
Shipment s = (Shipment) vrp.getJobs().get("3");
assertEquals(10.0,s.getPickupCoord().getX(),0.01);
assertEquals(10.0,s.getPickupCoord().getY(),0.01);
}
@Test
public void whenReadingJobs_deliveryIdShipment3IsReadCorrectly(){
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
new VrpXMLReader(builder, null).read(inFileName);
VehicleRoutingProblem vrp = builder.build();
Shipment s = (Shipment) vrp.getJobs().get("3");
assertEquals("i(9,9)",s.getDeliveryLocation());
}
@Test
public void whenReadingJobs_pickupIdShipment3IsReadCorrectly(){
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
new VrpXMLReader(builder, null).read(inFileName);
VehicleRoutingProblem vrp = builder.build();
Shipment s = (Shipment) vrp.getJobs().get("3");
assertEquals("i(3,9)",s.getPickupLocation());
}
@Test
public void whenReadingJobs_pickupLocationIdShipment4IsReadCorrectly(){
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
new VrpXMLReader(builder, null).read(inFileName);
VehicleRoutingProblem vrp = builder.build();
Shipment s = (Shipment) vrp.getJobs().get("4");
assertEquals("[x=10.0][y=10.0]",s.getPickupLocation());
}
@Test
public void whenReadingJobs_deliveryLocationIdShipment4IsReadCorrectly(){
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
new VrpXMLReader(builder, null).read(inFileName);
VehicleRoutingProblem vrp = builder.build();
Shipment s = (Shipment) vrp.getJobs().get("4");
assertEquals("[x=10.0][y=0.0]",s.getDeliveryLocation());
}
@Test
public void whenReadingJobs_pickupServiceTimeOfShipment4IsReadCorrectly(){
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
new VrpXMLReader(builder, null).read(inFileName);
VehicleRoutingProblem vrp = builder.build();
Shipment s = (Shipment) vrp.getJobs().get("4");
assertEquals(0.0,s.getPickupServiceTime(),0.01);
}
@Test
public void whenReadingJobs_deliveryServiceTimeOfShipment4IsReadCorrectly(){
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
new VrpXMLReader(builder, null).read(inFileName);
VehicleRoutingProblem vrp = builder.build();
Shipment s = (Shipment) vrp.getJobs().get("4");
assertEquals(100.0,s.getDeliveryServiceTime(),0.01);
}
}

View file

@ -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();
}
}

View file

@ -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();
}
}

View file

@ -17,11 +17,17 @@
package jsprit.core.problem.job;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.util.HashSet;
import java.util.Set;
import jsprit.core.problem.solution.route.activity.TimeWindow;
import jsprit.core.util.Coordinate;
import org.junit.Test;
@ -86,4 +92,61 @@ public class ServiceTest {
assertEquals(1,one.getCapacity().get(0));
}
@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);
}
}

View file

@ -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,21 +38,160 @@ 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);
}
@Test(expected=IllegalStateException.class)

View file

@ -79,7 +79,7 @@
<locationId>j(1,5)</locationId>
<coord x="10.0" y="10.0"/>
<capacity-demand>1</capacity-demand>
<duration>0.0</duration>
<duration>10.0</duration>
<timeWindows>
<timeWindow>
<start>0.0</start>
@ -108,10 +108,10 @@
<pickup>
<locationId>i(3,9)</locationId>
<coord x="10.0" y="10.0"/>
<duration>0.0</duration>
<duration>10.0</duration>
<timeWindows>
<timeWindow>
<start>0.0</start>
<start>1000.0</start>
<end>4000.0</end>
</timeWindow>
</timeWindows>
@ -119,16 +119,40 @@
<delivery>
<locationId>i(9,9)</locationId>
<coord x="10.0" y="0.0"/>
<duration>0.0</duration>
<duration>100.0</duration>
<timeWindows>
<timeWindow>
<start>0.0</start>
<end>4000.0</end>
<start>6000.0</start>
<end>10000.0</end>
</timeWindow>
</timeWindows>
</delivery>
<capacity-demand>1</capacity-demand>
<capacity-demand>10</capacity-demand>
</shipment>
<shipment id="4">
<pickup>
<coord x="10.0" y="10.0"/>
<timeWindows>
<timeWindow>
<start>1000.0</start>
<end>4000.0</end>
</timeWindow>
</timeWindows>
</pickup>
<delivery>
<coord x="10.0" y="0.0"/>
<duration>100.0</duration>
<timeWindows>
<timeWindow>
<start>6000.0</start>
<end>10000.0</end>
</timeWindow>
</timeWindows>
</delivery>
<capacity-demand>10</capacity-demand>
</shipment>
</shipments>
</problem>

View file

@ -3,7 +3,7 @@
<parent>
<groupId>jsprit</groupId>
<artifactId>jsprit</artifactId>
<version>1.0.1-SNAPSHOT</version>
<version>1.1.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View file

@ -23,6 +23,7 @@ import jsprit.util.Examples;
* <a href=http://mistic.heig-vd.ch/taillard/problemes.dir/vrp.dir/vrp.html>.
*
* <p>You can find best results of different problems, instances and authors here:
* <br><a href="http://link.springer.com/article/10.1007%2Fs10732-011-9186-y">http://link.springer.com/article/10.1007%2Fs10732-011-9186-y</a>
* <br><a href="http://www2.ic.uff.br/~satoru/conteudo/artigos/PAPER%20PUCA-JHeuristics-2011.pdf">http://www2.ic.uff.br/~satoru/conteudo/artigos/PAPER%20PUCA-JHeuristics-2011.pdf</a>
* <br><a href="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.100.2331&rep=rep1&type=pdf">http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.100.2331&rep=rep1&type=pdf</a>
*

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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<4F>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

View file

@ -3,7 +3,7 @@
<parent>
<groupId>jsprit</groupId>
<artifactId>jsprit</artifactId>
<version>1.0.1-SNAPSHOT</version>
<version>1.1.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View file

@ -23,8 +23,6 @@ import jsprit.core.util.Coordinate;
*
* <p>See {@link VrphType} what kind of problems can be generated
*
* <p>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");
}

View file

@ -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();
}
}

View file

@ -4,7 +4,7 @@
<groupId>jsprit</groupId>
<artifactId>jsprit</artifactId>
<version>1.0.1-SNAPSHOT</version>
<version>1.1.2-SNAPSHOT</version>
<packaging>pom</packaging>