Debugging Tips: Does Your Model Do What You Think It Does?
We’ve compiled a series of tips and techniques to help streamline your debugging efforts. Below are the most common ways to overcome the modeling challenges you’ve been facing.
Take Baby Steps: Create an easy-to-solve instance. It’s easier to inspect a model that doesn’t have many variables. For the problem at hand, it could be 1 depot, 1 vehicle (capacity 1), and 1 customer (load 1). To make it even simpler, you could turn off time constraints for the customer (make them cover the entire time horizon). The solution for this model is trivial, and you know what to expect: the vehicle should leave the depot, pick up and deliver the node, and return to the depot.
Relax Some Constraints: If you think your time constraints are not being met, you could increase the time windows or increase the speed of the vehicles. If capacity is the problem, you could increase the capacity of the vehicles.
Inspect the Model: If you check the README.md file from the assignments, you will see that we ask you to save the
.log
and.ilp/.lp
files in the folder namedresults
. Learn how to write these files for your model using your preferred solver. For debugging, the.ilp
file can be very handy; it transforms your programmatically written constraints, variables, etc., into a mathematical model like:Maximize x + y + z Subject To c0: x + y = 1 c1: x + 5y + 2z <= 10 qc0: x + y + [x^2 - 2xy + 3y^2] <= 5 Bounds 0 <= x <= 5 z >= 2 Generals x y z End
This is like having an X-ray to check if your model makes sense. Instead of spending hours scrutinizing your Python constraints to find a mistaken index or arithmetic error, you could convert your model to this form and check if it aligns with your expectations. Note that the smaller the instance, the easier it is to review the model. Read more about this format on LP format - Gurobi Optimization.
When in Doubt, Print It Out: Print everything: the constraints, the sets, the variables, the parameters, the final solution. Are the numbers correct? Are the indices in the correct places?
Turn off Offending Parts: If a function is failing and you’re unsure why, try systematically disabling parts of it. For example, if the objective function has several components, deactivate them one by one to identify the error source. You can also replace parameters with constants; for instance, substitute your
t[i][j]
with 10. If the code runs post-substitution, you’ve pinpointed the issue.Check Error Messages Online or in ChatGPT: Look up the error messages you encounter on Google or ask ChatGPT.
Foolproof Your Constraints with Literature: The VRPPD or DARP has an extensive body of literature. The first hit on Google already provides a paper with all the elements needed to implement the correct model (check the problem formulation). Does your model incorporate these elements? For instance, some struggled with making the return-to-depot constraint work. If your model is set to return to the same depot node, your arrival time constraint might block it (since you’re considered to have already arrived at the depot at departure). The literature offers solutions to this.
Make Sure Your Solver Can Handle Your Formulation: Keep in mind that we’re dealing with a linear formulation; therefore, typical arrival time sequencing constraints like \(x_{ij}^k(s_{ik} + t_{ij} - s_{jk}) = 0\) are infeasible because you are multiplying variables \(s_{ik}\) (arrival time of vehicle \(k\) at node \(i\)) and \(x_{ij}^k\) (1 if vehicle \(k\) traveled from \(i\) to \(j\)). Although such constraints are commonly presented in the literature as shorthand (avoiding immediate introduction of BIG M values to maintain model simplicity), most authors demonstrate how they linearize the problem later, especially concerning arrival sequencing and loading constraints.