diff --git a/jsprit-core/src/main/java/jsprit/core/problem/VehicleRoutingProblem.java b/jsprit-core/src/main/java/jsprit/core/problem/VehicleRoutingProblem.java index 7a29b094..eb263d6f 100644 --- a/jsprit-core/src/main/java/jsprit/core/problem/VehicleRoutingProblem.java +++ b/jsprit-core/src/main/java/jsprit/core/problem/VehicleRoutingProblem.java @@ -198,6 +198,8 @@ public class VehicleRoutingProblem { private double penaltyFactor = 1.0; + private Double penaltyFixedCosts = null; + /** * @deprecated use static method .newInstance() instead */ @@ -378,10 +380,14 @@ public class VehicleRoutingProblem { } } for(Vehicle v : uniqueVehicles){ + double fixed = v.getType().getVehicleCostParams().fix * penaltyFactor; + if(penaltyFixedCosts!=null){ + fixed = penaltyFixedCosts; + } VehicleTypeImpl t = VehicleTypeImpl.Builder.newInstance(v.getType().getTypeId(), v.getCapacity()) .setCostPerDistance(penaltyFactor*v.getType().getVehicleCostParams().perDistanceUnit) .setCostPerTime(penaltyFactor*v.getType().getVehicleCostParams().perTimeUnit) - .setFixedCost(penaltyFactor*v.getType().getVehicleCostParams().fix) + .setFixedCost(fixed) .build(); PenaltyVehicleType penType = new PenaltyVehicleType(t,penaltyFactor); String vehicleId = "penaltyVehicle_" + v.getLocationId() + "_" + t.getTypeId(); @@ -453,7 +459,8 @@ public class VehicleRoutingProblem { } /** - * Adds penaltyVehicles, i.e. for every unique vehicle-location and type combination a penalty-vehicle is constructed having penaltyFactor times higher fixed and variable costs. + * Adds penaltyVehicles, i.e. for every unique vehicle-location and type combination a penalty-vehicle is constructed having penaltyFactor times higher fixed and variable costs + * (see .addPenaltyVehicles(double penaltyFactor, double penaltyFixedCosts) if fixed costs = 0.0). * *

This only makes sense for FleetSize.FINITE. Thus, penaltyVehicles are only added if is FleetSize.FINITE. *

The id of penaltyVehicles is constructed as follows vehicleId = "penaltyVehicle" + "_" + {locationId} + "_" + {typeId}. @@ -468,6 +475,24 @@ public class VehicleRoutingProblem { return this; } + /** + * Adds penaltyVehicles, i.e. for every unique vehicle-location and type combination a penalty-vehicle is constructed having penaltyFactor times higher fixed and variable costs. + *

This method takes penaltyFixedCosts as absolute value in contrary to the method without penaltyFixedCosts where fixedCosts is the product of penaltyFactor and typeFixedCosts. + *

This only makes sense for FleetSize.FINITE. Thus, penaltyVehicles are only added if is FleetSize.FINITE. + *

The id of penaltyVehicles is constructed as follows vehicleId = "penaltyVehicle" + "_" + {locationId} + "_" + {typeId}. + *

By default: no penalty-vehicles are added + * + * @param penaltyFactor + * @param penaltyFixedCosts which is an absolute penaltyValue (in contrary to penaltyFactor) + * @return this builder + */ + public Builder addPenaltyVehicles(double penaltyFactor, double penaltyFixedCosts){ + this.addPenaltyVehicles = true; + this.penaltyFactor = penaltyFactor; + this.penaltyFixedCosts = penaltyFixedCosts; + return this; + } + /** * Returns an unmodifiable collection of already added jobs. * diff --git a/jsprit-core/src/test/java/jsprit/core/problem/VehicleRoutingProblemTest.java b/jsprit-core/src/test/java/jsprit/core/problem/VehicleRoutingProblemTest.java index e5aff4cf..fb2ce5b2 100644 --- a/jsprit-core/src/test/java/jsprit/core/problem/VehicleRoutingProblemTest.java +++ b/jsprit-core/src/test/java/jsprit/core/problem/VehicleRoutingProblemTest.java @@ -391,6 +391,32 @@ public class VehicleRoutingProblemTest { } + @Test + public void whenSettingAddPenaltyVehicleOptionsWithAbsoluteFixedCostsAndTwoVehiclesWithSameLocationAndType_onePenaltyVehicleIsAddedWithTheCorrectPenaltyFixedCosts(){ + VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance(); + VehicleType type = VehicleTypeImpl.Builder.newInstance("type", 0).build(); + Vehicle vehicle = VehicleImpl.Builder.newInstance("v").setLocationId("loc").setType(type).build(); + Vehicle vehicle2 = VehicleImpl.Builder.newInstance("v2").setLocationId("loc").setType(type).build(); + + builder.addVehicle(vehicle); + builder.addVehicle(vehicle2); + builder.setFleetSize(FleetSize.FINITE); + builder.addPenaltyVehicles(3.0,10000); + + VehicleRoutingProblem vrp = builder.build(); + + assertEquals(3,vrp.getVehicles().size()); + + double fix = 0.0; + for(Vehicle v : vrp.getVehicles()){ + if(v.getId().equals("penaltyVehicle_loc_type")) { + fix = v.getType().getVehicleCostParams().fix; + } + } + assertEquals(10000,fix,0.01); + + } + @Test public void whenSettingAddPenaltyVehicleOptionsAndTwoVehiclesWithDiffLocationAndType_twoPenaltyVehicleIsAdded(){ VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();