Пример #1
0
// This routine separates Benders' cuts violated by the current x solution.
// Violated cuts are found by solving the worker LP
//
IloBool
separate(const Arcs x, const IloNumArray2 xSol, IloCplex cplex,
         const IloNumVarArray v, const IloNumVarArray u,
         IloObjective obj, IloExpr cutLhs, IloNum& cutRhs)
{
   IloBool violatedCutFound = IloFalse;

   IloEnv env = cplex.getEnv();
   IloModel mod = cplex.getModel();

   IloInt numNodes = xSol.getSize();
   IloInt numArcs  = numNodes * numNodes;
   IloInt i, j, k, h;

   // Update the objective function in the worker LP:
   // minimize sum(k in V0) sum((i,j) in A) x(i,j) * v(k,i,j)
   //          - sum(k in V0) u(k,0) + sum(k in V0) u(k,k)
   
   mod.remove(obj);
   IloExpr objExpr = obj.getExpr();
   objExpr.clear();
   for (k = 1; k < numNodes; ++k) {
      for (i = 0; i < numNodes; ++i) {
         for (j = 0; j < numNodes; ++j) {
               objExpr +=  xSol[i][j] * v[(k-1)*numArcs + i*numNodes + j];
         }
      }
   }
   for (k = 1; k < numNodes; ++k) {
      objExpr += u[(k-1)*numNodes + k];
      objExpr -= u[(k-1)*numNodes];
   }
   obj.setExpr(objExpr);
   mod.add(obj);
   objExpr.end(); 

   // Solve the worker LP

   cplex.solve();

   // A violated cut is available iff the solution status is Unbounded

   if ( cplex.getStatus() == IloAlgorithm::Unbounded ) {

      IloInt vNumVars = (numNodes-1) * numArcs;
      IloNumVarArray var(env);
      IloNumArray val(env);

      // Get the violated cut as an unbounded ray of the worker LP

      cplex.getRay(val, var);

      // Compute the cut from the unbounded ray. The cut is:
      // sum((i,j) in A) (sum(k in V0) v(k,i,j)) * x(i,j) >=
      // sum(k in V0) u(k,0) - u(k,k)

      cutLhs.clear();
      cutRhs = 0.;

      for (h = 0; h < val.getSize(); ++h) {

         IloInt *index_p = (IloInt*) var[h].getObject();
         IloInt index = *index_p;

         if ( index >= vNumVars ) {
            index -= vNumVars;
            k = index / numNodes + 1;
            i = index - (k-1)*numNodes;
            if ( i == 0 )
               cutRhs += val[h];
            else if ( i == k )
               cutRhs -= val[h];
         }
         else {
            k = index / numArcs + 1;
            i = (index - (k-1)*numArcs) / numNodes;
            j = index - (k-1)*numArcs - i*numNodes;
            cutLhs += val[h] * x[i][j];
         }
      }

      var.end();
      val.end();

      violatedCutFound = IloTrue;
   }

   return violatedCutFound;

} // END separate
Пример #2
0
ILOSTLBEGIN

