Topic
9 replies Latest Post - ‏2012-12-15T14:15:10Z by JDalal
JDalal
JDalal
50 Posts
ACCEPTED ANSWER

Pinned topic A question reg getRay()

‏2012-12-09T18:08:19Z |
I am using C++/CPLRX 12 to implement Benders decomposition. Got some issues in using getRay().
I have gone through posts related to getRay() by previous users in this forum. Those helped me to fix some first-time user issues like turning off pre-solve, using Primal as RootAlg etc.
I am trying to explain my issue with a very small example.

Now, in Benders, I solve an IP as master problem (MP), pass the binary vector Y to dual subproblem(DSP). The objective of DSP contains terms of Y vector, like : x[0]*y_MP[0] + x[1]*y_MP[1]+... where y_MP[i] are the values passed from MP. Obviously, many x[i] coefficients will be 0 in DSP. After invoking cplex.solve() when I try to use the following code, I get error due to array index getting out of bound :

{code}
IloNumVarArray vars(envSub);
IloNumArray vals(envSub);

cplex.getRay(vals, vars);

cout<<"see size==="<<vars.getSize()<<endl;

for (int i = 0; i < vars.getSize(); ++i)
cout << i << ", " << vals[i] << " [" << vars"<< std::endl;
{\code}

On a closer look, I found that as per model formulation I have total 200 variables. But, many of them have 0 coefficients and only 56 variables are there with nonzero coefficients in the model. But, vars.getSize() returns 200, not 56 what I expected. From earlier threads, I thought that getRay() returns sparse representation - eliminating zero coefficient variables.

Can someone please explain my mistake?
Updated on 2012-12-15T14:15:10Z at 2012-12-15T14:15:10Z by JDalal
  • SystemAdmin
    SystemAdmin
    7929 Posts
    ACCEPTED ANSWER

    Re: A question reg getRay()

    ‏2012-12-10T23:25:45Z  in response to JDalal
    The closing tag for code on the forum is the same as the opening tag -- the word 'code' in braces -- with no backslash.

    You are correct that getRay should return just nonzero terms. Is the code you listed complete (meaning that you declare vars and vals and do nothing with them other than to pass them to getRay)? Specifically, is it the case that neither vars nor vals contained 200 entries prior to the call to getRay?

    Paul
    • JDalal
      JDalal
      50 Posts
      ACCEPTED ANSWER

      Re: A question reg getRay()

      ‏2012-12-11T02:01:16Z  in response to SystemAdmin
      Thanks Paul, for responding.
      From several code snippets in this forum and also from a blog of yours related to Extreme ray, I thought it is the way of using getRay()! Yes, there is no other line in my code between the declaration of vars and vals and their use as parameter in getRay(). I assumed that after calling the vals and vars would be populated by the variable names and values as per the obtained ray. Have I missed something elementary?

      cplex.getRay(vals, vars); 
       
      IloNumVarArray vars(envSub);
      IloNumArray vals(envSub);
       
      cplex.getRay(vals, vars);   
       
      cout<<"see size==="<<vars.getSize()<<endl;
       
       for (int i = 0; i < vars.getSize(); ++i)
            cout << i << ", " << vals[i] << " [" << vars[i].getName() << "]"<< std::endl;
      
      Updated on 2014-03-24T22:44:08Z at 2014-03-24T22:44:08Z by iron-man
      • JDalal
        JDalal
        50 Posts
        ACCEPTED ANSWER

        Re: A question reg getRay()

        ‏2012-12-11T02:02:46Z  in response to JDalal
        Please ignore the 1st line of code snippet above : a copy/paste error!
      • SystemAdmin
        SystemAdmin
        7929 Posts
        ACCEPTED ANSWER

        Re: A question reg getRay()

        ‏2012-12-11T23:00:15Z  in response to JDalal
        Just to be clear, this prints out 200 for the array size and then proceeds to print 200 lines, where something like 144 of them have a zero for vals[i]?

        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)
        • JDalal
          JDalal
          50 Posts
          ACCEPTED ANSWER

          Re: A question reg getRay()

          ‏2012-12-12T01:48:54Z  in response to SystemAdmin
          Thanks Paul for your response.

          No. Actually, it prints 56 lines and then throws error at the beginning of 57th line : "56, "... (index i starts from 0) and then error msg window pops up! It looks like some error occurs while trying to access 57th element of the array.

          Now, with a specific instance that I created, I could trace that only 56 terms of the objective function of my Benders Dual Subproblem out of 200 are with nonzero coefficients. Others get simply eliminated as they have binaries y[j]'s and z[k]'s in their coefficients, with 0 values. So, I think at the first place, the getsize() should not have returned 200 !

          I understand it is complicated to try to explain by message. So, I am sending you the relevant code. I have added comments to make the code better readable. If you find time to take a look at it and point out any possible source of error, it would be very helpful.

          Thanks in advance for your time and help.
          • SystemAdmin
            SystemAdmin
            7929 Posts
            ACCEPTED ANSWER

            Re: A question reg getRay()

            ‏2012-12-13T16:08:18Z  in response to JDalal
            Where in your code are 'vars' and 'vals' initialized? I don't even see them declared anywhere. Should that be 'rayVal' and 'rayVar' instead?
            • JDalal
              JDalal
              50 Posts
              ACCEPTED ANSWER

              Re: A question reg getRay()

              ‏2012-12-13T17:44:29Z  in response to SystemAdmin
              Yes. I forgot to change the variable name correctly at all places before sending you the file. I just thought rayVal, rayVar would give better readability.
          • SystemAdmin
            SystemAdmin
            7929 Posts
            ACCEPTED ANSWER

            Re: A question reg getRay()

            ‏2012-12-15T01:15:08Z  in response to JDalal
            I don't see anything wrong with your code (other than the name mismatch about which Daniel asked), but then I'm no C++ programmer. If the error message you get when the loop index is 56 is either a null pointer exception or something about an empty handle, then I would say the getSize() method (which, rather oddly, is not documented at all that I can find in the CPLEX 12.5 manual!) is returning an incorrect value. Since getRay is supposed to return a sparse representation, it makes sense that entries with index above 55 would not exist.

            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)
            • JDalal
              JDalal
              50 Posts
              ACCEPTED ANSWER

              Re: A question reg getRay()

              ‏2012-12-15T14:15:10Z  in response to SystemAdmin
              Thanks for informing that my code is okay. I asked this question particularly for the odd behavior of getSize(). I think, I have to handle it differently - keeping a count of the number of terms in objective function.
              Thanks for your time.