Topic
11 replies Latest Post - ‏2013-01-02T08:50:45Z by SystemAdmin
SystemAdmin
SystemAdmin
7929 Posts
ACCEPTED ANSWER

Pinned topic Impossible to access to the LP solution value in a CallBack

‏2012-12-10T16:22:57Z |
Dear All,

I just start with the Callbacks so, I surely did wrong things... let me just introduce what I would like to do.

I want, at each node, to solve the LP, next retrieve some information from the LP solution (for instance the reduced costs and the Driebeeck penalties) to fix some variables. Each time variables are fixed, I want again to do that process: solve the LP, try to fix variables...

I used Callback and more precisely I wrote the following code :

ILOSOLVECALLBACK1(UserSolve, IloNumVarArray, vars) {

// We implement preprocessing here

unsigned int uiBoucle, uiCompteur;
double dUB, LBpls;
FILE *ficpc;
IloNum res;

ficpc=fopen("FixVarNodes.txt","at");
printf("Trying to get the UB\n");
try{
dUB=getIncumbentObjValue();
}
catch(...)
{ dUB=uiUB;}

printf("I get the UB\n");

uiCompteur = 0;
while (uiCompteur==0)
{
uiCompteur = 0;
printf("Solving the LP\n");
if (!solve(IloCplex::Primal))
{
printf("LP Unsuccessfull solved\n");
}
if ( getStatus() != IloAlgorithm::Optimal ) printf("Solver has not solved to optimality\n");
printf("The LP is solved\n");
try{
res=cplex.getObjValue(); //We need to consider the real valued LB for fixing the variables
LBpls=(double)res;
}
catch(...)
{printf("I cannot retrieve the LB\n");
printf("res=%lf\n",res);
LBpls=0;}
//We fix for variables xij
//printf("We enter the loop\n");

for (uiBoucle=0;uiBoucle<vars.getSize();uiBoucle++)
{
//printf("We test upper costs\n");
if ((double)getUpPseudoCost(varsuiBoucle)>dUB-LBpls+sensibility)
{ // I fix it to 0 since it cannot be fixed to 1
varsuiBoucle.setUB(0);
uiCompteur++;
printf("\t ONe fix\n");
}
//printf("We test lower costs\n");
if ((double)getDownPseudoCost(varsuiBoucle)>dUB-LBpls+sensibility)
{ // I fix it to 0 since it cannot be fixed to 1
varsuiBoucle.setLB(1);
uiCompteur++;
printf("\t ONe fix\n"); }
}
if (uiCompteur!=0) fprintf(ficpc,"~~~ %d variables fixed \n",uiCompteur);
else fprintf(ficpc,"No var fix\n");
}

if ( getStatus() == IloAlgorithm::Optimal ) useSolution();
fclose(ficpc);
}

Unfortunately, each time I want to access to the LP solution value thanks to getObjValue() I have an exception from the solver and, then, I cannot get that value.

Where am I wrong?

NB: I also try Cut Callback, Branch Callback, and I always have the same problem.
NB: I have seen how to retrieve the reduced costs and Driebeeck penalties, so to test my general procedure I used the up and down pseudo costs... which may result in a wrong exact algorithm, but for the moment I don't care.

