jsprit VRP Related jobs hard Contraint

899 Views Asked by At

Is it possible to have two or multiple shipment in same route by hard Contraint.

If not, do you know other java libraries that can handle such kind of restrictions?

Thank you!

1

There are 1 best solutions below

2
On BEST ANSWER

The easiest way do make sure that shipments are in the same route is to tag these shipment with a skill

shipmentBuilder.addRequiredSkill("tag")

but then you need to tag a particular vehicle as well:

vehicleBuilder.addSkill("tag")

And make sure you make the algorithm consider skills/these tags (see https://github.com/jsprit/jsprit/blob/master/WHATS_NEW.md - you need to use 1.3.2-SNAPSHOT).

If you do not want to assign a particular vehicle with a tag, you need to implement a core.problem.constraint.HardRouteStateLevelConstraint which is basically this method

public boolean fulfilled(JobInsertionContext insertionContext)

Make sure that insertionContext.getJob() [which is the job to be inserted] can be inserted into insertionContext.getRoute(). At this point you need to know two things:

  • the associated shipments of insertionContext.getJob(), i.e. shipments that need to be in same route as insertionContext.getJob()
  • whether one of these associated jobs has already been assigned to a route and if so whether this route is the same as insertionContext.getRoute()

For latter information you need to define states that provides you with a job-route assignment. I would define a problemState and its according updater like this:

static class UpdateJobRouteAssignment implements StateUpdater,JobInsertedListener,InsertionStartsListener {

        StateManager stateManager;

        UpdateJobRouteAssignment(StateManager stateManager) {
            this.stateManager = stateManager;
        }

        @Override
        public void informJobInserted(Job job2insert, VehicleRoute inRoute, double additionalCosts, double additionalTime) {
            stateManager.putProblemState(stateManager.createStateId(job2insert.getId()), VehicleRoute.class, inRoute);
        }

        @Override
        public void informInsertionStarts(Collection<VehicleRoute> vehicleRoutes, Collection<Job> unassignedJobs) {
            for(VehicleRoute r : vehicleRoutes){
                for(Job j : r.getTourActivities().getJobs()){
                    informJobInserted(j,r,0.,0.);
                }
            }
        }
    }

Add your state updater and your constraint to your State/ConstraintManager and you are done.