示例#1
0
void profit_create_objective(graph g, IloModel model, IloNumVarArray x, IloNumVarArray z, int **columns) {
  IloNumExpr e(model.getEnv());
  for(int i = 0; i < g->bidders; i++) {
    e += z[i];
  }
  model.add(IloMaximize(model.getEnv(), e));
}
示例#2
0
 void update()
 {
   switch (dir_)
   {
     case IP::MAX: model_.add(IloMaximize(env_, obj_)); break;
     case IP::MIN: model_.add(IloMinimize(env_, obj_)); break;
   }
 }
示例#3
0
void BNC::buildModelNF(){
	env = new IloEnv;
	model = new IloModel(*env);
	variables = new IloNumVarArray(*env);
	constraints = new IloRangeArray(*env);
	
	//create variables
	for( int i = 0; i < n; ++i ){
		variables->add( IloIntVar( *env, 0, 1 ) );
		variables->add( IloIntVar( *env, 0, 1 ) );
	}
	
	
	for( int i = 0, k = 0; i < n; ++i ){
		for( int j = i; j < n; ++j ){
			if( graph[i][j] ){
				IloRange newconstraintA( *env, 0, 1 );
				IloRange newconstraintB( *env, 0, 1 );
				
				newconstraintA.setLinearCoef( (*variables)[i], 1 );
				newconstraintA.setLinearCoef( (*variables)[j], 1 );
				
				newconstraintB.setLinearCoef( (*variables)[n+i], 1 );
				newconstraintB.setLinearCoef( (*variables)[n+j], 1 );
				
				constraints->add( newconstraintA );
				constraints->add( newconstraintB );
				++k;
			}
		}
	}
	
	for( int i = 0; i < n; ++i ){
		IloRange newconstraintAB( *env, 0, 1 );
		newconstraintAB.setLinearCoef( (*variables)[i], 1 );
		newconstraintAB.setLinearCoef( (*variables)[n+i], 1 );
		constraints->add( newconstraintAB );
	}
		
	//objective function
	IloObjective obj = IloMaximize(*env);
	
	//objective
	for( int i = 0 ; i < n; i++ ){
		obj.setLinearCoef((*variables)[i], 1 );
		obj.setLinearCoef((*variables)[n+i], 1 );
	}
	
	model->add( *constraints );
	model->add( obj );
	
	cplex = new IloCplex(*model);
	
	configureCPLEX();
	
	//write model in file cplexmodel.lp
	cplex->exportModel("cplexmodel.lp");
}
示例#4
0
static void
populatebynonzero (IloModel model, IloIntVarArray x, IloRangeArray c)
{
   IloEnv env = model.getEnv();

   IloObjective obj = IloMaximize(env);
	int n, a;
	scanf("%d", &n);

		
	scanf("%d", &a);
	//restrição
   c.add(IloRange(env, -IloInfinity, a));

	//variaveis
	for(int i=0 ; i<n; i++){
		x.add(IloIntVar(env, 0, 1));
	}

   /*x.add(IloIntVar(env, 0.0, 40.0));
   x.add(IloIntVar(env));
   x.add(IloIntVar(env));*/

	
   /*obj.setLinearCoef(x[0], 1.0);
   obj.setLinearCoef(x[1], 2.0);
   obj.setLinearCoef(x[2], 3.0);*/

	/*restricoes*/
	for(int i=0 ; i<n; i++){
		scanf("%d", &a);
		c[0].setLinearCoef(x[i], a);
	}

	//objetivo	
	for(int i=0 ; i<n; i++){
		scanf("%d", &a);
		obj.setLinearCoef(x[i], a);
	}
   
   /*c[0].setLinearCoef(x[1],  1.0);
   c[0].setLinearCoef(x[2],  1.0);
   c[1].setLinearCoef(x[0],  1.0);
   c[1].setLinearCoef(x[1], -3.0);
   c[1].setLinearCoef(x[2],  1.0);*/

   c[0].setName("c1");
	for(int i=0; i<n; i++){
		char tmp[10];
		printf("x%d", i+1);
		x[i].setName(tmp);	
	}

   model.add(obj);
   model.add(c);
}  // END populatebynonzero
示例#5
0
 void Instance::ComputeCPLEXRevenue() {
     IloEnv env;
     IloInt i, j;
     IloModel model(env);
     IloInt nbImpressions = num_impressions_;
     IloInt nbAdvertisers = num_advertisers_;
     
     NumVarMatrix x(env, nbImpressions);
     
     for(i = 0; i < nbImpressions; i++) {
         x[i] = IloNumVarArray(env, nbAdvertisers, 0.0, 1.0, ILOFLOAT);
     }
     
     // Add impression constraints.
     for(i = 0; i < nbImpressions; i++) {
         model.add(IloSum(x[i]) <= 1.0);
     }
     
     // Add weighted contraint.
     for(j = 0; j < nbAdvertisers; j++) {
         IloExpr curr_adv_constraint(env);
         for (__gnu_cxx::hash_map<int, long double>::iterator iter = bids_matrix_[j].begin();
              iter != bids_matrix_[j].end();
              ++iter) {
             curr_adv_constraint += ((double) iter->second) * ((double) weights_[j]) * x[iter->first][j];
         }
         model.add(curr_adv_constraint <= ((double) budgets_[j]));
     }
     
     IloExpr obj_exp(env);
     for(i = 0; i < nbImpressions; i++) {
         for(j = 0; j < nbAdvertisers; j++) {
             obj_exp += ((double) transpose_bids_matrix_[i][j]) * x[i][j];
         }
     }
     
     model.add(IloMaximize(env, obj_exp));
     obj_exp.end();
     
     IloCplex cplex(env);
     cplex.setOut(env.getNullStream());
     cplex.extract(model);
     
     // Optimize the problem and obtain solution.
     if ( !cplex.solve() ) {
         env.error() << "Failed to optimize LP" << endl;
         throw(-1);
     }
     
     cplex.exportModel("/Users/ciocan/Documents/Google/data/example.lp");
     
     cout << "CPLEX opt is " << cplex.getObjValue() << "\n";
     
     env.end();    
 }
