0

I have been trying to use Optaplanner with my multiple traveling salesman problem, using the Vehicle Routing example as a base. The problem I am having is that it optimizes total distance traveled and ends up having a single vehicle do the vast majority of the work. How do I get it to spread the work around?

I guess I don't want total distance traveled as cost, but rather the time when all the locations are visited. The result will be that two vehicles will divide the locations between them and visit in parallel, though the total distance (by both vehicles) will be higher.

How do I write a Constraint that does that? I tried adding quadratic cost associated with the number of locations visited by vehicles, and it kind of worked, but I don't think that's right either.

Here are the current constraints. The salesman is Actor; locations are Sectors (aligns with business problem)

protected Constraint costFromPreviousSector(ConstraintFactory factory) {
    return factory.forEach(Sector.class)
            .filter(sector -> sector.getActor() != null)
            .penalizeLong(HardSoftLongScore.ONE_SOFT,
                          Sector::getCostFromPreviousSector)
            .asConstraint("costFromPreviousSector");

 protected Constraint actorUsage(ConstraintFactory factory) {
    return factory.forEach(Actor.class)
            .penalizeLong(HardSoftLongScore.ONE_SOFT, Actor::usage)
            .asConstraint("actorUsage");

where sector.getCostFromPreviousSector is just distance and actor.usage looks like:

    public Long usage() {
        return 100 * ((long) sectors.size() * sectors.size());
    }
Lukáš Petrovický
  • 3,945
  • 1
  • 11
  • 20
C Dorman
  • 551
  • 5
  • 12

1 Answers1

1

You have to ask yourself, how is the solver supposed to figure out that you don't want all visits done by the same vehicle. If assigning everything to one vehicle results in the same score as spreading the load across all available vehicles, why would the solver do what you want?

You will have to figure out some constraint that tells the solver to distribute visits across vehicles. I can not do it for you - I am not familiar with your domain, or the problem you are solving. As a hypothetical example, you can write a constraint that penalizes unused vehicles. Your idea of minimizing the time of the final visit could also work.

This is a very generic advice, so it applies to both OptaPlanner and Timefold.

Lukáš Petrovický
  • 3,945
  • 1
  • 11
  • 20