Skip to main content

Feature request: Crossover only if suboptimal

Ongoing

Comments

5 comments

  • Tobias Achterberg
    Gurobi Staff Gurobi Staff

    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
  • Martin Staadecker
    Gurobi-versary
    First Comment
    First Question

    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
  • Tobias Achterberg
    Gurobi Staff Gurobi Staff

    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
  • Martin Staadecker
    Gurobi-versary
    First Comment
    First Question

    Ok thank you Tobias!

    0
  • Christian Perau
    Curious
    Gurobi-versary
    Conversationalist

    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

Please sign in to leave a comment.