Quick followup while I try to finish up a blog post with all the gory details.
I’ve found that a flat disjunction value (the cost of allowing a node to be dropped) is bad. The solver drops lots of nodes in that case.
A slightly better result comes from setting the disjunction of the first pickup and all deliver nodes to one value, and then all intermediate pickup nodes to a higher value.
But much better results come when I systematically increased the disjunction cost for each subsequent node in each sequence. I used powers of 2, so for a sequence like [a, b, bb, c, cc, d], where bb and cc are pickups at b and c, respectively, I assigned disjunctions of
a-> 1000 * 2**i = 1000
b, bb -> 1000 * 2**i = 2000
c, cc-> 1000 * 2**i = 4000
d-> 1000 * 2**i = 8000
Etc.
My test case uses chains of 2, 3, 4, and 5 nodes, so [a, b] all the way to [a, b, c, d, e] (ignoring the intermediate dummy pickup nodes for clarity).
I’m not really sure *why* that works so well, but it does. It gets most of the way to the final solution in about 10 s, then gradually improves and is about done at 60s (I let it run for 90s).
The final answer drops 6 nodes (3 pickup and delivery pairs). In comparison, the flat disjunction case drops 26 nodes (13 pairs) after 90s.
James
I have an additional hack using variable disjunction penalties that works pretty well but it is a mystery to me why it works so I’m going to play around with it a bit before posting here.