From e33590b3801bacb45e00a12936b1713abab2265a Mon Sep 17 00:00:00 2001 From: oblonski <4sschroeder@gmail.com> Date: Tue, 16 Dec 2014 21:50:24 +0100 Subject: [PATCH] introduce Location obj --- .../java/jsprit/core/problem/Location.java | 93 ++++++++ .../jsprit/core/problem/job/Delivery.java | 19 +- .../java/jsprit/core/problem/job/Pickup.java | 19 +- .../java/jsprit/core/problem/job/Service.java | 66 ++++-- .../jsprit/core/problem/job/Shipment.java | 116 ++++++---- .../jsprit/core/problem/vehicle/Vehicle.java | 19 +- .../core/problem/vehicle/VehicleImpl.java | 201 +++++++++++++----- .../jsprit/core/problem/LocationTest.java | 62 ++++++ .../jsprit/core/problem/job/ServiceTest.java | 12 ++ .../jsprit/core/problem/job/ShipmentTest.java | 17 ++ 10 files changed, 489 insertions(+), 135 deletions(-) create mode 100644 jsprit-core/src/main/java/jsprit/core/problem/Location.java create mode 100644 jsprit-core/src/test/java/jsprit/core/problem/LocationTest.java diff --git a/jsprit-core/src/main/java/jsprit/core/problem/Location.java b/jsprit-core/src/main/java/jsprit/core/problem/Location.java new file mode 100644 index 00000000..b6e91b9b --- /dev/null +++ b/jsprit-core/src/main/java/jsprit/core/problem/Location.java @@ -0,0 +1,93 @@ +/******************************************************************************* + * Copyright (C) 2014 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 . + ******************************************************************************/ + +package jsprit.core.problem; + +import jsprit.core.util.Coordinate; + +/** + * Created by schroeder on 16.12.14. + */ +public final class Location implements HasIndex, HasId{ + + public static class Builder { + + private String id; + + private int index = -1; + + private Coordinate coordinate; + + public static Builder newInstance(){ return new Builder(); } + + public Builder setIndex(int index){ + if(index < 0) throw new IllegalArgumentException("index must be >= 0"); + this.index = index; + return this; + } + + public Builder setCoordinate(Coordinate coordinate){ + this.coordinate = coordinate; + return this; + } + + public Builder setId(String id){ + this.id = id; + return this; + } + + public Location build(){ + if(id == null && coordinate == null){ + if(index == -1) throw new IllegalStateException("either id or coordinate or index must be set"); + } + if(coordinate != null && id == null){ + this.id = coordinate.toString(); + } + if(index != -1 && id == null){ + this.id = Integer.toString(index); + } + return new Location(this); + } + + } + + private final int index; + + private final Coordinate coordinate; + + private final String id; + + private Location(Builder builder) { + this.index = builder.index; + this.coordinate = builder.coordinate; + this.id = builder.id; + } + + @Override + public String getId() { + return id; + } + + @Override + public int getIndex() { + return index; + } + + public Coordinate getCoordinate(){ + return coordinate; + } +} diff --git a/jsprit-core/src/main/java/jsprit/core/problem/job/Delivery.java b/jsprit-core/src/main/java/jsprit/core/problem/job/Delivery.java index 6b069b5b..4cd298be 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/job/Delivery.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/job/Delivery.java @@ -1,22 +1,24 @@ /******************************************************************************* - * Copyright (C) 2013 Stefan Schroeder - * + * Copyright (C) 2014 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 + * 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 . ******************************************************************************/ package jsprit.core.problem.job; +import jsprit.core.problem.Location; + /** * Delivery extends Service and is intended to model a Service where smth is UNLOADED (i.e. delivered) from a transport unit. * @@ -48,9 +50,10 @@ public class Delivery extends Service{ * @throws IllegalStateException if neither locationId nor coord is set */ public Delivery build(){ - if(locationId == null) { - if(coord == null) throw new IllegalStateException("either locationId or a coordinate must be given. But is not."); - locationId = coord.toString(); + if(location == null) { + location = Location.Builder.newInstance().setCoordinate(coord).setId(locationId).build(); +// if(coord == null) throw new IllegalStateException("either locationId or a coordinate must be given. But is not."); +// locationId = coord.toString(); } this.setType("delivery"); super.capacity = super.capacityBuilder.build(); diff --git a/jsprit-core/src/main/java/jsprit/core/problem/job/Pickup.java b/jsprit-core/src/main/java/jsprit/core/problem/job/Pickup.java index 8efe2f04..9b191b7b 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/job/Pickup.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/job/Pickup.java @@ -1,22 +1,24 @@ /******************************************************************************* - * Copyright (C) 2013 Stefan Schroeder - * + * Copyright (C) 2014 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 + * 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 . ******************************************************************************/ package jsprit.core.problem.job; +import jsprit.core.problem.Location; + /** * Pickup extends Service and is intended to model a Service where smth is LOADED (i.e. picked up) to a transport unit. * @@ -50,9 +52,10 @@ public class Pickup extends Service { * @throws IllegalStateException if neither locationId nor coordinate has been set */ public Pickup build(){ - if(locationId == null) { - if(coord == null) throw new IllegalStateException("either locationId or a coordinate must be given. But is not."); - locationId = coord.toString(); + if(location == null) { + location = Location.Builder.newInstance().setCoordinate(coord).setId(locationId).build(); +// if(coord == null) throw new IllegalStateException("either locationId or a coordinate must be given. But is not."); +// locationId = coord.toString(); } this.setType("pickup"); super.capacity = super.capacityBuilder.build(); diff --git a/jsprit-core/src/main/java/jsprit/core/problem/job/Service.java b/jsprit-core/src/main/java/jsprit/core/problem/job/Service.java index e0679f64..b60653fc 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/job/Service.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/job/Service.java @@ -18,6 +18,7 @@ package jsprit.core.problem.job; import jsprit.core.problem.AbstractJob; import jsprit.core.problem.Capacity; +import jsprit.core.problem.Location; import jsprit.core.problem.Skills; import jsprit.core.problem.solution.route.activity.TimeWindow; import jsprit.core.util.Coordinate; @@ -37,6 +38,7 @@ public class Service extends AbstractJob { + /** * Builder that builds a service. * @@ -79,6 +81,8 @@ public class Service extends AbstractJob { private String name = "no-name"; + protected Location location; + Builder(String id){ this.id = id; } @@ -101,18 +105,33 @@ public class Service extends AbstractJob { * * @param locationId the location id of the service * @return builder + * @deprecated use .setLocation(..) instead */ + @Deprecated public Builder setLocationId(String locationId){ this.locationId = locationId; return this; } + + /** + * Sets location + * + * @param location location + * @return builder + */ + public Builder setLocation(Location location){ + this.location = location; + return this; + } /** * Sets the coordinate of this service. * * @param coord the coordinate of service * @return builder + * @deprecated use .setLocation(..) instead and add coordinate ot Location obj */ + @Deprecated public Builder setCoord(Coordinate coord){ this.coord = coord; return this; @@ -170,10 +189,14 @@ public class Service extends AbstractJob { * @throws IllegalStateException if neither locationId nor coordinate is set. */ public Service build(){ - if(locationId == null) { - if(coord == null) throw new IllegalStateException("either locationId or a coordinate must be given. But is not."); - locationId = coord.toString(); - } + if(location == null) { + location = Location.Builder.newInstance().setCoordinate(coord).setId(locationId).build(); +// if (locationId == null) { +// if (coord == null) throw new IllegalStateException("either locationId or a coordinate must be given. But is not."); +// locationId = coord.toString(); +// } +// + } this.setType("service"); capacity = capacityBuilder.build(); skills = skillBuilder.build(); @@ -193,13 +216,9 @@ public class Service extends AbstractJob { private final String id; - - private final String locationId; private final String type; - private final Coordinate coord; - private final double serviceTime; private final TimeWindow timeWindow; @@ -210,16 +229,17 @@ public class Service extends AbstractJob { private final String name; + private final Location location; + Service(Builder builder){ id = builder.id; - locationId = builder.locationId; - coord = builder.coord; - serviceTime = builder.serviceTime; + serviceTime = builder.serviceTime; timeWindow = builder.timeWindow; type = builder.type; size = builder.capacity; skills = builder.skills; name = builder.name; + location = builder.location; } @Override @@ -231,19 +251,33 @@ public class Service extends AbstractJob { * Returns the location-id of this service. * * @return String that indicates the location + * @deprecated use .getLocation().getId() instead */ + @Deprecated public String getLocationId() { - return locationId; + return location.getId(); } + +// public AbstractLocation getLocation() /** * Returns the coordinate of this service. * * @return {@link Coordinate} + * @deprecated use .getLocation().getCoordinate() instead */ - public Coordinate getCoord(){ - return coord; - } + @Deprecated + public Coordinate getCoord(){ return location.getCoordinate(); } + + /** + * Returns location. + * + * @return location + */ + public Location getLocation(){ + return location; + } + /** * Returns the service-time/duration a service takes at service-location. @@ -277,7 +311,7 @@ public class Service extends AbstractJob { */ @Override public String toString() { - return "[id=" + id + "][name="+name+"][type="+type+"][locationId=" + locationId + "][coord="+coord+"][capacity=" + size + "][serviceTime=" + serviceTime + "][timeWindow=" + timeWindow + "]"; + return "[id=" + id + "][name="+name+"][type="+type+"][location=" + location + "][capacity=" + size + "][serviceTime=" + serviceTime + "][timeWindow=" + timeWindow + "]"; } diff --git a/jsprit-core/src/main/java/jsprit/core/problem/job/Shipment.java b/jsprit-core/src/main/java/jsprit/core/problem/job/Shipment.java index fbe5994d..a31977e8 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/job/Shipment.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/job/Shipment.java @@ -18,6 +18,7 @@ package jsprit.core.problem.job; import jsprit.core.problem.AbstractJob; import jsprit.core.problem.Capacity; +import jsprit.core.problem.Location; import jsprit.core.problem.Skills; import jsprit.core.problem.solution.route.activity.TimeWindow; import jsprit.core.util.Coordinate; @@ -79,6 +80,10 @@ public class Shipment extends AbstractJob{ private String name = "no-name"; + private Location pickupLocation_; + + private Location deliveryLocation_; + /** * Returns new instance of this builder. * @@ -100,13 +105,26 @@ public class Shipment extends AbstractJob{ * @param pickupLocationId the location id of shipment's pickup * @return builder * @throws IllegalArgumentException if location is null + * @deprecated use .setLocation(..) instead */ + @Deprecated public Builder setPickupLocationId(String pickupLocationId){ if(pickupLocationId == null) throw new IllegalArgumentException("location must not be null"); this.pickupLocation = pickupLocationId; return this; } + /** + * Sets pickup location. + * + * @param pickupLocation pickup location + * @return builder + */ + public Builder setPickupLocation(Location pickupLocation){ + this.pickupLocation_ = pickupLocation; + return this; + } + /** * Sets pickup-location id. * @@ -128,7 +146,9 @@ public class Shipment extends AbstractJob{ * @param pickupCoord the coordinate of shipment's pickup location * @return builder * @throws IllegalArgumentException if pickupCoord is null + * @deprecated use .setLocation(..) instead and add coordinate to location obj. */ + @Deprecated public Builder setPickupCoord(Coordinate pickupCoord){ if(pickupCoord == null) throw new IllegalArgumentException("coord must not be null"); this.pickupCoord = pickupCoord; @@ -172,13 +192,26 @@ public class Shipment extends AbstractJob{ * @param deliveryLocationId the delivery location id * @return builder * @throws IllegalArgumentException if location is null + * @deprecated use .setDeliveryLocation instead */ + @Deprecated public Builder setDeliveryLocationId(String deliveryLocationId){ if(deliveryLocationId == null) throw new IllegalArgumentException("delivery location must not be null"); this.deliveryLocation = deliveryLocationId; return this; } + /** + * Sets delivery location. + * + * @param deliveryLocation delivery location + * @return builder + */ + public Builder setDeliveryLocation(Location deliveryLocation){ + this.deliveryLocation_ = deliveryLocation; + return this; + } + /** * Sets the delivery-location. * @@ -186,6 +219,7 @@ public class Shipment extends AbstractJob{ * @return builder * @throws IllegalArgumentException if location is null * @deprecated use .setDeliveryLocationId(deliveryLocationId) + * */ @Deprecated public Builder setDeliveryLocation(String deliveryLocation){ @@ -200,7 +234,9 @@ public class Shipment extends AbstractJob{ * @param deliveryCoord the coordinate of shipment's delivery location * @return builder * @throws IllegalArgumentException if coord is null; + * @deprecated use .setDeliveryLocation(..) instead and add coordinate to location obj */ + @Deprecated public Builder setDeliveryCoord(Coordinate deliveryCoord){ if(deliveryCoord == null) throw new IllegalArgumentException("coord must not be null"); this.deliveryCoord = deliveryCoord; @@ -261,13 +297,15 @@ public class Shipment extends AbstractJob{ * is set */ public Shipment build(){ - if(pickupLocation == null) { - if(pickupCoord == null) throw new IllegalStateException("either locationId or a coordinate must be given. But is not."); - pickupLocation = pickupCoord.toString(); - } - if(deliveryLocation == null) { - if(deliveryCoord == null) throw new IllegalStateException("either locationId or a coordinate must be given. But is not."); - deliveryLocation = deliveryCoord.toString(); + if(pickupLocation_ == null) { + this.pickupLocation_ = Location.Builder.newInstance().setCoordinate(pickupCoord).setId(pickupLocation).build(); +// if(pickupCoord == null) throw new IllegalStateException("either locationId or a coordinate must be given. But is not."); +// pickupLocation = pickupCoord.toString(); + } + if(deliveryLocation_ == null) { + this.deliveryLocation_ = Location.Builder.newInstance().setCoordinate(deliveryCoord).setId(deliveryLocation).build(); +// if(deliveryCoord == null) throw new IllegalStateException("either locationId or a coordinate must be given. But is not."); +// deliveryLocation = deliveryCoord.toString(); } capacity = capacityBuilder.build(); skills = skillBuilder.build(); @@ -287,16 +325,8 @@ public class Shipment extends AbstractJob{ } private final String id; - - private final String pickupLocation; - - private final Coordinate pickupCoord; - + private final double pickupServiceTime; - - private final String deliveryLocation; - - private final Coordinate deliveryCoord; private final double deliveryServiceTime; @@ -308,21 +338,23 @@ public class Shipment extends AbstractJob{ private final Skills skills; - private String name; + private final String name; + + private final Location pickupLocation_; + + private final Location deliveryLocation_; Shipment(Builder builder){ this.id = builder.id; - this.pickupLocation = builder.pickupLocation; - this.pickupCoord = builder.pickupCoord; this.pickupServiceTime = builder.pickupServiceTime; this.pickupTimeWindow = builder.pickupTimeWindow; - this.deliveryLocation = builder.deliveryLocation; - this.deliveryCoord = builder.deliveryCoord; this.deliveryServiceTime = builder.deliveryServiceTime; this.deliveryTimeWindow = builder.deliveryTimeWindow; this.capacity = builder.capacity; this.skills = builder.skills; this.name = builder.name; + this.pickupLocation_ = builder.pickupLocation_; + this.deliveryLocation_ = builder.deliveryLocation_; } @Override @@ -330,35 +362,30 @@ public class Shipment extends AbstractJob{ return id; } - /** - * Returns the pickup-location. - * - * @return pickup-location - * @deprecated use .getPickupLocationId() instead - */ - @Deprecated - public String getPickupLocation() { - return pickupLocation; - } - /** * Returns the pickup-location. * * @return pickup-location + * @deprecated use .getLocation().getId() instead */ + @Deprecated public String getPickupLocationId() { - return pickupLocation; + return pickupLocation_.getId(); } /** * Returns the pickup-coordinate. * * @return coordinate of the pickup + * @deprecated use .getLocation(..).getCoordinate() instead */ + @Deprecated public Coordinate getPickupCoord() { - return pickupCoord; + return pickupLocation_.getCoordinate(); } + public Location getPickupLocation(){ return pickupLocation_; } + /** * Returns the pickup service-time. * @@ -370,35 +397,30 @@ public class Shipment extends AbstractJob{ return pickupServiceTime; } - /** - * Returns delivery-location. - * - * @return delivery-location - * @deprecated use .getDeliveryLocationId() instead - */ - @Deprecated - public String getDeliveryLocation() { - return deliveryLocation; - } - /** * Returns delivery-location. * * @return delivery-location + * @deprecated use .getLocation().getId() instead */ + @Deprecated public String getDeliveryLocationId() { - return deliveryLocation; + return deliveryLocation_.getId(); } /** * Returns coordinate of the delivery. * * @return coordinate of delivery + * @deprecated use .getLocation().getCoordinate() instead */ + @Deprecated public Coordinate getDeliveryCoord() { - return deliveryCoord; + return deliveryLocation_.getCoordinate(); } + public Location getDeliveryLocation() { return deliveryLocation_; } + /** * Returns service-time of delivery. * diff --git a/jsprit-core/src/main/java/jsprit/core/problem/vehicle/Vehicle.java b/jsprit-core/src/main/java/jsprit/core/problem/vehicle/Vehicle.java index 1f46f93e..ac7da47c 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/vehicle/Vehicle.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/vehicle/Vehicle.java @@ -1,16 +1,16 @@ /******************************************************************************* - * Copyright (C) 2013 Stefan Schroeder - * + * Copyright (C) 2014 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 + * 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 . ******************************************************************************/ @@ -18,6 +18,7 @@ package jsprit.core.problem.vehicle; import jsprit.core.problem.HasId; import jsprit.core.problem.HasIndex; +import jsprit.core.problem.Location; import jsprit.core.problem.Skills; import jsprit.core.util.Coordinate; @@ -68,22 +69,30 @@ public interface Vehicle extends HasId, HasIndex { /** * Returns the start-locationId of this vehicle. */ + @Deprecated public abstract String getStartLocationId(); /** * Returns the start-locationCoord of this vehicle. */ + @Deprecated public abstract Coordinate getStartLocationCoordinate(); + + public abstract Location getStartLocation(); /** * Returns the end-locationId of this vehicle. * */ + @Deprecated public abstract String getEndLocationId(); + + public abstract Location getEndLocation(); /** * Returns the end-locationCoord of this vehicle. */ + @Deprecated public abstract Coordinate getEndLocationCoordinate(); public abstract VehicleTypeKey getVehicleTypeIdentifier(); diff --git a/jsprit-core/src/main/java/jsprit/core/problem/vehicle/VehicleImpl.java b/jsprit-core/src/main/java/jsprit/core/problem/vehicle/VehicleImpl.java index 48ea5033..66bb14d9 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/vehicle/VehicleImpl.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/vehicle/VehicleImpl.java @@ -17,6 +17,7 @@ package jsprit.core.problem.vehicle; import jsprit.core.problem.AbstractVehicle; +import jsprit.core.problem.Location; import jsprit.core.problem.Skills; import jsprit.core.util.Coordinate; import org.apache.logging.log4j.LogManager; @@ -35,6 +36,7 @@ public class VehicleImpl extends AbstractVehicle{ + /** * Extension of {@link VehicleImpl} representing an unspecified vehicle with the id 'noVehicle' * (to avoid null). @@ -42,13 +44,75 @@ public class VehicleImpl extends AbstractVehicle{ * @author schroeder * */ - public static class NoVehicle extends VehicleImpl { - + public static class NoVehicle extends AbstractVehicle { + + private String id = "noVehicle"; + + private VehicleType type = VehicleTypeImpl.Builder.newInstance("noType").build(); + public NoVehicle() { - super(Builder.newInstance("noVehicle").setType(VehicleTypeImpl.Builder.newInstance("noType").build())); } - - } + + @Override + public double getEarliestDeparture() { + return 0; + } + + @Override + public double getLatestArrival() { + return 0; + } + + @Override + public VehicleType getType() { + return type; + } + + @Override + public String getId() { + return id; + } + + @Override + public boolean isReturnToDepot() { + return false; + } + + @Override + public String getStartLocationId() { + return null; + } + + @Override + public Coordinate getStartLocationCoordinate() { + return null; + } + + @Override + public Location getStartLocation() { + return null; + } + + @Override + public String getEndLocationId() { + return null; + } + + @Override + public Location getEndLocation() { + return null; + } + + @Override + public Coordinate getEndLocationCoordinate() { + return null; + } + + @Override + public Skills getSkills() { + return null; + } + } /** * Builder that builds the vehicle. @@ -90,6 +154,10 @@ public class VehicleImpl extends AbstractVehicle{ private Skills skills; + private Location startLocation; + + private Location endLocation; + private Builder(String id) { super(); this.id = id; @@ -131,7 +199,9 @@ public class VehicleImpl extends AbstractVehicle{ * @param startLocationId the location id of vehicle's start * @return this builder * @throws IllegalArgumentException if startLocationId is null + * @deprecated use .setStartLocation(..) instead */ + @Deprecated public Builder setStartLocationId(String startLocationId){ if(startLocationId == null) throw new IllegalArgumentException("startLocationId cannot be null"); this.startLocationId = startLocationId; @@ -144,19 +214,33 @@ public class VehicleImpl extends AbstractVehicle{ * * @param coord the coordinate of vehicle's start location * @return this builder + * @deprecated use .setStartLocation(..) instead */ + @Deprecated public Builder setStartLocationCoordinate(Coordinate coord){ this.startLocationCoord = coord; this.locationCoord = coord; return this; } + + /** + * Sets start location. + * @param startLocation start location + * @return start location + */ + public Builder setStartLocation(Location startLocation){ + this.startLocation = startLocation; + return this; + } /** * Sets the end-locationId of this vehicle. * * @param endLocationId the location id of vehicle's end * @return this builder + * @deprecated use .setEndLocation(..) instead */ + @Deprecated public Builder setEndLocationId(String endLocationId){ this.endLocationId = endLocationId; return this; @@ -167,11 +251,18 @@ public class VehicleImpl extends AbstractVehicle{ * * @param coord the coordinate of vehicle's end location * @return this builder + * @deprecated use .setEndLocation(..) instead */ + @Deprecated public Builder setEndLocationCoordinate(Coordinate coord){ this.endLocationCoord = coord; return this; } + + public Builder setEndLocation(Location endLocation){ + this.endLocation = endLocation; + return this; + } /** * Sets earliest-start of vehicle which should be the lower bound of the vehicle's departure times. @@ -217,23 +308,35 @@ public class VehicleImpl extends AbstractVehicle{ * or (endLocationId!=null AND returnToDepot=false) */ public VehicleImpl build(){ - if((locationId == null && locationCoord == null) && (startLocationId == null && startLocationCoord == null)){ - throw new IllegalStateException("vehicle requires startLocation. but neither locationId nor locationCoord nor startLocationId nor startLocationCoord has been set"); - } - if(locationId == null && locationCoord != null) { - locationId = locationCoord.toString(); - startLocationId = locationCoord.toString(); - } - if(locationId == null && locationCoord == null) throw new IllegalStateException("locationId and locationCoord is missing."); - if(locationCoord == null) log.warn("locationCoord for vehicle " + id + " is missing."); - if(endLocationId == null && endLocationCoord != null) endLocationId = endLocationCoord.toString(); - if(endLocationId == null && endLocationCoord == null) { - endLocationId = startLocationId; - endLocationCoord = startLocationCoord; - } - if( !startLocationId.equals(endLocationId) && !returnToDepot) throw new IllegalStateException("this must not be. you specified both endLocationId and open-routes. this is contradictory.
" + - "if you set endLocation, returnToDepot must be true. if returnToDepot is false, endLocationCoord must not be specified."); - skills = skillBuilder.build(); + if(startLocation != null && endLocation != null){ + if( !startLocation.getId().equals(endLocation.getId()) && !returnToDepot) throw new IllegalStateException("this must not be. you specified both endLocationId and open-routes. this is contradictory.
" + + "if you set endLocation, returnToDepot must be true. if returnToDepot is false, endLocationCoord must not be specified."); + } + if (startLocation != null && endLocation == null && endLocationId == null && endLocationCoord == null) { + endLocation = startLocation; + } + if(startLocation == null && endLocation == null) { + if ((locationId == null && locationCoord == null) && (startLocationId == null && startLocationCoord == null)) { + throw new IllegalStateException("vehicle requires startLocation. but neither locationId nor locationCoord nor startLocationId nor startLocationCoord has been set"); + } + if(locationId == null && locationCoord == null) throw new IllegalStateException("locationId and locationCoord is missing."); + if(locationCoord == null) log.warn("locationCoord for vehicle " + id + " is missing."); + if (locationId == null && locationCoord != null) { + locationId = locationCoord.toString(); + startLocationId = locationCoord.toString(); + } + startLocation = Location.Builder.newInstance().setCoordinate(locationCoord).setId(locationId).build(); + + if (endLocationId == null && endLocationCoord != null) endLocationId = endLocationCoord.toString(); + if (endLocationId == null && endLocationCoord == null) { + endLocationId = startLocationId; + endLocationCoord = startLocationCoord; + } + endLocation = Location.Builder.newInstance().setCoordinate(endLocationCoord).setId(endLocationId).build(); + if( !startLocationId.equals(endLocationId) && !returnToDepot) throw new IllegalStateException("this must not be. you specified both endLocationId and open-routes. this is contradictory.
" + + "if you set endLocation, returnToDepot must be true. if returnToDepot is false, endLocationCoord must not be specified."); + } + skills = skillBuilder.build(); return new VehicleImpl(this); } @@ -266,40 +369,28 @@ public class VehicleImpl extends AbstractVehicle{ private final VehicleType type; - private final String locationId; - - private final Coordinate coord; - private final double earliestDeparture; private final double latestArrival; private final boolean returnToDepot; - private final Coordinate endLocationCoord; + private final Skills skills; - private final String endLocationId; + private final Location endLocation; - private final Coordinate startLocationCoord; - - private final String startLocationId; - - private Skills skills; + private final Location startLocation; private VehicleImpl(Builder builder){ id = builder.id; type = builder.type; - coord = builder.locationCoord; - locationId = builder.locationId; earliestDeparture = builder.earliestStart; latestArrival = builder.latestArrival; returnToDepot = builder.returnToDepot; - startLocationId = builder.startLocationId; - startLocationCoord = builder.startLocationCoord; - endLocationId = builder.endLocationId; - endLocationCoord = builder.endLocationCoord; - skills = builder.skills; - setVehicleIdentifier(new VehicleTypeKey(type.getTypeId(),startLocationId,endLocationId,earliestDeparture,latestArrival,skills)); + skills = builder.skills; + endLocation = builder.endLocation; + startLocation = builder.startLocation; + setVehicleIdentifier(new VehicleTypeKey(type.getTypeId(),startLocation.getId(),endLocation.getId(),earliestDeparture,latestArrival,skills)); } /** @@ -311,10 +402,8 @@ public class VehicleImpl extends AbstractVehicle{ public String toString() { return "[id="+id+"]" + "[type="+type+"]" + - "[startLocationId="+startLocationId+"]" + - "[startLocationCoordinate=" + startLocationCoord + "]" + - "[endLocationId=" + endLocationId+"]" + - "[endLocationCoordinate=" + endLocationCoord + "]" + + "[startLocation="+startLocation+"]" + + "[endLocation=" + endLocation+"]" + "[isReturnToDepot=" + isReturnToDepot() + "]" + "[skills="+ skills + "]"; @@ -346,22 +435,32 @@ public class VehicleImpl extends AbstractVehicle{ @Override public String getStartLocationId() { - return this.startLocationId; + return this.startLocation.getId(); } @Override public Coordinate getStartLocationCoordinate() { - return this.startLocationCoord; + return this.startLocation.getCoordinate(); } - @Override + @Override + public Location getStartLocation() { + return startLocation; + } + + @Override public String getEndLocationId() { - return this.endLocationId; + return this.endLocation.getId(); } - @Override + @Override + public Location getEndLocation() { + return endLocation; + } + + @Override public Coordinate getEndLocationCoordinate() { - return this.endLocationCoord; + return this.endLocation.getCoordinate(); } @Override diff --git a/jsprit-core/src/test/java/jsprit/core/problem/LocationTest.java b/jsprit-core/src/test/java/jsprit/core/problem/LocationTest.java new file mode 100644 index 00000000..dff29663 --- /dev/null +++ b/jsprit-core/src/test/java/jsprit/core/problem/LocationTest.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (C) 2014 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 . + ******************************************************************************/ + +package jsprit.core.problem; + +import jsprit.core.util.Coordinate; +import junit.framework.Assert; +import org.junit.Test; + +/** + * Created by schroeder on 16.12.14. + */ +public class LocationTest { + + @Test + public void whenIndexSet_buildLocation(){ + Location l = Location.Builder.newInstance().setIndex(1).build(); + Assert.assertEquals(1,l.getIndex()); + Assert.assertTrue(true); + } + + @Test(expected = IllegalArgumentException.class) + public void whenIndexSmallerZero_throwException(){ + Location l = Location.Builder.newInstance().setIndex(-1).build(); + } + + @Test(expected = IllegalStateException.class) + public void whenCoordinateAndIdAndIndexNotSet_throwException(){ + Location l = Location.Builder.newInstance().build(); + } + + @Test + public void whenIdSet_build(){ + Location l = Location.Builder.newInstance().setId("id").build(); + Assert.assertEquals("id",l.getId()); + Assert.assertTrue(true); + } + + @Test + public void whenCoordinateSet_build(){ + Location l = Location.Builder.newInstance().setCoordinate(Coordinate.newInstance(10,20)).build(); + Assert.assertEquals(10.,l.getCoordinate().getX()); + Assert.assertEquals(20.,l.getCoordinate().getY()); + Assert.assertTrue(true); + } + + +} diff --git a/jsprit-core/src/test/java/jsprit/core/problem/job/ServiceTest.java b/jsprit-core/src/test/java/jsprit/core/problem/job/ServiceTest.java index cae24484..7e17913d 100644 --- a/jsprit-core/src/test/java/jsprit/core/problem/job/ServiceTest.java +++ b/jsprit-core/src/test/java/jsprit/core/problem/job/ServiceTest.java @@ -16,6 +16,7 @@ ******************************************************************************/ package jsprit.core.problem.job; +import jsprit.core.problem.Location; import jsprit.core.problem.solution.route.activity.TimeWindow; import jsprit.core.util.Coordinate; import org.junit.Test; @@ -102,13 +103,24 @@ public class ServiceTest { public void whenSettingLocation_itShouldBeSetCorrectly(){ Service s = Service.Builder.newInstance("s").setLocationId("loc").build(); assertEquals("loc",s.getLocationId()); + assertEquals("loc",s.getLocation().getId()); } + + @Test + public void whenSettingLocation_itShouldWork(){ + Service s = Service.Builder.newInstance("s").setLocation(Location.Builder.newInstance().setId("loc").build()).build(); + assertEquals("loc",s.getLocationId()); + assertEquals("loc",s.getLocation().getId()); + } + @Test public void whenSettingLocationCoord_itShouldBeSetCorrectly(){ Service s = Service.Builder.newInstance("s").setCoord(Coordinate.newInstance(1, 2)).build(); assertEquals(1.0,s.getCoord().getX(),0.01); assertEquals(2.0,s.getCoord().getY(),0.01); + assertEquals(1.0,s.getLocation().getCoordinate().getX(),0.01); + assertEquals(2.0,s.getLocation().getCoordinate().getY(),0.01); } @Test(expected=IllegalStateException.class) diff --git a/jsprit-core/src/test/java/jsprit/core/problem/job/ShipmentTest.java b/jsprit-core/src/test/java/jsprit/core/problem/job/ShipmentTest.java index 5f4ea73b..4dff6e49 100644 --- a/jsprit-core/src/test/java/jsprit/core/problem/job/ShipmentTest.java +++ b/jsprit-core/src/test/java/jsprit/core/problem/job/ShipmentTest.java @@ -16,6 +16,7 @@ ******************************************************************************/ package jsprit.core.problem.job; +import jsprit.core.problem.Location; import jsprit.core.problem.solution.route.activity.TimeWindow; import jsprit.core.util.Coordinate; import org.junit.Test; @@ -91,6 +92,7 @@ public class ShipmentTest { public void whenPickupLocationIdIsSet_itShouldBeDoneCorrectly(){ Shipment s = Shipment.Builder.newInstance("s").setDeliveryLocationId("delLoc").setPickupLocationId("pickLoc").build(); assertEquals("pickLoc",s.getPickupLocationId()); + assertEquals("pickLoc",s.getPickupLocation().getId()); } @Test(expected=IllegalArgumentException.class) @@ -104,6 +106,8 @@ public class ShipmentTest { Shipment s = Shipment.Builder.newInstance("s").setDeliveryLocationId("delLoc").setPickupLocationId("pickLoc").setPickupCoord(Coordinate.newInstance(1, 2)).build(); assertEquals(1.0,s.getPickupCoord().getX(),0.01); assertEquals(2.0,s.getPickupCoord().getY(),0.01); + assertEquals(1.0,s.getPickupLocation().getCoordinate().getX(),0.01); + assertEquals(2.0,s.getPickupLocation().getCoordinate().getY(),0.01); } @Test(expected=IllegalArgumentException.class) @@ -116,6 +120,7 @@ public class ShipmentTest { public void whenDeliveryLocationIdIsSet_itShouldBeDoneCorrectly(){ Shipment s = Shipment.Builder.newInstance("s").setDeliveryLocationId("delLoc").setPickupLocationId("pickLoc").build(); assertEquals("delLoc",s.getDeliveryLocationId()); + assertEquals("delLoc",s.getDeliveryLocation().getId()); } @Test(expected=IllegalArgumentException.class) @@ -129,6 +134,8 @@ public class ShipmentTest { Shipment s = Shipment.Builder.newInstance("s").setDeliveryLocationId("delLoc").setPickupLocationId("pickLoc").setDeliveryCoord(Coordinate.newInstance(1, 2)).build(); assertEquals(1.0,s.getDeliveryCoord().getX(),0.01); assertEquals(2.0,s.getDeliveryCoord().getY(),0.01); + assertEquals(1.0,s.getDeliveryLocation().getCoordinate().getX(),0.01); + assertEquals(2.0,s.getDeliveryLocation().getCoordinate().getY(),0.01); } @Test(expected=IllegalArgumentException.class) @@ -277,4 +284,14 @@ public class ShipmentTest { .setName("name").build(); assertEquals("name",s.getName()); } + + @Test + public void whenSettingLocation_itShouldWork(){ + Shipment s = Shipment.Builder.newInstance("s").setPickupLocation(Location.Builder.newInstance().setId("loc").build()) + .setDeliveryLocation(Location.Builder.newInstance().setId("del").build()).build(); + assertEquals("loc", s.getPickupLocationId()); + assertEquals("loc", s.getPickupLocation().getId()); + assertEquals("del",s.getDeliveryLocation().getId()); + assertEquals("del",s.getDeliveryLocationId()); + } }