optapy / optapy-quickstarts

OptaPy quick starts for AI optimization: showcases many different use cases.
Apache License 2.0
19 stars 13 forks source link

VRP failing to solve simple constraint #27

Closed slali-dev closed 1 year ago

slali-dev commented 1 year ago

Hello,

I've tried this demo locally and it's working fine. However, I want to use one constraint for a production use-case and the solver keeps violating this constraint.

def cut_long_edges(constraint_factory: ConstraintFactory):
return constraint_factory.for_each(Vehicle) \
    .filter(lambda vehicle: vehicle.get_long_edges() > 0) \
    .penalize("cut_long_edges", HardSoftScore.ONE_HARD,
              lambda vehicle: (vehicle.get_long_edges()) )

method get_long_edges just loops through customer_list and accumulates the number of adjacent customers with distance > X.

So I removed all the constraints and just kept this one

@constraint_provider
def vehicle_routing_constraints(constraint_factory: ConstraintFactory):
    return [
        cut_long_edges(constraint_factory)
    ]

The score is 1Hard/0Soft and it's using only 1 vehicle out of 11, which is weird because it's obvious that score 0Hard/0Soft is achievable with 11 vehicles and a timelimit of 600 seconds !!

Here is the output: image

Where have I gone wrong in the above scenario?

Thanks in advance.

Christopher-Chianelli commented 1 year ago

A way to debug the issue is to use constraint_verifier to verify that cut_long_edges is working as expected; see https://github.com/optapy/optapy-quickstarts/blob/4bdf9cce4a5e1ed4ffb3691b940abb0168251d63/vehicle-routing/tests.py#L15-L22 for an example. I expect the issue is you only have 1 depot (which is in the lower right), meaning there will always be at least one long edge (since the depot is too far from the edges in the top left). You would need to add a depot in the top left, and assign some vehicles to it. As for why only single vehicle is being used in the above example, it because there are no constraints to encourage using multiple vehicles (since each vehicle will have at least one long edge because they all come from the lower right depot).

slali-dev commented 1 year ago

Hey @Christopher-Chianelli, thanks for your quick response.

You are right the issue here is having 1 depot IDK how I missed that, I've just solved it by updating get_long_edges to ignore the distance between the depot and any other point.