Feature request: Crossover only if suboptimal
OngoingFor "hard" problems, the barrier method often returns a sub-optimal solution and crossover is required to convert that solution to an optimal one.
As such my workflow is currently the following:
-
Run the model without crossover.
-
If it returns a sub-optimal solution run it again with crossover.
What would greatly speed up my workflow is having an option to run crossover only if the solution is suboptimal.
-
Official comment
This post is more than three years old. Some information may not be up to date. For current information, please check the Gurobi Documentation or Knowledge Base. If you need more help, please create a new post in the community forum. Or why not try our AI Gurobot?. -
Hi Martin!
You can obtain the desired behavior directly through a combination of parameter and attribute settings. What you would do is to do the first optimization with Crossover=0 as usual. Then, if the status is suboptimal, you would query the X and Pi vectors from this suboptimal solution. Then, you set Crossover=1, set the PStart attributes to X, the DStart attributes to Pi, and call the optimization again. This second optimization call will then directly go into crossover, starting from the previous barrier solution that you set via PStart and DStart.
In C, this would look like this:
double *x = NULL;
double *pi = NULL;
GRBenv *menv = GRBgetenv(model);
int status;
error = GRBsetintparam(menv, GRB_INT_PAR_CROSSOVER, 0);
if (error) goto QUIT;
error = GRBoptimize(model);
if (error) goto QUIT;
error = GRBgetintattr(model, GRB_INT_ATTR_STATUS, &status);
if (error) goto QUIT;
if (status == GRB_SUBOPTIMAL) {
int cols;
int rows;
error = GRBgetintattr(model, GRB_INT_ATTR_NUMVARS, &cols);
if (error) goto QUIT;
error = GRBgetintattr(model, GRB_INT_ATTR_NUMCONSTRS, &rows);
if (error) goto QUIT;
x = malloc(cols * sizeof(*x));
if (x == NULL) goto QUIT;
pi = malloc(rows * sizeof(*pi));
if (pi == NULL) goto QUIT;
error = GRBgetdblattrarray(model, GRB_DBL_ATTR_X, 0, cols, x);
if (error) goto QUIT;
error = GRBgetdblattrarray(model, GRB_DBL_ATTR_PI, 0, rows, pi);
if (error) goto QUIT;
error = GRBsetdblattrarray(model, GRB_DBL_ATTR_PSTART, 0, cols, x);
if (error) goto QUIT;
error = GRBsetdblattrarray(model, GRB_DBL_ATTR_DSTART, 0, rows, pi);
if (error) goto QUIT;
error = GRBsetintparam(menv, GRB_INT_PAR_CROSSOVER, 1);
if (error) goto QUIT;
error = GRBoptimize(model);
if (error) goto QUIT;
}
QUIT:
if (x != NULL)
free(x);
if (pi != NULL)
free(pi);1 -
Hello Tobias,
I was aware of this method however I'm using the Pyomo Python library which doesn't give me this much flexibility (unless I re-write the solver interface myself). Hence why it would be great to be able to do this through the solver parameters.
Best,
Martin
0 -
Uhh... I fear that in this case you are out of luck. I doubt that we will want to increase the complexity of our parameter settings and combinations (that we have to document and also to test) for a relatively obscure thing that one can already accomplish via our current API. But I will discuss it with the rest of the dev team.
Meanwhile, you could try to convince the Pyomo folks to add this feature to their library. Or that they create the solver interfaces in such a way that you could overwrite the solve method (rather than having to re-write the whole solver interface yourself).
Regards,
Tobias
0 -
Ok thank you Tobias!
0 -
Hi Tobias,
I was wondering if you could also post an equivalent formulation for the solution for the python API as I am not too familiar with C.Thank you in advance!Best,
Christian
0
Post is closed for comments.
Comments
6 comments