Decision Optimization

Decision Optimization

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


#Analytics
#DecisionOptimization
#DecisionOptimization
 View Only
  • 1.  IloIfThen and memory error - (Crew Recovery Scheduling problem)

    Posted 08/12/12 07:07 AM

    Originally posted by: Dmartinc


    Hi all,

    I am having some issues trying to model a certain situation in a crew scheduling problem, which tries to represent the changes from a given initial roster to a new recovery roster, minimizing the changing costs. Therefore, I am using an IloIntArray Tasks_initial(env, NTasks), which keeps the initial roster, being -1 not assigned employee, 0 employee 1 assigned, and so on until MEmployees, and a decision variable IloIntVarArray Tasks(env, NTasks, 1, MEmployees). In order to illustrate the logic of the recovery, here there is an example:

    Tasks_initial -1,-1, 2,-1,-1, 5,-1,-1
    Tasks 2, 3, 6, 7, 8, 5, 1, 0

    So, if Tasks_initial[j] != Tasks[j], there is a change that should be counted, otherwise Tasks remains assigned to the same employee as in the initial roster. Therefore, I am trying to use an IloIfThen command within the objective function, which gives an error: error C2665: 'IloIfThen::IloIfThen' : none of the 4 overloads could convert all the argument types.

    How could it be modeled this situation?

    
    
    //Objective function IloNumArray c2(env, MEmployees*NTasks); 
    
    for (i=0; i<MEmployees; ++i) 
    
    for (j=0; j<NTasks; ++j) c2[i*NTasks+j] = c[i][j];   IloExpr Obj_Func_1(env); 
    
    for (j = 0; j < NTasks; j++) 
    { Obj_Func_1 += IloIfThen(env, Tasks[j]!=Tasks_initial[j] && Tasks_initial[j]!=-1 , c2[Tasks[j]*NTasks+j]+c2[Tasks_initial[j]*NTasks+j]) ; 
    } IloObjective obj1 = IloMinimize(env, Obj_Func_1); Obj_Func_1.end();
    


    Another issue that I am encountering in my model is that I get this message error (not enough memory) when I am building the following constraint:

    
    
    //Minimum experience level over certain group of tasks IloNumArray exp2(env, MEmployees*NTasks); 
    
    for (i=0; i<MEmployees; ++i) 
    
    for (j=0; j<NTasks; ++j) exp2[i*NTasks+j] = exp[i][j]; 
    
    for(k=0;k<KProjects;++k) 
    { IloExpr Experience(env); 
    
    for(j=0; j< NTasks; ++j) 
    { Experience += Projects[k][j]*exp2[Tasks[j]*NTasks+j]; 
    } model.add(Experience >= Min_experience[k]); Experience.end(); 
    } cout << 
    " *Project experiences - checked"<<endl;
    


    Is there a bug or something? Because my model works properly for small instances, this happens when the number of tasks and projects to schedule reach 200 and 40 respectively.
    Please find my whole model and the dataset of instance where I encounter the error. I really appreciate if someone could answer my questions. Thanks in advance.

    David

    
    #include <ilcp/cp.h> using namespace std;   ILOSTLBEGIN   typedef IloArray<IloNumArray>     NumMatrix;                
    //Coeffiecients matrix typedef IloArray<IloBoolArray>    BoolMatrix;                         
    //Boolean coefficients matrix typedef IloArray<IloIntVarArray>  VarMatrix;                         
    //Integer Decision variable matrix typedef IloArray<IloBoolVarArray> BoolVarMatrix;                        
    //Boolean Decision variable matrix      
    
    int main(int, 
    
    const 
    
    char * []) 
    { IloEnv env; 
    
    try 
    { IloModel model(env); IloInt i, j, t, f, g, k; IloInt MEmployees, NTasks, KProjects; IloInt p, alpha = 0, beta = 1, constraint_required = 0; IloInt min_rest = 14, Rest_number=0; IloIntVar b;   ifstream file(
    "Normal Instances/Inst_50_10_(0.5-0.2-0.5-0.5)_14.csv"); file >> t; file.get(); cout << 
    "Time:" << t << endl; file >> NTasks; file.get(); cout << 
    "Number of tasks:" << NTasks << endl; file >> KProjects; file.get(); cout << 
    "Number of Projects:" << KProjects << endl; file >> MEmployees; file.get(); cout << 
    "Number of Employees:" << MEmployees << endl;   p=t/7;   IloNumArray T(env, p+1); 
    
    for(g=1; g<=p;g++) 
    { T[g] = T[g-1] + 7; 
    } 
    
    for(j=1; j<p-1; j++) 
    { 
    
    if(T[j]<t-min_rest+1) 
    { Rest_number = Rest_number + 1; 
    } 
    }   
    //Decision variables domain IloIntVarArray Tasks(env, NTasks, 0, MEmployees-1);  
    //Tasks decision 
    
    for(j=0; j<NTasks;++j) 
    { stringstream nn; nn << 
    "Task(" << j+1 << 
    ")"; Tasks[j].setName(nn.str().c_str()); 
    }   BoolVarMatrix y(env, MEmployees);                                
    //Decision variable related to change y[i][j] of Size MEmployees x NTasks  
    
    for(i = 0; i < MEmployees; i++) 
    { y[i] = IloBoolVarArray(env, NTasks); 
    
    for(j=0; j<NTasks;++j) 
    { stringstream nn; nn << 
    "y(" << i+1 << 
    " " <<j+1 << 
    ")"; y[i][j].setName(nn.str().c_str()); 
    } 
    } IloIntVarArray o(env, MEmployees-1, 0, t/2);                                
    //o[i] Overpaid decision variables 
    
    for(j=0; j<MEmployees-1;++j) 
    { stringstream nn; nn << 
    "o(" << j+1 << 
    ")"; o[j].setName(nn.str().c_str()); 
    } IloIntVarArray u(env, MEmployees-1, 0, t/8);                                
    //u[i] Underpaid decision variables 
    
    for(j=0; j<MEmployees-1;++j) 
    { stringstream nn; nn << 
    "u(" << j+1 << 
    ")"; u[j].setName(nn.str().c_str()); 
    }   
    //Coefficients BoolMatrix x(env, MEmployees);                                   
    //eligebility matrix e[i][j] of Size MEmployees x NTasks  
    
    for(i = 0; i < MEmployees; i++) 
    { x[i] = IloBoolArray(env, NTasks); 
    } BoolMatrix e(env, MEmployees);                             
    //eligebility matrix e[i][j] of Size MEmployees x NTasks  
    
    for(i = 0; i < MEmployees; i++) 
    { e[i] = IloBoolArray(env, NTasks); 
    } NumMatrix c(env, MEmployees);                                           
    //c[i][j]Cost coefficients 
    
    for(i = 0; i < MEmployees; i++) 
    { c[i] = IloNumArray(env, NTasks); 
    } IloNumArray s(env,NTasks);                                         
    //s[i] start time of task i IloNumArray d(env,NTasks);                                           
    //d[i] duration time of task i BoolMatrix Projects(env,KProjects);                               
    //Projects in which is required an evaluation of the experience of Employee i in task j 
    
    for(i = 0; i < KProjects; i++) 
    { Projects[i] = IloBoolArray(env, NTasks); 
    } NumMatrix exp(env, MEmployees);                                                
    //e[i][j] Experience of Employee i in task j  
    
    for(i = 0; i < MEmployees; i++) 
    { exp[i] = IloNumArray(env, NTasks); 
    } IloNumArray Min_experience(env,KProjects);        
    //Min Experience required for project k IloNumArray G(env, MEmployees-1);                                    
    //g[i] Employees i with guaranteed days in his/her contract IloNumArray W_bar(env, MEmployees-1);                                
    //W_bar[i] Expected work time for employee i IloNumArray nu(env,MEmployees-1);                                   
    //Underpaid rate IloNumArray phi(env, MEmployees-1);                         
    //Overpaid rate IloNumArray omega(env, MEmployees-1);                            
    //Overpaid rate IloBoolArray C(env, NTasks+Rest_number);                     
    //Set of overlapping and sequencing constraints   
    //-----------------------------------------------Initilization--------------------------------------------------     
    
    for (j=0;j<NTasks;j++) 
    { file >> s[j]; file.get(); 
    } 
    //cout << "Tasks start time:" << s << endl;   
    
    for (j=0;j<NTasks;j++) 
    { file >> d[j]; file.get(); 
    } 
    //cout << "Tasks duration:" << d << endl; 
    
    for (i=0;i<MEmployees;i++) 
    { 
    
    for(
    
    int j=0;j<NTasks;j++) 
    { file >> e[i][j]; file.get(); 
    } 
    } 
    //cout << "Employees´ Eligibility:" << e << endl << endl;   
    
    for (i=0;i<MEmployees;i++) 
    { 
    
    for(
    
    int j=0;j<NTasks;j++) 
    { file >> x[i][j]; file.get(); 
    } 
    } 
    //cout << "Previous Roster:" << endl<< x << endl << endl;   
    
    for (i=0;i<MEmployees;i++) 
    { 
    
    for(
    
    int j=0;j<NTasks;j++) 
    { file >> c[i][j]; file.get(); 
    } 
    } 
    //cout << "Scheduling costs:" << c << endl << endl;   
    
    for (j=0;j<MEmployees-1;j++) 
    { file >> nu[j]; file.get(); 
    } 
    //cout << "Underpaid rate:" << endl<< nu << endl;   
    
    for (j=0;j<MEmployees-1;j++) 
    { file >> phi[j]; file.get(); 
    } 
    //cout << "Overpaid rate:" << endl<< phi << endl <<endl;   
    
    for (j=0;j<MEmployees-1;j++) 
    { file >> omega[j]; file.get(); 
    } 
    //cout << "Current excess:" << endl<< omega << endl <<endl;   
    
    for (j=0;j<MEmployees-1;j++) 
    { file >> G[j]; file.get(); 
    } 
    //cout << "Guaranteed days:" << endl<< G << endl;   
    
    for (j=0;j<MEmployees-1;j++) 
    { file >> W_bar[j]; file.get(); 
    } 
    //cout << "Expected work time:" << endl<< W_bar << endl;   
    
    for (j=0;j<KProjects;j++) 
    { 
    
    for(k=0;k<NTasks;k++) 
    { file >> Projects[j][k]; file.get(); 
    } 
    } 
    //cout << "Projects:" << Projects << endl;   
    
    for (i=0;i<MEmployees;i++) 
    { 
    
    for(
    
    int j=0;j<NTasks;j++) 
    { file >> exp[i][j]; file.get(); 
    } 
    } 
    //cout << "Experience matrix:" << exp << endl << endl;         
    
    for (j=0;j<KProjects;j++) 
    { file >> Min_experience[j]; file.get(); 
    } cout << 
    "Minimum experience:" << Min_experience << endl <<endl;   IloIntArray Tasks_initial(env, NTasks); 
    
    for(j=0; j<NTasks; j++) 
    { Tasks_initial[j]= -1; 
    }   
    
    for(j=0; j<NTasks; j++) 
    { 
    
    for(i = 0; i < MEmployees; i++) 
    { 
    
    if(x[i][j]==1) 
    { Tasks_initial[j]=i; 
    } 
    } 
    }     
    /* ------------------------------------------------------MODEL------------------------------------------------------------. */ 
    //Elegibility         IloNumArray e2(env, MEmployees*NTasks); 
    
    for (i=0; i<MEmployees; ++i) 
    
    for (j=0; j<NTasks; ++j) e2[i*NTasks+j] = e[i][j];   IloExpr expr(env); 
    
    for(j=0; j< NTasks; ++j) 
    { expr = e2[Tasks[j]*NTasks+j]; model.add(expr==1); expr.end(); 
    } cout << 
    " *Eligibility - checked"<<endl; 
    //Minimum experience level over certain group of tasks IloNumArray exp2(env, MEmployees*NTasks); 
    
    for (i=0; i<MEmployees; ++i) 
    
    for (j=0; j<NTasks; ++j) exp2[i*NTasks+j] = exp[i][j]; 
    
    for(k=0;k<KProjects;++k) 
    { IloExpr Experience(env); 
    
    for(j=0; j< NTasks; ++j) 
    { Experience += Projects[k][j]*exp2[Tasks[j]*NTasks+j]; 
    } model.add(Experience >= Min_experience[k]); Experience.end(); 
    } cout << 
    " *Project experiences - checked"<<endl;   
    //Emplpoyees cannot be assigned to overlaping tasks IloInt Sum=0; 
    
    while(alpha < p)   
    //Algorithm to produce constraints preventing employees being allocated overlapping tasks 
    { 
    
    for(j=0; j<NTasks;j++) 
    { 
    
    if(T[alpha]==s[j]+d[j]) 
    { 
    
    if(constraint_required == 1) 
    { IloIntVarArray Overlapped_Tasks(env, Sum); g=0; 
    
    for(i = 0; i < NTasks; i++) 
    { 
    
    if((C[i]==1)&&(g<Sum)) 
    { Overlapped_Tasks[g]=Tasks[i]; g++; 
    } 
    } model.add(IloAllDiff(env, Overlapped_Tasks)); beta = beta + 1; constraint_required = 0; Sum=0; 
    } C[j]=0; 
    } 
    } 
    
    for(j=0; j<NTasks;j++) 
    { 
    
    if(T[alpha]==s[j]) 
    { constraint_required = 1; C[j]=1; 
    } 
    } 
    //cout <<" Constraint set("<< beta <<"):"<< C << endl <<endl;;     
    
    for(j=0; j<NTasks;j++) 
    { 
    
    if(C[j]==1) Sum++; 
    } alpha = alpha + 1; 
    }   cout << 
    " *Overlapped tasks - checked"<<endl; 
    //Employees cannot be assigned to sequence tasks alpha=0; beta=1; constraint_required = 0; Sum=0; 
    
    for(i=0; i<NTasks; i++) 
    { C[i]=0; 
    } 
    
    while(alpha < p-1)   
    //Algorithm to produce constraints preventing employees being allocated sequencing tasks 
    { 
    
    for(j=0; j<NTasks;j++) 
    { 
    
    if(T[alpha]==s[j]+d[j]) 
    { 
    
    if(constraint_required == 1) 
    { IloIntVarArray Sequenced_Tasks(env, Sum); g=0; 
    
    for(i = 0; i < NTasks; i++) 
    { 
    
    if((C[i]==1)&&(g<Sum)) 
    { Sequenced_Tasks[g]=Tasks[i]; g++; 
    } 
    } model.add(IloAllDiff(env, Sequenced_Tasks)); beta = beta + 1; constraint_required = 0; Sum=0; 
    } C[j]=0; 
    
    for(i=0; i<NTasks;i++) 
    { 
    
    if(T[alpha]==s[i]) 
    { C[i]=0; 
    } 
    
    if(T[alpha+1]==s[i]) 
    { C[i]=0; 
    } 
    } 
    } 
    } 
    
    for(i=0; i<NTasks-1;i++) 
    { 
    
    if(T[alpha+1]==s[i]+d[i]) 
    { 
    
    for(j=0; j<NTasks;j++) 
    { 
    
    for(g=0; g<NTasks;g++) 
    { 
    
    if((T[alpha+1]==s[i]+d[i])&&(T[alpha+1]==s[j])&&(T[alpha+2]==s[g])) 
    { constraint_required = 1; C[j]=1;     
    //s[]  C[i]=1;     
    //s[]+d[] C[g]=1;     
    //s[] before 14 days 
    } 
    } 
    
    if(T[alpha+1]==t-7) 
    { 
    
    if((T[alpha+1]==s[i]+d[i])&&(T[alpha+1]==s[j])) 
    { constraint_required = 1; C[j]=1;     
    //s[]  C[i]=1;     
    //s[]+d[]                                                           
    } 
    } 
    } 
    } 
    } 
    
    for(j=0; j<NTasks;j++) 
    { 
    
    if(C[j]==1) Sum++; 
    } 
    //cout <<" Constraint set("<< beta <<"):"<< C << endl <<endl;                alpha = alpha + 1; 
    } cout << 
    " *Sequenced tasks - checked"<<endl;   IloBoolVarArray Tasks2(env, MEmployees*NTasks); 
    
    for(j=0; j<NTasks; j++) 
    { model.add(Tasks2[Tasks[j]*NTasks+j]==1); 
    } BoolVarMatrix Tasks3(env, MEmployees);                               
    //Tasks matrix z[i][j] of Size MEmployees x NTasks  
    
    for(i = 0; i < MEmployees; i++) 
    { Tasks3[i] = IloBoolVarArray(env, NTasks); 
    }   
    
    for (i=0; i<MEmployees; ++i) 
    
    for (j=0; j<NTasks; ++j) Tasks3[i][j]=Tasks2[i*NTasks+j];   
    //Calculation of any undertime payments 
    
    for(i=0; i<MEmployees-1; i++) 
    { IloExpr Sum(env); 
    
    for(j=0; j<NTasks; j++) 
    { Sum += d[j]*Tasks2[i*NTasks+j]; 
    } 
    
    if(G[i]!=0) 
    { model.add(u[i]>= G[i]-(W_bar[i]+ Sum)); Sum.end(); 
    } 
    }   
    //Calculation of any overtime payments 
    
    for(i=0; i<MEmployees-1; i++) 
    { IloExpr Sum(env); 
    
    for(j=0; j<NTasks; j++) 
    { Sum += d[j]*Tasks2[i*NTasks+j]; 
    } 
    
    if(G[i]!=0) 
    { model.add(o[i]>= (W_bar[i]+ Sum)-G[i]); Sum.end(); 
    } 
    } 
    
    for(i=0;i<MEmployees;i++) 
    { 
    
    for(j=0; j<NTasks; j++) 
    { 
    
    if(x[i][j] == 1) 
    { model.add(Tasks2[i*NTasks+j]==x[i][j]-y[i][j]); 
    } 
    
    else 
    { model.add(Tasks2[i*NTasks+j]==x[i][j]+y[i][j]); 
    } 
    } 
    }   
    //Objective function IloNumArray c2(env, MEmployees*NTasks); 
    
    for (i=0; i<MEmployees; ++i) 
    
    for (j=0; j<NTasks; ++j) c2[i*NTasks+j] = c[i][j];   IloExpr Obj_Func_1(env); 
    
    for (j = 0; j < NTasks; j++) 
    { Obj_Func_1 += IloIfThen(env, Tasks[j]!=Tasks_initial[j] && Tasks_initial[j]!=-1 , c2[Tasks[j]*NTasks+j]+c2[Tasks_initial[j]*NTasks+j]) ; 
    } IloExpr Obj_Func_2(env); 
    
    for (i = 0; i < MEmployees-1; i++) 
    { 
    
    if(G[i]!=0) Obj_Func_2 += ((nu[i]*u[i]) + (phi[i]*o[i])); 
    } IloObjective obj1 = IloMinimize(env, Obj_Func_1); IloObjective obj2 = IloMinimize(env, Obj_Func_1+Obj_Func_2); Obj_Func_1.end(); Obj_Func_2.end(); cout << 
    " *Objective function - checked"<<endl;   
    /* ---------------------------------------EXTRACTING THE MODEL AND SOLVING-----------------------------------------. */ 
    //Call to Ilog Optimizer IloCP cp(model); 
    //EXTRACT cp.extract(model); 
    //PROPAGATION cp.propagate(); 
    //Parameters settings 
    //cp.setParameter(IloCP::LogVerbosity, IloCP::Quiet);                                               //Avoid Log 
    //cp.setParameter(IloCP::PropagationLog, IloCP::Verbose);                                    //Propagation log 
    //cp.setParameter(IloCP::CountInferenceLevel, IloCP::Extended); //Extended info on search cp.setParameter(IloCP::OptimalityTolerance, 10); cp.setParameter(IloCP::RelativeOptimalityTolerance, 0.1);                             
    //Sets optimality tolerance cp.setParameter(IloCP::BranchLimit, 500000);                                                         
    //Limit number of search branches 
    //cp.setParameter(IloCP::DynamicProbing, 1); cp.setParameter(IloCP::RestartFailLimit,100); 
    //cp.setParameter(IloCP::TimeLimit, 300); cp.setParameter(IloCP::TemporalRelaxation, 1); cp.setParameter(IloCP::AllDiffInferenceLevel, 4);   
    //STRATEGY SEARCH 
    //cp.setParameter(IloCP::SearchType, IloCP::MultiPoint);                       //Multi-point search strategy   -> Heuristic-Concentrates on finding good solutions        
    //cp.setParameter(IloCP::MultiPointNumberOfSearchPoints, 2); 
    //cp.setParameter(IloCP::RestartGrowthFactor ,10);                                                 //Restart search strategy       -> Heuristic-It can prove optimality 
    //cp.setParameter(IloCP::SearchType, IloCP::DepthFirst);                                         //Depth first search strategy   -> Exact method   model.add(obj1); 
    /*cp.solve(); // Store solution IloSolution sol1(env); for ( i=0; i<MEmployees; ++i) { for ( j=0; j<NTasks; ++j) { // For illustration purpose, we only save start values sol1.setValue(y[i][j], cp.getValue(y[i][j])); } } // Change objective model.remove(obj2); //model.add(Obj_Func_2 <= cp.getValue(Obj_Func_2)); // f1 should not worsen model.add(obj1); // Minimize f2 using sol1 as starting point cp.setStartingPoint(sol1);*/ 
    
    if (cp.solve(IloSearchPhase(env,Tasks))) 
    { cp.out() << std::endl << 
    "- Solution:" << endl << endl; 
    /*env.out() << " - Changes in previous schedule: " << endl; for(i = 0; i < MEmployees-1; i++) { env.out() << " Employee(" << i+1 << "): \t"; for(j = 0; j < NTasks; j++) { env.out() << cp.getValue(y[i][j]); } env.out() << endl; } env.out() << " Agency: \t"; for(j = 0; j < NTasks; j++) { env.out() <<cp.getValue(y[MEmployees-1][j]) ; } env.out() << endl;*/ env.out() << endl <<
    " - New Schedule: " << endl; 
    /*for(i = 0; i < MEmployees-1; i++) { env.out() << " Employee(" << i+1 << "): \t"; for(j = 0; j < NTasks; j++) { env.out() <<cp.getValue(e[i][j]*Tasks3[i][j]) ; } env.out() << endl; } env.out() << " Agency: \t"; for(j = 0; j < NTasks; j++) { env.out() <<cp.getValue(e[MEmployees-1][j]*Tasks3[MEmployees-1][j]) ; } env.out() << endl;*/ 
    
    for(i=0; i<NTasks ; i++) 
    { 
    
    if(cp.getValue(Tasks[i])<MEmployees-1) cp.out() << 
    " Task("<<i+1<<
    ") -> Employee(" << cp.getValue(Tasks[i])+1 <<
    ")"<< endl; 
    
    else cp.out() << 
    " Task("<<i+1<<
    ") -> Agency"<<endl; 
    } 
    /*env.out() << endl <<" - Over-utilisation: " << endl; for(i = 0; i < 1; i++) { env.out() << " Days(Cost): "; for(j = 0; j < MEmployees-1; j++) { if(G[j]!=0) { env.out() << cp.getValue(o[j]); env.out() <<"(" <<ceil(cp.getValue(o[j]*phi[j]))<<")" <<"\t"; } } env.out() << endl << endl; } env.out()  <<" - Under-utilisation: " << endl; for(i = 0; i < 1; i++) { env.out() << " Days(Cost): "; for(j = 0; j < MEmployees-1; j++) { if(G[j]!=0) { env.out() << cp.getValue(u[j]); env.out() <<"(" <<ceil(cp.getValue(u[j]*nu[j]))<<")" <<"\t"; } } env.out() << endl << endl; }*/ env.out() << 
    " Minimal Cost = " << cp.getObjValue() << 
    "\t"; env.out() << 
    "Elapsed time   = " << env.getTime() << endl<<endl; cp.out() << 
    "Is it optimal ? = " << cp.getStatus() << endl << endl;   
    } 
    
    else 
    { cp.out() << 
    "No solution found. " << std::endl; 
    } 
    } 
    
    catch (IloException& ex) 
    { env.out() << 
    "Error: " << ex << std::endl; 
    } env.end(); 
    
    return 0; 
    }
    

    #CPOptimizer
    #DecisionOptimization


  • 2.  Re: IloIfThen and memory error - (Crew Recovery Scheduling problem)

    Posted 08/12/12 07:08 AM

    Originally posted by: Dmartinc


    Please find an instance which doesn´t get the memory error.

    David
    #CPOptimizer
    #DecisionOptimization


  • 3.  Re: IloIfThen and memory error - (Crew Recovery Scheduling problem)

    Posted 08/12/12 07:21 AM

    Originally posted by: Dmartinc


    This is the constraint that I am trying to avoid, which correspond to the MILP formulation of my model and represents
    the changes from the initial roster, therefore it can be deleted from the initial model.

    David

    
    
    //Combination of x[i][j] current roster and y[i][j] change in current roster in to z[i][j] new roster 
    
    for(i=0;i<MEmployees;i++) 
    { 
    
    for(j=0; j<NTasks; j++) 
    { 
    
    if(x[i][j] == 1) 
    { model.add(Tasks2[i*NTasks+j]==x[i][j]-y[i][j]); 
    } 
    
    else 
    { model.add(Tasks2[i*NTasks+j]==x[i][j]+y[i][j]); 
    } 
    } 
    }
    

    #CPOptimizer
    #DecisionOptimization


  • 4.  Re: IloIfThen and memory error - (Crew Recovery Scheduling problem)

    Posted 08/13/12 05:32 AM

    Originally posted by: SystemAdmin


    Hello.

    I split my answer into several parts.

    IloIfThen problem


    Function IloIfThen operate on constraints, it is not something like an operator ? in C(++). For example, IloIfThen(env, constraintA, constraintB) says that if constraintA is true then constraintB must hold. However if constraintA is false then there's no conditin for constraintB. Also, there's operator && defined for IloConstraint class:
    
    IloConstraint && IloConstraint
    

    However the following is not allowed:
    
    IloConstraint && bool
    

    Instead of combining IloConstraint with bool, and if statement should be used. My guess is that you wanted to write something like this:
    
    
    
    if (Tasks_initial[j] != -1) Obj_Func_1 += (Tasks[j]!=Tasks_initial[j]) * (c2[Tasks[j]*NTasks+j]+c2[Tasks_initial[j]*NTasks+j]) ;
    

    Above, constraint
    
    (Tasks[j]!=Tasks_initial[j])
    
    is used as an expression (0 = false, 1 = true).

    Memory issue


    The memory problem likes in exp2[j] in the following code:
    
    
    
    for(k=0;k<KProjects;++k) 
    { IloExpr Experience(env); 
    
    for(j=0; j< NTasks; ++j) 
    { Experience += Projects[k][j]*exp2[Tasks[j]*NTasks+j]; 
    } model.add(Experience >= Min_experience[k]); Experience.end(); 
    }
    

    Expression exp2[j] is quite memory consuming and it is created again for every k. A better solution is:
    
    IloNumExprArray exp2Expressions(env, NTasks); 
    
    for (j = 0; j < NTasks; ++j) exp2Expressions[j] = exp2[Tasks[j]*NTasks+j]; 
    
    for(k=0;k<KProjects;++k) 
    { IloExpr Experience(env); 
    
    for(j=0; j< NTasks; ++j) 
    { Experience += Projects[k][j]*exp2Expressions[j]; 
    //exp2[Tasks[j]*NTasks+j]; 
    } model.add(Experience >= Min_experience[k]); Experience.end(); 
    }
    


    Final comments


    It seems to me that y and Tasks3 variables are useless, they are just derived from Tasks2. Removing them could speed up the search.

    The bool var matrix Tasks2 is very expensive, both in memory and resolution time. I would try to avoid it if it is possible.

    I hope it helps, Petr
    #CPOptimizer
    #DecisionOptimization


  • 5.  Re: IloIfThen and memory error - (Crew Recovery Scheduling problem)

    Posted 08/13/12 06:13 AM

    Originally posted by: Dmartinc


    Hi Petr,

    your comments were very helpful and all my model´s issues were sort out.

    Cheers,

    David
    #CPOptimizer
    #DecisionOptimization


  • 6.  Re: IloIfThen and memory error - (Crew Recovery Scheduling problem)

    Posted 08/13/12 07:48 AM

    Originally posted by: Dmartinc


    One last question, Why does the CP optimizer keep searching without finding none solution when I increase the instance size?
    Because when I solve small instances I get a solution, but for large instances it doesn´t.

    Cheers,

    David
    #CPOptimizer
    #DecisionOptimization


  • 7.  Re: IloIfThen and memory error - (Crew Recovery Scheduling problem)

    Posted 08/13/12 09:44 AM

    Originally posted by: SystemAdmin


    CP Optimizer is made to deal with certain type of NP-complete problems. So no tool (including CP Optimizer) can give a guarantee that it will find a solution in reasonable time. Especially when the problem size increases, the problem may become exponentially more hard and therefore it takes much more time to find a solution.

    Usually, the same problem can be modeled in multiple ways in CP Optimizer. Some ways work better than others, that's a matter of experience and experimentation. For development, I would recommend to start with input data of realistic size so that you know right from the start what parts of your model work and what doesn't. It's also good to check the performance on multiple problem instances and/or multiple random seeds.

    In your model, I think the problem may lie in the bool var matrix. For big problems it takes too much memory what slows down everything. I'm not sure you can avoid it, I didn't study your problem in detail, but if there is an alternative way to model the problem then I would recommend to give it a try.

    Cheers, Petr
    #CPOptimizer
    #DecisionOptimization