Hello all,
First of all, thank you for your help in advance!
I’m triying to solve a BikeSharing reallocation problem with JSPRIT and their HardConstraints.
The idea of the problem is the following:
Multiple customers who have shipments and deliveries (The bike stations which need be rebalanced taking or putting bikes).
The trucks have a fixed capacity (e.g 10 bikes). In this case, the transported commodity is the same. For instance, bikes picked from a station could be put in other station in the same route.
Following the example in the documentation (MultipleProductsWithLoadConstraintExample) I have tried to adapt it to my problem:
public class SingleProductWithRouteConstraintExample {
private static final Logger logger = LoggerFactory.getLogger(VehicleRoutingAlgorithm.class);
static final int BIKES_DIMENSION_INDEX = 0;
//static class EnoughPickupsForDeliveriesimplements HardActivityStateLevelConstraint { //v1.3.1
static class EnoughPickupsForDeliveriesimplements HardActivityConstraint {
private StateManager stateManager;
EnoughPickupsForDeliveries(StateManager stateManager) {
this.stateManager = stateManager;
}
private boolean hasBikesInVehicle(TourActivity prevAct) {
Capacity prevLoad = stateManager.getActivityState(prevAct, InternalStates.LOAD, Capacity.class); //1.3.2-SNAPSHOT & upcoming release v1.4
if (prevLoad == null) {
return false;
} else {
return prevLoad.get(BIKES_DIMENSION_INDEX) > 0;
}
}
private Capacity getLoadAtPreviousAct(TourActivity prevAct) {
Capacity prevLoad = stateManager.getActivityState(prevAct, InternalStates.LOAD, Capacity.class); //1.3.2-SNAPSHOT & upcoming release v1.4
if (prevLoad != null) return prevLoad;
else return Capacity.Builder.newInstance().build();
}
@Override
public ConstraintsStatus fulfilled(JobInsertionContext jobInsertionContext, TourActivity prevAct, TourActivity newAct, TourActivity nextAct, double departureTimeAtPrevAct) {
if (newAct.getName().equals("pickup")) {
//Check current capacity
return ConstraintsStatus.FULFILLED;
} else {
if(hasBikesInVehicle(prevAct)){
return ConstraintsStatus.FULFILLED;
}else{
return ConstraintsStatus.NOT_FULFILLED;
}
}
}
}
public static void main(String[] args) {
VehicleType type = VehicleTypeImpl.Builder.newInstance("type").addCapacityDimension(BIKES_DIMENSION_INDEX, 10).build();
VehicleImpl vehicle = VehicleImpl.Builder.newInstance("vehicle").setStartLocation(loc(Coordinate.newInstance(0, 0)))
.setType(type).build();
Delivery bikes_1 = Delivery.Builder.newInstance("bikes_1_delivery")
.addSizeDimension(BIKES_DIMENSION_INDEX, 1)
.setLocation(loc(Coordinate.newInstance(5, 5))).build();
Delivery bikes_2 = Delivery.Builder.newInstance("bikes_2_delivery")
.addSizeDimension(BIKES_DIMENSION_INDEX, 1)
.setLocation(loc(Coordinate.newInstance(5, 2))).build();
Delivery bikes_3 = Delivery.Builder.newInstance("bikes_3_delivery")
.addSizeDimension(BIKES_DIMENSION_INDEX, 1)
.setLocation(loc(Coordinate.newInstance(5, 3))).build();
Pickup bikes_4 = Pickup.Builder.newInstance("bikes_4_pickup").addSizeDimension(BIKES_DIMENSION_INDEX, 1).setLocation(loc(Coordinate.newInstance(5, 4))).build();
Pickup bikes_5 = Pickup.Builder.newInstance("bikes_5_pickup").addSizeDimension(BIKES_DIMENSION_INDEX, 1).setLocation(loc(Coordinate.newInstance(5, 1))).build();
Pickup bikes_6 = Pickup.Builder.newInstance("bikes_6_pickup").addSizeDimension(BIKES_DIMENSION_INDEX, 1).setLocation(loc(Coordinate.newInstance(5, 6))).build();
VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder.newInstance()
.setFleetSize(VehicleRoutingProblem.FleetSize.FINITE)
.addJob(bikes_1)
.addJob(bikes_2)
.addJob(bikes_3)
.addJob(bikes_4)
.addJob(bikes_5)
.addJob(bikes_6)
.addVehicle(vehicle)
//.addJob(bikes_7)
.build();
StateManager stateManager = new StateManager(vrp);
ConstraintManager constraintManager = new ConstraintManager(vrp, stateManager);
constraintManager.addLoadConstraint();
constraintManager.addConstraint(new EnoughtPickupsForDeliveries(stateManager), ConstraintManager.Priority.CRITICAL);
VehicleRoutingAlgorithm vra = Jsprit.Builder.newInstance(vrp)
.setStateAndConstraintManager(stateManager, constraintManager)
.setCustomAcceptor(new SolutionAcceptor() {
@Override
public boolean acceptSolution(Collection<VehicleRoutingProblemSolution> collection, VehicleRoutingProblemSolution vehicleRoutingProblemSolution) {
return vehicleRoutingProblemSolution.getUnassignedJobs().size() == 0;
}
})
.buildAlgorithm();
Collection<VehicleRoutingProblemSolution> solutions = vra.searchSolutions();
SolutionPrinter.print(vrp, Solutions.bestOf(solutions), SolutionPrinter.Print.VERBOSE);
new GraphStreamViewer(vrp, Solutions.bestOf(solutions)).labelWith(GraphStreamViewer.Label.ID).setRenderShipments(true).display();
}
private static Location loc(Coordinate coordinate) {
return Location.Builder.newInstance().setCoordinate(coordinate).build();
}
}
I’m always getting a invalid solution with more deliveries before pickups.
Thank you so much in advance!!!