reinterpretcat / vrp

A Vehicle Routing Problem solver
https://reinterpretcat.github.io/vrp/
Apache License 2.0
331 stars 68 forks source link

Quality issues with shift end position #22

Open K-Leon opened 3 years ago

K-Leon commented 3 years ago

Thanks for your hard work - again!

I just found a strange inconsistency between shift time limit and shift end position.

Task Constraints:

a) Ich specify job the "proper" way

        "limits": { "maxDistance": 140000 },
        "costs": { "fixed": 22, "distance": 0.0002, "time": 0.004806 },
        "shifts": [
          {
            "start": { "earliest": "2023-02-21T16:30:00Z", "location": { "lat": 47.4157792, "lng": 8.3939315 } },
            "end": { "latest": "2023-02-21T21:30:00Z", "location": { "lat": 47.4157792, "lng":8.3939315 } }
          }

=> The Result ist remarkable bad. Around 40 unassigned Stops. 29 Tours! image

b) I specify shiftTime Limit as 4 hours and shorten Max Distance to calculate Backroute manually I specify shiftTime Backroute as 100 km

 "limits": { "maxDistance": 100000, "shiftTime": 14400 },
    "shifts": [
       {
         "start": { "earliest": "2023-02-21T16:30:00Z", "location": { "lat": xxxxx, "lng": xxxxxx } }
        }

At the end i add the route back to depot manually and everything is fine and well in time constraint of 5 hours and except one overflow of 3 km i got a great solution with 26 Tours. The Overflow is completely gone when i lower my distance limit to 95. Still with a saving of 2 tours compared to the other solution. (With a little processing afterwards to handle distance overflows the result would be even better) image

This is such a large difference that i got curious what is going on.

reinterpretcat commented 3 years ago

My guess it is related to search path in solution space: the variant b is open VRP and it leads to more efficient search path as there is no constraint for returning to depot. Also the quality depends on amount of time given to the solver: maybe try to increase it if it is too short.

K-Leon commented 3 years ago

I tried it with calculation Time of up to 20 Minutes without significant change.

What surprises me is the big difference between the two constraints. I expected a small hit due to the "return" constraint, but not that huge.

reinterpretcat commented 3 years ago

This would be interesting to analyze as better solution is kind of already known. I'm working on experimental hyper-heuristic (hyperh branch) which might improve results a bit, but hard to say for sure.

Btw, how many jobs and vehicles are defined in original problem?

K-Leon commented 3 years ago

29 Vehicles, 1650 Jobs. I saw the same effect while experimenting with larger dataset. I haven't researched small ones yet

reinterpretcat commented 3 years ago

Can you try to run the problem using https://github.com/reinterpretcat/vrp/tree/hyperh branch? Just curious will it improve a bit results or not.

K-Leon commented 3 years ago

sure! compiling right now

K-Leon commented 3 years ago

The initial Solution is reproducable better. Even though it isn't solving the problem. ( I executed the Problem multiple times )

Hyper: rank: 0, cost: 3512.12(0.000%), tours: 29, unassigned: 451, fitness: (451.000, 3512.124, 0.125) (Down to 350 after 3 Minutes)
Cur Release: rank: 0, cost: 3514.88(0.000%), tours: 29, unassigned: 488, fitness: (488.000, 3514.876, 0.099)

Looking at the large number of unassigned it is nearly impossible for the algorithm to get a "complete" solution. VRP Mode starts as an initial solution with 0 unassigned and - if i remember correctly - one or two vehicles less.

Edit: As a long shot i tried seeding it with a mostly proper solution - hoping that it adapts. Sadly without success.

reinterpretcat commented 3 years ago

It looks like you're using balancing objective (third one in fitness). It is a bit experimental as it's performance depends on tolerance and threshold parameters which user needs to set. Have you tried to play with their values?

Also it is important how primary and secondary objectives are defined. Do you have minimize-unassigned as primary and minimize-cost and balance as secondary objectives?

K-Leon commented 3 years ago

I use more or less defaults - "objectives": { "primary": [{ "type": "minimize-tours" }, { "type": "minimize-unassigned" }], "secondary": [{ "type": "minimize-cost" }] }

I'll try to anonymize the dataset without hiding the base issue and provide it by mail like last time. I think this will work better than remote diagnosis.

Edit: I experimented with balancing - but it shows the same effect like discussed above. Just even worse. In this example we're talking round about 700 unassigned