public void testWithPenalty_whenHavingTwoRegularVehicleAvailablePlusOnePenaltyVehicle_andOneIsLocked_returnTheOtherRegularVehicle() { VehicleTypeImpl penaltyType = VehicleTypeImpl.Builder.newInstance("standard").build(); PenaltyVehicleType penaltyVehicleType = new PenaltyVehicleType(penaltyType); Vehicle penalty4standard = VehicleImpl.Builder.newInstance("standard_penalty") .setStartLocationId("loc") .setType(penaltyVehicleType) .build(); Vehicle v3 = VehicleImpl.Builder.newInstance("standard_v3") .setStartLocationId("loc") .setType(penaltyType) .build(); List<Vehicle> vehicles = new ArrayList<Vehicle>(); vehicles.add(v1); vehicles.add(v2); vehicles.add(penalty4standard); vehicles.add(v3); VehicleFleetManager fleetManager = new FiniteFleetManagerFactory(vehicles).createFleetManager(); fleetManager.lock(v1); fleetManager.lock(v2); Collection<Vehicle> availableVehicles = fleetManager.getAvailableVehicles(); assertEquals(1, availableVehicles.size()); assertEquals(v3, availableVehicles.iterator().next()); }
public void setUp() { List<Vehicle> vehicles = new ArrayList<Vehicle>(); v1 = VehicleImpl.Builder.newInstance("standard") .setStartLocationId("loc") .setType(VehicleTypeImpl.Builder.newInstance("standard").build()) .build(); v2 = VehicleImpl.Builder.newInstance("foo") .setStartLocationId("fooLoc") .setType(VehicleTypeImpl.Builder.newInstance("foo").build()) .build(); // v1. vehicles.add(v1); vehicles.add(v2); fleetManager = new FiniteFleetManagerFactory(vehicles).createFleetManager(); }
/** * Extension of {@link VehicleImpl} representing an unspecified vehicle with the id 'noVehicle' * (to avoid null). * * @author schroeder */ public static class NoVehicle extends AbstractVehicle { private String id = "noVehicle"; private VehicleType type = VehicleTypeImpl.Builder.newInstance("noType").build(); public NoVehicle() {} @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 Location getStartLocation() { return null; } @Override public Location getEndLocation() { return null; } @Override public Skills getSkills() { return null; } }
@Test public void maxCapacityShouldNotBeExceeded() { VehicleType type = VehicleTypeImpl.Builder.newInstance("type").addCapacityDimension(0, 100).build(); VehicleImpl vehicle = VehicleImpl.Builder.newInstance("veh") .setStartLocationCoordinate(Coordinate.newInstance(0, 0)) .setType(type) .setStartLocationId("start") .build(); Shipment shipment = Shipment.Builder.newInstance("s") .setPickupLocationId("pick") .setDeliveryLocationId("del") .setPickupCoord(Coordinate.newInstance(10, 0)) .setDeliveryCoord(Coordinate.newInstance(0, 10)) .addSizeDimension(0, 100) .build(); Shipment another_shipment = Shipment.Builder.newInstance("another_s") .setPickupLocationId("pick") .setDeliveryLocationId("del") .setPickupCoord(Coordinate.newInstance(10, 0)) .setDeliveryCoord(Coordinate.newInstance(0, 10)) .addSizeDimension(0, 50) .build(); VehicleRoute iniRoute = VehicleRoute.Builder.newInstance(vehicle).addPickup(shipment).addDelivery(shipment).build(); VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance() .addJob(shipment) .addVehicle(vehicle) .addJob(another_shipment) .setFleetSize(VehicleRoutingProblem.FleetSize.FINITE) .addInitialVehicleRoute(iniRoute) .build(); VehicleRoutingAlgorithm vra = new GreedySchrimpfFactory().createAlgorithm(vrp); vra.setNuOfIterations(10); Collection<VehicleRoutingProblemSolution> solutions = vra.searchSolutions(); assertFalse(secondActIsPickup(solutions)); }
public void testWithPenalty_whenHavingOneRegularVehicleAvailable_noPenaltyVehicleIsReturn() { Vehicle penalty4standard = VehicleImpl.Builder.newInstance("standard_penalty") .setStartLocationId("loc") .setType(VehicleTypeImpl.Builder.newInstance("standard").build()) .build(); List<Vehicle> vehicles = new ArrayList<Vehicle>(); vehicles.add(v1); vehicles.add(v2); vehicles.add(penalty4standard); VehicleFleetManager fleetManager = new FiniteFleetManagerFactory(vehicles).createFleetManager(); Collection<Vehicle> availableVehicles = fleetManager.getAvailableVehicles(); assertEquals(2, availableVehicles.size()); }
/** * Builder that builds the vehicle. * * <p>By default, earliestDepartureTime is 0.0, latestDepartureTime is Double.MAX_VALUE, it * returns to the depot and its {@link VehicleType} is the DefaultType with typeId equal to * 'default' and a capacity of 0. * * @author stefan */ public static class Builder { static final Logger log = LogManager.getLogger(Builder.class.getName()); private String id; private double earliestStart = 0.0; private double latestArrival = Double.MAX_VALUE; private boolean returnToDepot = true; private VehicleType type = VehicleTypeImpl.Builder.newInstance("default").build(); private Skills.Builder skillBuilder = Skills.Builder.newInstance(); private Skills skills; private Location startLocation; private Location endLocation; private Builder(String id) { super(); this.id = id; } /** * Sets the {@link VehicleType}.<br> * * @param type the type to be set * @throws IllegalStateException if type is null * @return this builder */ public Builder setType(VehicleType type) { if (type == null) throw new IllegalStateException("type cannot be null."); this.type = type; return this; } /** * Sets the flag whether the vehicle must return to depot or not. * * <p>If returnToDepot is true, the vehicle must return to specified end-location. If you omit * specifying the end-location, vehicle returns to start-location (that must to be set). If you * specify it, it returns to specified end-location. * * <p>If returnToDepot is false, the end-location of the vehicle is endogenous. * * @param returnToDepot true if vehicle need to return to depot, otherwise false * @return this builder */ public Builder setReturnToDepot(boolean returnToDepot) { this.returnToDepot = returnToDepot; return this; } /** * Sets start location. * * @param startLocation start location * @return start location */ public Builder setStartLocation(Location startLocation) { this.startLocation = startLocation; 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. * * @param earliest_startTime the earliest start time / departure time of the vehicle at its * start location * @return this builder */ public Builder setEarliestStart(double earliest_startTime) { this.earliestStart = earliest_startTime; return this; } /** * Sets the latest arrival at vehicle's end-location which is the upper bound of the vehicle's * arrival times. * * @param latest_arrTime the latest arrival time of the vehicle at its end location * @return this builder */ public Builder setLatestArrival(double latest_arrTime) { this.latestArrival = latest_arrTime; return this; } public Builder addSkill(String skill) { skillBuilder.addSkill(skill); return this; } /** * Builds and returns the vehicle. * * <p>if {@link VehicleType} is not set, default vehicle-type is set with id="default" and * capacity=0 * * <p>if startLocationId || locationId is null (=> startLocationCoordinate || locationCoordinate * must be set) then startLocationId=startLocationCoordinate.toString() and * locationId=locationCoordinate.toString() [coord.toString() --> [x=x_val][y=y_val]) * * <p>if endLocationId is null and endLocationCoordinate is set then * endLocationId=endLocationCoordinate.toString() * * <p>if endLocationId==null AND endLocationCoordinate==null then endLocationId=startLocationId * AND endLocationCoord=startLocationCoord Thus endLocationId can never be null even * returnToDepot is false. * * @return vehicle * @throws IllegalStateException if both locationId and locationCoord is not set or * (endLocationCoord!=null AND returnToDepot=false) or (endLocationId!=null AND * returnToDepot=false) */ public VehicleImpl 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. <br>" + "if you set endLocation, returnToDepot must be true. if returnToDepot is false, endLocationCoord must not be specified."); } if (startLocation != null && endLocation == null) { endLocation = startLocation; } if (startLocation == null && endLocation == null) { throw new IllegalStateException( "vehicle requires startLocation. but neither locationId nor locationCoord nor startLocationId nor startLocationCoord has been set"); } skills = skillBuilder.build(); return new VehicleImpl(this); } /** * Returns new instance of vehicle builder. * * @param vehicleId the id of the vehicle which must be a unique identifier among all vehicles * @return vehicle builder */ public static Builder newInstance(String vehicleId) { return new Builder(vehicleId); } public Builder addSkills(Skills skills) { this.skillBuilder.addAllSkills(skills.values()); return this; } }
public void read(String filename) { BufferedReader reader = getReader(filename); String line = null; boolean firstline = true; Coordinate depotCoord = null; int customerCount = 0; Integer nuOfCustomer = 0; while ((line = readLine(reader)) != null) { String trimedLine = line.trim(); if (trimedLine.startsWith("//")) continue; String[] tokens = trimedLine.split("\\s+"); if (firstline) { nuOfCustomer = Integer.parseInt(tokens[0]); customerCount = 0; firstline = false; } else if (customerCount <= nuOfCustomer) { if (customerCount == 0) { depotCoord = Coordinate.newInstance(Double.parseDouble(tokens[1]), Double.parseDouble(tokens[2])); } else { Service.Builder serviceBuilder = Service.Builder.newInstance(tokens[0]) .addSizeDimension(0, Integer.parseInt(tokens[3])); serviceBuilder.setCoord( Coordinate.newInstance(Double.parseDouble(tokens[1]), Double.parseDouble(tokens[2]))); vrpBuilder.addJob(serviceBuilder.build()); } customerCount++; } else if (trimedLine.startsWith("v")) { VehicleTypeImpl.Builder typeBuilder = VehicleTypeImpl.Builder.newInstance("type_" + tokens[1]) .addCapacityDimension(0, Integer.parseInt(tokens[2])); int nuOfVehicles = 1; if (vrphType.equals(VrphType.FSMF)) { typeBuilder.setFixedCost(Double.parseDouble(tokens[3])); } else if (vrphType.equals(VrphType.FSMFD)) { typeBuilder.setFixedCost(Double.parseDouble(tokens[3])); if (tokens.length > 4) { typeBuilder.setCostPerDistance(Double.parseDouble(tokens[4])); } else throw new IllegalStateException( "option " + vrphType + " cannot be applied with this instance"); } else if (vrphType.equals(VrphType.FSMD)) { if (tokens.length > 4) { typeBuilder.setCostPerDistance(Double.parseDouble(tokens[4])); } else throw new IllegalStateException( "option " + vrphType + " cannot be applied with this instance"); } else if (vrphType.equals(VrphType.HVRPD)) { if (tokens.length > 4) { typeBuilder.setCostPerDistance(Double.parseDouble(tokens[4])); nuOfVehicles = Integer.parseInt(tokens[5]); vrpBuilder.setFleetSize(FleetSize.FINITE); vrpBuilder.addPenaltyVehicles(5.0, 5000); } else throw new IllegalStateException( "option " + vrphType + " cannot be applied with this instance"); } else if (vrphType.equals(VrphType.HVRPFD)) { if (tokens.length > 4) { typeBuilder.setFixedCost(Double.parseDouble(tokens[3])); typeBuilder.setCostPerDistance(Double.parseDouble(tokens[4])); nuOfVehicles = Integer.parseInt(tokens[5]); vrpBuilder.setFleetSize(FleetSize.FINITE); vrpBuilder.addPenaltyVehicles(5.0, 5000); } else throw new IllegalStateException( "option " + vrphType + " cannot be applied with this instance"); } for (int i = 0; i < nuOfVehicles; i++) { VehicleTypeImpl type = typeBuilder.build(); Vehicle vehicle = VehicleImpl.Builder.newInstance("vehicle_" + tokens[1] + "_" + i) .setStartLocationCoordinate(depotCoord) .setType(type) .build(); vrpBuilder.addVehicle(vehicle); } } } closeReader(reader); }
private void readVehiclesAndTheirTypes(XMLConfiguration vrpProblem) { // read vehicle-types Map<String, VehicleType> types = new HashMap<String, VehicleType>(); List<HierarchicalConfiguration> typeConfigs = vrpProblem.configurationsAt("vehicleTypes.type"); for (HierarchicalConfiguration typeConfig : typeConfigs) { String typeId = typeConfig.getString("id"); if (typeId == null) throw new IllegalStateException("typeId is missing."); String capacityString = typeConfig.getString("capacity"); boolean capacityDimensionsExist = typeConfig.containsKey("capacity-dimensions.dimension(0)"); if (capacityString == null && !capacityDimensionsExist) { throw new IllegalStateException("capacity of type is not set. use 'capacity-dimensions'"); } if (capacityString != null && capacityDimensionsExist) { throw new IllegalStateException( "either use capacity or capacity-dimension, not both. prefer the use of 'capacity-dimensions' over 'capacity'."); } VehicleTypeImpl.Builder typeBuilder; if (capacityString != null) { typeBuilder = VehicleTypeImpl.Builder.newInstance(typeId) .addCapacityDimension(0, Integer.parseInt(capacityString)); } else { typeBuilder = VehicleTypeImpl.Builder.newInstance(typeId); List<HierarchicalConfiguration> dimensionConfigs = typeConfig.configurationsAt("capacity-dimensions.dimension"); for (HierarchicalConfiguration dimension : dimensionConfigs) { Integer index = dimension.getInt("[@index]"); Integer value = dimension.getInt(""); typeBuilder.addCapacityDimension(index, value); } } Double fix = typeConfig.getDouble("costs.fixed"); Double timeC = typeConfig.getDouble("costs.time"); Double distC = typeConfig.getDouble("costs.distance"); if (fix != null) typeBuilder.setFixedCost(fix); if (timeC != null) typeBuilder.setCostPerTime(timeC); if (distC != null) typeBuilder.setCostPerDistance(distC); VehicleType type = typeBuilder.build(); String id = type.getTypeId(); String penalty = typeConfig.getString("[@type]"); if (penalty != null) { if (penalty.equals("penalty")) { String penaltyFactor = typeConfig.getString("[@penaltyFactor]"); if (penaltyFactor != null) { type = new PenaltyVehicleType(type, Double.parseDouble(penaltyFactor)); } else type = new PenaltyVehicleType(type); id = id + "_penalty"; } } types.put(id, type); } // read vehicles List<HierarchicalConfiguration> vehicleConfigs = vrpProblem.configurationsAt("vehicles.vehicle"); boolean doNotWarnAgain = false; for (HierarchicalConfiguration vehicleConfig : vehicleConfigs) { String vehicleId = vehicleConfig.getString("id"); if (vehicleId == null) throw new IllegalStateException("vehicleId is missing."); Builder builder = VehicleImpl.Builder.newInstance(vehicleId); String typeId = vehicleConfig.getString("typeId"); if (typeId == null) throw new IllegalStateException("typeId is missing."); String vType = vehicleConfig.getString("[@type]"); if (vType != null) { if (vType.equals("penalty")) { typeId += "_penalty"; } } VehicleType type = types.get(typeId); if (type == null) throw new IllegalStateException("vehicleType with typeId " + typeId + " is missing."); builder.setType(type); String locationId = vehicleConfig.getString("location.id"); if (locationId == null) { locationId = vehicleConfig.getString("startLocation.id"); } if (locationId == null) throw new IllegalStateException("location.id is missing."); builder.setStartLocationId(locationId); String coordX = vehicleConfig.getString("location.coord[@x]"); String coordY = vehicleConfig.getString("location.coord[@y]"); if (coordX == null || coordY == null) { coordX = vehicleConfig.getString("startLocation.coord[@x]"); coordY = vehicleConfig.getString("startLocation.coord[@y]"); } if (coordX == null || coordY == null) { if (!doNotWarnAgain) { logger.warn("location.coord is missing. will not warn you again."); doNotWarnAgain = true; } } else { Coordinate coordinate = Coordinate.newInstance(Double.parseDouble(coordX), Double.parseDouble(coordY)); builder.setStartLocationCoordinate(coordinate); } String endLocationId = vehicleConfig.getString("endLocation.id"); if (endLocationId != null) builder.setEndLocationId(endLocationId); String endCoordX = vehicleConfig.getString("endLocation.coord[@x]"); String endCoordY = vehicleConfig.getString("endLocation.coord[@y]"); if (endCoordX == null || endCoordY == null) { if (!doNotWarnAgain) { logger.warn("endLocation.coord is missing. will not warn you again."); doNotWarnAgain = true; } } else { Coordinate coordinate = Coordinate.newInstance(Double.parseDouble(endCoordX), Double.parseDouble(endCoordY)); builder.setEndLocationCoordinate(coordinate); } String start = vehicleConfig.getString("timeSchedule.start"); String end = vehicleConfig.getString("timeSchedule.end"); if (start != null) builder.setEarliestStart(Double.parseDouble(start)); if (end != null) builder.setLatestArrival(Double.parseDouble(end)); String returnToDepot = vehicleConfig.getString("returnToDepot"); if (returnToDepot != null) { builder.setReturnToDepot(vehicleConfig.getBoolean("returnToDepot")); } VehicleImpl vehicle = builder.build(); vrpBuilder.addVehicle(vehicle); vehicleMap.put(vehicleId, vehicle); } }
public void read(String fileName) { vrpBuilder.setFleetSize(FleetSize.FINITE); BufferedReader reader = getReader(fileName); int vrpType; int nOfDepots = 0; int nOfCustomers = 0; int nOfVehiclesAtEachDepot = 0; int counter = 0; String line; List<List<Builder>> vehiclesAtDepot = new ArrayList<List<Builder>>(); int depotCounter = 0; while ((line = readLine(reader)) != null) { line = line.replace("\r", ""); line = line.trim(); String[] tokens = line.split("\\s+"); if (counter == 0) { vrpType = Integer.parseInt(tokens[0].trim()); if (vrpType != 2) throw new IllegalStateException("expect vrpType to be equal to 2 and thus to be MDVRP"); nOfVehiclesAtEachDepot = Integer.parseInt(tokens[1].trim()); nOfCustomers = Integer.parseInt(tokens[2].trim()); nOfDepots = Integer.parseInt(tokens[3].trim()); } else if (counter <= nOfDepots) { String depot = Integer.valueOf(counter).toString(); int duration = Integer.parseInt(tokens[0].trim()); if (duration == 0) duration = 999999; int capacity = Integer.parseInt(tokens[1].trim()); VehicleTypeImpl vehicleType = VehicleTypeImpl.Builder.newInstance(counter + "_cordeauType") .addCapacityDimension(0, capacity) .setCostPerDistance(1.0) .setFixedCost(0) .build(); List<Builder> builders = new ArrayList<VehicleImpl.Builder>(); for (int vehicleCounter = 0; vehicleCounter < nOfVehiclesAtEachDepot; vehicleCounter++) { Builder vBuilder = VehicleImpl.Builder.newInstance( depot + "_" + (vehicleCounter + 1) + "_cordeauVehicle"); vBuilder.setLatestArrival(duration).setType(vehicleType); builders.add(vBuilder); } vehiclesAtDepot.add(builders); } else if (counter <= (nOfCustomers + nOfDepots)) { String id = tokens[0].trim(); Coordinate customerCoord = makeCoord(tokens[1].trim(), tokens[2].trim()); double serviceTime = Double.parseDouble(tokens[3].trim()); int demand = Integer.parseInt(tokens[4].trim()); Service service = Service.Builder.newInstance(id) .addSizeDimension(0, demand) .setServiceTime(serviceTime) .setLocation( Location.Builder.newInstance().setId(id).setCoordinate(customerCoord).build()) .build(); vrpBuilder.addJob(service); } else if (counter <= (nOfCustomers + nOfDepots + nOfDepots)) { Coordinate depotCoord = makeCoord(tokens[1].trim(), tokens[2].trim()); List<Builder> vBuilders = vehiclesAtDepot.get(depotCounter); for (Builder vBuilder : vBuilders) { vBuilder.setStartLocation(Location.newInstance(depotCoord.getX(), depotCoord.getY())); VehicleImpl vehicle = vBuilder.build(); vrpBuilder.addVehicle(vehicle); } depotCounter++; } else { throw new IllegalStateException("there are more lines than expected in file."); } counter++; } close(reader); }