Thank you for your help...
Vincent
Updated on 2013-01-02T08:50:45Z at 2013-01-02T08:50:45Z by SystemAdmin
  • SystemAdmin
    SystemAdmin
    7929 Posts
    ACCEPTED ANSWER

    Re: Impossible to access to the LP solution value in a CallBack

    ‏2012-12-11T13:03:17Z  in response to SystemAdmin
    In order to access the objective function value of the relaxation at the current node you must invoke the callback's getObjValue() function (see here). Using 'cplex.getObjValue()' in your callback is wrong.
    So replacing 'cplex.getObjValue()' by 'getObjValue()' should rid you of the exception.
    • SystemAdmin
      SystemAdmin
      7929 Posts
      ACCEPTED ANSWER

      Re: Impossible to access to the LP solution value in a CallBack

      ‏2012-12-11T13:11:03Z  in response to SystemAdmin
      Thank you, I will look at your example. However, even when I used getObjValue() I get an exception.....

      How can I retrieve the reduced cost and Driebeeck penalties in my callback?
      • SystemAdmin
        SystemAdmin
        7929 Posts
        ACCEPTED ANSWER

        Re: Impossible to access to the LP solution value in a CallBack

        ‏2012-12-11T13:17:11Z  in response to SystemAdmin
        You send me to the documentation, which I already read. I am stuck with that problem which I don't understand since the call to getObjValue() should have worked.

        Besides, there is one thing that I don't understand with the callback.
        As far as I understand, the declaration of one parameter in the macro (my IlNumVarArray parameter) implies that when my callback is running, this parameter refers to the array of variables in the Cplex model. How is it made? For instance, if I set a binary variable to 1 (or 0) in that array does it mean that in all child nodes of the current node (on which the callback is running) that variable will remain equal to 1 (or 0)?
        • SystemAdmin
          SystemAdmin
          7929 Posts
          ACCEPTED ANSWER

          Re: Impossible to access to the LP solution value in a CallBack

          ‏2012-12-11T13:40:19Z  in response to SystemAdmin
          > You send me to the documentation, which I already read. I am stuck with that problem which I don't understand since the call to getObjValue() should have worked.
          >
          Can you please provide more details about your problem? For example, what exactly is the exception and the exception message you get when you invoke getObjValue()?

          > Besides, there is one thing that I don't understand with the callback.
          > As far as I understand, the declaration of one parameter in the macro (my IlNumVarArray parameter) implies that when my callback is running, this parameter refers to the array of variables in the Cplex model. How is it made? For instance, if I set a binary variable to 1 (or 0) in that array does it mean that in all child nodes of the current node (on which the callback is running) that variable will remain equal to 1 (or 0)?
          >
          There is no such connection between the arguments to the callback and the IloCplex instance. Changing the bound of a variable while a solve is running will not affect the solve and will in fact result in undefined behavior. You must not change the model that is being optimized while it is optimized. The only valid changes are those that can be done using the API provided by the callbacks.
          • SystemAdmin
            SystemAdmin
            7929 Posts
            ACCEPTED ANSWER

            Re: Impossible to access to the LP solution value in a CallBack

            ‏2012-12-11T15:06:02Z  in response to SystemAdmin
            How can I get the exception? I just put the following catch:
            catch(...)
            {
            printf("I cannot retrieve the LB\n");
            printf("res=%lf\n",res);
            LBpls=0;
            }

            I am afraid to understand what you mean in the last part of your answer: when solving a MIP, I cannot change the bounds for some free variables at given node of the search tree. Is it right? And, what about adding a cut like x[j]=0 if I want to set this variable to 0? It should remain in the child node of the one in which I added the cut to the model, no ?
            • SystemAdmin
              SystemAdmin
              7929 Posts
              ACCEPTED ANSWER

              Re: Impossible to access to the LP solution value in a CallBack

              ‏2012-12-11T16:11:27Z  in response to SystemAdmin
              > How can I get the exception? I just put the following catch:
              > catch(...)
              > {
              > printf("I cannot retrieve the LB\n");
              > printf("res=%lf\n",res);
              > LBpls=0;
              > }
              >
              You need to add a more specific 'catch' statement:
              
              
              
              try 
              { ... 
              } 
              
              catch (IloException& e) 
              { printf (
              "IloException: %s\n", e.getMessage()); LBlps = 0; 
              } 
              
              catch (...) 
              { 
              // Your old code here. 
              }
              

              > I am afraid to understand what you mean in the last part of your answer: when solving a MIP, I cannot change the bounds for some free variables at given node of the search tree. Is it right? And, what about adding a cut like x[j]=0 if I want to set this variable to 0? It should remain in the child node of the one in which I added the cut to the model, no ?
              >
              If you want to fix a variable to a certain value in a subtree rooted at a particular node then there are two ways to do that:
              1. Use a branch callback and fix the variable in each branch you create.
              2. Use a user cut/lazy constraint callback and add a local cut that performs the fixing (like you suggested).
              You can also use a user cut/lazy constraint callback and inject a global cut. But if you do that then the variable will be fixed in all nodes.
              • SystemAdmin
                SystemAdmin
                7929 Posts
                ACCEPTED ANSWER

                Re: Impossible to access to the LP solution value in a CallBack

                ‏2012-12-11T16:26:09Z  in response to SystemAdmin
                The returned exception is :
                Cplex error 1003: Bad argument to Callable Library function.
                • SystemAdmin
                  SystemAdmin
                  7929 Posts
                  ACCEPTED ANSWER

                  Re: Impossible to access to the LP solution value in a CallBack

                  ‏2012-12-12T11:50:06Z  in response to SystemAdmin
                  I have not mentionned it, but I work with Cplex 12.2.

                  NB: I get the same exception when invoking getIncumbentSolution() at the beginning of my callback.

                  Thank you for your help
                  • SystemAdmin
                    SystemAdmin
                    7929 Posts
                    ACCEPTED ANSWER

                    Re: Impossible to access to the LP solution value in a CallBack

                    ‏2012-12-14T16:42:37Z  in response to SystemAdmin
                    Did you had time to look at my problem?
                    • SystemAdmin
                      SystemAdmin
                      7929 Posts
                      ACCEPTED ANSWER

                      Re: Impossible to access to the LP solution value in a CallBack

                      ‏2013-01-02T08:50:45Z  in response to SystemAdmin
                      Yes, and unfortunately, there are bad news: getObjValue() cannot be used in a solve callback. That is considered a bug and will be fixed in the next fixpack.
                      The only workaround I see at the moment is to query the objective function value of the current node in a subsequent callback, for example a user cut callback and perform the action that depends on the objective function value in this callback.
                • SystemAdmin
                  SystemAdmin
                  7929 Posts
                  ACCEPTED ANSWER

                  Re: Impossible to access to the LP solution value in a CallBack

                  ‏2012-12-15T01:42:09Z  in response to SystemAdmin
                  Does changing solve(IloCplex::Primal) to solve(IloCplex::Algorithm::Primal) fix it?

                  Paul

                  Mathematicians are like Frenchmen: whenever you say something to them, they translate it into their own language, and at once it is something entirely different. (Goethe)