示例#6
0
static void
populatebynonzero(IloModel model, NumVarMatrix varOutput, NumVar3Matrix varHelp, Range3Matrix con)
{
	IloEnv env = model.getEnv();

	IloObjective obj = IloMaximize(env); //maximization function


	for (int j = current; j < current + J; ++j)
	{
		for (int k = 0; k < K; ++k)
		{
			
			obj.setLinearCoef(varOutput[j][k], 1.0);//add all variables to objective function, factor 1 
			
			//constraint 0: express value of output objective variables
			model.add(varOutput[j][k] + varHelp[j][k][2] - varHelp[j][k][3] == 0);

			//constraint 1: Td2a>=+Td2b
			model.add(varHelp[j][k][5] - varHelp[j][k][4] >= 0);

			//constraint 2: Tj>=Td2a + Tdc + Tblow
			model.add(varHelp[j][k][5] <= T[j] - Tdc - Tblow[j] - Tslack);

			//constraint 3: Td2b = Tfa+Tfd
			model.add(Tfd[k] == varHelp[j][k][4] - varHelp[j][k][3]);

			//constraint 4: Td1a >= Td1b
			model.add(0 <= varHelp[j][k][1] - varHelp[j][k][0]);

			//constraint 5: Tfb >= Td1a+Tdf
			model.add(Tdf[k] <= varHelp[j][k][2] - varHelp[j][k][1]);

			//constraint 6: Td1b = T(j-a)+Tcd
			model.add(T[j - a[k]] + Tcd == varHelp[j][k][0]);

			//constraint 7: Td1a >= Td2b(j-b) + Tloss, 1
			model.add(TlossD[k] <= varHelp[j][k][1] - varHelp[j - b[k]][k][4]);

			//constraint 8: Tfb >= Tfa(j-1)+Tloss, 2
			model.add(TlossF[k] <= varHelp[j][k][2] - varHelp[j - 1][k][3]);

			//constraint 9: at least X s for every load
			model.add(varOutput[j][k] >= TloadMin[k]);

		}
		//constraint 10: both spoons are picked up at same time at dropoff: Td2a,1 == Td2a,2
		model.add(varHelp[j][1][5] == varHelp[j][0][5]);

	}

	model.add(obj);
	

}
示例#7
0
void CPLEXSolver::add_in_constraint(LinearConstraint *con, double coef){
    DBG("Creating a Gurobi representation of a constriant %s\n", "");
    IloNumArray weights(*env, (IloInt)con->_coefficients.size());
    IloNumVarArray vars(*env, (IloInt)con->_variables.size());
    
    for(unsigned int i = 0; i < con->_variables.size(); ++i){
        DBG("\tAdding variable to CPLEX\n%s", "");
        IloNumVar var_ptr;
        
        if(con->_variables[i]->_var == NULL){
            
            IloNumVar::Type type;
        
            if(con->_variables[i]->_continuous) type = IloNumVar::Float;
            // else if(con->_lower == 0 && con->_upper == 1) type = IloNumVar::Bool;
            else type = IloNumVar::Int;

            var_ptr = IloNumVar(getEnv(),
                                con->_variables[i]->_lower, // LB
                                con->_variables[i]->_upper, // UB
                                type);

            int *var_id = new int;
            *var_id = variables->getSize();
            variables->add(var_ptr);
            con->_variables[i]->_var = (void*) var_id;
            
            DBG("Created new variable with id %d. type:%c lb:%f ub:%f coef:%f\n", *var_id, type, con->_variables[i]->_lower, con->_variables[i]->_upper, coef);
        } else {
            var_ptr = (*variables)[*(int*)(con->_variables[i]->_var)];
        }

        vars[i] = (*variables)[*(int*)(con->_variables[i]->_var)];
        weights[i] = con->_coefficients[i];
    }

    IloNumExprArg lin_expr = IloScalProd(weights, vars);

    if(coef < -0.1){
        model->add(IloMinimize(*env, lin_expr));
    } else if(coef > 0.1){
        model->add(IloMaximize(*env, lin_expr));
    } else {
        if(con->_lhs > -INFINITY && con->_rhs < INFINITY){
            if(con->_lhs == con->_rhs) {
                model->add(lin_expr == con->_lhs);
            } else {
                model->add(IloRange(*env, con->_lhs, lin_expr, con->_rhs));
            }
        } else if(con->_lhs > -INFINITY) model->add(lin_expr >= con->_lhs);
        else if(con->_rhs < INFINITY) model->add(lin_expr <= con->_rhs);
    }
}
示例#8
0
bool MIQPSolver::createModel()
{
	try
	{
		model.add(IloMaximize(environment, g - h - p + s));
		model.add(constraints);
		cplex = IloCplex(model);
	}
	catch (...)
	{
		return false;
	}
	return true;
}
示例#9
0
static void
populatebycolumn (IloModel model, IloNumVarArray x, IloRangeArray c)
{
   IloEnv env = model.getEnv();

   IloObjective obj = IloMaximize(env);
   c.add(IloRange(env, -IloInfinity, 20.0));
   c.add(IloRange(env, -IloInfinity, 30.0));

   x.add(IloNumVar(obj(1.0) + c[0](-1.0) + c[1]( 1.0), 0.0, 40.0));
   x.add(obj(2.0) + c[0]( 1.0) + c[1](-3.0));
   x.add(obj(3.0) + c[0]( 1.0) + c[1]( 1.0));

   model.add(obj);
   model.add(c);
}  // END populatebycolumn
示例#10
0
static void
populatebyrow (IloModel model, IloNumVarArray x, IloRangeArray c)
{
   IloEnv env = model.getEnv();

   x.add(IloNumVar(env, 0.0, 40.0));
   x.add(IloNumVar(env));
   x.add(IloNumVar(env));
   x.add(IloNumVar(env, 2.0, 3.0, ILOINT));
   model.add(IloMaximize(env, x[0] + 2 * x[1] + 3 * x[2] + x[3]));

   c.add( - x[0] +     x[1] + x[2] + 10 * x[3] <= 20);
   c.add(   x[0] - 3 * x[1] + x[2]             <= 30);
   c.add(              x[1]        - 3.5* x[3] == 0);
   model.add(c);

}  // END populatebyrow
示例#11
0
static void
populatebyrow (IloModel model, IloNumVarArray x, IloRangeArray c)
{
   IloEnv env = model.getEnv();

   x.add(IloNumVar(env, 0.0, 40.0));
   x.add(IloNumVar(env));
   x.add(IloNumVar(env));
   model.add(IloMaximize(env, x[0] + 2 * x[1] + 3 * x[2]
                            - 0.5 * (33*x[0]*x[0] + 22*x[1]*x[1] +
                                     11*x[2]*x[2] - 12*x[0]*x[1] -
                                     23*x[1]*x[2]                 ) ));

   c.add( - x[0] +     x[1] + x[2] <= 20);
   c.add(   x[0] - 3 * x[1] + x[2] <= 30);
   model.add(c);
}  // END populatebyrow
示例#12
0
static void
populatebyrow (IloModel model, IloNumVarArray x, IloRangeArray c)
{
   IloEnv env = model.getEnv();

   x.add(IloNumVar(env, 0.0, 40.0));
   x.add(IloNumVar(env, 0.0, IloInfinity, ILOINT));
   x.add(IloNumVar(env, 0.0, IloInfinity, ILOINT));
   x.add(IloNumVar(env, 2.0, 3.0, ILOINT));
   model.add(IloMaximize(env, x[0] + 2 * x[1] + 3 * x[2] + x[3]));

   c.add( - x[0] +     x[1] + x[2] + 10 * x[3] <= 20);
   c.add(   x[0] - 3 * x[1] + x[2]             <= 30);
   c.add(              x[1]        - 3.5* x[3] == 0);
   model.add(c);

   IloNumVarArray sosvar(env, 2);
   IloNumArray    sosval(env, 2);
   sosvar[0] = x[2]; sosvar[1] = x[3];
   sosval[0] = 25.0; sosval[1] = 18.0;

   model.add(IloSOS1(model.getEnv(), sosvar, sosval));

}  // END populatebyrow
示例#13
0
void BNC::buildModelCF(){
	env = new IloEnv;
	model = new IloModel(*env);
	variables = new IloNumVarArray(*env);
	constraints = new IloRangeArray(*env);
	
	list< list<int> > cliques;
	
	
	int count_chose = 0;
	
	bool chose_edge[n][n];
	for( int i = 0; i < n; ++i )
		for( int j = 0; j < n; ++j )
			chose_edge[i][j] = false;
	
	while( count_chose < m ){
		list<int> current_clique;
		
		//choose a initial node
		for( int i = 0; i < n; ++i ){
			for( int j = 0; j < n; ++j ){
				if( graph[i][j] ){
					if( !chose_edge[i][j] ){
						chose_edge[i][j] = chose_edge[j][i] = true;
						++count_chose;
						current_clique.push_back(i);
						current_clique.push_back(j);
						goto done;
					}
				}
			}
		}
		done:
		//build a clique
		int i = current_clique.front();
		for( int j = 0; j < n; ++j ){
			if( graph[i][j] ){
				
				if( !chose_edge[i][j] ){
					bool add_node = true;
					
					list<int>::iterator it = current_clique.begin();
					while( it != current_clique.end() ){
						if( !graph[*it][j] ){
							add_node = false;
							break;
						}
						++it;
					}
					
					if( add_node ){
						{
						list<int>::iterator it = current_clique.begin();
						while( it != current_clique.end() ){
							if( !chose_edge[*it][j] )
								++count_chose;
							
							chose_edge[*it][j] = chose_edge[j][*it] = true;
							++it;
						}
						}
						current_clique.push_back(j);
					}
				}
			}
		}
		
		cliques.push_back( current_clique );
	}
	
	//create variables
	for( int i = 0; i < n; ++i ){
		variables->add( IloIntVar( *env, 0, 1 ) );
		variables->add( IloIntVar( *env, 0, 1 ) );
	}
	
	list< list<int> >::iterator it1 = cliques.begin();
	while( it1 !=  cliques.end() ){
		list<int>::iterator it2 = it1->begin();
		IloRange newconstraintA( *env, 0, 1 );
		IloRange newconstraintB( *env, 0, 1 );
		while( it2 != it1->end() ){
			newconstraintA.setLinearCoef( (*variables)[*it2], 1 );
			newconstraintB.setLinearCoef( (*variables)[n+*it2], 1 );
			++it2;
		}
		constraints->add( newconstraintA );
		constraints->add( newconstraintB );
		++it1;
	}

	for( int i = 0; i < n; ++i ){
		IloRange newconstraintAB( *env, 0, 1 );
		newconstraintAB.setLinearCoef( (*variables)[i], 1 );
		newconstraintAB.setLinearCoef( (*variables)[n+i], 1 );
		constraints->add( newconstraintAB );
	}
		
	//objective function
	IloObjective obj = IloMaximize(*env);
	
	//objective
	for( int i = 0 ; i < n; i++ ){
		obj.setLinearCoef((*variables)[i], 1 );
		obj.setLinearCoef((*variables)[n+i], 1 );
	}
	
	model->add( *constraints );
	model->add( obj );
	
	cplex = new IloCplex(*model);
	
	configureCPLEX();
	
	//write model in file cplexmodel.lp
	cplex->exportModel("cplexmodel.lp");
}
示例#14
0
文件: mmkp.cpp 项目: AiTeamUSTC/ipge
//on the reduced problem
void solveIP(double time_limit, int ite, double gap){
	IloEnv env;
	IloModel model(env);
	IloIntVarArray x(env, n_var, 0, 1);
	IloRangeArray con(env);

	IloExpr obj(env);
	int i,j,k;
	for(i=0;i<n;i++){
		for(j=0;j<group[i].nItem;j++){
			obj+=group[i].profit[j]*x[sum_n_item[i]+j];
		}
	}
	model.add(IloMaximize(env, obj));
	obj.end();
	
	for(k=0;k<m;k++){
		IloExpr expr(env);
		for(i=0;i<n;i++){
			for(j=0;j<group[i].nItem;j++){
				expr+=group[i].consume[j][k]*x[sum_n_item[i]+j];
			}
		}
		con.add(expr<=Gb[k]);
		expr.end();
	}

	for(i=0;i<n;i++){
		IloExpr expr(env);
		for(j=0;j<group[i].nItem;j++){
			expr+=x[sum_n_item[i]+j];
		}
		con.add(expr==1);
		expr.end();
	}

	/*
	int *tempFix=new int[n_var];
	memset(tempFix, 0, n_var*sizeof(int));
	for(i=0;i<rp.len;i++){
		tempFix[rp.posi[i]]=1;
	}
	//force those not appeared in rp to 0
	for(i=0;i<n;i++){
		IloExpr expr(env);
		for(j=0;j<group[i].nItem;j++){
			if(tempFix[sum_n_item[i]+j]==0){
				expr+=x[sum_n_item[i]+j];
			}
		}
		con.add(expr==0);
		expr.end();
	}
	delete []tempFix;
	*/
	//add constrains from the last iteration
	if(ite>0){
		for(k=0;k<ite;k++){
			IloExpr expr(env);
			for(i=0;i<len_v1[k];i++){
				expr+=x[pre_v1[k][i]];
			}
			for(i=0;i<len_v0[k];i++){
				expr-=x[pre_v0[k][i]];
			}
			con.add(expr<=sum_pre_v1[k]-1);
			expr.end();
		}
	}
	if(0&&len_rdCost0>0&&len_rdCost1>0){
		IloExpr expr(env);
		for(i=0;i<len_rdCost1;i++){
			expr+=(1-x[rdCost_sort1[i].posi])*rdCost_sort1[i].value;
		}

		for(i=0;i<len_rdCost0;i++){
			expr+=x[rdCost_sort[i].posi]*rdCost_sort[i].value;
		}
		con.add(expr<=gap);
		expr.end();
	}
	if(len_rdCost0>0){
		printf("0 rdCostSort_len:%d. \n",len_rdCost0);
		k=1;
		int start=0, end;
		int cnt=0;
		//for(i=0;i<len_rdCost0;i++) printf("%lf, ", rdCost_sort[i].value);
		while(start<len_rdCost0){
			double sum=0;
			for(i=start;i<len_rdCost0-k;i++){
				sum=0;
				for(int ii=i;ii<i+k;ii++){
					sum+=rdCost_sort[ii].value;
				}
				if(sum<gap) break;
			}
			if(i>=len_rdCost0-k && sum<gap) break;
			//printf("cut %d, start=%d, end=%d\n",k-1, start, i+k);
			end=i+k;
			IloExpr expr1(env);
			for(i=start;i<end;i++){
				expr1+=x[rdCost_sort[i].posi];
			}
			con.add(expr1<=k-1);
			expr1.end();
			for(i=start;i<end;i++){
				pre_v0[ite][cnt++]=rdCost_sort[i].posi;
			}
			start=end;
			k++;
		}
		len_v0[ite]=cnt;
	}
	if(len_rdCost1>0){
		printf("1 rdCost_sort length:%d. \n",len_rdCost1);
		k=1;
		int start=0, end;
		int cnt=0;
		sum_pre_v1[ite]=0;
		//for(i=0;i<len_rdCost1;i++) printf("%lf, ", rdCost_sort1[i].value);
		while(start<len_rdCost1){
			double sum=0;
			for(i=start;i<len_rdCost1-k;i++){
				sum=0;
				for(int ii=i;ii<i+k;ii++){
					sum+=rdCost_sort1[ii].value;
				}
				if(sum<gap) break;
			}
			if(i>=len_rdCost1-k && sum<gap) break;
			//printf("cut %d, start=%d, end=%d\n",k-1, start, i+k);
			end=i+k;
			IloExpr expr1(env);
			for(i=start;i<end;i++){
				expr1+=x[rdCost_sort1[i].posi];
			}
			int cnt1=(end-start)-(k-1);
			con.add(expr1>=cnt1);
			expr1.end();
			for(i=start;i<end;i++){
				pre_v1[ite][cnt++]=rdCost_sort1[i].posi;
			}
			sum_pre_v1[ite]=sum_pre_v1[ite]+(end-start);
			start=end;
			k++;
		}
		len_v1[ite]=cnt;
	}
	model.add(con);
	IloCplex cplex(model);
	cplex.setParam(IloCplex::TiLim, time_limit);
	cplex.setParam(IloCplex::Threads, 1);
	cplex.setParam(IloCplex::NodeFileInd,2);
	//cplex.setOut(env.getNullStream());
	if(LB>0){
		printf("\t add start point\n");
		IloNumVarArray start_var(env);
		IloNumArray start_val(env);
		int k=0;
		for(i=0;i<n;i++){
			for(j=0;j<group[i].nItem;j++){
				if(bestSolVec[i]==j){
					start_val.add(1);
				} else start_val.add(0);
				start_var.add(x[k]);
				k++;
			}
		}
		cplex.addMIPStart(start_var, start_val);
		start_var.end();
		start_val.end();
	}
	if(!cplex.solve()){
		std::cout<<"not solved IP."<<std::endl;
	} else {
		std::cout<<"solution status "<<cplex.getStatus()<<std::endl;
		std::cout<<"solution value "<<cplex.getObjValue()<<std::endl;
		
		if((double)cplex.getObjValue()>LB){
			LB=(double)cplex.getObjValue();	
			IloNumArray vals(env);
			cplex.getValues(vals, x);
			printf("new best solution vector is: ");
			for(i=0;i<n;i++){
				for(j=0;j<group[i].nItem;j++){
					if(cplex.getValue(x[sum_n_item[i]+j])>1-EPSILON){
					printf("%d ", j);
					bestSolVec[i]=j;
					}
				}
			}
			printf("\n\n");
		}
	}
	env.end();
}
示例#15
0
文件: mmkp.cpp 项目: AiTeamUSTC/ipge
void solveLP(){
	IloEnv env;
	IloModel model(env);
	IloNumVarArray x(env, n_var, 0,1);
	IloRangeArray con(env);
	IloExpr obj(env);
	int i,j,k;
	for(i=0;i<n;i++){
		for(j=0;j<group[i].nItem;j++){
			obj+=group[i].profit[j]*x[sum_n_item[i]+j];
		}
	}
	model.add(IloMaximize(env,obj));
	obj.end();
	for(k=0;k<m;k++){
		IloExpr expr(env);
		for(i=0;i<n;i++){
			for(j=0;j<group[i].nItem;j++){
				expr+=group[i].consume[j][k]*x[sum_n_item[i]+j];
			}
		}
		con.add(expr<=Gb[k]);
		expr.end();
	}
	for(i=0;i<n;i++){
		IloExpr expr(env);
		for(j=0;j<group[i].nItem;j++){
			expr+=x[sum_n_item[i]+j];
		}
		con.add(expr==1);
		expr.end();
	}
	
	model.add(con);
	IloCplex cplex(model);
	cplex.setOut(env.getNullStream());
	cplex.setParam(IloCplex::Threads,1);
	if(cplex.solve()){
		printf("LP solved with new value: %lf \n\n", cplex.getObjValue());
		UB=cplex.getObjValue();
		len_rdCost0=len_rdCost1=0;
		for(i=0;i<n_var;i++) {
			primal_sol[i]=(double)cplex.getValue(x[i]);
			rdCosts[i]=FABS((double)cplex.getReducedCost(x[i]));
			if(primal_sol[i]<EPSILON && rdCosts[i]>EPSILON){// non-basic variables at 0
				rdCost_sort[len_rdCost0].value=rdCosts[i];
				rdCost_sort[len_rdCost0++].posi=i;
			} else if(primal_sol[i]>1-EPSILON && rdCosts[i]>EPSILON){// non-basic variables at 1
				rdCost_sort1[len_rdCost1].value=rdCosts[i];
				rdCost_sort1[len_rdCost1++].posi=i;
			}
		}
		qsort(rdCost_sort, len_rdCost0,sizeof(ValuePosi), cmp);
		qsort(rdCost_sort1, len_rdCost1, sizeof(ValuePosi), cmp);
		
		len_v1=new int[maxIte];
		len_v0=new int[maxIte];

		pre_v0=new int*[maxIte];
		pre_v1=new int*[maxIte];
		for(i=0;i<maxIte;i++){
			pre_v1[i]=new int[len_rdCost1];
			pre_v0[i]=new int[len_rdCost0];
		}
		sum_pre_v1=new int[maxIte];
		memset(len_v0, 0,maxIte*sizeof(int));
		memset(len_v1, 0, maxIte*sizeof(int));
		memset(sum_pre_v1, 0, maxIte*sizeof(int));
	} else{ 
		printf("LP not solved\n");
	}
}
int main(int argc, char **argv) {
	clock_t t1, t2;
	t1 = clock();

	IloEnv env;
	IloModel model(env);
	IloCplex cplex(model);

	/************************** Defining the parameters ************************************/
	IloInt N;							//No. of nodes
	IloInt M;							//No. of calls
	Num2DMatrix links(env);				//Defines the topology of the network
	IloNumArray call_demand(env);		//link bandwidth requirement of each call
	IloNumArray call_revenue(env);		//revenue generated from the call
	IloNumArray call_origin(env);		//origin node index of each call
	IloNumArray call_destination(env);	//destination node index of each call
	Num2DMatrix Q(env);					//Bandwidth capacity of each link
	Num2DMatrix sigma(env);				//Standard deviation of service times on link (i,j)
	Num2DMatrix cv(env);				//coefficient of variation of service times on the link (i,j)
	IloNum C;							//Unit queueing delay cost per unit time
	IloNumArray R_approx_init(env);

	ifstream fin;
	const char* filename = "BPP_data_sample - Copy.txt";
	if (argc > 1)
		filename = argv[1];
		
	fin.open(filename);
	//fin.open("BPP_10node_navneet.txt");
	fin >> links >> call_origin >> call_destination >> call_demand >>
		call_revenue >> Q >> cv >> R_approx_init >> C ;
	cout << "Reading Data from the file - "<<filename<<endl;

	N = links.getSize();
	M = call_origin.getSize();

	IloInt H = R_approx_init.getSize();
	Num3DMatrix R_approx(env, N);			//The tangential linear function approximation to R.
	for (IloInt i=0; i<N; i++) {
		R_approx[i] = Num2DMatrix(env, N);
		for (IloInt j=0; j<N; j++) {
			R_approx[i][j] = IloNumArray(env, H);
			for (IloInt h=0; h<H; h++)
				R_approx[i][j][h] = R_approx_init[h];
		}
	}

	/************************** Defining the parameters ENDS ************************************/

	/************* Defining the variables defined in the model formulation **********************/
	IloNumVarArray Y(env, M, 0, 1, ILOINT); //Variable to define whether a call m is routed or not
	IloNumArray Y_sol(env, M); //Solution values

	NumVar3DMatrix X(env, N); //Variable to define whether a call m is routed along path i-j
	Num3DMatrix X_sol(env, N);
	for (IloInt i=0; i<N; i++) {
		X[i] = NumVar2DMatrix(env, N);
		X_sol[i] = Num2DMatrix(env, N);
		for (IloInt j=0; j<N; j++) {
			X[i][j] = IloNumVarArray(env, M, 0, 1, ILOINT);
			X_sol[i][j] = IloNumArray(env, M);
		}
	}

	NumVar3DMatrix W(env, N); //Variable to define whether a call m is routed along path i-j
	for (IloInt i=0; i<N; i++) {
		W[i] = NumVar2DMatrix(env, N);
		for (IloInt j=0; j<N; j++)
			W[i][j] = IloNumVarArray(env, M, 0, 1, ILOINT);
	}

	NumVar2DMatrix R(env, (IloInt)N); //The linearization Variable
	for (IloInt i=0; i<N; i++)
		R[i] = IloNumVarArray(env, (IloInt)N, 0, IloInfinity, ILOFLOAT);
	
	/************* Defining the variables defined in the model formulation ENDS *****************/

	/**************************** Defining the Constraints *******************************/
	// Constraint #1 : Flow Conservation Constraint
	for (IloInt m=0; m<M; m++) {
		for (IloInt i=0; i<N; i++) {
			IloExpr constraint1(env);
			for (IloInt j=0; j<N; j++) {
				if (links[i][j] == 1)
					constraint1 += W[i][j][m];
			}
			for (IloInt j=0; j<N; j++) {
				if (links[j][i] == 1)
					constraint1 += -W[j][i][m];
			}
			
			if (i == call_origin[m])
				model.add(constraint1 == Y[m]);
			else if (i == call_destination[m])
				model.add(constraint1 == -Y[m]);
			else 
				model.add(constraint1 == 0);

			constraint1.end();
		}
	}

	// Constraint #2 :
	for (IloInt m=0; m<M; m++) {
		for (IloInt i=0; i<N; i++) {			
			for (IloInt j=0; j<N; j++) {
				if (links[i][j] == 1)
					model.add(W[i][j][m] + W[j][i][m] <= X[i][j][m]);					
			}			
		}
	}

	// Constraint #3 : Link Capacity Constraint
	for (IloInt i=0; i<N; i++) {
		for (IloInt j=i+1; j<N; j++) {
			if (links[i][j] == 1) {
				IloExpr constraint3(env);
				for (IloInt m=0; m<M; m++)
					constraint3 += call_demand[m]*X[i][j][m];
				model.add(constraint3 <= Q[i][j]);
				constraint3.end();
			}
		}
	}
	
	// Constraint #4 : Defining the constraint for initial values of R_approx, 
	//				   Cuts must be added during the iterations whenever the values are updated
	for (IloInt i=0; i<N; i++) {
		for (IloInt j=i+1; j<N; j++) {	
			if (links[i][j] == 1) {
				for (IloInt h=0; h<H; h++) {
					IloExpr constraint4_lhs(env);
					IloNum constraint4_rhs = 0;
					for (IloInt m=0; m<M; m++)
						constraint4_lhs += call_demand[m]*X[i][j][m];

					constraint4_lhs -= (Q[i][j]/((1+R_approx[i][j][h])*(1+R_approx[i][j][h])))*R[i][j];
					constraint4_rhs = Q[i][j]*((R_approx[i][j][h]/(1+R_approx[i][j][h])) *
											(R_approx[i][j][h]/(1+R_approx[i][j][h])));
					model.add(constraint4_lhs <= constraint4_rhs);
					constraint4_lhs.end();
				}
			}
		}
	}

	/************************** Defining the Constraints ENDS ****************************/

	/************************ Defining the Objective Function ****************************/
	IloExpr Objective(env);
	IloExpr Obj_expr1(env);
	IloExpr Obj_expr2(env);
	
	for (IloInt m=0; m<M; m++)
		Obj_expr1 += call_revenue[m]*Y[m];

	for (IloInt i=0; i<N; i++) {
		for (IloInt j=i+1; j<N; j++) {
			if (links[i][j] == 1) {
				Obj_expr2 += (1+cv[i][j] * cv[i][j])*R[i][j];
				for (IloInt m=0; m<M; m++) 
					Obj_expr2 += ((1-cv[i][j] * cv[i][j])/Q[i][j])*call_demand[m]*X[i][j][m];
			}
		}
	}
	Objective += Obj_expr1 - 0.5*C*Obj_expr2;
	model.add(IloMaximize(env, Objective));
	//model.add(IloMinimize(env, -Objective));

	Objective.end();
	Obj_expr1.end();
	Obj_expr2.end();

	/********************** Defining the Objective Function ENDS **************************/

	IloNum eps = cplex.getParam(IloCplex::EpInt);

	IloNum UB = IloInfinity;
	IloNum LB = -IloInfinity;

	/***************** Solve ***********************/
	do {
		cplex.setParam(IloCplex::MIPInterval, 5);
		cplex.setParam(IloCplex::NodeFileInd ,2);
		cplex.setOut(env.getNullStream());

		cplex.exportModel("BPP_model.lp");

		if(!cplex.solve()) {
			cout << "Infeasible"<<endl;
			system("pause");
		}
		else {
			for (IloInt m=0; m<M; m++) {
				if (cplex.getValue(Y[m]) > eps) {
					cout << "Call(m) = "<<m+1<<" : "<<call_origin[m]+1<<" --> "<<call_destination[m]+1
						<<"; demand = "<<call_demand[m]<<endl;
					cout << "Path : ";
					for (IloInt i=0; i<N; i++) {
						for (IloInt j=i+1; j<N; j++) {
							if (links[i][j] == 1) {
								if (cplex.getValue(X[i][j][m]) > eps) {
									X_sol[i][j][m] = 1;
									cout <<i+1<<"-"<<j+1<<"; ";
								}
							}
						}
					}
					cout << endl << endl;
				}				
			}		

			//system("pause");
		}

		UB = min(UB, cplex.getObjValue());

		IloNum lbound = 0;
		for (IloInt m=0; m<M; m++) 
			if(cplex.getValue(Y[m]) > eps)
				lbound += call_revenue[m];

		for (IloInt i=0; i<N; i++) {
			for (IloInt j=i+1; j<N; j++) {
				if (links[i][j] == 1) {
					IloNum lbound_temp1 = 0;
					IloNum lbound_temp2 = 0;
					for (IloInt m=0; m<M; m++)
						lbound_temp1 += call_demand[m]*X_sol[i][j][m];
					lbound_temp2 = 0.5*(1+cv[i][j]*cv[i][j]) * (lbound_temp1*lbound_temp1) / (Q[i][j]*(Q[i][j]-lbound_temp1));
					lbound_temp2 += lbound_temp1 / Q[i][j];

					lbound -= C*lbound_temp2;
				}
			}
		}

		LB = max(LB, lbound);
		
		Num2DMatrix R_approx_new(env, N);
		for (IloInt i=0; i<N; i++)
			R_approx_new[i] = IloNumArray(env, N);

		for (IloInt i=0; i<N; i++) {			
			for (IloInt j=i+1; j<N; j++) {	
				if (links[i][j] == 1) {
					IloExpr cut_lhs(env);
					IloNum cut_rhs = 0;		

					IloNum cut_temp = 0;
					for (IloInt m=0; m<M; m++) {
						cut_temp += call_demand[m]*X_sol[i][j][m];
					}

					R_approx_new[i][j] = cut_temp / (Q[i][j] - cut_temp);
					//cout << "R_approx_new = "<<R_approx_new<<endl;
										
					for (IloInt m=0; m<M; m++)
						cut_lhs += call_demand[m]*X[i][j][m];					

					cut_lhs -= (Q[i][j]/((1+R_approx_new[i][j])*(1+R_approx_new[i][j])))*R[i][j];
					cut_rhs = Q[i][j]*((R_approx_new[i][j]/(1+R_approx_new[i][j])) *
												(R_approx_new[i][j]/(1+R_approx_new[i][j])));

					model.add(cut_lhs <= cut_rhs);
					cut_lhs.end();
				}				
			}
		}

		cout << "UB = "<<UB<<endl;
		cout << "LB = "<<LB<<endl;
		cout << "Gap (%) = "<<(UB-LB)*100/LB<<endl;
		//system("pause");

	}while ((UB-LB)/UB > eps);
	t2 = clock();
	float secs = (float)t2 - (float)t1;
	secs = secs / CLOCKS_PER_SEC;
	cout << "CPUTIME = "<<secs <<endl<<endl;
}
示例#17
0
void ScenarioProblem::addSimProblem(IloModel mod){

	mod.add(_simSP.getP());
	mod.add(_simSP.getD());
	mod.add(_simSP.getTheta());
	
	if(_pd->getGeneratorSwitch()){
		mod.add(_simSP.getY());
	}
	
	if(_pd->getEnergyStorage()){
		mod.add(_simSP.getE());
		mod.add(_simSP.getEDeltaPlus());
		mod.add(_simSP.getEDeltaMinus());
		mod.add(_simSP.getEnergyStorage());
	}

//	if(_pd->getReDispatch()&&index>0){
//		mod.add(_simSP.getPDelta());
//		mod.add(_simSP.getGenReDispatch());
//	}
	if(_pd->getReserve()){
		mod.add(_simSP.getR());
		mod.add(_simSP.getReserveMargin());
	//	if(index>0)	mod.add(_simSP.getRampingCapacity());
	}
	
	mod.add(_simSP.getF());
	mod.add(_simSP.getX());

	if(_pd->getLineSwitch()){
		mod.add(_simSP.getZ());
		mod.add(_simSP.getW());
	}
	
	mod.add(_simSP.getEnergyConservation());
	mod.add(_simSP.getPhaseAngleUp());
	mod.add(_simSP.getPhaseAngleDown());
	mod.add(_simSP.getLineLimitsUp());
	mod.add(_simSP.getLineLimitsDown());

	if(_pd->getCapacity()){
		mod.add(_simSP.getLineLimitsUpM());
		mod.add(_simSP.getLineLimitsDownM());
	}

	if(_pd->getLineSwitch()){
		mod.add(_simSP.getLineSwitch());
		mod.add(_simSP.getLineBurnt());
	}
	mod.add(_simSP.getGenLimitsUp());
	mod.add(_simSP.getGenLimitsDown());

	if(_pd->getEnergyStorage()){
		mod.add(	IloMaximize(	_pd->getEnv(),	_simSP.getSumD()	
					-.1*(  IloSum(_simSP.getEDeltaPlus()) + IloSum(_simSP.getEDeltaMinus())	)	
					));
	}
	else{
		mod.add(	IloMaximize(	_pd->getEnv(),	_simSP.getSumD() ));	
	}


}
示例#18
0
 void Instance::VerifySolution() {
     IloEnv env;
     IloInt i, j;
     IloModel model(env);
     IloInt nbImpressions = num_impressions_;
     IloInt nbAdvertisers = num_advertisers_;
     
     NumVarMatrix x(env, nbImpressions);
     // NumVarMatrix y(env, nbImpressions);
     
     for(i = 0; i < nbImpressions; i++) {
         x[i] = IloNumVarArray(env, nbAdvertisers, 0.0, 1.0, ILOFLOAT);
         // y[i] = IloNumVarArray(env, nbAdvertisers, 0.0, 1.0, ILOFLOAT);
     }
     
     // Add impression constraints.
     for(i = 0; i < nbImpressions; i++) {
         model.add(IloSum(x[i]) <= 1.0);
     }
     
     // Add weighted contraint.
     IloExpr weighted_constraint(env);
     for(j = 0; j < nbImpressions; j++) {      // demand must meet supply
         for(i = 0; i < nbAdvertisers; i++) {
             weighted_constraint += ((double) transpose_bids_matrix_[j][i]) * ((double) weights_[i]) * x[j][i];
         }
     }
     model.add(weighted_constraint <= ((double) global_problem_.budget_));
     weighted_constraint.end();
     
     IloExpr obj_exp(env);
     for(i = 0; i < nbImpressions; i++) {
         for(j = 0; j < nbAdvertisers; j++) {
             obj_exp += ((double) transpose_bids_matrix_[i][j]) * x[i][j];
         }
     }
     
     model.add(IloMaximize(env, obj_exp));
     obj_exp.end();
 
     IloCplex cplex(env);
     cplex.setOut(env.getNullStream());
     cplex.extract(model);
     
     // Optimize the problem and obtain solution.
     if ( !cplex.solve() ) {
         env.error() << "Failed to optimize LP" << endl;
         throw(-1);
     }
     
     IloNumArray vals(env);
     
     long double sum_b = 0;
     for (int a = 0; a < num_advertisers_; ++a) {
         //slacks_[a] = 0;
         for (i = 0; i < nbImpressions; i++) {
             if (cplex.getValue(x[i][a]) > 0) {
                 //slacks_[a] = slacks_[a] + cplex.getValue(x[i][a]) * bids_matrix_[a].find(i)->second;
                 sum_b += cplex.getValue(x[i][a]) * bids_matrix_[a].find(i)->second * weights_[a];
             }
         }
     }
     
     cout << "Cplex buget allocation is = ";
     cout << sum_b;
     cout << "\n";
     
     if (cplex.getObjValue() == CalculateGlobalMWProblemOpt()) {
         cout << "Solution checks \n";
     } else {
         cout << "Solution does not check, Cplex opt is ";
         cout << cplex.getObjValue();
         cout << "\n";
     }
     env.end();
 }