int main(int argc, char **argv) 
{
	IloEnv env;	
	try 
	{
		
		IloArray<IloNumArray> distance(env);
		
		//Model Initialization
		IloModel model(env);

		//Taking Data from Distance Data File
		ifstream in;
		in.open("carpool-data.txt",ios::in);
		in >> distance;
		in.close();
		cout<<distance<<endl;
		
		//2D Array for Results
		IloArray<IloNumArray> X_val(env, 7);
		for (int i = 0; i < 7; i++)
		{
			X_val[i] = IloNumArray(env,7);
		}

		IloArray<IloNumArray> Y_val(env, 7);
		for (int i = 0; i < 7; i++)
		{
			Y_val[i] = IloNumArray(env,7);
		}

		//2D Array for Xij
		IloArray<IloNumVarArray> X(env, 7);
		for (int i = 0; i < 7; i++)
		{
			X[i] = IloNumVarArray(env,7,0,1,ILOINT);
		}

		//2D Array for Yij
		IloArray<IloNumVarArray> Y(env, 7);
		for (int i = 0; i < 7; i++)
		{
			Y[i] = IloNumVarArray(env,7,0,1,ILOINT);
		}

		// 1D array for Ui and U-val
		//IloNumVarArray U(env,7,0,7,ILOINT);
		//IloNumArray U_val(env,7);

		// Defining Obj to be equal to sum-product(Dij*Xij + Dij*Yij)
 		IloExpr Obj(env);
 		for (int i = 0; i < 7; ++i)
 		{
 			for (int j = 0; j < 7; j++)
 			{
				if(i != j)
				{
 				Obj += distance[i][j]*X[i][j] + distance[i][j]*Y[i][j];
				}
 			}
 		}
		
		//model.add(IloMaximize(env,Obj)); // IloMinimize is used for minimization problems
		//Alternatively, model.add(IloMaximize(env,Obj)); can be replaced by the following three lines.
		//This is useful while iterating in Decomposition Techniques where the objective function is redefined at each iteration
		IloObjective Objective = IloMinimize(env); 
		model.add(Objective); 
		Objective.setExpr(Obj);
		Obj.end();

		//Constraints for the model

		//One Input per Node except Office
		IloExpr Input(env);
		for (int i = 0; i < 6; i++)
		{
			for (int j = 0; j < 7; j++)
			{
				if(i != j )
				{
				Input += X[i][j] + Y[i][j];
				}
			}
			model.add(Input == 1);
		}
		Input.end();
		
		//One Output per Node except Office
		IloExpr Output(env);
		for (int j = 0; j < 6; j++)
		{
			for (int i = 0; i < 7; i++)
			{
				if(i != j )
				{
				Output += X[i][j] + Y[i][j];
				}
			}
			model.add(Output == 1);
		}
		Output.end();
	
		//Ensuring 2 entries and exits for the Office node
		IloExpr Entryx(env);
		for (int i = 0; i <6; i++)
		{
			Entryx = Entryx + X[i][6];		
		}
		model.add(Entryx == 1);
		Entryx.end();

		IloExpr Exitx(env);
		for (int i = 0; i <6; i++)
		{
			Exitx = Exitx + X[6][i];
		}
		model.add(Exitx == 1);
		Exitx.end();

		IloExpr Entryy(env);
		for (int i = 0; i <6; i++)
		{
			Entryy = Entryy + Y[i][6];		
		}
		model.add(Entryy == 1);
		Entryy.end();

		IloExpr Exity(env);
		for (int i = 0; i <6; i++)
		{
			Exity = Exity + Y[6][i];
		}
		model.add(Exity == 1);
		Exity.end();

		// Optimize
		IloCplex cplex(model);
		cplex.setOut(env.getNullStream()); // if we get an empty stream in return
		//cplex.setWarning(env.getNullStream());
		cplex.solve();//solving the MODEL
		//cout << "hey there I reached the breakpoint" << endl;
		if (cplex.getStatus() == IloAlgorithm::Infeasible) // if the problem is infeasible
		{
			env.out() << "Problem Infeasible" << endl; 
		}
		for(int i = 0; i < 7 ; i++)
		{
			cplex.getValues(X_val[i], X[i]);
		}
		cout<<X_val<<endl;
		for(int i = 0; i < 7 ; i++)
		{
			cplex.getValues(Y_val[i], Y[i]);
		}
		cout<<Y_val<<endl;
		//	cplex.getValues(U_val,U);
		// Print results
		cout<< "Objective Value = " << cplex.getObjValue() << endl;
		//cout<<"X = "<<X_val<<endl;
	}
	catch(IloException &e) 
	{
		env.out() << "ERROR: " << e << endl;
	}
	catch(...)
	{
		env.out() << "Unknown exception" << endl;
	}
	env.end();
	return 0;
}
Пример #3
0
/** Separation function.
 * This function is invoked whenever CPLEX finds an integer feasible
 * solution. It then separates either feasibility or optimality cuts
 * on this solution.
 */
