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:
commit
ef2723d801
34 changed files with 1517 additions and 203 deletions
41
CHANGELOG.md
41
CHANGELOG.md
|
|
@ -1,5 +1,46 @@
|
||||||
Change-log
|
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)
|
**v1.0.0** @ 2013-11-26 (break change)
|
||||||
|
|
||||||
- re-organized API
|
- re-organized API
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
jsprit
|
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).
|
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
|
- Capacitated VRP
|
||||||
- Multiple Depot VRP
|
- Multiple Depot VRP
|
||||||
- VRP with Time Windows
|
- 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
|
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.
|
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
|
##In Development
|
||||||
- continues improvement of code, handling and performance
|
- continues improvement of code, handling and performance
|
||||||
- soft constraints
|
- 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).
|
[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
|
####If not
|
||||||
|
|
||||||
The following documentation is recommended:
|
The following documentation is recommended:
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>jsprit</groupId>
|
<groupId>jsprit</groupId>
|
||||||
<artifactId>jsprit</artifactId>
|
<artifactId>jsprit</artifactId>
|
||||||
<version>1.0.1-SNAPSHOT</version>
|
<version>1.1.2-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>jsprit-analysis</artifactId>
|
<artifactId>jsprit-analysis</artifactId>
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>jsprit</groupId>
|
<groupId>jsprit</groupId>
|
||||||
<artifactId>jsprit</artifactId>
|
<artifactId>jsprit</artifactId>
|
||||||
<version>1.0.1-SNAPSHOT</version>
|
<version>1.1.2-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>jsprit-core</artifactId>
|
<artifactId>jsprit-core</artifactId>
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ import jsprit.core.util.CalculationUtils;
|
||||||
if(arrTimeAtNextAct > latestArrTimeAtNextAct){
|
if(arrTimeAtNextAct > latestArrTimeAtNextAct){
|
||||||
return ConstraintsStatus.NOT_FULFILLED;
|
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 vehicle cannot even manage direct-route - break
|
||||||
if(arrTimeAtNextOnDirectRouteWithNewVehicle > latestArrTimeAtNextAct){
|
if(arrTimeAtNextOnDirectRouteWithNewVehicle > latestArrTimeAtNextAct){
|
||||||
return ConstraintsStatus.NOT_FULFILLED_BREAK;
|
return ConstraintsStatus.NOT_FULFILLED_BREAK;
|
||||||
|
|
|
||||||
|
|
@ -316,13 +316,16 @@ public class VrpXMLReader{
|
||||||
int cap = getCap(shipmentConfig);
|
int cap = getCap(shipmentConfig);
|
||||||
Shipment.Builder builder = Shipment.Builder.newInstance(id, cap);
|
Shipment.Builder builder = Shipment.Builder.newInstance(id, cap);
|
||||||
|
|
||||||
|
//pickup-locationId
|
||||||
String pickupLocationId = shipmentConfig.getString("pickup.locationId");
|
String pickupLocationId = shipmentConfig.getString("pickup.locationId");
|
||||||
builder.setPickupLocation(pickupLocationId);
|
if(pickupLocationId != null){
|
||||||
|
builder.setPickupLocation(pickupLocationId);
|
||||||
|
}
|
||||||
|
|
||||||
|
//pickup-coord
|
||||||
Coordinate pickupCoord = getCoord(shipmentConfig,"pickup.");
|
Coordinate pickupCoord = getCoord(shipmentConfig,"pickup.");
|
||||||
builder.setPickupCoord(pickupCoord);
|
|
||||||
|
|
||||||
if(pickupCoord != null){
|
if(pickupCoord != null){
|
||||||
|
builder.setPickupCoord(pickupCoord);
|
||||||
if(pickupLocationId != null){
|
if(pickupLocationId != null){
|
||||||
vrpBuilder.addLocation(pickupLocationId,pickupCoord);
|
vrpBuilder.addLocation(pickupLocationId,pickupCoord);
|
||||||
}
|
}
|
||||||
|
|
@ -331,32 +334,49 @@ public class VrpXMLReader{
|
||||||
builder.setPickupLocation(pickupCoord.toString());
|
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");
|
//pickup-tw
|
||||||
// String pickupTWEnd = shipmentConfig.getString("pickup.timeWindows.timeWindow(0).end");
|
String pickupTWStart = shipmentConfig.getString("pickup.timeWindows.timeWindow(0).start");
|
||||||
// TimeWindow pickupTW = TimeWindow.newInstance(Double.parseDouble(pickupTWStart), Double.parseDouble(pickupTWEnd));
|
String pickupTWEnd = shipmentConfig.getString("pickup.timeWindows.timeWindow(0).end");
|
||||||
// builder.setPickupTimeWindow(pickupTW);
|
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");
|
String deliveryLocationId = shipmentConfig.getString("delivery.locationId");
|
||||||
builder.setDeliveryLocation(deliveryLocationId);
|
if(deliveryLocationId != null){
|
||||||
|
builder.setDeliveryLocation(deliveryLocationId);
|
||||||
|
}
|
||||||
|
|
||||||
|
//delivery-coord
|
||||||
Coordinate deliveryCoord = getCoord(shipmentConfig,"delivery.");
|
Coordinate deliveryCoord = getCoord(shipmentConfig,"delivery.");
|
||||||
builder.setDeliveryCoord(deliveryCoord);
|
|
||||||
|
|
||||||
if(deliveryCoord != null){
|
if(deliveryCoord != null){
|
||||||
|
builder.setDeliveryCoord(deliveryCoord);
|
||||||
if(deliveryLocationId != null){
|
if(deliveryLocationId != null){
|
||||||
vrpBuilder.addLocation(deliveryLocationId,deliveryCoord);
|
vrpBuilder.addLocation(deliveryLocationId,deliveryCoord);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
vrpBuilder.addLocation(deliveryCoord.toString(),deliveryCoord);
|
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 delTWStart = shipmentConfig.getString("delivery.timeWindows.timeWindow(0).start");
|
||||||
String delTWEnd = shipmentConfig.getString("delivery.timeWindows.timeWindow(0).end");
|
String delTWEnd = shipmentConfig.getString("delivery.timeWindows.timeWindow(0).end");
|
||||||
TimeWindow delTW = TimeWindow.newInstance(Double.parseDouble(delTWStart), Double.parseDouble(delTWEnd));
|
if(delTWStart != null && delTWEnd != null){
|
||||||
builder.setDeliveryTimeWindow(delTW);
|
TimeWindow delTW = TimeWindow.newInstance(Double.parseDouble(delTWStart), Double.parseDouble(delTWEnd));
|
||||||
|
builder.setDeliveryTimeWindow(delTW);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Shipment shipment = builder.build();
|
Shipment shipment = builder.build();
|
||||||
vrpBuilder.addJob(shipment);
|
vrpBuilder.addJob(shipment);
|
||||||
|
|
@ -391,10 +411,10 @@ public class VrpXMLReader{
|
||||||
int cap = getCap(serviceConfig);
|
int cap = getCap(serviceConfig);
|
||||||
Service.Builder builder = serviceBuilderFactory.createBuilder(type, id, cap);
|
Service.Builder builder = serviceBuilderFactory.createBuilder(type, id, cap);
|
||||||
String serviceLocationId = serviceConfig.getString("locationId");
|
String serviceLocationId = serviceConfig.getString("locationId");
|
||||||
builder.setLocationId(serviceLocationId);
|
if(serviceLocationId != null) builder.setLocationId(serviceLocationId);
|
||||||
Coordinate serviceCoord = getCoord(serviceConfig,"");
|
Coordinate serviceCoord = getCoord(serviceConfig,"");
|
||||||
builder.setCoord(serviceCoord);
|
|
||||||
if(serviceCoord != null){
|
if(serviceCoord != null){
|
||||||
|
builder.setCoord(serviceCoord);
|
||||||
if(serviceLocationId != null){
|
if(serviceLocationId != null){
|
||||||
vrpBuilder.addLocation(serviceLocationId,serviceCoord);
|
vrpBuilder.addLocation(serviceLocationId,serviceCoord);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,19 +16,44 @@
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
package jsprit.core.problem.job;
|
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 class Delivery extends Service{
|
||||||
|
|
||||||
public static class Builder extends Service.Builder {
|
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){
|
public static Builder newInstance(String id, int size){
|
||||||
return new Builder(id,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) {
|
Builder(String id, int size) {
|
||||||
super(id, size);
|
super(id, size);
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Builds Delivery.
|
||||||
|
*
|
||||||
|
* @return delivery
|
||||||
|
* @throw IllegalStateException if neither locationId nor coord is set
|
||||||
|
*/
|
||||||
public Delivery build(){
|
public Delivery build(){
|
||||||
if(locationId == null) {
|
if(locationId == null) {
|
||||||
if(coord == null) throw new IllegalStateException("either locationId or a coordinate must be given. But is not.");
|
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) {
|
Delivery(Builder builder) {
|
||||||
super(builder);
|
super(builder);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,12 +16,32 @@
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
package jsprit.core.problem.job;
|
package jsprit.core.problem.job;
|
||||||
|
|
||||||
|
|
||||||
import jsprit.core.problem.Capacity;
|
import jsprit.core.problem.Capacity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Basic interface for all jobs.
|
||||||
|
*
|
||||||
|
* @author schroeder
|
||||||
|
*
|
||||||
|
*/
|
||||||
public interface Job {
|
public interface Job {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the unique identifier (id) of a job.
|
||||||
|
*
|
||||||
|
* @return id
|
||||||
|
*/
|
||||||
public String getId();
|
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
|
@Deprecated
|
||||||
public int getCapacityDemand();
|
public int getCapacityDemand();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,18 +16,47 @@
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
package jsprit.core.problem.job;
|
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 class Pickup extends Service {
|
||||||
|
|
||||||
public static class Builder extends Service.Builder {
|
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){
|
public static Builder newInstance(String id, int size){
|
||||||
return new Builder(id,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) {
|
Builder(String id, int size) {
|
||||||
super(id, 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(){
|
public Pickup build(){
|
||||||
if(locationId == null) {
|
if(locationId == null) {
|
||||||
if(coord == null) throw new IllegalStateException("either locationId or a coordinate must be given. But is not.");
|
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) {
|
Pickup(Builder builder) {
|
||||||
super(builder);
|
super(builder);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,11 +20,35 @@ import jsprit.core.problem.Capacity;
|
||||||
import jsprit.core.problem.solution.route.activity.TimeWindow;
|
import jsprit.core.problem.solution.route.activity.TimeWindow;
|
||||||
import jsprit.core.util.Coordinate;
|
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 {
|
public class Service implements Job {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builder that builds a service.
|
||||||
|
*
|
||||||
|
* @author schroeder
|
||||||
|
*
|
||||||
|
*/
|
||||||
public static class Builder {
|
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){
|
public static Builder newInstance(String id, int size){
|
||||||
Builder builder = new Builder(id,size);
|
Builder builder = new Builder(id,size);
|
||||||
builder.addCapacityDimension(0, size);
|
builder.addCapacityDimension(0, size);
|
||||||
|
|
@ -36,17 +60,31 @@ public class Service implements Job {
|
||||||
}
|
}
|
||||||
|
|
||||||
private String id;
|
private String id;
|
||||||
|
|
||||||
protected String locationId;
|
protected String locationId;
|
||||||
|
|
||||||
private String type = "service";
|
private String type = "service";
|
||||||
|
|
||||||
protected Coordinate coord;
|
protected Coordinate coord;
|
||||||
|
|
||||||
protected double serviceTime;
|
protected double serviceTime;
|
||||||
|
|
||||||
protected TimeWindow timeWindow = TimeWindow.newInstance(0.0, Double.MAX_VALUE);
|
protected TimeWindow timeWindow = TimeWindow.newInstance(0.0, Double.MAX_VALUE);
|
||||||
|
|
||||||
protected int demand;
|
protected int demand;
|
||||||
protected Capacity.Builder capacityBuilder = Capacity.Builder.newInstance();
|
protected Capacity.Builder capacityBuilder = Capacity.Builder.newInstance();
|
||||||
protected Capacity capacity;
|
protected Capacity capacity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs the builder.
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @param size
|
||||||
|
* @throws IllegalArgumentException if size < 0 or id is null
|
||||||
|
*/
|
||||||
Builder(String id, int size) {
|
Builder(String id, int size) {
|
||||||
if(size < 0) throw new IllegalArgumentException("size must be greater than or equal to zero");
|
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.id = id;
|
||||||
this.demand = size;
|
this.demand = size;
|
||||||
}
|
}
|
||||||
|
|
@ -55,37 +93,84 @@ public class Service implements Job {
|
||||||
this.id = id;
|
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){
|
protected Builder setType(String name){
|
||||||
this.type = name;
|
this.type = name;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the location-id of this service.
|
||||||
|
*
|
||||||
|
* @param locationId
|
||||||
|
* @return builder
|
||||||
|
*/
|
||||||
public Builder setLocationId(String locationId){
|
public Builder setLocationId(String locationId){
|
||||||
this.locationId = locationId;
|
this.locationId = locationId;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the coordinate of this service.
|
||||||
|
*
|
||||||
|
* @param coord
|
||||||
|
* @return builder
|
||||||
|
*/
|
||||||
public Builder setCoord(Coordinate coord){
|
public Builder setCoord(Coordinate coord){
|
||||||
this.coord = coord;
|
this.coord = coord;
|
||||||
return this;
|
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){
|
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;
|
this.serviceTime = serviceTime;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Builder addCapacityDimension(int dimensionIndex, int dimensionValue){
|
public Builder addCapacityDimension(int dimensionIndex, int dimensionValue){
|
||||||
capacityBuilder.addDimension(dimensionIndex, dimensionValue);
|
capacityBuilder.addDimension(dimensionIndex, dimensionValue);
|
||||||
return this;
|
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){
|
public Builder setTimeWindow(TimeWindow tw){
|
||||||
|
if(tw == null) throw new IllegalArgumentException("time-window arg must not be null");
|
||||||
this.timeWindow = tw;
|
this.timeWindow = tw;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds the service.
|
||||||
|
*
|
||||||
|
* @return {@link Service}
|
||||||
|
* @throws IllegalStateException if neither locationId nor coordinate is set.
|
||||||
|
*/
|
||||||
public Service build(){
|
public Service build(){
|
||||||
if(locationId == null) {
|
if(locationId == null) {
|
||||||
if(coord == null) throw new IllegalStateException("either locationId or a coordinate must be given. But is not.");
|
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;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the location-id of this service.
|
||||||
|
*
|
||||||
|
* @return String that indicates the location
|
||||||
|
*/
|
||||||
public String getLocationId() {
|
public String getLocationId() {
|
||||||
return locationId;
|
return locationId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the coordinate of this service.
|
||||||
|
*
|
||||||
|
* @return {@link Coordinate}
|
||||||
|
*/
|
||||||
public Coordinate getCoord(){
|
public Coordinate getCoord(){
|
||||||
return coord;
|
return coord;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the service-time/duration a service takes at service-location.
|
||||||
|
*
|
||||||
|
* @return service duration
|
||||||
|
*/
|
||||||
public double getServiceDuration() {
|
public double getServiceDuration() {
|
||||||
return serviceTime;
|
return serviceTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the time-window a service(-operation) is allowed to start.
|
||||||
|
*
|
||||||
|
* @return time window
|
||||||
|
*/
|
||||||
public TimeWindow getTimeWindow(){
|
public TimeWindow getTimeWindow(){
|
||||||
return timeWindow;
|
return timeWindow;
|
||||||
}
|
}
|
||||||
|
|
@ -159,14 +264,17 @@ public class Service implements Job {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a string with the service's attributes.
|
||||||
|
*
|
||||||
|
* <p>String is built as follows: [attr1=val1][attr2=val2]...
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "[id=" + id + "][type="+type+"][locationId=" + locationId + "][coord="+coord+"][size=" + demand + "][serviceTime=" + serviceTime + "][timeWindow=" + timeWindow + "]";
|
return "[id=" + id + "][type="+type+"][locationId=" + locationId + "][coord="+coord+"][size=" + demand + "][serviceTime=" + serviceTime + "][timeWindow=" + timeWindow + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see java.lang.Object#hashCode()
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
final int prime = 31;
|
final int prime = 31;
|
||||||
|
|
@ -175,8 +283,9 @@ public class Service implements Job {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/**
|
||||||
* @see java.lang.Object#equals(java.lang.Object)
|
* Two services are equal if they have the same id.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,31 @@ import jsprit.core.problem.Capacity;
|
||||||
import jsprit.core.problem.solution.route.activity.TimeWindow;
|
import jsprit.core.problem.solution.route.activity.TimeWindow;
|
||||||
import jsprit.core.util.Coordinate;
|
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{
|
public class Shipment implements Job{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builder that builds the shipment.
|
||||||
|
*
|
||||||
|
* @author schroeder
|
||||||
|
*
|
||||||
|
*/
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
|
|
||||||
private int demand;
|
private int demand;
|
||||||
|
|
@ -32,6 +55,14 @@ public class Shipment implements Job{
|
||||||
|
|
||||||
private Capacity capacity;
|
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){
|
public static Builder newInstance(String id, int size){
|
||||||
Builder builder = new Builder(id,size);
|
Builder builder = new Builder(id,size);
|
||||||
builder.addCapacityDimension(0, size);
|
builder.addCapacityDimension(0, size);
|
||||||
|
|
@ -42,8 +73,16 @@ public class Shipment implements Job{
|
||||||
return new Builder(id);
|
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) {
|
Builder(String id, int size) {
|
||||||
if(size < 0) throw new IllegalArgumentException("size must be greater than or equal to zero");
|
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.id = id;
|
||||||
this.demand = size;
|
this.demand = size;
|
||||||
}
|
}
|
||||||
|
|
@ -52,51 +91,140 @@ public class Shipment implements Job{
|
||||||
this.id = id;
|
this.id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets pickup-location.
|
||||||
|
*
|
||||||
|
* @param pickupLocation
|
||||||
|
* @return builder
|
||||||
|
* @throws IllegalArgumentException if location is null
|
||||||
|
*/
|
||||||
public Builder setPickupLocation(String pickupLocation){
|
public Builder setPickupLocation(String pickupLocation){
|
||||||
|
if(pickupLocation == null) throw new IllegalArgumentException("location must not be null");
|
||||||
this.pickupLocation = pickupLocation;
|
this.pickupLocation = pickupLocation;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets pickup-coordinate.
|
||||||
|
*
|
||||||
|
* @param pickupCoord
|
||||||
|
* @return builder
|
||||||
|
* @throws IllegalArgumentException if pickupCoord is null
|
||||||
|
*/
|
||||||
public Builder setPickupCoord(Coordinate pickupCoord){
|
public Builder setPickupCoord(Coordinate pickupCoord){
|
||||||
|
if(pickupCoord == null) throw new IllegalArgumentException("coord must not be null");
|
||||||
this.pickupCoord = pickupCoord;
|
this.pickupCoord = pickupCoord;
|
||||||
return this;
|
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){
|
public Builder setPickupServiceTime(double serviceTime){
|
||||||
|
if(serviceTime < 0.0) throw new IllegalArgumentException("serviceTime must not be < 0.0");
|
||||||
this.pickupServiceTime = serviceTime;
|
this.pickupServiceTime = serviceTime;
|
||||||
return this;
|
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){
|
public Builder setPickupTimeWindow(TimeWindow timeWindow){
|
||||||
|
if(timeWindow == null) throw new IllegalArgumentException("timeWindow cannot be null");
|
||||||
this.pickupTimeWindow = timeWindow;
|
this.pickupTimeWindow = timeWindow;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the delivery-location.
|
||||||
|
*
|
||||||
|
* @param deliveryLocation
|
||||||
|
* @return builder
|
||||||
|
* @throws IllegalArgumentException if location is null
|
||||||
|
*/
|
||||||
public Builder setDeliveryLocation(String deliveryLocation){
|
public Builder setDeliveryLocation(String deliveryLocation){
|
||||||
|
if(deliveryLocation == null) throw new IllegalArgumentException("delivery location must not be null");
|
||||||
this.deliveryLocation = deliveryLocation;
|
this.deliveryLocation = deliveryLocation;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets delivery-coord.
|
||||||
|
*
|
||||||
|
* @param deliveryCoord
|
||||||
|
* @return builder
|
||||||
|
* @throws IllegalArgumentException if coord is null;
|
||||||
|
*/
|
||||||
public Builder setDeliveryCoord(Coordinate deliveryCoord){
|
public Builder setDeliveryCoord(Coordinate deliveryCoord){
|
||||||
|
if(deliveryCoord == null) throw new IllegalArgumentException("coord must not be null");
|
||||||
this.deliveryCoord = deliveryCoord;
|
this.deliveryCoord = deliveryCoord;
|
||||||
return this;
|
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){
|
public Builder setDeliveryServiceTime(double deliveryServiceTime){
|
||||||
|
if(deliveryServiceTime < 0.0) throw new IllegalArgumentException("deliveryServiceTime must not be < 0.0");
|
||||||
this.deliveryServiceTime = deliveryServiceTime;
|
this.deliveryServiceTime = deliveryServiceTime;
|
||||||
return this;
|
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){
|
public Builder setDeliveryTimeWindow(TimeWindow timeWindow){
|
||||||
|
if(timeWindow == null) throw new IllegalArgumentException("delivery time-window must not be null");
|
||||||
this.deliveryTimeWindow = timeWindow;
|
this.deliveryTimeWindow = timeWindow;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds capacity dimension.
|
||||||
|
*
|
||||||
|
* @param dimIndex
|
||||||
|
* @param dimVal
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
public Builder addCapacityDimension(int dimIndex, int dimVal) {
|
public Builder addCapacityDimension(int dimIndex, int dimVal) {
|
||||||
capacityBuilder.addDimension(dimIndex, dimVal);
|
capacityBuilder.addDimension(dimIndex, dimVal);
|
||||||
return this;
|
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(){
|
public Shipment build(){
|
||||||
if(pickupLocation == null) {
|
if(pickupLocation == null) {
|
||||||
if(pickupCoord == null) throw new IllegalStateException("either locationId or a coordinate must be given. But is not.");
|
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 TimeWindow pickupTimeWindow;
|
||||||
|
|
||||||
private final Capacity capacity;
|
private final Capacity capacity;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs the shipment.
|
||||||
|
*
|
||||||
|
* @param builder
|
||||||
|
*/
|
||||||
Shipment(Builder builder){
|
Shipment(Builder builder){
|
||||||
this.id = builder.id;
|
this.id = builder.id;
|
||||||
this.demand = builder.demand;
|
this.demand = builder.demand;
|
||||||
|
|
@ -159,34 +293,76 @@ public class Shipment implements Job{
|
||||||
return demand;
|
return demand;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the pickup-location.
|
||||||
|
*
|
||||||
|
* @return pickup-location
|
||||||
|
*/
|
||||||
public String getPickupLocation() {
|
public String getPickupLocation() {
|
||||||
return pickupLocation;
|
return pickupLocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the pickup-coordinate.
|
||||||
|
*
|
||||||
|
* @return coordinate of the pickup
|
||||||
|
*/
|
||||||
public Coordinate getPickupCoord() {
|
public Coordinate getPickupCoord() {
|
||||||
return pickupCoord;
|
return pickupCoord;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the pickup service-time.
|
||||||
|
*
|
||||||
|
* <p>By default service-time is 0.0.
|
||||||
|
*
|
||||||
|
* @return service-time
|
||||||
|
*/
|
||||||
public double getPickupServiceTime() {
|
public double getPickupServiceTime() {
|
||||||
return pickupServiceTime;
|
return pickupServiceTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns delivery-location.
|
||||||
|
*
|
||||||
|
* @return delivery-location
|
||||||
|
*/
|
||||||
public String getDeliveryLocation() {
|
public String getDeliveryLocation() {
|
||||||
return deliveryLocation;
|
return deliveryLocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns coordinate of the delivery.
|
||||||
|
*
|
||||||
|
* @return coordinate of delivery
|
||||||
|
*/
|
||||||
public Coordinate getDeliveryCoord() {
|
public Coordinate getDeliveryCoord() {
|
||||||
return deliveryCoord;
|
return deliveryCoord;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns service-time of delivery.
|
||||||
|
*
|
||||||
|
* @return service-time of delivery
|
||||||
|
*/
|
||||||
public double getDeliveryServiceTime() {
|
public double getDeliveryServiceTime() {
|
||||||
return deliveryServiceTime;
|
return deliveryServiceTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the time-window of delivery.
|
||||||
|
*
|
||||||
|
* @return time-window of delivery
|
||||||
|
*/
|
||||||
public TimeWindow getDeliveryTimeWindow() {
|
public TimeWindow getDeliveryTimeWindow() {
|
||||||
return deliveryTimeWindow;
|
return deliveryTimeWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the time-window of pickup.
|
||||||
|
*
|
||||||
|
* @return time-window of pickup
|
||||||
|
*/
|
||||||
public TimeWindow getPickupTimeWindow() {
|
public TimeWindow getPickupTimeWindow() {
|
||||||
return pickupTimeWindow;
|
return pickupTimeWindow;
|
||||||
}
|
}
|
||||||
|
|
@ -199,6 +375,11 @@ public class Shipment implements Job{
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Two shipments are equal if they have the same id.
|
||||||
|
*
|
||||||
|
* @return true if shipments are equal (have the same id)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
if (this == obj)
|
if (this == obj)
|
||||||
|
|
|
||||||
|
|
@ -37,22 +37,65 @@ import jsprit.core.problem.vehicle.Vehicle;
|
||||||
import jsprit.core.problem.vehicle.VehicleImpl;
|
import jsprit.core.problem.vehicle.VehicleImpl;
|
||||||
import jsprit.core.problem.vehicle.VehicleImpl.NoVehicle;
|
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 {
|
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) {
|
public static VehicleRoute copyOf(VehicleRoute route) {
|
||||||
|
if(route == null) throw new IllegalArgumentException("route must not be null");
|
||||||
return new VehicleRoute(route);
|
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) {
|
public static VehicleRoute newInstance(TourActivities tour, Driver driver, Vehicle vehicle) {
|
||||||
return new VehicleRoute(tour,driver,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() {
|
public static VehicleRoute emptyRoute() {
|
||||||
return new VehicleRoute(TourActivities.emptyTour(), DriverImpl.noDriver(), VehicleImpl.createNoVehicle());
|
return new VehicleRoute(TourActivities.emptyTour(), DriverImpl.noDriver(), VehicleImpl.createNoVehicle());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builder that builds the vehicle route.
|
||||||
|
*
|
||||||
|
* @author stefan
|
||||||
|
*
|
||||||
|
*/
|
||||||
public static class Builder {
|
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){
|
public static Builder newInstance(Vehicle vehicle, Driver driver){
|
||||||
return new Builder(vehicle,driver);
|
return new Builder(vehicle,driver);
|
||||||
}
|
}
|
||||||
|
|
@ -73,10 +116,24 @@ public class VehicleRoute {
|
||||||
|
|
||||||
private Set<Shipment> openShipments = new HashSet<Shipment>();
|
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) {
|
public void setServiceActivityFactory(TourActivityFactory serviceActivityFactory) {
|
||||||
this.serviceActivityFactory = serviceActivityFactory;
|
this.serviceActivityFactory = serviceActivityFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the shipmentActivityFactory to create shipmentActivities.
|
||||||
|
*
|
||||||
|
* <p>By default {@link DefaultShipmentActivityFactory} is used.
|
||||||
|
*
|
||||||
|
* @param shipmentActivityFactory
|
||||||
|
*/
|
||||||
public void setShipmentActivityFactory(TourShipmentActivityFactory shipmentActivityFactory) {
|
public void setShipmentActivityFactory(TourShipmentActivityFactory shipmentActivityFactory) {
|
||||||
this.shipmentActivityFactory = 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
|
* @param departureTime
|
||||||
* @return
|
* @return
|
||||||
|
|
@ -110,16 +167,46 @@ public class VehicleRoute {
|
||||||
return this;
|
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){
|
public Builder setRouteEndArrivalTime(double endTime){
|
||||||
end.setArrTime(endTime);
|
end.setArrTime(endTime);
|
||||||
return this;
|
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){
|
public Builder addService(Service service){
|
||||||
|
if(service == null) throw new IllegalArgumentException("service must not be null");
|
||||||
addService(service,0.0,0.0);
|
addService(service,0.0,0.0);
|
||||||
return this;
|
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){
|
public Builder addService(Service service, double arrTime, double endTime){
|
||||||
TourActivity act = serviceActivityFactory.createActivity(service);
|
TourActivity act = serviceActivityFactory.createActivity(service);
|
||||||
act.setArrTime(arrTime);
|
act.setArrTime(arrTime);
|
||||||
|
|
@ -266,15 +353,38 @@ public class VehicleRoute {
|
||||||
return tourActivities;
|
return tourActivities;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the vehicle operating this route.
|
||||||
|
*
|
||||||
|
* @return Vehicle
|
||||||
|
*/
|
||||||
public Vehicle getVehicle() {
|
public Vehicle getVehicle() {
|
||||||
return vehicle;
|
return vehicle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the driver operating this route.
|
||||||
|
*
|
||||||
|
* @return Driver
|
||||||
|
*/
|
||||||
public Driver getDriver() {
|
public Driver getDriver() {
|
||||||
return driver;
|
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){
|
public void setVehicle(Vehicle vehicle, double vehicleDepTime){
|
||||||
this.vehicle = vehicle;
|
this.vehicle = vehicle;
|
||||||
setStartAndEnd(vehicle, vehicleDepTime);
|
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){
|
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.");
|
if(start == null) throw new IllegalStateException("cannot set departureTime without having a vehicle on this route. use setVehicle(vehicle,departureTime) instead.");
|
||||||
start.setEndTime(vehicleDepTime);
|
start.setEndTime(vehicleDepTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the departureTime of this vehicle.
|
||||||
|
*
|
||||||
|
* @return departureTime
|
||||||
|
* @throws IllegalStateException if start is null
|
||||||
|
*/
|
||||||
public double getDepartureTime(){
|
public double getDepartureTime(){
|
||||||
if(start == null) throw new IllegalStateException("cannot get departureTime without having a vehicle on this route. use setVehicle(vehicle,departureTime) instead.");
|
if(start == null) throw new IllegalStateException("cannot get departureTime without having a vehicle on this route. use setVehicle(vehicle,departureTime) instead.");
|
||||||
return start.getEndTime();
|
return start.getEndTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns tour if tour-activity-sequence is empty, i.e. to activity on the tour yet.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
return tourActivities.isEmpty();
|
return tourActivities.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns start-activity of this route.
|
||||||
|
*
|
||||||
|
* @return start
|
||||||
|
*/
|
||||||
public Start getStart() {
|
public Start getStart() {
|
||||||
return start;
|
return start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns end-activity of this route.
|
||||||
|
*
|
||||||
|
* @return end
|
||||||
|
*/
|
||||||
public End getEnd() {
|
public End getEnd() {
|
||||||
return end;
|
return end;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
package jsprit.core.problem.solution.route.activity;
|
package jsprit.core.problem.solution.route.activity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* TimeWindow consists of a startTime and endTime.
|
||||||
*
|
*
|
||||||
* @author stefan schroeder
|
* @author stefan schroeder
|
||||||
*
|
*
|
||||||
|
|
@ -24,6 +25,14 @@ package jsprit.core.problem.solution.route.activity;
|
||||||
|
|
||||||
public class TimeWindow {
|
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){
|
public static TimeWindow newInstance(double start, double end){
|
||||||
return new TimeWindow(start,end);
|
return new TimeWindow(start,end);
|
||||||
}
|
}
|
||||||
|
|
@ -31,16 +40,35 @@ public class TimeWindow {
|
||||||
private final double start;
|
private final double start;
|
||||||
private final double end;
|
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) {
|
public TimeWindow(double start, double end) {
|
||||||
super();
|
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.start = start;
|
||||||
this.end = end;
|
this.end = end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns startTime of TimeWindow.
|
||||||
|
*
|
||||||
|
* @return startTime
|
||||||
|
*/
|
||||||
public double getStart() {
|
public double getStart() {
|
||||||
return start;
|
return start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns endTime of TimeWindow.
|
||||||
|
*
|
||||||
|
* @return endTime
|
||||||
|
*/
|
||||||
public double getEnd() {
|
public double getEnd() {
|
||||||
return end;
|
return end;
|
||||||
}
|
}
|
||||||
|
|
@ -62,6 +90,9 @@ public class TimeWindow {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Two timeWindows are equal if they have the same start AND endTime.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
if (this == obj)
|
if (this == obj)
|
||||||
|
|
|
||||||
|
|
@ -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++;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -40,7 +40,7 @@
|
||||||
<xs:element name="location">
|
<xs:element name="location">
|
||||||
<xs:complexType>
|
<xs:complexType>
|
||||||
<xs:all>
|
<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:element name="coord" minOccurs="0" maxOccurs="1">
|
||||||
<xs:complexType>
|
<xs:complexType>
|
||||||
<xs:attribute name="x" type="xs:decimal" use="required"/>
|
<xs:attribute name="x" type="xs:decimal" use="required"/>
|
||||||
|
|
@ -95,7 +95,7 @@
|
||||||
<xs:element name="service" minOccurs="0" maxOccurs="unbounded">
|
<xs:element name="service" minOccurs="0" maxOccurs="unbounded">
|
||||||
<xs:complexType>
|
<xs:complexType>
|
||||||
<xs:all>
|
<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="coord" type="coordType" minOccurs="0" maxOccurs="1"/>
|
||||||
<xs:element name="capacity-demand" type="xs:integer" minOccurs="0" maxOccurs="1" default="0"/>
|
<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"/>
|
<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:element name="pickup" minOccurs="1" maxOccurs="1">
|
||||||
<xs:complexType>
|
<xs:complexType>
|
||||||
<xs:all>
|
<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="coord" type="coordType" minOccurs="0" maxOccurs="1"/>
|
||||||
<xs:element name="duration" type="xs:decimal" minOccurs="0" maxOccurs="1" default="0.0"/>
|
<xs:element name="duration" type="xs:decimal" minOccurs="0" maxOccurs="1" default="0.0"/>
|
||||||
<xs:element name="timeWindows" minOccurs="0" maxOccurs="1">
|
<xs:element name="timeWindows" minOccurs="0" maxOccurs="1">
|
||||||
|
|
@ -141,7 +141,7 @@
|
||||||
<xs:element name="delivery" minOccurs="1" maxOccurs="1">
|
<xs:element name="delivery" minOccurs="1" maxOccurs="1">
|
||||||
<xs:complexType>
|
<xs:complexType>
|
||||||
<xs:all>
|
<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="coord" type="coordType" minOccurs="0" maxOccurs="1"/>
|
||||||
<xs:element name="duration" type="xs:decimal" minOccurs="0" maxOccurs="1" default="0.0"/>
|
<xs:element name="duration" type="xs:decimal" minOccurs="0" maxOccurs="1" default="0.0"/>
|
||||||
<xs:element name="timeWindows" minOccurs="0" maxOccurs="1">
|
<xs:element name="timeWindows" minOccurs="0" maxOccurs="1">
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -37,6 +37,8 @@ import jsprit.core.problem.solution.VehicleRoutingProblemSolution;
|
||||||
import jsprit.core.problem.vehicle.Vehicle;
|
import jsprit.core.problem.vehicle.Vehicle;
|
||||||
import jsprit.core.problem.vehicle.VehicleImpl;
|
import jsprit.core.problem.vehicle.VehicleImpl;
|
||||||
import jsprit.core.problem.vehicle.VehicleTypeImpl;
|
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.Solutions;
|
||||||
import jsprit.core.util.VehicleRoutingTransportCostsMatrix;
|
import jsprit.core.util.VehicleRoutingTransportCostsMatrix;
|
||||||
import jsprit.core.util.VehicleRoutingTransportCostsMatrix.Builder;
|
import jsprit.core.util.VehicleRoutingTransportCostsMatrix.Builder;
|
||||||
|
|
@ -188,6 +190,8 @@ public class RefuseCollection_IT {
|
||||||
vra.setPrematureAlgorithmTermination(new IterationWithoutImprovementTermination(100));
|
vra.setPrematureAlgorithmTermination(new IterationWithoutImprovementTermination(100));
|
||||||
Collection<VehicleRoutingProblemSolution> solutions = vra.searchSolutions();
|
Collection<VehicleRoutingProblemSolution> solutions = vra.searchSolutions();
|
||||||
|
|
||||||
|
SolutionPrinter.print(vrp, Solutions.bestOf(solutions), Print.VERBOSE);
|
||||||
|
|
||||||
assertEquals(397.0,Solutions.bestOf(solutions).getCost(),0.01);
|
assertEquals(397.0,Solutions.bestOf(solutions).getCost(),0.01);
|
||||||
assertEquals(2,Solutions.bestOf(solutions).getRoutes().size());
|
assertEquals(2,Solutions.bestOf(solutions).getRoutes().size());
|
||||||
}
|
}
|
||||||
|
|
@ -227,6 +231,7 @@ public class RefuseCollection_IT {
|
||||||
}
|
}
|
||||||
String[] lineTokens = line.split(",");
|
String[] lineTokens = line.split(",");
|
||||||
matrixBuilder.addTransportDistance(lineTokens[0],lineTokens[1], Integer.parseInt(lineTokens[2]));
|
matrixBuilder.addTransportDistance(lineTokens[0],lineTokens[1], Integer.parseInt(lineTokens[2]));
|
||||||
|
matrixBuilder.addTransportTime(lineTokens[0],lineTokens[1], Integer.parseInt(lineTokens[2]));
|
||||||
}
|
}
|
||||||
reader.close();
|
reader.close();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -106,12 +106,19 @@ public class VrpReaderV2Test {
|
||||||
assertEquals(FleetSize.FINITE,vrp.getFleetSize());
|
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
|
@Test
|
||||||
public void whenReadingServices_itReadsThemCorrectly(){
|
public void whenReadingServices_itReadsThemCorrectly(){
|
||||||
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
|
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
|
||||||
new VrpXMLReader(builder, null).read(inFileName);
|
new VrpXMLReader(builder, null).read(inFileName);
|
||||||
VehicleRoutingProblem vrp = builder.build();
|
VehicleRoutingProblem vrp = builder.build();
|
||||||
assertEquals(3, vrp.getJobs().size());
|
|
||||||
int servCounter = 0;
|
int servCounter = 0;
|
||||||
for(Job j : vrp.getJobs().values()){
|
for(Job j : vrp.getJobs().values()){
|
||||||
if(j instanceof Service) servCounter++;
|
if(j instanceof Service) servCounter++;
|
||||||
|
|
@ -124,23 +131,171 @@ public class VrpReaderV2Test {
|
||||||
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
|
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
|
||||||
new VrpXMLReader(builder, null).read(inFileName);
|
new VrpXMLReader(builder, null).read(inFileName);
|
||||||
VehicleRoutingProblem vrp = builder.build();
|
VehicleRoutingProblem vrp = builder.build();
|
||||||
assertEquals(3, vrp.getJobs().size());
|
|
||||||
int shipCounter = 0;
|
int shipCounter = 0;
|
||||||
for(Job j : vrp.getJobs().values()){
|
for(Job j : vrp.getJobs().values()){
|
||||||
if(j instanceof Shipment) shipCounter++;
|
if(j instanceof Shipment) shipCounter++;
|
||||||
}
|
}
|
||||||
assertEquals(1,shipCounter);
|
assertEquals(2,shipCounter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@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();
|
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
|
||||||
new VrpXMLReader(builder, null).read(inFileName);
|
new VrpXMLReader(builder, null).read(inFileName);
|
||||||
VehicleRoutingProblem vrp = builder.build();
|
VehicleRoutingProblem vrp = builder.build();
|
||||||
Service s1 = (Service) vrp.getJobs().get("1");
|
Service s1 = (Service) vrp.getJobs().get("1");
|
||||||
assertEquals("service",s1.getType());
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -17,11 +17,17 @@
|
||||||
package jsprit.core.problem.job;
|
package jsprit.core.problem.job;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import jsprit.core.problem.solution.route.activity.TimeWindow;
|
||||||
|
import jsprit.core.util.Coordinate;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -86,4 +92,61 @@ public class ServiceTest {
|
||||||
assertEquals(1,one.getCapacity().get(0));
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
package jsprit.core.problem.job;
|
package jsprit.core.problem.job;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import jsprit.core.problem.job.Shipment;
|
|
||||||
import jsprit.core.problem.solution.route.activity.TimeWindow;
|
import jsprit.core.problem.solution.route.activity.TimeWindow;
|
||||||
import jsprit.core.util.Coordinate;
|
import jsprit.core.util.Coordinate;
|
||||||
|
|
||||||
|
|
@ -38,21 +38,160 @@ public class ShipmentTest {
|
||||||
assertEquals(10,one.getCapacityDemand());
|
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
|
@Test
|
||||||
public void whenShipmentIsDefined_itsFieldsShouldBeDefinedCorrectly(){
|
public void whenCallingForANewBuilderInstance_itShouldReturnBuilderCorrectly(){
|
||||||
Shipment one = Shipment.Builder.newInstance("s", 10).setPickupLocation("foo").setPickupCoord(Coordinate.newInstance(0, 0)).setPickupServiceTime(1.0)
|
Shipment.Builder builder = Shipment.Builder.newInstance("s", 0);
|
||||||
.setPickupTimeWindow(TimeWindow.newInstance(0.0, 1.0))
|
assertNotNull(builder);
|
||||||
.setDeliveryLocation("foofoo").setDeliveryServiceTime(20).setDeliveryCoord(Coordinate.newInstance(1, 1)).
|
}
|
||||||
setDeliveryTimeWindow(TimeWindow.newInstance(1.0, 2.0)).build();
|
|
||||||
assertEquals("s",one.getId());
|
@Test(expected=IllegalStateException.class)
|
||||||
assertEquals(10,one.getCapacityDemand());
|
public void whenNeitherPickupLocationIdNorPickupCoord_itThrowsException(){
|
||||||
assertEquals("foo",one.getPickupLocation());
|
@SuppressWarnings("unused")
|
||||||
assertEquals(0,one.getPickupCoord().getX(),0.01);
|
Shipment s = Shipment.Builder.newInstance("s", 0).setDeliveryLocation("delLoc").build();
|
||||||
assertEquals(1.0,one.getPickupServiceTime(),0.01);
|
}
|
||||||
assertEquals("foofoo",one.getDeliveryLocation());
|
|
||||||
assertEquals(20.0,one.getDeliveryServiceTime(),0.01);
|
@Test(expected=IllegalStateException.class)
|
||||||
assertEquals(1.0,one.getDeliveryCoord().getX(),0.01);
|
public void whenNeitherDeliveryLocationIdNorDeliveryCoord_itThrowsException(){
|
||||||
assertEquals(1.0,one.getDeliveryTimeWindow().getStart(),0.01);
|
@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)
|
@Test(expected=IllegalStateException.class)
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@
|
||||||
<locationId>j(1,5)</locationId>
|
<locationId>j(1,5)</locationId>
|
||||||
<coord x="10.0" y="10.0"/>
|
<coord x="10.0" y="10.0"/>
|
||||||
<capacity-demand>1</capacity-demand>
|
<capacity-demand>1</capacity-demand>
|
||||||
<duration>0.0</duration>
|
<duration>10.0</duration>
|
||||||
<timeWindows>
|
<timeWindows>
|
||||||
<timeWindow>
|
<timeWindow>
|
||||||
<start>0.0</start>
|
<start>0.0</start>
|
||||||
|
|
@ -108,10 +108,10 @@
|
||||||
<pickup>
|
<pickup>
|
||||||
<locationId>i(3,9)</locationId>
|
<locationId>i(3,9)</locationId>
|
||||||
<coord x="10.0" y="10.0"/>
|
<coord x="10.0" y="10.0"/>
|
||||||
<duration>0.0</duration>
|
<duration>10.0</duration>
|
||||||
<timeWindows>
|
<timeWindows>
|
||||||
<timeWindow>
|
<timeWindow>
|
||||||
<start>0.0</start>
|
<start>1000.0</start>
|
||||||
<end>4000.0</end>
|
<end>4000.0</end>
|
||||||
</timeWindow>
|
</timeWindow>
|
||||||
</timeWindows>
|
</timeWindows>
|
||||||
|
|
@ -119,16 +119,40 @@
|
||||||
<delivery>
|
<delivery>
|
||||||
<locationId>i(9,9)</locationId>
|
<locationId>i(9,9)</locationId>
|
||||||
<coord x="10.0" y="0.0"/>
|
<coord x="10.0" y="0.0"/>
|
||||||
<duration>0.0</duration>
|
<duration>100.0</duration>
|
||||||
<timeWindows>
|
<timeWindows>
|
||||||
<timeWindow>
|
<timeWindow>
|
||||||
<start>0.0</start>
|
<start>6000.0</start>
|
||||||
<end>4000.0</end>
|
<end>10000.0</end>
|
||||||
</timeWindow>
|
</timeWindow>
|
||||||
</timeWindows>
|
</timeWindows>
|
||||||
</delivery>
|
</delivery>
|
||||||
<capacity-demand>1</capacity-demand>
|
<capacity-demand>10</capacity-demand>
|
||||||
</shipment>
|
</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>
|
</shipments>
|
||||||
|
|
||||||
</problem>
|
</problem>
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>jsprit</groupId>
|
<groupId>jsprit</groupId>
|
||||||
<artifactId>jsprit</artifactId>
|
<artifactId>jsprit</artifactId>
|
||||||
<version>1.0.1-SNAPSHOT</version>
|
<version>1.1.2-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ import jsprit.util.Examples;
|
||||||
* <a href=http://mistic.heig-vd.ch/taillard/problemes.dir/vrp.dir/vrp.html>.
|
* <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:
|
* <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://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>
|
* <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>
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -78,10 +78,11 @@
|
||||||
//Vehicles characteristics: volume, fixed cost, variable cost, number available
|
//Vehicles characteristics: volume, fixed cost, variable cost, number available
|
||||||
//See E. D. Taillard, "A heuristic column generation method for the heterogeneous fleet vrp"
|
//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)
|
//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
|
//see http://ina2.eivd.ch/collaborateurs/etd/articles.dir/vrphen.pdf
|
||||||
v 1 120 80 1.2 4
|
v 1 50 25 1.0 4
|
||||||
v 2 200 150 1.5 2
|
v 2 120 80 1.2 4
|
||||||
v 3 350 320 1.8 1
|
v 3 200 150 1.5 2
|
||||||
|
v 4 350 320 1.8 1
|
||||||
|
|
||||||
7 350 0 1000000 703.124497 + 7 * 150 = 1753.12
|
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
|
14 27 57 15 37 20 70 60 71 69 36 47 5 29 45 2685412
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>jsprit</groupId>
|
<groupId>jsprit</groupId>
|
||||||
<artifactId>jsprit</artifactId>
|
<artifactId>jsprit</artifactId>
|
||||||
<version>1.0.1-SNAPSHOT</version>
|
<version>1.1.2-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,6 @@ import jsprit.core.util.Coordinate;
|
||||||
*
|
*
|
||||||
* <p>See {@link VrphType} what kind of problems can be generated
|
* <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
|
* @author schroeder
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
@ -110,6 +108,7 @@ public class VrphGoldenReader {
|
||||||
typeBuilder.setCostPerDistance(Double.parseDouble(tokens[4]));
|
typeBuilder.setCostPerDistance(Double.parseDouble(tokens[4]));
|
||||||
nuOfVehicles = Integer.parseInt(tokens[5]);
|
nuOfVehicles = Integer.parseInt(tokens[5]);
|
||||||
vrpBuilder.setFleetSize(FleetSize.FINITE);
|
vrpBuilder.setFleetSize(FleetSize.FINITE);
|
||||||
|
vrpBuilder.addPenaltyVehicles(5.0, 5000);
|
||||||
}
|
}
|
||||||
else throw new IllegalStateException("option " + vrphType + " cannot be applied with this instance");
|
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]));
|
typeBuilder.setCostPerDistance(Double.parseDouble(tokens[4]));
|
||||||
nuOfVehicles = Integer.parseInt(tokens[5]);
|
nuOfVehicles = Integer.parseInt(tokens[5]);
|
||||||
vrpBuilder.setFleetSize(FleetSize.FINITE);
|
vrpBuilder.setFleetSize(FleetSize.FINITE);
|
||||||
|
vrpBuilder.addPenaltyVehicles(5.0, 5000);
|
||||||
}
|
}
|
||||||
else throw new IllegalStateException("option " + vrphType + " cannot be applied with this instance");
|
else throw new IllegalStateException("option " + vrphType + " cannot be applied with this instance");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import static org.junit.Assert.assertTrue;
|
||||||
import jsprit.core.problem.VehicleRoutingProblem;
|
import jsprit.core.problem.VehicleRoutingProblem;
|
||||||
import jsprit.core.problem.job.Job;
|
import jsprit.core.problem.job.Job;
|
||||||
import jsprit.core.problem.job.Service;
|
import jsprit.core.problem.job.Service;
|
||||||
|
import jsprit.core.problem.vehicle.PenaltyVehicleType;
|
||||||
import jsprit.core.problem.vehicle.Vehicle;
|
import jsprit.core.problem.vehicle.Vehicle;
|
||||||
import jsprit.core.util.Coordinate;
|
import jsprit.core.util.Coordinate;
|
||||||
import jsprit.instance.reader.VrphGoldenReader.VrphType;
|
import jsprit.instance.reader.VrphGoldenReader.VrphType;
|
||||||
|
|
@ -20,7 +21,13 @@ public class GoldenReaderTest {
|
||||||
new VrphGoldenReader(vrpBuilder, VrphType.HVRPD)
|
new VrphGoldenReader(vrpBuilder, VrphType.HVRPD)
|
||||||
.read(this.getClass().getClassLoader().getResource("cn_13mix.txt").getPath());
|
.read(this.getClass().getClassLoader().getResource("cn_13mix.txt").getPath());
|
||||||
VehicleRoutingProblem vrp = vrpBuilder.build();
|
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
|
@Test
|
||||||
|
|
@ -31,7 +38,7 @@ public class GoldenReaderTest {
|
||||||
VehicleRoutingProblem vrp = vrpBuilder.build();
|
VehicleRoutingProblem vrp = vrpBuilder.build();
|
||||||
int nuOfType1Vehicles = 0;
|
int nuOfType1Vehicles = 0;
|
||||||
for(Vehicle v : vrp.getVehicles()){
|
for(Vehicle v : vrp.getVehicles()){
|
||||||
if(v.getType().getTypeId().equals("type_1")){
|
if(v.getType().getTypeId().equals("type_1") && !(v.getType() instanceof PenaltyVehicleType) ){
|
||||||
nuOfType1Vehicles++;
|
nuOfType1Vehicles++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -46,7 +53,7 @@ public class GoldenReaderTest {
|
||||||
VehicleRoutingProblem vrp = vrpBuilder.build();
|
VehicleRoutingProblem vrp = vrpBuilder.build();
|
||||||
int sumOfType1Cap = 0;
|
int sumOfType1Cap = 0;
|
||||||
for(Vehicle v : vrp.getVehicles()){
|
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();
|
sumOfType1Cap+=v.getCapacity();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -61,7 +68,7 @@ public class GoldenReaderTest {
|
||||||
VehicleRoutingProblem vrp = vrpBuilder.build();
|
VehicleRoutingProblem vrp = vrpBuilder.build();
|
||||||
int nuOfType1Vehicles = 0;
|
int nuOfType1Vehicles = 0;
|
||||||
for(Vehicle v : vrp.getVehicles()){
|
for(Vehicle v : vrp.getVehicles()){
|
||||||
if(v.getType().getTypeId().equals("type_2")){
|
if(v.getType().getTypeId().equals("type_2") && !(v.getType() instanceof PenaltyVehicleType) ){
|
||||||
nuOfType1Vehicles++;
|
nuOfType1Vehicles++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -76,7 +83,7 @@ public class GoldenReaderTest {
|
||||||
VehicleRoutingProblem vrp = vrpBuilder.build();
|
VehicleRoutingProblem vrp = vrpBuilder.build();
|
||||||
int sumOfType1Cap = 0;
|
int sumOfType1Cap = 0;
|
||||||
for(Vehicle v : vrp.getVehicles()){
|
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();
|
sumOfType1Cap+=v.getCapacity();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -91,7 +98,7 @@ public class GoldenReaderTest {
|
||||||
VehicleRoutingProblem vrp = vrpBuilder.build();
|
VehicleRoutingProblem vrp = vrpBuilder.build();
|
||||||
int nuOfType1Vehicles = 0;
|
int nuOfType1Vehicles = 0;
|
||||||
for(Vehicle v : vrp.getVehicles()){
|
for(Vehicle v : vrp.getVehicles()){
|
||||||
if(v.getType().getTypeId().equals("type_3")){
|
if(v.getType().getTypeId().equals("type_3") && !(v.getType() instanceof PenaltyVehicleType) ){
|
||||||
nuOfType1Vehicles++;
|
nuOfType1Vehicles++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -106,7 +113,7 @@ public class GoldenReaderTest {
|
||||||
VehicleRoutingProblem vrp = vrpBuilder.build();
|
VehicleRoutingProblem vrp = vrpBuilder.build();
|
||||||
int sumOfType1Cap = 0;
|
int sumOfType1Cap = 0;
|
||||||
for(Vehicle v : vrp.getVehicles()){
|
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();
|
sumOfType1Cap+=v.getCapacity();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -121,7 +128,7 @@ public class GoldenReaderTest {
|
||||||
VehicleRoutingProblem vrp = vrpBuilder.build();
|
VehicleRoutingProblem vrp = vrpBuilder.build();
|
||||||
int nuOfType1Vehicles = 0;
|
int nuOfType1Vehicles = 0;
|
||||||
for(Vehicle v : vrp.getVehicles()){
|
for(Vehicle v : vrp.getVehicles()){
|
||||||
if(v.getType().getTypeId().equals("type_4")){
|
if(v.getType().getTypeId().equals("type_4") && !(v.getType() instanceof PenaltyVehicleType) ){
|
||||||
nuOfType1Vehicles++;
|
nuOfType1Vehicles++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -136,7 +143,7 @@ public class GoldenReaderTest {
|
||||||
VehicleRoutingProblem vrp = vrpBuilder.build();
|
VehicleRoutingProblem vrp = vrpBuilder.build();
|
||||||
int sumOfType1Cap = 0;
|
int sumOfType1Cap = 0;
|
||||||
for(Vehicle v : vrp.getVehicles()){
|
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();
|
sumOfType1Cap+=v.getCapacity();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -151,7 +158,7 @@ public class GoldenReaderTest {
|
||||||
VehicleRoutingProblem vrp = vrpBuilder.build();
|
VehicleRoutingProblem vrp = vrpBuilder.build();
|
||||||
int nuOfType1Vehicles = 0;
|
int nuOfType1Vehicles = 0;
|
||||||
for(Vehicle v : vrp.getVehicles()){
|
for(Vehicle v : vrp.getVehicles()){
|
||||||
if(v.getType().getTypeId().equals("type_5")){
|
if(v.getType().getTypeId().equals("type_5") && !(v.getType() instanceof PenaltyVehicleType) ){
|
||||||
nuOfType1Vehicles++;
|
nuOfType1Vehicles++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -166,7 +173,7 @@ public class GoldenReaderTest {
|
||||||
VehicleRoutingProblem vrp = vrpBuilder.build();
|
VehicleRoutingProblem vrp = vrpBuilder.build();
|
||||||
int sumOfType1Cap = 0;
|
int sumOfType1Cap = 0;
|
||||||
for(Vehicle v : vrp.getVehicles()){
|
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();
|
sumOfType1Cap+=v.getCapacity();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -181,7 +188,7 @@ public class GoldenReaderTest {
|
||||||
VehicleRoutingProblem vrp = vrpBuilder.build();
|
VehicleRoutingProblem vrp = vrpBuilder.build();
|
||||||
int nuOfType1Vehicles = 0;
|
int nuOfType1Vehicles = 0;
|
||||||
for(Vehicle v : vrp.getVehicles()){
|
for(Vehicle v : vrp.getVehicles()){
|
||||||
if(v.getType().getTypeId().equals("type_6")){
|
if(v.getType().getTypeId().equals("type_6") && !(v.getType() instanceof PenaltyVehicleType) ){
|
||||||
nuOfType1Vehicles++;
|
nuOfType1Vehicles++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -196,7 +203,7 @@ public class GoldenReaderTest {
|
||||||
VehicleRoutingProblem vrp = vrpBuilder.build();
|
VehicleRoutingProblem vrp = vrpBuilder.build();
|
||||||
int sumOfType1Cap = 0;
|
int sumOfType1Cap = 0;
|
||||||
for(Vehicle v : vrp.getVehicles()){
|
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();
|
sumOfType1Cap+=v.getCapacity();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
2
pom.xml
2
pom.xml
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
<groupId>jsprit</groupId>
|
<groupId>jsprit</groupId>
|
||||||
<artifactId>jsprit</artifactId>
|
<artifactId>jsprit</artifactId>
|
||||||
<version>1.0.1-SNAPSHOT</version>
|
<version>1.1.2-SNAPSHOT</version>
|
||||||
|
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue