Decision Optimization

Decision Optimization

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


#Analytics
#DecisionOptimization
#DecisionOptimization
 View Only
  • 1.  Error: IloExtractable has not been extracted

    Posted 06/09/18 02:29 AM

    Originally posted by: NancyX


    Hi!

      I use concert technology to solve MIP. The model have been already build,but  when running, I do get the exception:"IloIntVarArray has not been extracted by The IloAlgorithm". someone said that this exception is thrown if  you try to use a variable that does not appear in any constraint or in the objective function. but I have been already check that variable  is appear in the objective,but it is error,so....


    #CPLEXOptimizers
    #DecisionOptimization


  • 2.  Re: Error: IloExtractable has not been extracted

    Posted 06/11/18 10:17 AM

    Did you already try calling IloModel.add() for each of the offending variables? Note that you have to do this before calling solve().


    #CPLEXOptimizers
    #DecisionOptimization


  • 3.  Re: Error: IloExtractable has not been extracted

    Posted 06/11/18 09:42 PM

    Originally posted by: NancyX


    Thank you for your Reply.  In fact,  I did not add each decision variable through IloModel.add(),But not to say that as long as these decision variables appear in the objective function or constrtaint ,OK?


    #CPLEXOptimizers
    #DecisionOptimization


  • 4.  Re: Error: IloExtractable has not been extracted

    Posted 06/12/18 02:41 AM

    Yes, it should work. But apparently it does not. That is why I asked you to explicit add() those variables. Just to double-check and make sure you did not forgot anything.

    Can you share your code?


    #CPLEXOptimizers
    #DecisionOptimization


  • 5.  Re: Error: IloExtractable has not been extracted

    Posted 06/12/18 09:19 PM

    Originally posted by: NancyX


    Thank you.Here is the code, do you have a look at this code for any problems?

     

    void CMyCplex::build_model(){
        int flight_nums = data.N1.size() + data.N2.size() + data.N3.size();
        
        typedef IloArray<IloIntVarArray> IntMatrix;
        typedef IloArray<IntMatrix> Decision_X;                                

        Decision_X X(env, flight_nums);                                          

        for(int i = 0; i < flight_nums; i++){                              
            X[i] = IntMatrix(env,data.M.size());                          
            for(int j = 0 ; j < data.M.size(); j++){                        
       
                int kk;
                vector<Deci>::iterator it;
                it = find_if(data.deci.begin(), data.deci.end(),findsNum(i*10+(j+1)));
                if(it != data.deci.end()){                                   
                    kk = it->k;
                    if(i == 0){
                        X[i][j] = IloIntVarArray(env, kk , 1, 1);            
                    }else{
                        X[i][j] = IloIntVarArray(env, kk , 0, 1);    
                    }
                }else{                                                       
                    X[i][j] = NULL;
                }
            }
        }
      
        for(int i = 0; i < data.SS.size(); i++){        
            if(data.SS[i].fol.size() == 0 || data.SS[i].flight_id == 0){
                continue;    
            }
            int f_id = data.SS[i].flight_id;                     
            for(int j = 0; j < data.M.size() ; j++){                
            
                int kk = 0;
                vector<Deci>::iterator it;
                it = find_if(data.deci.begin(), data.deci.end(),findsNum(f_id*10+(j+1)));
                if(it != data.deci.end()){                            //在data.deci中找到了该记录
                    kk = it->k;
                }else{                                                //该飞机不能执行该航班
                    continue;
                }
                for(int k = 0; k < kk; k++){                        //对于所考察的航班i来说的所有执行方案
                    IloIntExpr tmp_Expr1(env);
                    int num = f_id*100+(j+1)*10+k+1;
                    for(int l = 0; l < data.XX.size(); l++){                 //从衔接航班对中查找元素
                        int t_f_id = data.XX[l][0];
                        int t_s_id = data.XX[l][1];
                        if(num == t_f_id){
                            int b = t_s_id/100;                             //用于表示航班
                            int s;                                         //获取num十位上的数,表示飞机的 id
                            if(t_s_id > 100){
                                s = t_s_id/10%10 - 1;
                            }else{
                                s = t_s_id/10 - 1;  
                            }
                            int g = t_s_id % 10 -1 ;
                             tmp_Expr1 += X[b][s][g];
                        }
                    }
                    model.add(tmp_Expr1 == X[f_id][j][k]);
                    tmp_Expr1.end();
                }
            }
        }
        
        //添加约束条件二   ,每个航班至多只能被一架飞机执行
        for(int i = 1; i < data.F.size(); i++){
            if(data.F[i].size() == 0){
                continue;
            }
            IloIntExpr tmp_Expr2(env);
            for(int j = 0; j < data.F[i].size(); j++){ //每个航班的可执行方案
                int f_id; //航班id
                int p_id; //飞机id
                int k_id; //执行方案
                f_id = i;
                k_id = data.F[i][j]%10 - 1;
                if(data.F[i][j] >100){
                    p_id = data.F[i][j]/10%10 -1;
                }else{
                    p_id = data.F[i][j]/10 -1;
                }
                tmp_Expr2 += X[f_id][p_id][k_id];
            }
            model.add(tmp_Expr2 <= 1);
            tmp_Expr2.end();
        }
        
        //约束条件三
        for(int i = 0; i < data.N4.size(); i++){
            int str_id = data.N4[i][0];                    //联程拉直航班
            int fir_id = data.N4[i][1];                    //联程航班的第一个航班
            int sed_id = data.N4[i][2];                    //联程航班的第二个航班
            IloIntExpr tmp_Expr3(env);
            IloIntExpr tmp_Expr31(env);
            //根据sttr_id 获得联程航班的执行方案
            for(int j = 0; j < data.F[str_id].size(); j++){    //先获取联程拉直航班的执行方案
            //    cout<<data.F[str_id][j]<<endl;
                int f_id; //航班id
                int p_id; //飞机id
                int k_id; //执行方案
                f_id = str_id;
                k_id = data.F[str_id][j]%10 - 1;
                if(data.F[str_id][j] >100){
                    p_id = data.F[str_id][j]/10%10 -1;
                }else{
                    p_id = data.F[str_id][j]/10 - 1;
                }
                tmp_Expr3 += X[f_id][p_id][k_id];
            }
            for(int j = 0; j < data.F[fir_id].size(); j++){
                int f_id; //航班id
                int p_id; //飞机id
                int k_id; //执行方案
                f_id = fir_id;
                k_id = data.F[fir_id][j]%10 - 1;
                if(data.F[fir_id][j] >100){
                    p_id = data.F[fir_id][j]/10%10 -1;
                }else{
                    p_id = data.F[fir_id][j]/10 - 1;
                }
                tmp_Expr31 += X[f_id][p_id][k_id];
            }
            model.add(tmp_Expr3 <= (1 - tmp_Expr31));
            tmp_Expr3.end();
            tmp_Expr31.end();
        }
        
        //约束四
        for(int i = 0;  i < data.N6.size(); i++){
            int fir_id = data.N6[i][0]; //联程航班的第一个航班
            int sed_id = data.N6[i][1];
            for(int j = 0; j < data.M.size(); j++){
                IloIntExpr sub1_Expr4(env);
                IloIntExpr sub2_Expr4(env);
                 //通过i和j确定k的值
                int kk = 0;
                vector<Deci>::iterator it;
                int num = fir_id *10 + j+1;        //联程航班的第一个航班的执行方案对应的决策变量
                it = find_if(data.deci.begin(), data.deci.end(),findsNum(num));
                if(it != data.deci.end()){//在data.deci中找到了该记录
                    kk = it->k;
                }else{
                    continue;
                }
                for(int k = 0; k < kk; k++){
                    sub1_Expr4 += X[fir_id][j][k];
                }
                int kk2 = 0;
                int num2 = sed_id * 10 + j+1;
                vector<Deci>::iterator it2;
                it2 = find_if(data.deci.begin(), data.deci.end(),findsNum(num2));
                if(it2 != data.deci.end()){//在data.deci中找到了该记录
                    kk2 = it2->k;
                }else{
                    continue;
                }
                for(int k = 0; k < kk2; k++){
                    sub2_Expr4 += X[sed_id][j][k];
                }
                model.add(sub1_Expr4 >= sub2_Expr4);
                sub2_Expr4.end();
                sub1_Expr4.end();
            }    
        }
        //约束五
        for(int i = 0; i < data.N5.size(); i++){
            int dead_id = data.N5[i][0];    //调机航班
            int ff_id = data.N5[i][1];        //调机替换的航班
            IloIntExpr tmp_Expr5;
            IloIntExpr tmp_Expr51;
            //根据sttr_id 获得联程航班的执行方案
            for(int j = 0; j < data.F[dead_id].size(); j++){ //考察调机航班的执行情况
                int f_id; //航班id
                int p_id; //飞机id
                int k_id; //执行方案
                f_id = dead_id;
                k_id = data.F[f_id][j]%10 -1;
                if(data.F[f_id][j] < 100){
                    p_id = data.F[f_id][j]/10 -1;
                }else{
                    p_id = data.F[f_id][j]/10%10 -1;
                }
                tmp_Expr5 += X[f_id][p_id][k_id];
            }
            for(int j = 0; j < data.F[ff_id].size(); j++){
                int f_id; //航班id
                int p_id; //飞机id
                int k_id; //执行方案
                f_id = ff_id;
                k_id = data.F[f_id][j]%10;
                if(j == 0){
                    p_id = data.F[f_id][j]/10 - 1;
                }else{
                    p_id = data.F[f_id][j]/10%10 -1;
                }
                tmp_Expr51 += X[f_id][p_id][k_id];
            }
            model.add(tmp_Expr5 <= (1 - tmp_Expr51));
            tmp_Expr5.end();
            tmp_Expr51.end();
        }
        
        //约束六
        cout<<"约束六"<<endl;
        for(int j = 0; j < data.M.size(); j++){
            IloIntExpr tmp_Expr6(env);
            for(int t = 0; t < data.T[j].size(); t++){
                cout<<data.T[j][t]<<endl;
                int f_id ;                                    //航班id
                int p_id;                                    //飞机id
                int k_id;                                    //执行方案
                f_id = data.T[j][t] / 100;
                p_id = j;
                k_id = data.T[j][t]%10 - 1;
                tmp_Expr6 += X[f_id][p_id][k_id];
            }
            model.add(tmp_Expr6 == 1);
            tmp_Expr6.end();
            
        }
        cout<<"约束七"<<endl;
        ////约束七
        for(int i = 0; i < data.SS.size(); i++){
            if(data.SS[i].fol.size() == 0){
                int flight_id = data.SS[i].flight_id;                        //航班id
                IloIntExpr tmp_Expr7(env);
                for(int j = 0; j < data.F[flight_id].size(); j++){
                //    cout<<"航班"<<data.F[flight_id][j]<<"没有后继航班"<<endl;
                    int f_id;                                               //航班id
                    int p_id;                                               //飞机id
                    int k_id;                                               //执行方案
                    f_id = flight_id;
                    k_id = data.F[f_id][j]%10 -1;
                    if(data.F[f_id][j] <  100){
                        p_id = data.F[f_id][j]/10 - 1 ;
                    }else{
                        p_id = data.F[f_id][j]/10%10 - 1;
                    }
                    tmp_Expr7 += X[f_id][p_id][k_id];
                }
                model.add(tmp_Expr7 == 1);
                tmp_Expr7.end();
            }
        }

        cout<<"约束八"<<endl;
        //0号航班必须执行
        for(int i = 0; i < data.F[0].size(); i++){
            int num  = data.F[0][i];
            int b = num / 100;
            int s;
            if(num > 100){
                s = num /10%10 -1;
            }else{
                s = num/10 - 1;
            }
            int g = num%10 -1;
            model.add(X[b][s][g]);
        }

        
        //目标函数
        IloExpr expr(env);
        //获取目标函数中的第一部分
        for(int i = 0; i < flight_nums; i++){
            for(int j = 0; j < data.M.size(); j++){
                //通过i和j确定k的值
                int kk = 0;
                vector<Deci>::iterator it;
                it = find_if(data.deci.begin(), data.deci.end(),findsNum(i*10+(j+1)));
                if(it != data.deci.end()){//在data.deci中找到了该记录
                    kk = it->k;
                }else{
                    continue;
                }
                for(int k = 0; k < kk; k++ ){                                    //方案编号也是从0开始的
                    int cost = 0;
                    vector<Cost>::iterator ite;
                    ite = find_if(data.f_cost.begin(), data.f_cost.end(), finddCost(i*100+(j+1)*10+(k+1)));
                    if(ite != data.f_cost.end()){
                        cost = ite->cost;
                    }else{
                        continue;
                    }
                    cout<<i<<" , "<<j<<", "<<k<<endl;
                    expr += X[i][j][k] * cost;
                }
            }
        }
        cout<<"目标函数"<<endl;
        IloExpr expr2(env) ;
        for(int i = 1; i<data.N1.size(); i++){                        //此时刨除0号航班
            //获取F中航班i对应的执行方案
            vector<int> tmp_F = data.F[i];
            IloExpr tmp_expr(env);
            for(auto j : tmp_F){
                //tmp_expr中元素的每一位表示一个索引
                int b = j /100; //百位,表示航班编号
                int s;    //十位,表示飞机编号
                if(j > 100){
                    s = j /10 % 10 -1;
                }else{
                    s = j / 10 - 1;
                }
                int g = j % 10 - 1;   //个位,表示对应的执行方案
                tmp_expr += X[b][s][g];
            }
            expr2 +=( 1 - tmp_expr)* data.C[i];
        }
        IloExpr expr3(env) ;
        for(int i = 0; i < data.N4.size(); i++){
            vector<int> tmp = data.N4[i];
            int str = tmp[0];                            //联程拉直航班,相当于决策变量中的i
            int fir = tmp[1];                            //联程航班的第一个,相当于决策变量中的i'
            int sed = tmp[2];                            //联程航班的第二个,相当于决策变量中的i''
            for(int j = 0; j < data.M.size(); j++){
                //通过i和j确定k的值
                int kk = 0;
                int num = str* 10 + j+1;
                vector<Deci>::iterator it;
                it = find_if(data.deci.begin(), data.deci.end(),findsNum(num));
                if(it != data.deci.end()){//在data.deci中找到了该记录
                    kk = it->k;
                }else{
                    continue;
                }
                for(int k = 0; k <kk; k++){
                    expr3 += X[str][j][k] * (data.C[fir] + data.C[sed]);
                }
            }
        }

        IloExpr obj(env);
        obj = expr + expr2 + expr3;  //目标函数
        model.add(IloMinimize(env,obj));
        expr.end();
        expr2.end();
        expr3.end();
        obj.end();

        //求解模型
        vector<vector<int> >solutions(2);
        vector<vector<int> > routes(2); //飞机所执行路径集合
        vector<vector<double> > costs(2); //每个航班的执行成本
        
        cplex = IloCplex(model);
        /*cplex = IloCplex(env);
        cplex.extract(model);*/
        cplex.exportModel("flightRecovery.lp");
        cplex.setParam(IloCplex::TiLim, 600); //设置模型求解时间为10分钟
        std::cout<<"模型开始求解"<<endl;
        if(cplex.solve()){
            cplex.out()<<"Solution status: "<<cplex.getStatus()<<endl;
            cplex.out()<<"Total cost = "<<cplex.getObjValue()<<endl;
            //模型可解,生成飞机路线
            for(int j = 0; j < data.M.size(); j++){
                vector<int> r ;
                vector<double> c;
                int flight_nums = data.N1.size()+ data.N2.size() + data.N3.size();
                for(int i = 0; i < flight_nums; i++){  //从第一个航班开始考察
                    int kk = 0;
                    vector<Deci>::iterator it;
                    it = find_if(data.deci.begin(), data.deci.end(),findsNum(i*10+(j+1)));
                    if(it != data.deci.end()){
                        if((j+1) > X[i].getSize()){
                            continue;
                        }
                        for(int k = 0; k < X[i][j].getSize(); k++){
                            //cplex.out()<<cplex.getValue(X[i][j][k])<<endl;
                            if(cplex.getValue(X[i][j][k])){
                                r.push_back(i);
                                break;
                            }
                        }
                    }
                    
                }
                solutions.push_back(r);
            }    
            for(int i = 0; i < solutions.size(); i++){  //输出路径
                for(int j = 0; j <solutions[i].size(); j++){
                    std::cout<<solutions[i][j]<<"-->";
                }
                std::cout<<endl;
            }
        }else{
            cplex.out() <<"No Solution"<<endl;
            cplex.out() <<cplex.getStatus()<<endl;
        }
    }


    #CPLEXOptimizers
    #DecisionOptimization


  • 6.  Re: Error: IloExtractable has not been extracted

    Posted 06/13/18 02:16 AM

    I suggest to do the following:

    1. #include <sstream>

    2. After assigning X[i][j] assign names to variables like so

    std::stringstream s;
    s << "x(" << i << ")(" << j << ")";
    X[i][j].setNames(s.str().c_str());

    3. Wrap the code that queries solution values into a try-catch, catch the exception and dump the names of the offending extractables:

    try {
       // call getValue() here
       ...
    }
    catch (IloAlgorithm::NotExtractedException &e) {
       std::cerr << "Not extracted: " << e.getExtractable().getName() << std::endl
                 << e.getExtractable() << std::endl;
       throw;
    }

    4. Figure out where this variable was supposed to be used but was not.


    #CPLEXOptimizers
    #DecisionOptimization