void BendersOpt::LazyConstraintCallback::main() {
   std::cout << "Callback invoked. Separate Benders cuts." << std::endl;

   IloNumArray x(getEnv());
   IloNumArray rayVals(getEnv());
   IloNumVarArray rayVars(getEnv());
   IloNumArray cutVal(getEnv());
   IloNumVarArray cutVar(getEnv());

   getValues(x, master->vars);

   bool error = false;

   // Iterate over blocks and trigger a separation on each of them.
   // The separation is triggered asynchronously so that it can happen
   // on different remote objects simultaneously.
   for (BlockVector::size_type b = 0; b < blocks.size(); ++b) {
      Block *const block = blocks[b];

      // Remove current objective from the block's model.
      IloModel model = block->cplex.getModel();
      IloObjective obj = block->obj;
      model.remove(obj);
      IloExpr newObj = obj.getExpr();
         
      // Iterate over the fixed master variables in this block to update
      // the block's objective function.
      // Each fixed variable goes to the right-hand side and therefore
      // into the objective function.
      for (std::vector<Block::FixData>::const_iterator it = block->fixed.begin(); it != block->fixed.end(); ++it)
         newObj -= block->vars[it->row] * (it->val * x[it->col]);
      obj.setExpr(newObj);
      model.add(obj);
      newObj.end();

      // If the problem is unbounded we need to get an infinite ray in
      // order to be able to generate the respective Benders cut. If
      // CPLEX proves unboundedness in presolve then it will return
      // CPX_STAT_INForUNBD and no ray will be available. So we need to
      // disable presolve.
      block->cplex.setParam(IloCplex::Param::Preprocessing::Presolve, false);
      block->cplex.setParam(IloCplex::Param::Preprocessing::Reduce, 0);

      // Solve the updated problem to optimality.
      block->cplex.setParam(IloCplex::Param::RootAlgorithm, IloCplex::Primal);
      try {
         handles[b] = block->cplex.solve(true);
      } catch (...) {
         // If there is an exception then we need to kill and join
         // all remaining solves. Otherwise we may leak handles.
         while (--b > 0) {
            handles[b].kill();
            handles[b].join();
         }
         throw;
      }
   }

   // Wait for the various LP solves to complete.
   for (BlockVector::size_type b = 0; b < blocks.size(); ++b)
      handles[b].join();

   // See if we need to generate cuts.
   for (BlockVector::size_type b = 0; b < blocks.size(); ++b) {
      Block *const block = blocks[b];
      cutVal.clear();
      cutVar.clear();
      double cutlb = -IloInfinity;
      double cutub = IloInfinity;

      // We ust STL types here since they are exception safe.
      std::vector<double> tmp(master->vars.getSize(), 0);
      std::map<IloNumVar,double,ExtractableLess<IloNumVar> > rayMap;

      // Depending on the status either seperate a feasibility or an
      // optimality cut.
      switch (block->cplex.getStatus()) {
      case IloAlgorithm::Unbounded:
         {
            // The subproblem is unbounded. We need to extract a feasibility
            // cut from an unbounded ray of the problem (see also the comments
            // at the top of this file).
            std::cout << "unbounded ";
            block->cplex.getRay(rayVals, rayVars);
            cutub = 0.0;
            for (IloInt j = 0; j < rayVars.getSize(); ++j) {
               cutub -= rayVals[j] * block->objMap[rayVars[j]];
               rayMap[rayVars[j]] = rayVals[j];
            }
            for (std::vector<Block::FixData>::const_iterator it = block->fixed.begin(); it != block->fixed.end(); ++it)
               tmp[it->col] -= it->val * rayMap[block->vars[it->row]];
            for (IloInt j = 0; j < master->vars.getSize(); ++j) {
               if ( fabs (tmp[j]) > 1e-6 ) {
                  cutVar.add(master->vars[j]);
                  cutVal.add(tmp[j]);
               }
            }
         }
         break;
      case IloAlgorithm::Optimal:
         {
            // The subproblem has a finite optimal solution.
            // We need to check if this gives rise to an optimality cut (see
            // also the comments at the top of this file).            
            std::cout << "optimal ";
            double const objval = block->cplex.getObjValue();
            double const eta = x[etaind + b];
            block->cplex.getValues(block->vars, rayVals);
            
            if ( objval > eta + 1e-6 ) {
               cutub = 0.0;
               for (IloInt j = 0; j < block->vars.getSize(); ++j)
                  cutub -= rayVals[j] * block->objMap[block->vars[j]];
               for (std::vector<Block::FixData>::const_iterator it = block->fixed.begin(); it != block->fixed.end(); ++it)
                  tmp[it->col] -= it->val * rayVals[it->row];
               for (IloInt j = 0; j < master->vars.getSize(); ++j) {
                  if ( fabs (tmp[j]) > 1e-6 ) {
                     cutVal.add(tmp[j]);
                     cutVar.add(master->vars[j]);
                  }
               }
               cutVal.add(-1.0);
               cutVar.add(master->vars[etaind + b]);
            }
         }
         break;
      default:
         std::cerr << "Unexpected status " << block->cplex.getStatus()
                   << std::endl;
         error = true;
         break;
      }
      
      // If a cut was found then add that.
      if ( cutVar.getSize() > 0 ) {
         IloExpr expr(master->env);
         for (IloInt i = 0; i < cutVar.getSize(); ++i)
            expr += cutVar[i] * cutVal[i];
         IloRange cut(getEnv(), cutlb, expr, cutub);
         expr.end();
         std::cout << "cut found: " << cut << std::endl;
         add(cut).end();
      }
      else
         std::cout << "no cuts." << std::endl;
   }
   cutVar.end();
   cutVal.end();
   rayVars.end();
   rayVals.end();
   x.end();
   if ( error )
      throw -1;
}
Пример #4
0
int SolveLpByRuleGeneral(const RULES InputRule,
	const std::vector<REQ> &Request,
	const std::vector<DAY> &Day,
	const std::vector<AIRLINE> &AirLine,
	std::vector<CAPCONSTRAIN> &CapCon,
	std::vector<double> &SolVal)
{
	try{
		ofstream CheckSolStatus;
		CheckSolStatus.open("..//OutPut//CplexSatus.txt", ios::trunc);
		IloBool SolErr= 0;
		double CurrentProportionEps;
		if (isIterativeReduceEps)
		{
			CurrentProportionEps = StartingProptionEps;
		}
		else
		{
			CurrentProportionEps = ProportionFairEps;
		}
		std::vector<int> ReqSecq2Var;//map Request sequence to variable location
		std::vector<int> Var2ReqSecq;// revers map Var to request sequence
		std::vector<int> ReqSecq2ID; // map request sequence to request ID
		std::vector<int> ReqSecq2DumVar;  // map request to dummy variable locations
		std::vector<int> ID2ReqSecq(Request.size(), InvalidInt);// map request ID to reqeuset secquence
		std::vector<int> Rio2AirLine;// 

		int NumActRow = 0;
		int NumVar =
			getNumVar(InputRule, Request, ReqSecq2Var, Var2ReqSecq,
			ReqSecq2ID, ID2ReqSecq, ReqSecq2DumVar);
		int NumAirLineByRule = getAirNumVar(InputRule, AirLine, Rio2AirLine);
		assert(NumVar > 0); assert(NumAirLineByRule > 0);
		int Pos;
		double obj = 0.0;
		IloEnv env;
		/***********create variable***************/
		IloNumVarArray Xmt(env, NumVar, 0, 1, ILOINT);
		//IloNumVar DummyTotalObj(env);

		//IloNumVarArray Xmt(env, NumVar, 0, 1, ILOFLOAT);

		IloModel LpModel(env);
		IloExpr TotalDispExp(env);
		IloExpr WeightedTotalDispExp(env);
		IloExpr FairObjExp(env);
		IloExprArray GainEpr(env, Rio2AirLine.size()), LossEpr(env, Rio2AirLine.size());
		for (int i = 0; i < Rio2AirLine.size(); i++)
		{
			GainEpr[i] = IloExpr(env);
			LossEpr[i] = IloExpr(env);
		}
		/***********Add objective Function***************/
		//setDispObj(InputRule, env, LpModel, DummyDisplaceObj, Xmt, Rio2AirLine, Request, AirLine, ID2ReqSecq, ReqSecq2Var, ReqSecq2DumVar);

		getDispExps(InputRule, env, LpModel, TotalDispExp, WeightedTotalDispExp, Xmt, Rio2AirLine, Request, AirLine, ID2ReqSecq, ReqSecq2Var, ReqSecq2DumVar);
		//LpModel.add(DummyTotalObj >= TotalDispExp);
		IloObjective OBJ = IloMinimize(env);
		//set displacement objective

		if (DispObj == Disp)
		{
			OBJ.setExpr(TotalDispExp);
			//OBJ.setExpr(DummyTotalObj);
		}
		if (DispObj == WeightDisp)
		{
			OBJ.setExpr(WeightedTotalDispExp);
		}
		
		LpModel.add(OBJ);
		/***********Add definational constraints***************/
		setDefCon(InputRule, env, LpModel, Xmt, Request, ReqSecq2Var, ID2ReqSecq, ReqSecq2DumVar);
		/***********Solve the cplex model***************/
		IloCplex cplex(env);
		cplex.setOut(env.getNullStream());
#ifdef DEBUG
		cplex.setOut(CplexLog);
#endif
		cplex.setParam(IloCplex::Param::TimeLimit, CplexMaxCpuTime);
		//cplex.setParam(IloCplex::Param::MIP::Tolerances::MIPGap, CplexRelGap);

		/*if (FairObj!=NoFair)
			cplex.setParam(IloCplex::Param::MIP::Tolerances::MIPGap, CplexRelGap);*/
		cplex.extract(LpModel);
		SolErr = cplex.solve();
		CheckSolStatus << cplex.getCplexStatus() << "\t" << SolErr << "\t" << cplex.getMIPRelativeGap() << "\t" << cplex.getCplexTime() << endl;
		//cout << "obj = "<<cplex.getObjValue() << endl;
		/***********Add violated constraints***************/

		IloExprArray NewCons(env);
		addVioCapConByDay(InputRule, env, LpModel, cplex, NewCons, Xmt, CapCon, Request, Day, ReqSecq2Var, ID2ReqSecq);
		addTurnRoundCon(InputRule, env, LpModel, cplex, NewCons, Xmt, Request, ReqSecq2Var, ID2ReqSecq);

		while (NewCons.getSize() > 0)
		{
			for (int i = 0; i < NewCons.getSize(); i++)
			{
				LpModel.add(NewCons[i]);
			}
			NumActRow += (int)NewCons.getSize();
			cplex.extract(LpModel);
			SolErr = cplex.solve();
			CheckSolStatus << cplex.getCplexStatus() << "\t" << SolErr <<"\t"<<cplex.getMIPRelativeGap()<<"\t"<<cplex.getCplexTime()<<endl;
			//printf("disp = %f \n", cplex.getValue(TotalDispExp));
			//if (FairObj == EnvyFun)
			//{
			//	printf("disp = %f \n", cplex.getValue(DummyDisplaceObj));
			//	printf("envy obj = %f \n", cplex.getValue(FairObjExp));
			//}
			NewCons.clear();
			addVioCapConByDay(InputRule, env, LpModel, cplex, NewCons, Xmt, CapCon, Request, Day, ReqSecq2Var, ID2ReqSecq);
			addTurnRoundCon(InputRule, env, LpModel, cplex, NewCons, Xmt, Request, ReqSecq2Var, ID2ReqSecq);
		}
#ifdef DEBUG
		cout << "Dummy displacment obj ="<<cplex.getValue(TotalDispExp) <<" expre value"<<cplex.getValue(TotalDispExp)<< endl;
#endif
		
		if (FairObj == EnvyFun){
BiObj:
			LpModel.remove(OBJ);
			GetEnvyLossAndGainExp(InputRule, env, LpModel, GainEpr, LossEpr, Xmt, Rio2AirLine, Request, AirLine, ID2ReqSecq, ReqSecq2Var, ReqSecq2DumVar);
			FairObjExp.clear();
			for (int i = 0; i < Rio2AirLine.size(); i++)
			{
				FairObjExp += EnvyGainWeight*GainEpr[i] + EnvyLossWeight*LossEpr[i];
			}
			OBJ.setExpr(EnvyFairWeight*FairObjExp + TotalDispExp);
			LpModel.add(OBJ);
			cplex.extract(LpModel);
			SolErr = cplex.solve();
			//CheckSolStatus << cplex.getCplexStatus() << "\t" << SolErr << endl;
			//printf("disp = %f \n", cplex.getValue(TotalDispExp));
			//printf("envy obj = %f \n", cplex.getValue(FairObjExp));
			//GetEnvyLossAndGainValue(InputRule, env, LpModel, cplex, Xmt, Rio2AirLine, Request, AirLine, ID2ReqSecq, ReqSecq2Var, ReqSecq2DumVar);
			//for (int i = 0; i < Rio2AirLine.size(); i++)
			//{
			//	//LogMsg("gain = %f, loss = %f \n", cplex.getValue(Gain[i]), cplex.getValue(Loss[i]));
			//	LogMsg("gain = %f, loss = %f \n", cplex.getValue(GainEpr[i]), cplex.getValue(LossEpr[i]));
			//}
			NewCons.clear();
			addVioCapConByDay(InputRule, env, LpModel, cplex, NewCons, Xmt, CapCon, Request, Day, ReqSecq2Var, ID2ReqSecq);
			addTurnRoundCon(InputRule, env, LpModel, cplex, NewCons, Xmt, Request, ReqSecq2Var, ID2ReqSecq);
		
			while (NewCons.getSize() > 0)
			{
				for (int i = 0; i < NewCons.getSize(); i++)
				{
					LpModel.add(NewCons[i]);
				}
				NumActRow += (int)NewCons.getSize();
				cplex.extract(LpModel);
				SolErr = cplex.solve();
			
				CheckSolStatus << cplex.getCplexStatus() << "\t" << SolErr << "\t" << cplex.getMIPRelativeGap() << "\t" << cplex.getCplexTime() << endl;
				
				printf("disp = %f \n", cplex.getValue(TotalDispExp));
				printf("envy obj = %f \n", cplex.getValue(FairObjExp));
				NewCons.clear();
				addVioCapConByDay(InputRule, env, LpModel, cplex, NewCons, Xmt, CapCon, Request, Day, ReqSecq2Var, ID2ReqSecq);
				addTurnRoundCon(InputRule, env, LpModel, cplex, NewCons, Xmt, Request, ReqSecq2Var, ID2ReqSecq);
			}
			if (SolErr == 0)
			{// resolve displcement first
				LpModel.remove(OBJ);
				OBJ.setExpr(TotalDispExp);
				LpModel.add(OBJ);
				cplex.extract(LpModel);
				SolErr = cplex.solve();
				CheckSolStatus << cplex.getCplexStatus() << "\t" << SolErr << "\t" << cplex.getMIPRelativeGap() << "\t" << cplex.getCplexTime() << endl;
				cout << "reinitialize is called" << endl;

				if (SolErr == 0)
				{
					cout << "Resolve falils" << endl;
					system("Pause");
				}
				else
				{
					goto BiObj;
				}
			}
		}


	AddFairEpsConstraint:
		int totalFairConstraint = 0;
		if (ProportionFairEps>MyZero&&EpsCon != NoEps)
		{
			NewCons.clear();
			addEpsConstraint(InputRule, env, LpModel,  Xmt, cplex, NewCons, Rio2AirLine, Request, AirLine, ID2ReqSecq, ReqSecq2Var, ReqSecq2DumVar, CurrentProportionEps);
			totalFairConstraint += (int)NewCons.getSize();
			while (NewCons.getSize() > 0)
			{
				for (int i = 0; i < NewCons.getSize(); i++)
				{
					LpModel.add(NewCons[i]);
				}
				NumActRow += (int)NewCons.getSize();
				cplex.extract(LpModel);
				SolErr = cplex.solve();
				CheckSolStatus << cplex.getCplexStatus() << "\t" << SolErr << "\t" << cplex.getMIPRelativeGap() << "\t" << cplex.getCplexTime() << endl;
//#ifdef DEBUG
				//cout << "Dummy displacment obj ="<<cplex.getValue(DummyDisplaceObj) <<" expre value"<<cplex.getValue(TotalDispExp)<< endl;
				//cout << "Total fair constraint added is " << totalFairConstraint << "; Obj = " <<cplex.getObjValue() << endl;
//#endif // DEBUG
				NewCons.clear();
				//addFairConstraints(InputRule, env, LpModel, DummyDisplaceObj, Xmt, cplex, NewCons, Rio2AirLine, Request, AirLine, ID2ReqSecq, ReqSecq2Var, ReqSecq2DumVar);
				addEpsConstraint(InputRule, env, LpModel,  Xmt, cplex, NewCons, Rio2AirLine, Request, AirLine, ID2ReqSecq, ReqSecq2Var, ReqSecq2DumVar, CurrentProportionEps);
				totalFairConstraint += (int)NewCons.getSize();
				//addAbsFairnessConstraint(InputRule, env, LpModel, DummyDisplaceObj, Xmt, cplex, NewCons, Rio2AirLine, Request, AirLine, ID2ReqSecq, ReqSecq2Var, ReqSecq2DumVar);
				addVioCapConByDay(InputRule, env, LpModel, cplex, NewCons, Xmt, CapCon, Request, Day, ReqSecq2Var, ID2ReqSecq);
				addTurnRoundCon(InputRule, env, LpModel, cplex, NewCons, Xmt, Request, ReqSecq2Var, ID2ReqSecq);
			}
		}
		// iterative add eps constraints
		if (CurrentProportionEps > ProportionFairEps && (ProportionFairEps > MyZero) && EpsCon != NoEps)
		{
			if (isIterativeReduceEps)
			{
				CurrentProportionEps = std::max(CurrentProportionEps - 0.1, ProportionFairEps);
				goto AddFairEpsConstraint;
			}

		}

		if (isSolveByRule) UpdateCapConByDay(InputRule, cplex, Xmt, CapCon, Request, Day, ReqSecq2Var, ID2ReqSecq);
		//compute for the weighted
		//set SolValue
		for (auto r = Request.begin(); r != Request.end(); r++)
		{
			if (isSolveByRule)
			{
				if (r->Rule != InputRule) continue;
			}
			for (int t = 0; t < NT; t++)
			{
				Pos = ReqSecq2Var[ID2ReqSecq[r->ID]] + t;
				SolVal[r->ID*NT + t] = cplex.getValue(Xmt[Pos]);
			}
			if (isIngoreDummy) continue;
			SolVal[Request.size()*NT + r->ID] = cplex.getValue(Xmt[ReqSecq2DumVar[ID2ReqSecq[r->ID]]]);
		}

		TestCaseSum.back().NumRowGenByRule[InputRule] = NumActRow;
		CheckSolStatus.close();

		TestCaseSum.back().CplexRelativeGapByRule[InputRule] = cplex.getMIPRelativeGap();



		env.end();
		return 0;
	}
	catch (IloException& e) {
		ofstream FinalOut;
		if (isDefaultFolder) FinalOut.open("..//OutPut//Summary.txt", ios::app);
		else FinalOut.open((OutPutFolder + "Summary.txt").c_str(), ios::app);

		FinalOut << "************Warning on cplex****************" << endl;
		cerr << " ERROR: " << e << endl;
		FinalOut << " ERROR: " << e << endl;
		FinalOut.close();
		return 1;
	}
	catch (...) {
		cerr << " ERROR" << endl;
		return 1;
	}
}