You can follow these steps to help determine whether a model is experiencing numerical issues:
- Isolate the model for testing by exporting a model file and a
parameter file. The easiest way to do this is to create a gurobi.env file in your working directory that contains the following
Record 1Once you have done this, running your program will produce one recordingXYZ.grbr file for each Gurobi environment your program creates (where XYZ is a three-digit, 0-padded value that increases from 000). You can replay this recording file using gurobi_cl (e.g., gurobi_cl recording000.grbr). Consult this section for more information on recording files.
- Using the Gurobi Interactive shell, run some simple Python code
to read the model that the replay produces, and print the summary statistics:
m = read('gurobi.rew') m.printStats()The output will look like:
Statistics for model (null) : Linear constraint matrix : 25050 Constrs, 15820 Vars, 94874 NZs Variable types : 14836 Continuous, 984 Integer Matrix coefficient range : [ 0.00099, 6e+06 ] Objective coefficient range : [ 0.2, 65 ] Variable bound range : [ 1, 5e+07 ] RHS coefficient range : [ 1, 5e+07 ]The range of numerical coefficients is one indication of potential numerical issues. As a very rough guideline, the ratio of the largest to the smallest coefficient should be less than ; smaller is better.
In this example, the matrix range is
- If possible, re-solve the model using the same parameters and review
the logs. With the Python shell, use code like the following:
m.read('gurobi.prm') m.optimize()Here are some examples of warning messages that suggest numerical issues:
Warning: Model contains large matrix coefficient range Consider reformulating model or setting NumericFocus parameter to avoid numerical issues. Warning: Markowitz tolerance tightened to 0.5 Warning: switch to quad precision Numeric error Numerical trouble encountered Restart crossover... Sub-optimal termination Warning: ... variables dropped from basis Warning: unscaled primal violation = ... and residual = ... Warning: unscaled dual violation = ... and residual = ...
- When the optimize function completes, print solution
statistics. With the Python shell, use code like the following:
m.printQuality()which provides a summary of solution quality:
Solution quality statistics for model Unnamed : Maximum violation: Bound : 2.98023224e-08 (X234) Constraint : 9.30786133e-04 (C5) Integrality : 0.00000000e+00
Violations that are larger than the tolerances are another indication of numerical issues. Also, for a pure LP (without integer variables), print the condition number via the following Python command:
m.KappaExactThe condition number measures the potential for error in linear calculations; a large condition number, such as , is another indication of possible numerical issues, see this section for more details.
- If changing parameters (e.g., Method or Seed) leads to a different optimization status (e.g., Infeasible instead of optimal), or if the optimal objective values changes, this is usually a sign of numerical issues. To further assess this you can tighten tolerances (to the order of or even ), and see if the behavior of the solver becomes consistent again. Note that tightening tolerances usually comes at the price of more computing time, and should not be considered as a solution for numerical issues.