I’ve been writing a mixed integer linear model in C++ with Gurobi to solve for dispatch and commitment of electrical generators for a project at work. The problem space I’m working with is pretty big, so the model doesn’t solve on the order of seconds like it does for smaller problems. I’m more on the order of many minutes, and that’s with a much bigger MIP gap on the order of %’s, not hundredths of percents like is default. In any case, the problem is big, and that stinks.

Fortunately, Gurobi has a great tool it ships with that will run your model using various solution parameters, and show you which ones worked best. The solver has a bunch of settings like MIPFocus which tells it whether to focus on finding an improved feasible solution or to focus on proving optimality, SimplexPricing which helps direct the behavior of the simplex, and so forth.

I was using the tuning tool from the command line, which worked out pretty well, you just specify your tuning parameters, input your model, and go. For example, I had the following in my command line:

grbtune TuneTrials=5 TuneTimeLimit=7200 MIPGap=0.05 C:\users\me\desktop\model.lp

The tune trials specifies the # of times it runs your model. An MIP model’s search is impacted by the initial random seed, so specifying an # of trials to run tries to avoid recommending settings that only help with some random seeds. The time limit specifies how long the tune tool will run. I like setting mine for several hours or even days to run overnight or on the weekend. The MIPGap is how close I need a feasible solution to be to the unconstrained (non-integer) LP solution. This is a big gap, and I’m trying to find ways to speed up the solver so I can demand more optimal solutions. But for now, it’s sufficient.

One problem came up in that I couldn’t specify an initial solution file (*.mst). For my problem, an initial guess really helps the MIP solver get started. Gurobi says it’s a known limitation and in the next version (7.0) we’ll be able to specify an initial solution file along with the model file.

So I took to my C++ code where I write my model and constraints. Gurobi exposes the tuning functionality to its various API’s, so you can call tune from your C++, Python, etc. code.

I tried setting my tune parameters from my C++ code, but I just couldn’t get them to stick. Here is a snippet from my code.

GRBEnv env = GRBEnv(); GRBModel model = GRBModel(env); // add constraints and variables, etc. int numTuneTrials = 5; double tuneTimeLimit = 43200; env.set(GRB_IntParam_TuneTrials, numTuneTrials); env.set(GRB_DoubleParam_TuneTimeLimit, tuneTimeLimit); model.update(); model.tune();

I sent this off to Gurobi and they responded very quickly that I needed to set my parameters to the environment BEFORE instantiating the model. The model copies the environment. So simply by setting the environment parameters before instantiating the model, the tune proceeded using the specified settings!

Next on my list… Figure out why Gurobi’s C++ API is so slow… I’m probably doing something wrong there too…