Is 0.8% of error worth your attention?

Recently, I got the code for a mixed-integer linear programming (MILP) problem implemented using C++&Gurobi. The objective value of this optimization problem is 1.97308e6, while the correct answer that I got from a previous code is 1.98893e6. The error is 0.008 (0.8%). Do you think there is an error in the code?

The answer is, first, look at the MIP gap - if the error is smaller than the MIP gap, then it is acceptable. MILP solvers have MIP gaps. The MIP gap is the error tolerance when the solution converges. In this optimization code, we are using the default MIP gap of Gurobi, which is 1e-4 (0.01%). Since the code has an error of 0.8%, obviously, it is much larger than the MIP gap and that indicates there is an error in the code.

In order to find the error, I did the following:

  1. I outputted the values of P (generation) and uk (unit commitment) from the two pieces of code, and compared the values.

    • I found that the generation from both the correct and wrong code could meet the load demand, which means the most important constraint - power balance - is met.

    • However, I noticed that the unit commitment from the wrong code is obviously different from the correct code - some generators turned off at the end in the results from the wrong code, but no generator was turned off at the end from the correct code. This raised my doubt in the minimum up/down time constraints.

  2. I checked the minimum up/down time constraints, but they looked exactly the same as my previous code (it turned out that I missed the typo here this time, because the two pieces of code are so similar).

  3. I revised my correct code so that it could read the values of uk from a .txt file and use pre-determined uk values instead of solving uk as a variable. Then I used the uk values from the wrong code to see whether this result was feasible in the correct code.

    • Results showed that these uk values were not feasible for the correct code, which meant there had to be something wrong with the wrong code.

    • I commented out constraint by constraint to see which constraints made the problem infeasible. When I commented out the minimum up/down time constraints, I got exactly the same objective value as the wrong code (1.97308e6). Then that’s it!!! It must be the minimum up/down time constraints.

  4. I compared the minimum up/down time constraints in the correct code and wrong code letter by letter, and found a typo in the minimum down time constraint of the wrong code:
    DCOPF.addConstr(MiddleDown <= 1-ShutCost[t][j]);
    should be:
    DCOPF.addConstr(MiddleDown <= 1-ZeroLoadCost[t][j]);

So, if your code has a 0.8% of error, please don’t ignore it.

Many times, it is just a simple typo, but it can be hard to find. You just need to be patient and find it anyway.