Decision Optimization

 View Only
Expand all | Collapse all

Tagging children in a branch call back

  • 1.  Tagging children in a branch call back

    Posted Tue February 04, 2014 06:10 PM

    Originally posted by: AnahitaHz


    Hi! 

    I would like to attach some user_info to children of a node upon branching on it. I know this has been discussed in this link, yet it is not working for me. In the branch callback, I create a struct to hold the user_info (to simplify, say the objective of the parent node). I want to accept the vars, bounds, etc as CPLEX suggests but change the user info. Here is what I do:

    /* Create a struct to store objective */
       struct branchinfo{
          double obj;
       };
     
       struct branchinfo *branch_info = malloc(sizeof(*branch_info));
     
     
       /* Register the parent objective to the children */
       branch_info->obj = objval;

     

       printf("obj to tag children = %f \n", branch_info->obj);

     

        status = CPXbranchcallbackbranchasCPLEX (env, cbdata, wherefrom, 0, branch_info, &seqnum1);
          if (status) printf("failed to create left node\n");
     
          status = CPXbranchcallbackbranchasCPLEX (env, cbdata, wherefrom, 1, branch_info, &seqnum2);
          if (status) printf("failed to create right node\n");

     

       if ( status )  goto TERMINATE;
     
       *useraction_p = CPX_CALLBACK_SET;
     

    What happens with this piece of code is that CPLEX keeps creating left nodes until it a node has to be fathomed and a backtracking is needed to the parent node to create (or select?) the right child of the parent. At this point it says:  

    CPLEX Error  1200: Index is outside range of valid values.

    failed to create left node

    CPLEX Error  1200: Index is outside range of valid values.

    failed to create right node

     

    Not sure what is going wrong. Thank you!


    #CPLEXOptimizers
    #DecisionOptimization


  • 2.  Re: Tagging children in a branch call back

    Posted Wed February 05, 2014 02:36 AM

    I can see (at least) the following two problems in your code:

    1. You always create two nodes. What if CPLEX would create only one or even no node? In this case you will get the "index out of range" error. The number of nodes that CPLEX would create is passed to the callback in the nodecnt argument (see the description here). So you must only attempt to create a left child if nodecnt>0 and only attempt to create a right child if nodecnt>1.
    2. You are passing the same instance of branchinfo to the left and the right child. This is likely to create trouble in the long run, for example, it will be hard to decide when to free() that data. The user object created in a branch callback is usually freed in a delete callback when the node is deleted but you cannot tell if the sibling of that node is still active, so you cannot tell whether it is fine to delete the user object or not. So I suggest you do a separate malloc for the left and right children.

    #CPLEXOptimizers
    #DecisionOptimization