Suppose I have two vehicles with capacity 5 and 12 respectively, and
there are 4 shipments to be picked up. On solving this problem jsprit
usually assigns the 12 capacity vehicle to pickup/deliver the 4
shipments.
To workaround this problem, I modified the objective function using
vraBuilder.setObjectiveFunction(new SolutionCostCalculator() and set a
cost associated with under utilisation of vehicles.

Not quite sure what your problem is, I suppose that you want to use all the vehicles (in your case, use both 5 capacity and 12 capacity vehicles)?

If so, as far as I know, jsprit does not try to use all the vehicles (assuming finite fleet). In some cases, it can be achieved by setting finite fleet and 0 fixed cost for vehicles, but it is not guaranteed. You can refer to some previous discussions on this topic: e.g., #163 and this post in the old mailing list.

Thank you very much for your response. I apologise for having poorly phrased the question.

Suppose you have 4 shipments to pickup, and two vehicles, V5 of capacity 5 and V12 of capacity twelve. There are no constraints. So, ideally, jsprit should give one single route in which vehicle V5 picks up the four shipments and delivers them, but instead what happens is that it assigns V12 instead.

To workaround this, for now I am modifying the objective function, where I add a cost of 10000*(capacity of vehicle - number of shipments in route). The number 10000 is just arbitrary and it sometimes is able to mitigate around the stated issue, but when there are say around 100 shipments and numerous vehicles of varying capacity, jsprit sometimes assigns a vehicle to a route that has way fewer shipments than the vehicle capacity, and a smaller vehicle would have sufficed for the same route.

It would be very helpful if you could suggest a better way to solve this.

On your described problem, it will give the expected result.

The objective function is to minimize the total cost.
If the jsprit could perform all the shipments with only one vehicle, it will prefer to use the one with the littlest fixed cost.
Because it will consider the same route for both, the only difference will be this additionnal cost, which is to use V5 in this case.

However, when the capacity to deliver is between 5 and 12, it could prefer to use V12 and don’t use V5 at all. To define your preferences here, you will need to define a Distance or Time cost (resp. setCostPerDistance, setCostPerTransportTime).

I see. Your problem is similar to the second question of the OP in this post. I think @stefan’s suggestion there and @braktar’s suggestion here will work.

Did you get the solution for this problem?
It seems that the algorithm tries to use the vehicles with maximum capacity first. I tried sorting the shipments by their load in descending order but it didn’t work.