Search code examples
javaoptaplanner

Optaplanner constraints for time windows


I am trying to solve VRP with OptaPlanner. I have multiple customers that have different time windows. Here are my constraint providers

protected Constraint arrivalAfterDueTime(ConstraintFactory factory) {
        return factory.from(TimeWindowedCustomer.class)
                .filter(customer -> customer.getArrivalTime() >= customer.getDueTime())
                .penalizeLong("arrivalAfterDueTime",
                        HardSoftLongScore.ONE_HARD,
                        customer -> customer.getArrivalTime() - customer.getDueTime());
    }

protected Constraint arrivalBeforeReadyTime(ConstraintFactory factory) {
        return factory.from(TimeWindowedCustomer.class)
                .filter(customer -> customer.getArrivalTime() > customer.getReadyTime()
                && customer.getArrivalTime() < customer.getDueTime() )
                .penalizeLong("arrivalBeforeReadyTime",
                        HardSoftLongScore.ONE_HARD,
                        customer -> customer.getReadyTime() - customer.getArrivalTime());
    }

But in the solution I get arrival times that are < ready time. How can I fix this? Thank you in advance.


Solution

  • There are generally three approaches when arriving too early:

    • A) Wait until the time windows open, losing that time but with no extra penalty. So when it arrives at 9:30, with a service time of 0:10 and ready time of 10:00, the vehicle departs at 10:10 (not 9:40!). This will automatically be avoided if you have a general constraint to reduce the total activity time of vehicles (or a combination of max activity time per vehicle with too many tasks per day).
    • B) Same as A), with an extra soft penalty. This can be useful if you don't have a global constraint to reduce the total activity time of vehicles.
    • C) Same as A) with an extra hard penalty. This is dangerous because given 2 tasks, one with a time window from 9:00 to 10:00 and one from 11:00 to 12:00, with a 10 minute drive in between, and no other tasks, you're not allowing one vehicle to do both those tasks.

    In any case, use ConstraintVerifier to unit test your constraints!