Decision Optimization

Decision Optimization

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


#Analytics
#DecisionOptimization
#DecisionOptimization
 View Only
  • 1.  Segmentation Fault when calling cplex.getDual()

    Posted 09/12/15 11:23 PM

    Originally posted by: Iman_day


    I'm having some problem with CPLEX when I try to build my model iteratively by adding one column per iteration (think of a column generation procedure). My master problem takes the following form:

            x = IloNumVarArray2(env, Nc);
            for (int n = 0 ; n < Nc ; n++){
              x[n] = IloNumVarArray(env, Ns, -IloInfinity, IloInfinity, ILOFLOAT);
            }
            z = IloNumVarArray(env,0.0,1,ILOBOOL);
            model = IloModel(env);
            cplex=IloCplex(model);
            obj=IloMinimize(env);
    
            density_P=IloRangeArray(env);
            density_N=IloRangeArray(env);
            convexity=IloRange();
            char Name[100];
            
            for (int m = 0; m < Nt ; m++){
                    IloExpr  exp(env);
                    for (int n = 0; n < Nc ; n++){
                            for(int s = 0; s < Ns; s++){
                                    exp +=   AMNS[m][n][s] * x[n][s] * 1e7;
                            }            
                    }
                    model.add(exp <=  B_zero * (1 + tol)); 
                    exp.end();  
            }
    
            for (int m = 0; m < Nt ; m++){
                    IloExpr  exp(env);
                    for (int n = 0; n < Nc ; n++) {
                            for(int s = 0; s < Ns; s++){
                                    exp +=  AMNS[m][n][s] * x[n][s] * 1e7 ;
                            }           
                    }
                    model.add(- exp <= -  B_zero * (1 - tol)); 
                    exp.end();  
            }
                    
            convexity=IloRange(env,1,1,"convexity");
            model.add(convexity);
    
            for (int n = 0 ; n < Nc ; n++) {                 // J_s  sum_p  b_pns  z_p + x_ns >= 0
                 for (int s = 0; s < Ns ; s++){
                             IloExpr  exp(env);
                             exp += x[n][s]  ;
                             sprintf( Name, "density_P_%d_%d",n,s);
                             density_P.add(IloRange(env, 0, exp, IloInfinity, Name));
                             exp.end();  
                     }      
            }
            model.add(density_P);
        
            for (int n = 0 ; n < Nc ; n++) {                 // J_s  sum_p  b_pns  z_p - x_ns >= 0
                 for (int s = 0; s < Ns ; s++){
                             IloExpr  exp(env);
                             exp -= x[n][s]  ;
                             sprintf( Name, "density_N_%d_%d",n,s);
                             density_N.add(IloRange(env, 0, exp, IloInfinity, Name));
                             exp.end();  
                     }      
            }
            model.add(density_N);
            model.add(obj);
    

    In the first iteration, when I add my first column "z" and solve the master problem, I need to get the dual variable of my constraints. Here is the part of code that is supposed to return the duals of for instance "density_P" constraints:

       void ModelMP::GetDensity_P_dual(double** tab)
        {
            for (int n = 0; n < Nc ; n++){
                    for(int s = 0; s < Ns ; s++){
                            tab[n][s] = cplex.getDual(density_P[n * Ns + s]);
                    }
        }
    

    In my `main()` I call these function as follows:

     

    double convexityDual=0.0;                         
    double** density_P_dual;
    density_P_dual=new double* [Nc];                
    for (int i=0;i< Nc;i++)
      density_P_dual[i]=new double[Ns];
                    
    double** density_N_dual;
    density_N_dual=new double* [Nc];                
    for (int i=0;i< Nc;i++)
      density_N_dual[i]=new double[Ns];
    ModelMP* MP;
    MP = new ModelMP(IloEnv(), AMNS, CoilsR, CoilsZ, B_zero, tol, widths, cross_sections, CCD, Gamma);
                    
    double flag = -1;
    while(flag < 0){          
            MP->addColumn(newCol);
            MP->solve();
            MP->exportModel("model_MP.lp");          
            MP->GetDensity_P_dual(density_P_dual);
            MP->GetDensity_N_dual(density_N_dual);
            MP->GetConvexity_dual(convexityDual);
            ModelSP* SP;
            SP = new ModelSP(IloEnv(), density_P_dual, density_N_dual, convexityDual, CoilsR, CoilsZ, widths, cross_sections, CCD, Gamma);
            SP->solve();
            if(SP->getObjValue() < 0){
                 SP->getCol(newCol);
             }
             else{
                  flag = 1;
             }
             delete SP;
             }
    

    But, I get a segmentation fault, and based on GDB, the problem comes from the line that tries to get dual value:

     

    terminate called after throwing an instance of 'IloCplex::Exception'
        
        Program received signal SIGABRT, Aborted.
        0x0000003324632625 in raise () from /lib64/libc.so.6
        Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.149.el6_6.5.x86_64 libgcc-4.4.4-13.el6.x86_64 libstdc++-4.4.4-13.el6.x86_64
        (gdb) up
        #1  0x0000003324633e05 in abort () from /lib64/libc.so.6
        (gdb) 
        #2  0x00000033292beaad in __gnu_cxx::__verbose_terminate_handler() () from /usr/lib64/libstdc++.so.6
        (gdb) 
        #3  0x00000033292bcc36 in ?? () from /usr/lib64/libstdc++.so.6
        (gdb) 
        #4  0x00000033292bcc63 in std::terminate() () from /usr/lib64/libstdc++.so.6
        (gdb) 
        #5  0x00000033292bcd5e in __cxa_throw () from /usr/lib64/libstdc++.so.6
        (gdb) 
        #6  0x0000000000457ca1 in IloCplexI::cpxthrow(int) const ()
        (gdb) 
        #7  0x000000000046ad32 in IloCplexI::validatePi() const ()
        (gdb) 
        #8  0x000000000046b089 in IloCplexI::getDual(IloRangeI*) const ()
        (gdb) 
        #9  0x000000000045040f in IloCplex::getDual (this=0x124cd5b8, con=...)
            at /home/apps/Logiciels/IBM_ILOG/CPLEX_Studio12610/opl/include/ilcplex/ilocplex.h:78
        78   return (getImpl()->getDual(con.getImpl()));
        (gdb) 
        #10 0x000000000044eb9e in ModelMP::GetDensity_P_dual (this=0x124cd560, tab=0x123948a0) at ModelMP.cpp:243
        243                         tab[n][s] = cplex.getDual(density_P[n * Ns + s]);
    

     

    Could anyone help me by pointing out where the problem is coming from? Just in case, I also attached the model file.
    Many thanks in advance.


    #CPLEXOptimizers
    #DecisionOptimization


  • 2.  Re: Segmentation Fault when calling cplex.getDual()

    Posted 09/13/15 02:56 AM

    According to your gdb backtrace you don't get a segmentation fault. Instead your program is stopped due to an uncaught IloException. I suggest you analyze that exception, for example catch it and print its message. Getting an IloException at this point usually means you are trying to query a solution while there is none or trying to query solution information for a variable that was not extracted. The exception message should tell you the details.


    #CPLEXOptimizers
    #DecisionOptimization


  • 3.  Re: Segmentation Fault when calling cplex.getDual()

    Posted 09/13/15 06:48 AM

    Originally posted by: Iman_day


    Thanks a lot Daniel. I tried to catch the error and this is what I get: 

    Error: CPLEX Error  1017: Not available for mixed-integer programs.
    

    Is this what you meant? 


    #CPLEXOptimizers
    #DecisionOptimization


  • 4.  Re: Segmentation Fault when calling cplex.getDual()

    Posted 09/13/15 06:53 AM

    Aha, it looks like you solved a MIP and then attempt to query dual values for variables or constraints? Those values are not available for MIPs. You may want to consider IloCplex::solveFixed() to solve the LP resulting from fixing the MIP solution. After that you can query LP duals.


    #CPLEXOptimizers
    #DecisionOptimization


  • 5.  Re: Segmentation Fault when calling cplex.getDual()

    Posted 09/13/15 07:25 AM

    Originally posted by: Iman_day


    Thanks again! Yes, that's what I'm trying to do. As for using IloCplex::solveFixed(), I cannot seem to find any code example using it in a C++ code. Could you please point me to an existing example or give me some idea where and how I must use it. In the case of my code as described above, would it be something as simple as this:

    MP->solve();
    MP->solveFixed();
    MP->GetDensity_P_dual(density_P_dual);
    

    I'm a little bit confused as I did it this way, now I have no error but I get zero as for value of all my dual variables, something which is a bit bizarre. At this point I don't know if I should blame my way of coding or my model. 


    #CPLEXOptimizers
    #DecisionOptimization


  • 6.  Re: Segmentation Fault when calling cplex.getDual()

    Posted 09/14/15 01:51 AM

    Did you check the reference documentation of the function? From that I think it should be pretty clear that your code sample is the correct thing to do. It can be improved slightly by checking that solve() return true before calling solveFixed(). solveFixed() will throw an exception if there is no feasible solution to which values can be fixed.


    #CPLEXOptimizers
    #DecisionOptimization