示例#19
0
void fagoc::Modelo_solver::impl::solve()
{
	/*******************************************************
	 *     INICIALIZAÇÃO DE VARIÁVEIS E REFERÊNCIAS        *
	 ******************************************************/

	const auto& disciplinas = parent.curso().disciplinas();
	const auto& horario = parent.horario();
	const auto& ofertadas = parent.curso().ofertadas();
	const auto num_disciplinas = parent.curso().num_disciplinas();
	const auto num_horas = parent.horario().size();

	// Variáveis do aluno
	const auto& aprovacoes = parent.aluno().aprovacoes();
	const auto& cursadas = parent.aluno().cursadas(); 
	const auto& periodo_aluno = parent.aluno().periodo();
	const auto& turma_aluno = parent.aluno().turma();

	auto periodo_alu_num = split_curso_string(periodo_aluno).first;

	// Preferências do aluno (mesma turma/período)
	std::vector<char> pref(num_disciplinas, 0);
	for (auto d = 0u; d < num_disciplinas; d++) {
		if (disciplinas[d].periodo == periodo_aluno
			&& disciplinas[d].turma == turma_aluno) {
			pref[d] = 1;
		}
	}

	/******************************************************
	 *                ELABORAÇÃO DO MODELO                *
	 ******************************************************/
	
	IloModel mod{env};
	// Variáveis de decisão
	IloBoolVarArray y(env, num_disciplinas);

	// Carga horária
	IloExpr carga{env};
	for (auto d = 0u; d < num_disciplinas; d++) {
		carga += disciplinas[d].credito * y[d];
	}
	// Preferências
	IloExpr mesma_turma{env};
	for (auto d = 0u; d < num_disciplinas; d++) {
		mesma_turma += pref[d] * y[d];
	}
	IloExpr obj{env};
	// Função objetivo
	obj += carga + 0.1 * mesma_turma;
	mod.add(IloMaximize(env, obj));
	obj.end();

	/*****************************************************
	 *                   RESTRIÇÕES					     *
	 *****************************************************/

	// Período mínimo
	for (auto d = 0u; d < num_disciplinas; d++) {
		auto periodo_disc_num = split_curso_string(disciplinas[d].periodo_minimo).first;
		mod.add(y[d] * periodo_disc_num <= periodo_alu_num);
	}
	// Pré-requisitos
	for (auto d = 0u; d < num_disciplinas; d++) {
		auto num_prereq = 0;
		auto prereq_aprov = 0;
		for (auto p = 0u; p < num_disciplinas; p++) {
			if (!disciplinas[d].prerequisitos[p]) {
				continue;
			}
			num_prereq++;
			if (aprovacoes[p]) {
				prereq_aprov++;
			}
			/*
			for (auto i = 0u; i < num_disciplinas; i++) {
				if (disciplinas[p].equivalentes[i] && aprovacoes[i]) {
					prereq_aprov++;
					break;
				}
			}
			*/
		}
		mod.add(num_prereq * y[d] <= prereq_aprov);
	}

	// Co-requisitos
	for (auto d = 0u; d < num_disciplinas; d++) {
		for (auto c = 0u; c < num_disciplinas; c++) {
			if (disciplinas[d].corequisitos[c]) {
				/*
				auto coreq_cumprido = 0;
				for (auto i = 0u; i < num_disciplinas; i++) {
					if (disciplinas[c].equivalentes[i] && cursadas[i]) {
						coreq_cumprido = 1;
						break;
					}
				}
				*/
				auto coreq_cumprido = cursadas[c];
				mod.add(y[d] <= y[c] + coreq_cumprido);
			}
		}
	}

	// Disciplinas equivalentes
	/*
	for (auto d = 0u; d < num_disciplinas; d++) {
		IloExpr disc_equiv(env);
		for (auto e = 0u; e < num_disciplinas; e++) {
			disc_equiv += disciplinas[d].equivalentes[e] * y[e];
		}
		mod.add(disc_equiv <= 1);
		disc_equiv.end();
	}
	*/

	// Cria as restrições dos horários
	for (auto h = 0u; h < num_horas; h++) {
		IloExpr disc_concorrente(env);
		for (auto d = 0u; d < num_disciplinas; d++) {
			disc_concorrente += horario[h][d] * y[d];
		}
		mod.add(disc_concorrente <= 1);
		disc_concorrente.end();
	}

	// Disciplinas já aprovadas
	for (auto d = 0u; d < num_disciplinas; d++) {
		/*
		auto aprovacao_equivalente = 0;
		for (auto i = 0u; i < num_disciplinas; i++) {
			if (disciplinas[d].equivalentes[i] && aprovacoes[i]) {
				aprovacao_equivalente = 1;
				break;
			}
		}
		*/
		auto aprovacao_equivalente = aprovacoes[d];
		mod.add(y[d] <= 1 - aprovacao_equivalente);
	}

	// Disciplinas ofertadas
	for (auto d = 0u; d < num_disciplinas; d++) {
		mod.add(y[d] <= ofertadas[d]);
	}

	/********************************************************
	 *                RESOLUÇÃO DO MODELO                   *
	 ********************************************************/


	// Se o número de disciplinas for menor que 30, utiliza
	// o CPLEX. Se for maior, a versão community não resolve, então
	// utiliza-se o CP Optimizer
	IloNumArray solucao_cplex(env);
	double funcao_objetivo;
	if (num_disciplinas <= 30) {
		IloCplex cplex{mod};
		// Se o tempo limite foi configurado, aplicá-lo ao CPLEX
		if (tempo_limite != 0) {
			cplex.setParam(IloCplex::Param::TimeLimit, tempo_limite);
		}
		cplex.setOut(env.getNullStream());
		cplex.solve();

		funcao_objetivo = cplex.getObjValue();
		cplex.getValues(solucao_cplex, y);
	} else {
		IloCP cp{mod};
		// Se o tempo limite foi configurado, aplicá-lo ao CPLEX
		if (tempo_limite != 0) {
			cp.setParameter(IloCP::TimeLimit, tempo_limite);
		}
		cp.setOut(env.getNullStream());
		cp.solve();

		funcao_objetivo = cp.getObjValue();
		cp.getValues(y, solucao_cplex);
	}
	solucao = Solucao{num_disciplinas, funcao_objetivo, parent.aluno().nome()};
	// Atribui resposta às variáveis membro
	for (auto d = 0u; d < num_disciplinas; d++) {
		if (solucao_cplex[d]) {
			solucao.solucao_bool[d] = 1;
			solucao.nomes_disciplinas.push_back(disciplinas[d].id);
		}
	}
}
示例#20
0
int
main()
{
    IloEnv env;
    try {
        NumMatrix cost(env, nbMonths);
        cost[0]=IloNumArray(env, nbProducts, 110.0, 120.0, 130.0, 110.0, 115.0);
        cost[1]=IloNumArray(env, nbProducts, 130.0, 130.0, 110.0,  90.0, 115.0);
        cost[2]=IloNumArray(env, nbProducts, 110.0, 140.0, 130.0, 100.0,  95.0);
        cost[3]=IloNumArray(env, nbProducts, 120.0, 110.0, 120.0, 120.0, 125.0);
        cost[4]=IloNumArray(env, nbProducts, 100.0, 120.0, 150.0, 110.0, 105.0);
        cost[5]=IloNumArray(env, nbProducts,  90.0, 100.0, 140.0,  80.0, 135.0);

        // Variable definitions
        IloNumVarArray produce(env, nbMonths, 0, IloInfinity);
        NumVarMatrix   use(env, nbMonths);
        NumVarMatrix   buy(env, nbMonths);
        NumVarMatrix   store(env, nbMonths);
        IloInt i, p;
        for (i = 0; i < nbMonths; i++) {
            use[i]   = IloNumVarArray(env, nbProducts, 0, IloInfinity);
            buy[i]   = IloNumVarArray(env, nbProducts, 0, IloInfinity);
            store[i] = IloNumVarArray(env, nbProducts, 0, 1000);
        }
        IloExpr profit(env);

        IloModel model(env);

        // For each type of raw oil we must have 500 tons at the end
        for (p = 0; p < nbProducts; p++) {
            store[nbMonths-1][p].setBounds(500, 500);
        }

        // Constraints on each month
        for (i = 0; i < nbMonths; i++) {
            // Not more than 200 tons of vegetable oil can be refined
            model.add(use[i][v1] + use[i][v2] <= 200);

            // Not more than 250 tons of non-vegetable oil can be refined
            model.add(use[i][o1] + use[i][o2] + use[i][o3] <= 250);

            // Constraints on food composition
            model.add(3 * produce[i] <=
                      8.8 * use[i][v1] + 6.1 * use[i][v2] +
                      2   * use[i][o1] + 4.2 * use[i][o2] + 5 * use[i][o3]);
            model.add(8.8 * use[i][v1] + 6.1 * use[i][v2] +
                      2   * use[i][o1] + 4.2 * use[i][o2] + 5 * use[i][o3]
                      <= 6 * produce[i]);
            model.add(produce[i] == IloSum(use[i]));

            // Raw oil can be stored for later use
            if (i == 0) {
                for (IloInt p = 0; p < nbProducts; p++)
                    model.add(500 + buy[i][p] == use[i][p] + store[i][p]);
            }
            else {
                for (IloInt p = 0; p < nbProducts; p++)
                    model.add(store[i-1][p] + buy[i][p] == use[i][p] + store[i][p]);
            }

            // Logical constraints
            // The food cannot use more than 3 oils
            // (or at least two oils must not be used)
            model.add((use[i][v1] == 0) + (use[i][v2] == 0) + (use[i][o1] == 0) +
                      (use[i][o2] == 0) + (use[i][o3] == 0) >= 2);

            // When an oil is used, the quantity must be at least 20 tons
            for (p = 0; p < nbProducts; p++)
                model.add((use[i][p] == 0) || (use[i][p] >= 20));

            // If products v1 or v2 are used, then product o3 is also used
            model.add(IloIfThen(env, (use[i][v1] >= 20) || (use[i][v2] >= 20),
                                use[i][o3] >= 20));

            // Objective function
            profit += 150 * produce[i] - IloScalProd(cost[i], buy[i]) -
                      5 * IloSum(store[i]);
        }

        // Objective function
        model.add(IloMaximize(env, profit));

        IloCplex cplex(model);

        if (cplex.solve()) {
            cout << "Solution status: " << cplex.getStatus() << endl;
            cout << " Maximum profit = " << cplex.getObjValue() << endl;
            for (IloInt i = 0; i < nbMonths; i++) {
                IloInt p;
                cout << " Month " << i << " " << endl;
                cout << "  . buy   ";
                for (p = 0; p < nbProducts; p++) {
                    cout << cplex.getValue(buy[i][p]) << "\t ";
                }
                cout << endl;
                cout << "  . use   ";
                for (p = 0; p < nbProducts; p++) {
                    cout << cplex.getValue(use[i][p]) << "\t ";
                }
                cout << endl;
                cout << "  . store ";
                for (p = 0; p < nbProducts; p++) {
                    cout << cplex.getValue(store[i][p]) << "\t ";
                }
                cout << endl;
            }
        }
        else {
            cout << " No solution found" << endl;
        }
    }
    catch (IloException& ex) {
        cerr << "Error: " << ex << endl;
    }
    catch (...) {
        cerr << "Error" << endl;
    }
    env.end();
    return 0;
}