Dear James,
Thank you very much for taking your time to look into my problem. I was indeed not very clear in my previous description, I will try harder to explain my problem better haha.
Commenting on your initial comments: data['maxTimePerDay'] indeed should be the total time for the whole week, that was my bad. As you will see in the python code below, this has already been implemented. In my case, I have to optimise for the 5 workdays of the week, with a working day of 8.5 hours. So data['maxTimePerDay'] is indeed = (8.5 * 5 * 60)..
My provided code was indeed insufficient, hereby I provide my full code to run the optimisation. I also provide an example input inside the python code. The 3 keys stored in the dictionary are 1) 'travelTime_matrix' : is the matrix that contains the time in minutes to travel between two locations 2) 'service_time' : vector that contains the service time in minutes needed at each location. Obviously, for the depot and the dummy depots, the service time is 0. 3) 'penaltyScore' : vector that contains the penaltyscore for each location, if it is not included in the route, which is implemented through routing.addDisjunction. Note that for the depot, penalty is 0, and for the dummy depots it is very high penalty score, such that these dummy depots are for sure visited, as the service engineers need to return back home at the end of day.
Together with the python code, I provide the list of customers that should be considered for this specific optimisation, with confidential data filtered out. The last column 'UsedOrNot' is adjusted after the optimisation, whether or not this customer has been visited or not.
If you run the code, it should give an output as follows:
As you can see, it creates a nice route, where it indeed accounts for the service engineer to return back home at the end of the day (see the dummy depot indexes 1, 2, 3 and 4 in the route for vehicle 1). As you can also see, the objective value at the top of the screenshot is 2375 minutes, which is the total time in minutes it takes to complete the route (basically the sum of the printed travel times and service times, as you can see on the screenshot). But as can be seen inside the excel (see screenshot below), the model only takes the top 15 customers, and ignored the bottom 4 customers even though these customers have higher penalty scores (as these are considered more important customers).
The point of me using the routing.addDisjunction() is to include the most important customers in the route, and leave out the less important customers for the week thereafter, basically following the example as in: https://developers.google.com/optimization/routing/penalties . So what I would expect to happen with my objective value, is that besides the 2375 minutes in the objective value, the sum of the penalty scores of the locations that are not included in the route is added to the objective value. This would mean that I want the objective solution to minimize that sum, therefore trying to leave out customers that are less important in the optimisation, as that would decrease the objective value. As you can see, this does not seem to work anymore, because I added the code for the dummy depot time windows.
I hope this clears up a bit what I mean with my objective solution not being desirable with my expectations. I would be very grateful if you, or anybody on the google OR tools team, have a solution to this problem. Thanks in advance!
With regards,
Nikita