Decision Optimization

Decision Optimization

Delivers prescriptive analytics capabilities and decision intelligence to improve decision-making.

 View Only
Expand all | Collapse all

how to access the node ID inside the generic callback

  • 1.  how to access the node ID inside the generic callback

    Posted Mon October 11, 2021 09:38 AM
    Hi,

    I'd like to get the node number of the B&B tree inside the method that implements IloCplex.Callback.Function. When I call context.getId(), it always returns either 32 or 64. So I believe that is not the function that I am looking for. Which method should I be using?

    ------------------------------
    S Y
    ------------------------------

    #DecisionOptimization


  • 2.  RE: how to access the node ID inside the generic callback

    Posted Mon October 11, 2021 12:33 PM
    getId() gets the context from which the callback was called. Try getInfo(), passing it NodeUID as the "which" argument.

    ------------------------------
    Paul Rubin
    Professor Emeritus
    Michigan State University
    ------------------------------



  • 3.  RE: how to access the node ID inside the generic callback

    Posted Mon October 11, 2021 08:57 PM
    Edited by System Admin Fri January 20, 2023 04:29 PM
    Thanks for your message. I went through the links below, but could not figure it out. It seems like there is no method called Info. There are getIntInfo, getDOubleInfo and getLongInfo methods defined in context. As an argument, I pass NodeUID inside either of these methods, however, it does not work. 

    https://www.ibm.com/docs/de/icos/12.10.0?topic=enums-ilocplexcallbackcontextinfo
    https://www.ibm.com/docs/en/icos/20.1.0?topic=namespace-cplexcallbackcontextinfo-enumeration
    https://www.ibm.com/docs/en/icos/20.1.0?topic=manual-cpxcallbackinfo
    https://www.ibm.com/docs/api/v1/content/SSSA5P_12.10.0/ilog.odms.cplex.help/refjavacplex/html/ilog/cplex/IloCplex.Callback.Context.Info.html#valueOf(java.lang.String)

    ------------------------------
    S Y
    ------------------------------



  • 4.  RE: how to access the node ID inside the generic callback

    Posted Mon October 11, 2021 09:52 PM
    Sorry, I meant to say you want the getLongInfo() method. The node ID will be type long. If it does not work, you should tell us what goes wrong (exception thrown, error message, ...) and show us the syntax you are using. Also, you did not specify in the question what API you are using.

    ------------------------------
    Paul Rubin
    Professor Emeritus
    Michigan State University
    ------------------------------



  • 5.  RE: how to access the node ID inside the generic callback

    Posted Mon October 11, 2021 10:18 PM
    Edited by System Admin Fri January 20, 2023 04:25 PM
    I am using i) JAVA API and ii) synchronized keyword to guarantee thread safety.

    I pass IloCplex.Callback.Context context inside the invoke method. In order to obtain the node ID, I call
    long my_ID= context.getLongInfo(IloCplex.Callback.Context.Info, NODEUID);


    ------------------------------
    S Y
    ------------------------------



  • 6.  RE: how to access the node ID inside the generic callback

    Posted Mon October 11, 2021 10:27 PM
    Hi, 

    What if I use context.getLongInfo(IloCplex.Callback.Context.Info.NodeCount);? Would that work for me? For instance, when it is zero, does that mean I am at the root node? Also, when I print that nodeCount inside the callback function, this is what I see in the log. Why is it visiting the same node tens of times? 

    Nodes Cuts/
    Node Left Objective IInf Best Integer Best Bound ItCnt Gap

    * 0+ 0 12.1439 48.0425 295.61%
    0
    0
    0
    0 0 30.4616 2 12.1439 30.4616 7 150.84%
    0
    0
    0
    0
    0 0 30.4616 6 12.1439 Cuts: 3 65 150.84%
    0
    0
    0

    ------------------------------
    S Y
    ------------------------------



  • 7.  RE: how to access the node ID inside the generic callback

    Posted Tue October 12, 2021 11:18 AM
    NodeCount won't work -- it gives the cumulative number of nodes processed, not the ID number of the current node.

    I think the correct syntax for the call would be

    long my_ID = context.getLongInfo(IloCplex.Callback.Context.Info.NodeUID);

    ------------------------------
    Paul Rubin
    Professor Emeritus
    Michigan State University
    ------------------------------



  • 8.  RE: how to access the node ID inside the generic callback

    Posted Tue October 12, 2021 11:37 AM
    Thanks for the suggestion, but it was indeed the first thing I tried. I am getting an error.

    NodeUID cannot be resolved or is not a field

    IloCplex.Callback.Context.Info. only has the following methods. 




    ------------------------------
    S Y
    ------------------------------



  • 9.  RE: how to access the node ID inside the generic callback
    Best Answer

    Posted Tue October 12, 2021 12:17 PM
    Are you using a new version of CPLEX or an old one?
    Some fields of the callback info were introduced only starting with 12.10.

    ------------------------------
    Vincent Beraudier
    ------------------------------



  • 10.  RE: how to access the node ID inside the generic callback

    Posted Tue October 12, 2021 12:33 PM
    Hi,

    I am using CPLEX 12.8. Should I update CPLEX? If so, could you share a link for the academic version?

    ------------------------------
    S Y
    ------------------------------



  • 11.  RE: how to access the node ID inside the generic callback

    Posted Wed October 13, 2021 04:13 AM
    Follow this link to the CPLEX info page in Academic Initiative:
    https://www.ibm.com/academic/topic/data-science?ach_id=6fe17098-43df-4a9d-8412-3377286841a3

    Click the Download link - it will lead you to the IBM Academic Initiative download link.
    Click "Search for software" on the left menu.
    In the "Find by search text" section, enter "CPLEX Optimization Studio 20.1" as the product name.
    Then click the search icon.

    ------------------------------
    Vincent Beraudier
    ------------------------------



  • 12.  RE: how to access the node ID inside the generic callback

    Posted Wed October 13, 2021 08:29 AM
    Edited by System Admin Fri January 20, 2023 04:15 PM
    When I call context.getLongInfo(IloCplex.Callback.Context.Info.NodeUID);

    I receive the following error and I am using the last version of CPLEX.

    Exception from callback: ilog.cplex.CpxException: CPLEX Error  1811: Attempt to invoke unsupported operation..
     
    Exception in thread "main" ilog.cplex.CpxException: CPLEX Error  1006: Error during callback.
     
    at ilog.cplex.CplexI.CALL(CplexI.java:5314)
    at ilog.cplex.CplexI.setStatus(CplexI.java:6816)
    at ilog.cplex.CplexI.access$600(CplexI.java:191)
    at ilog.cplex.CplexI$SolveHandle.stop(CplexI.java:3175)
    at ilog.cplex.CplexI.solve(CplexI.java:3225)
    at ilog.cplex.CplexI.solve(CplexI.java:3217)
    at ilog.cplex.IloCplex.solve(IloCplex.java:13291)

    #DecisionOptimization


  • 13.  RE: how to access the node ID inside the generic callback

    Posted Wed October 13, 2021 09:39 AM
    Edited by System Admin Fri January 20, 2023 04:09 PM
    Here is more information:

    System.out.println("print:" +IloCplex.Callback.Context.Info.NodeUID);
    try {
           long node_ID=  context.getLongInfo(IloCplex.Callback.Context.Info.NodeUID);
    }catch(Exception e) {
           System.out.println("Something went wrong.");
    }


    print:NodeUID
    Something went wrong.

    The way I attach the callback in the main method is;

    int numThreads = cplex.getNumCores();
    final myCallback cb = new myCallback(x,y,t, numThreads);
    long contextmask = IloCplex.Callback.Context.Id.Candidate
    | IloCplex.Callback.Context.Id.ThreadUp
    | IloCplex.Callback.Context.Id.ThreadDown;
    contextmask |= IloCplex.Callback.Context.Id.Relaxation;
    cplex.use(cb, contextmask);


    ------------------------------
    Ser Y
    ------------------------------



  • 14.  RE: how to access the node ID inside the generic callback

    Posted Wed October 13, 2021 10:36 AM
    Some info getters are available only in some contexts otherwise will raise errors.
    See https://www.ibm.com/docs/en/icos/20.1.0?topic=manual-cpxcallbackinfo

    So NodeUID can be queried only in Relaxation and Candidate, not ThreadUp and not in ThreadDown.

    Did you check the context with a
    if (context.inRelaxation() || context.inCandidate() )
    before calling NodeUID ?



    ------------------------------
    Vincent Beraudier
    ------------------------------



  • 15.  RE: how to access the node ID inside the generic callback

    Posted Wed October 13, 2021 10:53 AM
    Edited by System Admin Fri January 20, 2023 04:11 PM
    Okay, I was mistaken. The problem is not solved. It has nothing to do with the number of threads.

    I have tried what you suggested. 

    if (context.inRelaxation() || context.inCandidate() ) {
            try {
              context.getLongInfo(IloCplex.Callback.Context.Info.NodeUID);
            }catch(Exception e) {
                 System.err.println("Still not working");
            }

    Version identifier: 20.1.0.0 | 2020-11-10 | 9bedb6d68
    CPXPARAM_Emphasis_MIP 2
    CPXPARAM_MIP_Strategy_RINSHeur 500
    CPXPARAM_TimeLimit 1800
    Generic callback 0x66
    Lazy constraint(s) or lazy constraint/branch callback is present.
    Disabling dual reductions (CPX_PARAM_REDUCE) in presolve.
    Disabling presolve reductions that prevent crushing forms (CPX_PARAM_PREREFORM).
    Still not working
    Still not working
    Still not working

    ------------------------------
    Ser Y
    ------------------------------



  • 16.  RE: how to access the node ID inside the generic callback

    Posted Wed October 13, 2021 11:50 AM
    Edited by System Admin Fri January 20, 2023 04:22 PM
    If I call  context.getLongInfo(IloCplex.Callback.Context.Info.NodeCount);, it is perfectly working tho. 

    If nodeCount is zero, doesn't that tell me that I am at the root node?

    ------------------------------
    Ser Y
    ------------------------------