示例#1
0
/*------------------------------------------------------------------------*/
CoinPackedVector *
DecompCutPool::createRowReform(const int                  n_corecols,
                               const CoinPackedVector* row,
                               const DecompVarList&       vars)
{
   double coeff;
   //---
   //--- Create a dense row from the original sparse row (in terms of x).
   //---
   double* rowDense  = row->denseVector(n_corecols);
   //---
   //--- In order to expand to the reformulated row (in terms of lambda),
   //--- we need to substitute x = sum{s in F'} s lambda[s]
   //---
   //--- Example - Given a cut:
   //---   a[1]x[1] + a[2]x[2] >= b
   //---   a[1]x[1]             = a[1] (s1[1] lam[1] + s2[1] lam[2])
   //---              a[2]x[2]  = a[2] (s1[2] lam[1] + s2[2] lam[2])
   //--- So,   lam[1]'s coeff   = a[1] s1[1] + a[2] s1[2]
   //---       lam[2]'s coeff   = a[1] s2[1] + a[2] s2[2]
   //---
   int col_index                  = 0;
   CoinPackedVector* rowReform = new CoinPackedVector();
   DecompVarList::const_iterator vli;

   for (vli = vars.begin(); vli != vars.end(); vli++) {
      coeff = (*vli)->m_s.dotProduct(rowDense);

      if (fabs(coeff) > 1.0e-12) { //m_app->m_param.tolerance)
         rowReform->insert(col_index, coeff);
      }

      col_index++;
   }

   if (rowReform->getNumElements() == 0) {
      cerr << "row size 0, don't add it" << endl;
      UTIL_DELPTR(rowReform);
      rowReform = 0;
   }

   UTIL_DELARR(rowDense);
   //---
   //--- delete the temporary memory
   //---
   UTIL_DELARR(rowDense);
   return rowReform;
}
示例#2
0
/*==========================================================================*/
int UtilScaleDblToIntArr(const int      arrLen,
                         const double* arrDbl,
                         int*           arrInt,
                         const double   epstol)
{
   //---
   //--- A very simple function to scale an array of doubles to integers.
   //---    Note: epstol denotes the preferred accuracy,
   //---    so, we will scale by 1.0/epstol, unless something smaller works.
   //--- It constructs the scaled array and returns the scale factor.
   //---
   //--- It can also scale oneDbl to oneInt wrt to the array (e.g..,
   //--- the rhs of row). If oneInt == NULL, then this part is skipped.
   //---
   int      i, scaleFactor = 1, n_aFrac = 0, factorToBig = 0;
   double* arrFrac = NULL;
   double   fractionalPart;
   double   oneOverEps = 1.0 / epstol;
   //TODO: pass in arrFrac?
   arrFrac = new double[arrLen];
   CoinAssertHint(arrFrac, "Error: Out of Memory");

   for (i = 0; i < arrLen; i++) {
      fractionalPart = UtilFracPart(arrDbl[i]);

      if (!UtilIsZero(fractionalPart)) {
         fractionalPart     *= oneOverEps;
         arrFrac[n_aFrac++]  = (int)fractionalPart * (double)epstol;
      }
   }

   for (i = 0; i < n_aFrac; i++) {
      CoinAssertDebug(arrFrac[i] < (INT_MAX / scaleFactor));
      arrFrac[i] *= scaleFactor;

      while (!UtilIsZero(UtilFracPart(arrFrac[i]))) {
         scaleFactor *= 10;

         if (scaleFactor >= oneOverEps) {
            factorToBig = 1;
            break;
         }

         CoinAssertDebug(arrFrac[i] < (INT_MAX / 10));
         arrFrac[i]    *= 10;
         CoinAssertDebug(arrFrac[i] >= 0);
      }

      if (factorToBig) {
         break;
      }
   }

   for (i = 0; i < arrLen; i++) {
      arrInt[i] = (int)(arrDbl[i] * scaleFactor);
   }

   UTIL_DELARR(arrFrac);
   return scaleFactor;
}
示例#3
0
// --------------------------------------------------------------------- //
//THINK: this is specific to PC and DC??
void DecompVarPool::reExpand(const DecompConstraintSet& modelCore,
                             const double                tolZero)
{
   //THIS IS WRONG...
   //in masterSI, we have
   //A'', convexity, cuts
   //in modelCore.M we have A'', cuts
   //the sparseCol that you come out with the end here has things in the wrong
   //order: //A'', cuts, convexity
   double* denseCol = new double[modelCore.getNumRows() + 1];
   vector<DecompWaitingCol>::iterator vi;

   for (vi = begin(); vi != end(); vi++) {
      // ---
      // --- get dense column = A''s, append convexity constraint on end
      // ---
      modelCore.M->times((*vi).getVarPtr()->m_s, denseCol);
      denseCol[modelCore.getNumRows()] = 1.0;
      // ---
      // --- create a sparse column from the dense column
      // ---
      CoinPackedVector* sparseCol
      = UtilPackedVectorFromDense(modelCore.getNumRows() + 1,
                                  denseCol, tolZero);
      (*vi).deleteCol();
      (*vi).setCol(sparseCol);
   }

   setColsAreValid(true);
   UTIL_DELARR(denseCol);
}
示例#4
0
void OSDipApp::createModelMasterOnlys2(vector<int> & masterOnlyCols) {

	int nBlocks = static_cast<int>(m_blocks.size());
	const int nCols = m_osInterface.getVariableNumber();
	const double * colLB = m_osInterface.getColLower();
	const double * colUB = m_osInterface.getColUpper();
	const char * integerVars = m_osInterface.getIntegerColumns();
	int nMasterOnlyCols = static_cast<int> (masterOnlyCols.size());

	if (m_appParam.LogLevel >= 1) {
		(*m_osLog) << "nCols = " << nCols << endl;
		(*m_osLog) << "nMasterOnlyCols = " << nMasterOnlyCols << endl;
	}

	if (nMasterOnlyCols == 0)
		return;

	int i;
	vector<int>::iterator vit;
	for (vit = masterOnlyCols.begin(); vit != masterOnlyCols.end(); vit++) {
		i = *vit;

		//THINK:
		//  what-if master-only var is integer and bound is not at integer?

		DecompConstraintSet * model = new DecompConstraintSet();
		model->m_masterOnly = true;
		model->m_masterOnlyIndex = i;
		model->m_masterOnlyLB = colLB[i];
		//std::cout << "MASTER ONLY LB =  " << model->m_masterOnlyLB << std::endl;
		model->m_masterOnlyUB = colUB[i];
		//std::cout << "MASTER ONLY UB =  " << model->m_masterOnlyUB << std::endl;
		//0=cont, 1=integer
		if(integerVars[i] == '1') model->m_masterOnlyIsInt = true;
		//model->m_masterOnlyIsInt = integerVars[i] ? true : false;
		if (m_appParam.ColumnUB < 1.0e15)
			if (colUB[i] > 1.0e15)
				model->m_masterOnlyUB = m_appParam.ColumnUB;
		if (m_appParam.ColumnLB > -1.0e15)
			if (colLB[i] < -1.0e15)
				model->m_masterOnlyLB = m_appParam.ColumnLB;

		m_modelMasterOnly.insert(make_pair(i, model)); //keep track for garbage collection
		setModelRelax(model, "master_only" + UtilIntToStr(i), nBlocks);
		nBlocks++;
	}
	//free local memory
	UTIL_DELARR( integerVars);
	return;
}//end createModelMasterOnlys2
示例#5
0
//===========================================================================//
DecompConstraintSet * ATM_DecompApp::createModelCore1(bool includeCount){

   UtilPrintFuncBegin(m_osLog, m_classTag,
		      "createModelCore1()", m_appParam.LogLevel, 2);

   int   a, d, pairIndex;

   pair<int,int>               adP;
   vector<int>::const_iterator vi;

   const int           nAtms   = m_instance.getNAtms();
   const int           nDates  = m_instance.getNDates();
   const vector<int> & pairsAD = m_instance.getPairsAD();   
   const double      * B_d     = m_instance.get_B_d();
   const int           nCols   = numCoreCols();
   int                 nRows   = nDates; 

   if(includeCount)
      nRows += nAtms;

   DecompConstraintSet * model = new DecompConstraintSet();
   CoinAssertHint(model, "Error: Out of Memory");

   model->M = new CoinPackedMatrix(false, 0.0, 0.0);
   CoinAssertHint(model->M, "Error: Out of Memory");
   model->M->setDimensions(0, nCols);
   model->reserve(nRows, nCols);

   //---
   //---    for d in D:
   //---      sum{a in A} (f+[a,d] - f-[a,d]) <= B[d]
   //---
   CoinPackedVector * rowsD = new CoinPackedVector[nDates];   
   pairIndex = 0;
   for(vi = pairsAD.begin(); vi != pairsAD.end(); vi++){
      adP = m_instance.getIndexADInv(*vi);
      a   = adP.first;
      d   = adP.second;
      rowsD[d].insert(getColOffset_fp() + pairIndex,  1.0);
      rowsD[d].insert(getColOffset_fm() + pairIndex, -1.0);
      pairIndex++;
   }

   for(d = 0; d < nDates; d++){
      string rowName = "budget(d_" 
	 + m_instance.getDateName(d) + ")";
      model->appendRow(rowsD[d], -DecompInf, B_d[d], rowName);
   }
   UTIL_DELARR(rowsD);

   if(includeCount){
      //---  for a in A:
      //---    sum{d in D} v[a,d] <= K[a]
      //---   
      for(a = 0; a < nAtms; a++){
	 createConCount(model, a);
      }
   }
   
   //---
   //--- create model columns
   //---
   createModelColumns(model);
   
   UtilPrintFuncEnd(m_osLog, m_classTag,
		    "createModelCore1()", m_appParam.LogLevel, 2);

   return model;
}
示例#6
0
//===========================================================================//
bool ATM_DecompApp::APPisUserFeasible(const double * x,
				      const int      nCols,
				      const double   tolZero){
   //---
   //--- sanity check - is this solution feasible?
   //---   since we provide a full matrix, DECOMP will also check 
   //---   that the algebra gives a feasible point
   //---

   UtilPrintFuncBegin(m_osLog, m_classTag,
		      "APPisUserFeasible()", m_appParam.LogLevel, 2);
   

   double lhs, rhs, coeff;
   int    a, d, t;
   int    pairIndex = 0;
   bool   isFeas    = true;

   const int           nSteps    = m_appParam.NumSteps;
   const int           nAtms     = m_instance.getNAtms();
   const vector<int> & pairsAD   = m_instance.getPairsAD();   
   const double      * K_a       = m_instance.get_K_a();
   const double      * a_ad      = m_instance.get_a_ad(); //dense storage
   const double      * b_ad      = m_instance.get_b_ad(); //dense storage
   const double      * c_ad      = m_instance.get_c_ad(); //dense storage
   const double      * d_ad      = m_instance.get_d_ad(); //dense storage
   const double      * e_ad      = m_instance.get_e_ad(); //dense storage
   double            * count     = new double[nAtms];
    
   //---
   //--- is the flow variable matching x,z variables
   //---    for a in A, d in D:
   //---       f+[a,d] - f-[a,d] =  
   //---         a[a,d] sum{t in T} (t/n) x1[a,t] +
   //---         b[a,d] x2[a]                     +     
   //---         c[a,d] sum{t in T} (t/n) z[a,t]  + 
   //---         d[a,d] x3[a]                     +
   //---         e[a,d]
   //---
   pair<int,int>                 adP;
   vector<int>::const_iterator   vi;
   double                        actViol = 0.0;
   double                        relViol = 0.0;
   for(vi = pairsAD.begin(); vi != pairsAD.end(); vi++){
      adP = m_instance.getIndexADInv(*vi);
      a   = adP.first;

      lhs  = x[getColOffset_fp() + pairIndex];
      lhs -= x[getColOffset_fm() + pairIndex];
      
      rhs  = e_ad[*vi]
	 + b_ad[*vi] * x[colIndex_x2(a)]
	 + d_ad[*vi] * x[colIndex_x3(a)];
      if(m_appParam.UseTightModel){
	 for(t = 0; t <= nSteps; t++){
	    coeff = (double)(t) / (double)nSteps;
	    rhs += a_ad[*vi] * coeff * x[colIndex_x1(a,t)];
	    rhs += c_ad[*vi] * coeff * x[colIndex_z (a,t)];
	 }
      }
      else{
	 for(t = 0; t < nSteps; t++){
	    coeff = (double)(t+1) / (double)nSteps;
	    rhs += a_ad[*vi] * coeff * x[colIndex_x1(a,t)];
	    rhs += c_ad[*vi] * coeff * x[colIndex_z (a,t)];
	 }
      }
      actViol = fabs(lhs-rhs);
      if(UtilIsZero(lhs,1.0e-3))
	relViol = actViol;
      else
	relViol = actViol / std::fabs(lhs);
      if(relViol > 0.05){
	printf("NOT FEASIBLE lhs=%12.10f, rhs=%12.10f\n", lhs, rhs);
	 isFeas = false;
      }      
      pairIndex++;
   }


   //---
   //--- did the indicators work correctly?
   //---    f+[a,d] - f-[a,d] < 0 ==> v[a,d] = 1
   //---
   pairIndex = 0;
   for(vi = pairsAD.begin(); vi != pairsAD.end(); vi++){
      adP  = m_instance.getIndexADInv(*vi);
      a    = adP.first;
      lhs  = x[getColOffset_fp() + pairIndex];
      lhs -= x[getColOffset_fm() + pairIndex];
      //if(lhs < -DecompEpsilon){
      if(lhs < -0.01){
	 if(fabs(x[getColOffset_v() + pairIndex] - 1.0) > tolZero){
	    printf("NOT FEASIBLE fp=%10.5f fm=%10.5f f=%10.5f < 0, but v=%g not 1\n",
		   x[getColOffset_fp() + pairIndex],
		   x[getColOffset_fm() + pairIndex],
		   lhs, x[getColOffset_v() + pairIndex]);	 
	    isFeas = false;
	 }
      }
      pairIndex++;
   }
   
   //---
   //--- did the surrogate z work correctly?
   //---   z[a,t] = sum{t in T} x1[a,t] * x2[a]
   //---

   //---
   //--- is budget satisfied?
   //---    for d in D:
   //---       sum{a in A} (f+[a,d] - f-[a,d]) <= B[d]
   //---

   //---
   //--- is the count constraint satisifed
   //---    for a in A:
   //---       sum{d in D} v[a,d]              <= K[a]
   //---
   pairIndex = 0;
   UtilFillN(count, nAtms, 0.0);
   for(vi = pairsAD.begin(); vi != pairsAD.end(); vi++){
      adP  = m_instance.getIndexADInv(*vi);
      a    = adP.first;
      d    = adP.second;
      count[a] += x[getColOffset_v() + pairIndex];
      pairIndex++;
   }
   for(a = 0; a < nAtms; a++){
#if 0
      printf("COUNT[a=%3d->%10s]: %5g <= K=%5g\n",
	     a, 
	     m_instance.getAtmName(a).c_str(),
	     count[a], 
	     K_a[a]);
#endif	     
      if(count[a] > (K_a[a] + 0.01)){
#if 0
	 printf("NOT FEASIBLE a:%d count=%g K=%g\n", a, count[a], K_a[a]);
#endif
	 isFeas = false;
      }
   }

#if 0
   printf("IsUserFeas = %d\n", isFeas);
#endif

   //---
   //--- free local memory
   //---
   UTIL_DELARR(count);

   UtilPrintFuncEnd(m_osLog, m_classTag,
		    "APPisUserFeasible()", m_appParam.LogLevel, 2);
   
   return isFeas;
}
示例#7
0
int OSDipApp::generateInitVars(DecompVarList & initVars) {

	//---
	//--- generateInitVars is a virtual method and can be overriden
	//---   if the user has some idea how to initialize the list of 
	//---   initial variables (columns in the DW master)
	//---
	std::cout << "GENERATE INIT VARS" << std::endl;
	UtilPrintFuncBegin(m_osLog, m_classTag, "generateInitVars()",
			m_appParam.LogLevel, 2);

	//---
	//--- Get the initial solution from the OSOption object
	//--- we want the variable other option where name="initialCol"
	//---

	//std::vector<OtherVariableOption*> getOtherVariableOptions(std::string solver_name); 
	std::vector<OtherVariableOption*> otherVarOptions;
	std::vector<OtherVariableOption*>::iterator vit;
	int *index = NULL;
	double *value = NULL;
	int i;
	double objValue;
	int whichBlock;
	DecompVar *var;

	try{
		if (m_osInterface.m_osoption != NULL
				&& m_osInterface.m_osoption->getNumberOfOtherVariableOptions() > 0) {
			std::cout << "Number of other variable options = "
					<< m_osInterface.m_osoption->getNumberOfOtherVariableOptions()
					<< std::endl;
			otherVarOptions = m_osInterface.m_osoption->getOtherVariableOptions(
					"Dip");
			//iterate over the vector
	
			for (vit = otherVarOptions.begin(); vit != otherVarOptions.end(); vit++) {
	
				// see if we have an initialCol option
	
				if ((*vit)->name.compare("initialCol") == 0) {
	
					index = new int[(*vit)->numberOfVar];
					value = new double[(*vit)->numberOfVar];
	
					objValue = 0.0;
	
					for (i = 0; i < (*vit)->numberOfVar; i++) {
	
						index[i] = (*vit)->var[i]->idx;
	
						//convert the string to integer
						value[ i] = atoi((*vit)->var[i]->value.c_str());
						objValue += m_objective[index[i]];
	
					}
					
					whichBlock = atoi( (*vit)->value.c_str() );
					var = new DecompVar((*vit)->numberOfVar, index, value, objValue);
					var->setBlockId(whichBlock);
					initVars.push_back(var);
					
					//free local memory
	 				UTIL_DELARR( index);
	 				UTIL_DELARR( value);
					
	
				}
	
			}
	
		}
	
	}//end try
	catch(const ErrorClass& eclass){
		
		throw ErrorClass( eclass.errormsg);
		
	} 

	UtilPrintFuncEnd(m_osLog, m_classTag, "generateInitVars()",
			m_appParam.LogLevel, 2);
	return static_cast<int> (initVars.size());
}
示例#8
0
//===========================================================================//
void OSDipApp::createModels() {

	UtilPrintFuncBegin(m_osLog, m_classTag, "createModels()",
			m_appParam.LogLevel, 2);
	int i;
	int j;
	const int nCols = m_osInterface.getVariableNumber();
	const int nRows = m_osInterface.getConstraintNumber();
	
	try{

		//First the define the objective function over the entire variable space
		//Create the memory for the objective  function
		m_objective = new double[nCols];
		for (i = 0; i < nCols; i++) {
			m_objective[i] = m_osInterface.getObjectiveFunctionCoeff()[i];
			//std::cout << "obj coeff = " << m_objective[i] << std::endl;
		}
		setModelObjective( m_objective);
	
		//---
		//--- Construct the core matrix.
		//---
		int nRowsRelax, nRowsCore;
		nRowsRelax = 0;
		nRowsCore = 0;
  
	

		std::vector<OtherConstraintOption*> otherConstraintOptions;
		std::vector<OtherConstraintOption*>::iterator vit;
		
		

		//
		// Now construct the block matrices
		//
		int *rowsRelax;
		int whichBlock;
		DecompConstraintSet *modelRelax = NULL;

		std::set<int> blockVars; //variables indexes in the specific block
		std::set<int> blockVarsAll; //all variable indexes that appear in a block
		std::set<int> blockConAll; //all constraint indexes that appear in a block
		std::set<int>::iterator sit;
		CoinPackedVector *row;
		int *rowVars;
		int rowSize;
		if (m_osInterface.m_osoption != NULL
				&& m_osInterface.m_osoption->getNumberOfOtherConstraintOptions()
						> 0) {
	
			otherConstraintOptions
					= m_osInterface.m_osoption->getOtherConstraintOptions("Dip");
			
			//iterate over the vector of contraint options
			for (vit = otherConstraintOptions.begin(); vit
					!= otherConstraintOptions.end(); vit++) {
	
				// see if we have a Core Constraint Set
	
				if( ( (*vit)->name.compare("constraintSet") == 0)
						&& ( (*vit)->type.compare("Block") == 0)) {
					
					
					//get the block number
	
					//ch = new char[(*vit)->value.size() + 1];
					//ch[(*vit)->value.size()] = 0;
					//memcpy(ch, (*vit)->value.c_str(), (*vit)->value.size());
					//whichBlock = atoi(ch);
					//delete ch;
					whichBlock = atoi( (*vit)->value.c_str() );
			
	
					
					// first get the number of constraints in this block
					nRowsRelax = (*vit)->numberOfCon;
					rowsRelax = new int[nRowsRelax];
	
					//now get the variable indexes for just this block
					//first clear indexes from a previous block
					blockVars.clear();
					for (i = 0; i < nRowsRelax; i++) {
						rowsRelax[i] = (*vit)->con[i]->idx;
						
						if( (*vit)->con[i]->idx >= nRows) throw ErrorClass( "found an invalid row index in OSoL file");
						
						m_blocks[ whichBlock].push_back( rowsRelax[i] );
						
						//also add to the set of all rows
						
						if (blockConAll.find(  (*vit)->con[i]->idx ) == blockConAll.end()) {
							blockConAll.insert(  (*vit)->con[i]->idx );	
						}					
						
						//add the variables for this row to the set blockVars
						row = m_osInterface.getRow(rowsRelax[i]);
						rowSize = row->getNumElements();
						rowVars = row->getIndices();
	
						for (j = 0; j < rowSize; j++) {
							
							if (blockVars.find(rowVars[j]) == blockVars.end()) {
								blockVars.insert(rowVars[j]);	
							}	
							
						}
						
						delete row;
	
					}//end for or rows in this block
	
					modelRelax = new DecompConstraintSet();
					CoinAssertHint(modelRelax, "Error: Out of Memory");
	
	
	
					//create the active columns in this block
					for (sit = blockVars.begin(); sit != blockVars.end(); sit++) {
	
						modelRelax->activeColumns.push_back( *sit);
						
						   
						//insert into the all variables set also, but throw an execption
						//if already there -- same variable cannot be in more than one block
						
						if (blockVarsAll.find( *sit) == blockVarsAll.end()) {
							blockVarsAll.insert (*sit);	
						}else{
							
							throw ErrorClass("Variable " + UtilIntToStr(*sit) + " appears in more than one block");
							
						}
	
					}
	
					//
					//
	
					if (m_appParam.LogLevel >= 3) {
						(*m_osLog) << "Active Columns : " << whichBlock << endl;
						UtilPrintVector(modelRelax->activeColumns, m_osLog);

					}
					createModelPartSparse(modelRelax, nRowsRelax, rowsRelax);  //does not work for cutting planes
					//createModelPart(modelRelax, nRowsRelax, rowsRelax);
					//modelRelax->fixNonActiveColumns();
					m_modelR.insert(make_pair(whichBlock + 1, modelRelax));
					setModelRelax(modelRelax, "relax" + UtilIntToStr(whichBlock),
							whichBlock);
					
					if (m_appParam.LogLevel >= 3) {
						(*m_osLog) <<  std::endl <<  std::endl;
						(*m_osLog) << "HERE COMES THE DUPLICATION (WHEN createModelPartSparse USED)" << std::endl;
					}

					UtilPrintVector( modelRelax->activeColumns, m_osLog); 
					
									
	 			//free local memory
	 			UTIL_DELARR( rowsRelax);
	
	
	
				}
			}//end for over constraint options
		}// if on ospton null
	
		//get the core constraints -- constraints NOT in a block
		int *rowsCore = NULL;
		
		int kount = 0;
		nRowsCore = nRows - blockConAll.size();
		
		if(nRowsCore <= 0) throw ErrorClass("We need at least one coupling constraint");
	
		rowsCore = new int[nRowsCore];
			
		for(i = 0; i < nRows; i++){
			
			if (blockConAll.find( i ) == blockConAll.end() ){
				
				
				rowsCore[ kount++] =  i;
				
				
				
			}
		}

		if( kount  !=  nRowsCore) throw ErrorClass("There was an error counting coupling constraints");
		
	
		DecompConstraintSet * modelCore = new DecompConstraintSet();
		createModelPart(modelCore, nRowsCore, rowsCore);
	
		setModelCore(modelCore, "core");
		//---
		//--- save a pointer so we can delete it later
		//---
		m_modelC = modelCore;
		

		//get the master only variables
		//modelCore->masterOnlyCols.push_back(i);
		for (i = 0; i < nCols; i++) {
			if (blockVarsAll.find(i) == blockVarsAll.end()) {
				modelCore->masterOnlyCols.push_back(i);
				std::cout << "MASTER ONLY VARIABLE " << i << std::endl;
			}
		}
	
		//---
		//--- create an extra "empty" block for the master-only vars
		//---   since I don't know what OSI will do with empty problem
		//---   we will make column bounds explicity rows
		//---
		int nMasterOnlyCols = static_cast<int> (modelCore->masterOnlyCols.size());
		if (nMasterOnlyCols) {
			if (m_appParam.LogLevel >= 1)
				(*m_osLog) << "Create model part Master-Only." << endl;
	
			createModelMasterOnlys2(modelCore->masterOnlyCols);
	
		}
		
		
		UtilPrintFuncBegin(m_osLog, m_classTag, "printCurrentProblem()",
				m_appParam.LogLevel, 2);
				
				
	 //free local memory
	 UTIL_DELARR( rowsCore);
	
	
	}//end try
	
	catch(const ErrorClass& eclass){
		
		throw ErrorClass( eclass.errormsg);
		
	} 

}// end createModels()
示例#9
0
//===========================================================================//
void OSDipApp::createModelPartSparse(DecompConstraintSet * model,
		const int nRowsPart, const int * rowsPart) {

	const int nColsOrig = m_osInterface.getVariableNumber();
	const double * rowLB = m_osInterface.getRowLower();
	const double * rowUB = m_osInterface.getRowUpper();
	const double * colLB = m_osInterface.getColLower();
	const double * colUB = m_osInterface.getColUpper();
	const char * integerVars = m_osInterface.getIntegerColumns();

	//---
	//--- set model as sparse
	//---
	model->setSparse(nColsOrig);
	int nCols, origIndex, newIndex;
	vector<int>::iterator vit;
	newIndex = 0;
	for (vit = model->activeColumns.begin(); vit != model->activeColumns.end(); vit++) {
		origIndex = *vit;

		//std::cout << "lower bound = " << colLB[origIndex] << std::endl;
		//std::cout << "upper bound = " << colUB[origIndex] << std::endl;

		model->pushCol(colLB[origIndex], colUB[origIndex],
				integerVars[origIndex] == '0' ? false : true, origIndex);
				
				
		if(integerVars[origIndex] == 0)  std::cout << "HERE I AM" << std::endl;
		

		//---
		//--- big fat hack... we don't deal with dual rays yet,
		//---  so, we assume subproblems are bounded
		//---

		if (m_appParam.ColumnUB < 1.0e15) {
			if (colUB[origIndex] > 1.0e15) {
				model->colUB[newIndex] = m_appParam.ColumnUB;
			}
		}
		if (m_appParam.ColumnLB > -1.0e15) {
			if (colLB[origIndex] < -1.0e15) {
				model->colLB[newIndex] = m_appParam.ColumnLB;
			}
		}

		if (m_appParam.UseNames) {
			//const char * colName =  m_osInterface.columnName(origIndex);
			const char * colName =
					m_osInterface.getConstraintNames()[origIndex].c_str();

			if (colName)
				model->colNames.push_back(colName);
		}
		newIndex++;
	}

	nCols = static_cast<int> (model->activeColumns.size());
	assert(static_cast<int> (model->colLB.size()) == nCols);
	assert(static_cast<int> (model->colUB.size()) == nCols);

	model->M = new CoinPackedMatrix(false, 0.0, 0.0);
	if (!model->M)
		throw UtilExceptionMemory("createModels", "OSDipApp");
	model->M->setDimensions(0, nCols);
	model->reserve(nRowsPart, nCols);

	//---
	//--- for each row in rowsPart, create the row using sparse mapping
	//---
	int i, k, r, begInd;
	const map<int, int> & origToSparse = model->getMapOrigToSparse();
	const CoinPackedMatrix * M = m_osInterface.getCoinPackedMatrix();
	const int * matInd = M->getIndices();
	const CoinBigIndex * matBeg = M->getVectorStarts();
	const int * matLen = M->getVectorLengths();
	const double * matVal = M->getElements();
	const int * matIndI = NULL;
	const double * matValI = NULL;

	vector<CoinBigIndex> & rowBeg = model->m_rowBeg;//used as temp
	vector<int> & rowInd = model->m_rowInd;//used as temp
	vector<double> & rowVal = model->m_rowVal;//used as temp
	map<int, int>::const_iterator mit;

	begInd = 0;
	rowBeg.push_back(0);
	for (i = 0; i < nRowsPart; i++) {
		r = rowsPart[i];
		if (m_appParam.UseNames) {
			const char * rowName =
					m_osInterface.getConstraintNames()[r].c_str();
			if (rowName)
				model->rowNames.push_back(rowName);
		}
		model->rowLB.push_back(rowLB[r]);
		model->rowUB.push_back(rowUB[r]);

		matIndI = matInd + matBeg[r];
		matValI = matVal + matBeg[r];
		for (k = 0; k < matLen[r]; k++) {
			origIndex = matIndI[k];
			mit = origToSparse.find(origIndex);
			assert(mit != origToSparse.end());
			rowInd.push_back(mit->second);
			rowVal.push_back(matValI[k]);
		}
		begInd += matLen[r];
		rowBeg.push_back(begInd);
	}
	model->M->appendRows(nRowsPart, &rowBeg[0], &rowInd[0], &rowVal[0]);
	
	//free local memory
	rowBeg.clear();
	rowInd.clear();
	rowVal.clear();
	UTIL_DELARR( integerVars);
}
示例#10
0
//===========================================================================//
void OSDipApp::createModelPart(DecompConstraintSet * model,
		const int nRowsPart, const int * rowsPart) {

	const int nCols = m_osInterface.getVariableNumber();
	const double * rowLB = m_osInterface.getRowLower();
	const double * rowUB = m_osInterface.getRowUpper();
	const double * colLB = m_osInterface.getColLower();
	const double * colUB = m_osInterface.getColUpper();
	const char * integerVars = m_osInterface.getIntegerColumns();

	std::cout << "STARTING createModelPart" << std::endl;

	model->M = new CoinPackedMatrix(false, 0.0, 0.0);

	if (!model->M)
		throw UtilExceptionMemory("createModels", "OSDipApp");
	model->reserve(nRowsPart, nCols);
	model->M->submatrixOf(*m_osInterface.m_coinpm, nRowsPart,
			rowsPart);

	//---
	//--- set the row upper and lower bounds
	//--- set the col upper and lower bounds
	//---
	m_appParam.UseNames = true;
	int i, r;
	for (i = 0; i < nRowsPart; i++) {
		r = rowsPart[i];
		if (m_appParam.UseNames == true) {
			const char * rowName =
					m_osInterface.getConstraintNames()[r].c_str();
			//		std::cout << "Row Name = " << m_osInterface.getConstraintNames()[r] << std::endl;
			if (rowName)
				model->rowNames.push_back(rowName);
			
			//std::cout << "Row Name = " << m_osInterface.getConstraintNames()[r] << std::endl;
		}
		model->rowLB.push_back(rowLB[r]);
		model->rowUB.push_back(rowUB[r]);
	}
	copy(colLB, colLB + nCols, back_inserter(model->colLB));
	copy(colUB, colUB + nCols, back_inserter(model->colUB));

	//---
	//--- big fat hack... we don't deal with dual rays yet,
	//---  so, we assume subproblems are bounded
	//---
	//--- NOTE: might also need to tighten LBs
	//---
	//--- Too small - ATM infeasible!
	//--- Too big   - round off issues with big coeffs in 
	//---             master-only vars
	//---
	//--- TODO: need extreme rays or bounded subproblems from user
	//---


	if (m_appParam.ColumnUB < 1.0e15) {
		for (i = 0; i < nCols; i++) {
			if (colUB[i] > 1.0e15) {
				model->colUB[i] = m_appParam.ColumnUB;
			}
		}
	}
	if (m_appParam.ColumnLB > -1.0e15) {
		for (i = 0; i < nCols; i++) {
			if (colLB[i] < -1.0e15) {
				model->colLB[i] = m_appParam.ColumnLB;
			}
		}
	}

	//---
	//--- set the indices of the integer variables of modelRelax
	//---  also set the column names, if they exist
	//---
	for (i = 0; i < nCols; i++) {
		if (m_appParam.UseNames == true) {
			//const char * colName =  m_osInterface.columnName(i);
			const char * colName =
					m_osInterface.getVariableNames()[i].c_str();

			if (colName)
				model->colNames.push_back(colName);
		}
		
		if ( (integerVars != NULL)   && integerVars[i] == '1' ) {
			//std::cout  << "WE HAVE AN INTEGER VARIABLE " << std::endl;
			model->integerVars.push_back(i);
		}
	}
	
					
	 //free local memory
	 UTIL_DELARR( integerVars);
	
}
示例#11
0
// --------------------------------------------------------------------- //
void MMKP_MCKnap::solveMCKnap(const double   * redCost,
			      const double   * origCost,
			      vector<int>    & solInd,
			      vector<double> & solEls,
			      double         & varRedCost,
			      double         & varOrigCost){
   
   int i, j, colIndex;

   //---
   //--- Pisinger's code (mcknap) solves a max problem. And, it assumes 
   //--- all positive costs/profits and weights.
   //---   
   memcpy(m_costDbl, redCost, m_nCols * sizeof(double));
#ifdef MMKP_MCKNAP_DEBUG
   for(i = 0; i < m_nCols; i++){
      pair<int,int> ij = getIndexInv(i);
      printf("\ncostDbl[%d: %d, %d]: %g",
	     i, ij.first, ij.second, m_costDbl[i]);
   }
#endif

   
   //---
   //--- flip reduced costs (max c == min -c)
   //---
   UtilNegateArr(m_nCols, m_costDbl);

   //---
   //--- add a constant so that all vertex weights are positive, inc alpha
   //---
   double offset = 0.0;
   double minrc  = *min_element(m_costDbl, m_costDbl + m_nCols);
#ifdef MMKP_MCKNAP_DEBUG
   printf("\nminrc   = %g", minrc);
#endif   
   if(minrc <= 0){
      offset = -minrc + 1;
      UtilAddOffsetArr(m_nCols, offset, m_costDbl);
   }

   //---
   //--- now scale the double array to an integer array
   //---
   //TODO: magic number - have to be careful of overflow... 
   m_cscale = UtilScaleDblToIntArr(m_nCols, m_costDbl, m_cost, MCKP_EPSILON);

#ifdef MMKP_MCKNAP_DEBUG
   double diff;
   printf("\noffset   = %g", offset);
   printf("\nm_cscale = %d", m_cscale);
   printf("\nm_wscale = %d", m_wscale);
   printf("\ncapacity = %d", m_capacity);
   for(i = 0; i < m_nCols; i++){
      pair<int,int> ij = getIndexInv(i);
      diff = fabs((m_costDbl[i]*m_cscale) - m_cost[i]);
      printf("\n[%d: %d, %d]: dbl-> %12.5f int-> %8d diff-> %12.5f",
	     i, ij.first, ij.second, m_costDbl[i], m_cost[i], diff);
      assert( diff < 0.99 );
   }
#endif

   //---
   //--- sanity check
   //---  if any cost value becomes negative that
   //---  denotes an overflow happened
   //--- TODO: not sure how to do this scaling safely and
   //---  accurately
   //---
   for(i = 0; i < m_nCols; i++){
      if(m_cost[i] < 0){
         throw UtilException("negative cost value",
                             "solveMCKnap", "MMKP_MCKnap");
      }
   }
      
   //---
   //--- setup the data structures for mcknap
   //---
   itemset * setPtr    = m_setset->fset;
   itemrec * recPtr    = NULL;
   itemrec * recSolPtr = NULL;
   
   //THINK: reset - assume memory is still there
   m_setset->size  = m_nGroupRows;
   setPtr = m_setset->fset;
   for(i = 0; i < m_setset->size; i++){
      setPtr->size = m_nGroupCols;
      recPtr       = setPtr->fset;    
      setPtr->lset = setPtr->fset + setPtr->size - 1;
      setPtr++;
   }
   m_setset->lset = m_setset->fset + m_setset->size - 1;
   

   colIndex            = 0;
   setPtr = m_setset->fset;
   for(i = 0; i < m_setset->size; i++){
      recPtr    = setPtr->fset;
      for(j = 0; j < setPtr->size; j++){
	 recPtr->i = i;
	 recPtr->j = j;
         recPtr->psum = m_cost[colIndex];
         recPtr->wsum = m_weight[colIndex];
#ifdef MMKP_MCKNAP_DEBUG
         printf("\ncolIndex: %d i: %d, j: %d, p: %d, w: %d",
		colIndex, i, j, recPtr->psum, recPtr->wsum);
#endif
         recPtr++;
         colIndex++;
      }
      setPtr++;
   }

   itemrec * solRec = new itemrec[m_setset->size];
   
   double minObj = 99999;
//   long minObj = 99999;
   int status  = minmcknapSolve(m_capacity, m_setset, solRec, &minObj);

   solInd.reserve(m_nGroupRows);
   solEls.reserve(m_nGroupRows);
   UtilFillN<double>(solEls, m_nGroupRows, 1.0);
   varRedCost  = 0.0;
   varOrigCost = 0.0;

   //---
   //--- TODO:
   //--- this is painful to get optimal assignments
   //---    wrote Dr. Pisinger for help (7/4/07)
   //--- NOTE: optsol is NOT reentrant
   //---
   //CoinAssert(optsol.size == 1); //TODO
#ifdef MMKP_MCKNAP_DEBUG
   printf("\nstatus=%d minObj=%g\n", status, minObj);
#endif

   switch(status){
   case MCKNAP_RC_INF:
      assert(status != MCKNAP_RC_INF);
      break;
   case MCKNAP_RC_OK:
      {
	 //---
	 //--- need to unravel:
	 //---    s * ((-x) + offset)
	 //---
	  
	 double solObj = minObj / static_cast<double>(m_cscale);
	 solObj -= (offset * m_setset->size);
	 solObj  = -solObj;
	  
#ifdef MMKP_MCKNAP_DEBUG
	 printf("\nminObj = %g, solObj = %g", minObj, solObj);
#endif
	  
	  
	 int c, i, j, g;
	 for(g = 0; g < m_setset->size; g++){
	    recSolPtr = &solRec[g];
	    i         = recSolPtr->i;//was missing - STOP
	    j         = recSolPtr->j;//was missing
	    c         = getIndexIJ(i, j);
	    solInd.push_back(c);
	    varRedCost  += redCost[c];
	    varOrigCost += origCost[c];
#ifdef MMKP_MCKNAP_DEBUG	     
	    printf("\nc: %d = (%d,%d) redCost: %g cost: %d wt: %d",
		   c, i, j, 
		   redCost[c], m_cost[c], m_weight[c]);
#endif
	    /*for(c = 0; c < m_nCols; c++){
	    //but could have more than one equal in p and w!
	    //this is NOT the right way to get back optimal
	    if((m_cost[c]   == recSolPtr->psum) &&
	    (m_weight[c] == recSolPtr->wsum)){
	    //TODO: why should the user have to calc origCost?
	    //framework should probably do that
	    solInd.push_back(c);
	    varRedCost  += redCost[c];
	    varOrigCost += origCost[c];
	    #ifdef MMKP_MCKNAP_DEBUG
	    pair<int,int> ij = getIndexInv(c);
	    printf("\nc: %d = (%d,%d) redCost: %g cost: %d wt: %d",
	    c,
	    ij.first, ij.second,
	    redCost[c], m_cost[c], m_weight[c]);
	    #endif
	    break;
	    }
	    }*/
	 }
	 //UtilPrintVector<int>(solInd);
	 break;
      }
   case MCKNAP_RC_TRIVIAL_MAXSUM:
     fflush(stdout);
      //maxwsum <= c, so just pick the max elements from each group
      solveTrivialMaxSum(redCost, origCost, solInd, 
			 varRedCost, varOrigCost);
#ifdef MMKP_MCKNAP_DEBUG	     
      printf("trivial sum varRedCost=%g varOrigCost=%g\n",
	     varRedCost, varOrigCost);
#endif
      break;
   default:
      assert(0);
   }
   UTIL_DELARR(solRec);
}
示例#12
0
/**
 * Called to create the core and relaxation models
 */
void DippyDecompApp::createModels()
{
   int i, len;
   string name;
   // create the core model
   DecompConstraintSet* modelCore = new DecompConstraintSet();
   // gets the master problem model
   PyObject* pMasterAsTuple = PyObject_CallMethod(m_pProb, "getMasterAsTuple", 
						  NULL);

   if (pMasterAsTuple == NULL) {
      throw UtilException("Error calling method prob.getMasterAsTuple()", 
			  "createModels", "DippyDecompApp");
   }

   PyObject* pObjective = PyTuple_GetItem(pMasterAsTuple, 0);
   PyObject* pRowList   = PyTuple_GetItem(pMasterAsTuple, 1);
   PyObject* pColList   = PyTuple_GetItem(pMasterAsTuple, 2);
   m_rowList = pRowList;
   Py_XINCREF(m_rowList);
   m_numCols = PyObject_Length(pColList);
   m_colList = pColList;
   Py_XINCREF(m_colList);
   int numRows = PyObject_Length(pRowList);
   PyObject* pRow, *pRowName, *pRowLb, *pRowUb;
   double lb, ub;

   for (int i = 0; i < numRows; i++) {
      pRow = PyList_GetItem(pRowList, i);
      pRowName = PyObject_CallMethod(pRow, "getName", NULL);

      if (pRowName == NULL) {
         throw UtilException("Error calling method row.getName()", 
			     "createModels", "DippyDecompApp");
      }

      pRowLb   = PyObject_CallMethod(pRow, "getLb", NULL);

      if (pRowLb == NULL) {
         throw UtilException("Error calling method row.getLb()", 
			     "createModels", "DippyDecompApp");
      }

      pRowUb   = PyObject_CallMethod(pRow, "getUb", NULL);

      if (pRowUb == NULL) {
         throw UtilException("Error calling method row.getUb()", 
			     "createModels", "DippyDecompApp");
      }

      name = PyString_AsString(pRowName);

      if (pRowLb == Py_None) {
         lb = -m_infinity;
      } else {
         lb = PyFloat_AsDouble(pRowLb);
      }

      if (pRowUb == Py_None) {
         ub = m_infinity;
      } else {
         ub = PyFloat_AsDouble(pRowUb);
      }

      modelCore->rowNames.push_back(name);
      modelCore->rowLB.push_back(lb);
      modelCore->rowUB.push_back(ub);
      m_rowIndices[pRow] = i; // Don't need to increase reference count here as m_rowList
      // references pRow
   }

   PyObject* pCol, *pColLb, *pColUb, *pIsInt;

   for (int j = 0; j < m_numCols; j++) {
      pCol = PyList_GetItem(pColList, j);
      PyObject* pColName = PyObject_CallMethod(pCol, "getName", NULL);

      if (pColName == NULL) {
         throw UtilException("Error calling method col.getName()", 
			     "createModels", "DippyDecompApp");
      }

      pColLb   = PyObject_CallMethod(pCol, "getLb", NULL);

      if (pColLb == NULL) {
         throw UtilException("Error calling method col.getLb()", 
			     "createModels", "DippyDecompApp");
      }

      pColUb   = PyObject_CallMethod(pCol, "getUb", NULL);

      if (pColUb == NULL) {
         throw UtilException("Error calling method col.getUb()", 
			     "createModels", "DippyDecompApp");
      }

      pIsInt   = PyObject_CallMethod(pCol, "isInteger", NULL);

      if (pIsInt == NULL) {
         throw UtilException("Error calling method col.isInteger()", 
			     "createModels", "DippyDecompApp");
      }

      name = PyString_AsString(pColName);

      if (pColLb == Py_None) {
         lb = -m_infinity;
      } else {
         lb = PyFloat_AsDouble(pColLb);
      }

      if (pColUb == Py_None) {
         ub = m_infinity;
      } else {
         ub = PyFloat_AsDouble(pColUb);
      }

      modelCore->colNames.push_back(name);
      modelCore->colLB.push_back(lb);
      modelCore->colUB.push_back(ub);

      if (PyObject_IsTrue(pIsInt)) {
         modelCore->integerVars.push_back(j);
      }

      m_colIndices[pCol] = j; // Don't need to increase reference count here 
      // as m_rowList references pCol
   }

   // set objective coefficients
   double* obj = new double[m_numCols];
   UtilFillN(obj, m_numCols, 0.0);
   PyObject* pObjKeys = PyDict_Keys(pObjective);
   PyObject* pCoeff;

   for (int j = 0; j < PyObject_Length(pObjKeys); j++) {
      pCol = PyList_GetItem(pObjKeys, j);
      pCoeff = PyDict_GetItem(pObjective, pCol);
      obj[m_colIndices[pCol]] = PyFloat_AsDouble(pCoeff);
   }

   setModelObjective(obj, m_numCols);
   // set constraint matrix
   modelCore->M = pyConstraints_AsPackedMatrix(pRowList, m_rowIndices, 
					       m_colIndices);
   modelCore->M->setDimensions(modelCore->rowLB.size(), 
			       modelCore->colLB.size());
   // subproblems
   PyObject* pRelaxedDict = PyObject_CallMethod(m_pProb, "getRelaxsAsDict", 
						NULL);

   if (pRelaxedDict == NULL) {
      throw UtilException("Error calling method prob.getRelaxsAsDict()", 
			  "createModels", "DippyDecompApp");
   }

   int* masterOnly = new int[m_numCols];

   if (!masterOnly) {
      throw UtilExceptionMemory("createModels", "DecompApp");
   }

   UtilFillN(masterOnly, m_numCols, 1);

   int nRelaxed = 0;

   if (pRelaxedDict != Py_None) {
      nRelaxed = PyObject_Length(pRelaxedDict);
   }

   // we have a list of relaxations
   m_relaxedKeys = PyDict_Keys(pRelaxedDict);
   Py_XINCREF(m_relaxedKeys);
   PyObject* pKey, *pRelax;

   for (int p = 0; p < nRelaxed; p++) {
      DecompConstraintSet* modelRelax = new DecompConstraintSet();
      // each relaxation is a LpProblem
      pKey = PyList_GetItem(m_relaxedKeys, p);
      pRelax = PyDict_GetItem(pRelaxedDict, pKey);
      m_relaxIndices[pKey] = p; // Don't need to increase reference count here 
      //as m_relaxedKey references pKey
      PyObject* pRelaxAsTuple = PyObject_CallMethod(m_pProb, "getRelaxAsTuple",
						    "O", pRelax);

      if (pRelaxAsTuple == NULL) {
         throw UtilException("Error calling method prob.getRelaxAsTuple()", 
			     "createModels", "DippyDecompApp");
      }

      // row names
      pRowList = PyTuple_GetItem(pRelaxAsTuple, 0);
      pColList = PyTuple_GetItem(pRelaxAsTuple, 1);
      numRows = PyObject_Length(pRowList);
      map<PyObject*, int> relaxRowIndices;

      for (int i = 0; i < numRows; i++) {
         pRow = PyList_GetItem(pRowList, i);
         pRowName = PyObject_CallMethod(pRow, "getName", NULL);

         if (pRowName == NULL) {
            throw UtilException("Error calling method row.getName()", 
				"createModels", "DippyDecompApp");
         }

         pRowLb   = PyObject_CallMethod(pRow, "getLb", NULL);

         if (pRowLb == NULL) {
            throw UtilException("Error calling method row.getLb()", 
				"createModels", "DippyDecompApp");
         }

         pRowUb   = PyObject_CallMethod(pRow, "getUb", NULL);

         if (pRowUb == NULL) {
            throw UtilException("Error calling method row.getUb()", 
				"createModels", "DippyDecompApp");
         }

         name = PyString_AsString(pRowName);

         if (pRowLb == Py_None) {
            lb = -m_infinity;
         } else {
            lb = PyFloat_AsDouble(pRowLb);
         }

         if (pRowUb == Py_None) {
            ub = m_infinity;
         } else {
            ub = PyFloat_AsDouble(pRowUb);
         }

         modelRelax->rowNames.push_back(name);
         modelRelax->rowLB.push_back(lb);
         modelRelax->rowUB.push_back(ub);
         relaxRowIndices[pRow] = i;
      }

      // get the constraint matrix for this relaxation
      modelRelax->M = pyConstraints_AsPackedMatrix(pRowList, relaxRowIndices,
						   m_colIndices);  

      // set all cols at their lower bounds
      for (int j = 0; j < modelCore->colLB.size(); j++) {
         modelRelax->colLB.push_back(modelCore->colLB[j]);
         modelRelax->colUB.push_back(modelCore->colLB[j]);
      }

      // get active cols
      int cols = PyObject_Length(pColList);
      int index;

      for (int j = 0; j < cols; j++) {
         pCol = PyList_GetItem(pColList, j);
         index = m_colIndices[pCol];

         if ( (index < 0) || (index >= m_colIndices.size()) ) {
            throw UtilException("Bad index for " + name, "createModels", 
				"DippyDecompApp");
         }

         modelRelax->colUB[index] = modelCore->colUB[index];
         modelRelax->activeColumns.push_back(index);
         masterOnly[index] = 0;
      }

      modelRelax->M->setDimensions(modelRelax->rowLB.size(), 
				   modelRelax->colLB.size());

      // copy integer vars (from master prob)
      for (int j = 0; j < modelCore->integerVars.size(); j++) {
         modelRelax->integerVars.push_back(modelCore->integerVars[j]);
      }

      setModelRelax(modelRelax, "BLOCK", p);
   }

   for (i = 0; i < m_numCols; i++) {
      if (masterOnly[i]){
	 modelCore->masterOnlyCols.push_back(i);
      }
   }

   printf("Num master-only cols: %d\n", modelCore->masterOnlyCols.size());

   // set the core problem
   setModelCore(modelCore, "CORE");
   UTIL_DELARR(masterOnly);
}
示例#13
0
//===========================================================================//
void ATM_Instance::generateRandom(const int nAtms,
				  const int nDates,
				  const int seed){

   /*
     Data from original:
        \\ordsrv3\ormp\sas\ATM_Badshah\atm_20ATMS_3\atm_doc
	nDates=272, nAtms=20, nPairs=4730 (max=5440)

     proc means data=FTPLIB.amul_atms_dates;
     var withdrawal allocation NET_IMPACT_AVG 
     NET_IMPACT_STD NORMAL_AVG NORMAL_STD TS1 TS2;
     run;
     
     The MEANS Procedure     
     Variable          Label                  Std Dev            Mean
     ................................................................
     WITHDRAWAL        WITHDRAWAL          1456368.37      1457077.41
     ALLOCATION        ALLOCATION          1752334.72      2068196.66
     NET_IMPACT_AVG    NET_IMPACT_AVG       0.8990607       1.1961954
     NET_IMPACT_STD    NET_IMPACT_STD       1.8979644       1.4240460
     NORMAL_AVG        NORMAL_AVG          1352731.38      1440849.71
     NORMAL_STD        NORMAL_STD           352658.50       364123.38
     TS1               TS1                 1267244.80      1371637.24
     S2                TS2                 1246864.33      1361954.95
     ................................................................
          

     Variable          Label                  Minimum         Maximum
     ................................................................
     WITHDRAWAL        WITHDRAWAL             8000.00      7080400.00
     ALLOCATION        ALLOCATION           100000.00      7020000.00
     NET_IMPACT_AVG    NET_IMPACT_AVG       0.0053384      18.7119586
     NET_IMPACT_STD    NET_IMPACT_STD       0.0046809      54.0086478
     NORMAL_AVG        NORMAL_AVG            38864.52      4375539.71
     NORMAL_STD        NORMAL_STD            26833.85      1141006.06
     TS1               TS1                   25245.45      5250885.71
     TS2               TS2                700.0000000      4182207.14
     ................................................................
     
     for{<a,d> in ATMS_DATES_THIS} do;
     CA[a,d] = (normal_avg[a,d]  * net_impact_avg[a,d] - ts_period_2[a,d]); 
     CB[a,d] = (ts_period_1[a,d] - ts_period_2[a,d]);
     CC[a,d] = (ts_period_2[a,d] - ts_period_1[a,d]);
     CD[a,d] = (normal_std[a,d]  * net_impact_std[a,d]); 
     CE[a,d] = (-actual_withdrawal[a,d] + ts_period_2[a,d]);
     end;

     These numbers are annoying big and causing lots of numerical 
     round-off issues. So, Let's scale by 1000.
   */
#define STDD 0
#define MEAN 1
#define MIN  2
#define MAX  3
   double s_withdrawal[4]   = {1456368,   1457077,   8000,       7080400};
   double s_allocation[4]   = {1752334,   2068196,   100000,     7020000};
   double s_netimpactAve[4] = {0.8990607, 1.1961954, 0.0053384, 18.7119586};
   double s_netimpactStd[4] = {1.8979644, 1.4240460, 0.0046809, 54.0086478};
   double s_normalAve[4]    = {13527318,  1440849,   38864,     4375539.71};
   double s_normalStd[4]    = {352658,    364123,    26833,     1141006};
   double s_ts1[4]          = {1267244,   1371637,   25245,     5250885};
   double s_ts2[4]          = {1246864,   1361954,   700,       4182207};
   double scale             = 1000;
   int i;
   for(i = 0; i < 4; i++){
      s_withdrawal[i] /= scale;
      s_allocation[i] /= scale;
      s_normalAve[i]  /= scale;
      s_normalStd[i]  /= scale;
      s_ts1[i]        /= scale;
      s_ts2[i]        /= scale;
   }


   int      nAD          = nAtms * nDates;
   double * withdrawal   = new double[nAD];
   double * allocation   = new double[nAD];
   double * netimpactAve = new double[nAD];
   double * netimpactStd = new double[nAD];
   double * normalAve    = new double[nAD];
   double * normalStd    = new double[nAD];
   double * ts1          = new double[nAD];
   double * ts2          = new double[nAD];
   assert(withdrawal   && allocation   && netimpactAve &&
	  netimpactStd && normalAve    && normalStd    &&
	  ts1          && ts2);
   
   string   fileNameAD   = "atm_randAD_";
   fileNameAD += UtilIntToStr(nAtms) + "_";
   fileNameAD += UtilIntToStr(nDates) + "_";
   fileNameAD += UtilIntToStr(seed) + ".txt";
   string   fileNameA   = "atm_randA_";
   fileNameA += UtilIntToStr(nAtms) + "_";
   fileNameA += UtilIntToStr(nDates) + "_";
   fileNameA += UtilIntToStr(seed) + ".txt";
   string   fileNameD   = "atm_randD_";
   fileNameD += UtilIntToStr(nAtms) + "_";
   fileNameD += UtilIntToStr(nDates) + "_";
   fileNameD += UtilIntToStr(seed) + ".txt";

   ofstream osAD, osA, osD;
   UtilOpenFile(osAD, fileNameAD.c_str());
   UtilOpenFile(osA,  fileNameA.c_str());
   UtilOpenFile(osD,  fileNameD.c_str());
   
   int a, d;
   srand(seed);
   //---
   //--- generate 'raw data' in N[mean,std-dev]
   //---
   int index = 0;//a * nDates + d
   for(a = 0; a < nAtms; a++){
      for(d = 0; d < nDates; d++){
	 do{
	    withdrawal[index]   = UtilNormRand(s_withdrawal[MEAN]  , 
					       s_withdrawal[STDD]);
	 }while( withdrawal[index] < s_withdrawal[MIN] ||
		 withdrawal[index] > s_withdrawal[MAX]);
	 do{
	 allocation[index]   = UtilNormRand(s_allocation[MEAN]  , 
					    s_allocation[STDD]);
	 }while( allocation[index] < s_allocation[MIN] ||
		 allocation[index] > s_allocation[MAX]);
	 do{
	    netimpactAve[index] = UtilNormRand(s_netimpactAve[MEAN], 
					    s_netimpactAve[STDD]);
	 }while( netimpactAve[index] < s_netimpactAve[MIN] ||
		 netimpactAve[index] > s_netimpactAve[MAX]);
	 do{
	    netimpactStd[index] = UtilNormRand(s_netimpactStd[MEAN], 
					       s_netimpactStd[STDD]);
	 }while( netimpactStd[index] < s_netimpactStd[MIN] ||
		 netimpactStd[index] > s_netimpactStd[MAX]);
	 do{
	    normalAve[index]    = UtilNormRand(s_normalAve[MEAN]   , 
					       s_normalAve[STDD]);
	 }while( normalAve[index] < s_normalAve[MIN] ||
		 normalAve[index] > s_normalAve[MAX]);
	 do{
	    normalStd[index]    = UtilNormRand(s_normalStd[MEAN]   , 
						s_normalStd[STDD]);
	 }while( normalStd[index] < s_normalStd[MIN] ||
		 normalStd[index] > s_normalStd[MAX]);
	 do{
	    ts1[index]          = UtilNormRand(s_ts1[MEAN]         , 
					       s_ts1[STDD]);
	 }while( ts1[index] < s_ts1[MIN] ||
		 ts1[index] > s_ts1[MAX]);
	 do{
	    ts2[index]          = UtilNormRand(s_ts2[MEAN]         , 
					    s_ts2[STDD]);
	 }while ( ts2[index] < s_ts2[MIN] ||
		  ts2[index] > s_ts2[MAX]);
	 index++; 
      }
   }
		
   //---
   //--- generate coefficients
   //--- 
   //CA[a,d] = (normal_avg[a,d]  * net_impact_avg[a,d] - ts_period_2[a,d]); 
   //CB[a,d] = (ts_period_1[a,d] - ts_period_2[a,d]);
   //CC[a,d] = (ts_period_2[a,d] - ts_period_1[a,d]);
   //CD[a,d] = (normal_std[a,d]  * net_impact_std[a,d]); 
   //CE[a,d] = (-actual_withdrawal[a,d] + ts_period_2[a,d]);
   double * ca = new double[nAD];
   double * cb = new double[nAD];
   double * cc = new double[nAD];
   double * cd = new double[nAD];
   double * ce = new double[nAD];
   assert(ca && cb && cc && cd && ce);
   
   index = 0;
   osAD << "a\td\tCA\tCB\tCC\tCD\tCD\tCE\tCW\n";
   for(a = 0; a < nAtms; a++){
      for(d = 0; d < nDates; d++){
	 ca[index] = normalAve[index] * netimpactAve[index] - ts2[index];
	 cb[index] = ts1[index] - ts2[index];
	 cc[index] = -cb[index];
	 cd[index] = normalStd[index] * netimpactStd[index];
	 ce[index] = -withdrawal[index] + ts2[index];
	 osAD << "ATM"  << UtilIntToStr(a) << "\t"
	      << "DATE" << UtilIntToStr(d) << "\t"
	      << setw(10) << UtilDblToStr(ca[index],0)
	      << setw(10) << UtilDblToStr(cb[index],0)
	      << setw(10) << UtilDblToStr(cc[index],0)
	      << setw(10) << UtilDblToStr(cd[index],0)
	      << setw(10) << UtilDblToStr(ce[index],0) 
	      << setw(10) << UtilDblToStr(withdrawal[index],0) 
	      << "\n";
	 index++;
      }
   }

   //---
   //--- generate B and K
   //---
   //--- f(a,d) = ca*x1[a] + cb*x2[a] + cc*x1[a]*x2[a] + cd*x3[a] + ce
   //---      x1,x2 in {0,1}, x3 >= 0
   //---
   //--- sum{a} f(a,d)           <= B[d], for d
   //--- |{d in D | f(a,d) <= 0} <= K[a], for a
   //---
   double x01, x1, x2, x3;
   double * f = new double[nAD];
   assert(f);
   index = 0;
   for(a = 0; a < nAtms; a++){
      x01 = UtilURand(0.0,1.0);
      x1  = x01 >= 0.5 ? 1 : 0;
      x01 = UtilURand(0.0,1.0);
      x2  = x01 >= 0.5 ? 1 : 0;
      x3 = UtilURand(0.0,1.0);
      printf("x1=%g x2=%g x3=%g\n", x1, x2, x3);
      for(d = 0; d < nDates; d++){
	 f[index]  = ca[index] * x1;
	 f[index] += cb[index] * x2;
	 f[index] += cc[index] * x1 * x2;
	 f[index] += cd[index] * x3;
	 f[index] += ce[index];	    
	 index++;
      }
   }   
   
   double * B    = new double[nDates];
   double   maxB = -1e20;
   for(d = 0; d < nDates; d++){
      B[d] = 0;
      for(a = 0; a < nAtms; a++){
	 B[d] += f[a * nDates + d];
      }
      if(B[d] > maxB) maxB=B[d];
   }
   //---
   //--- B=budget for cash flow
   //---   if negative does not make sense
   //---   protect against this
   //---
   osD << "d\tB\n";
   for(d = 0; d < nDates; d++){
      if(B[d] < 0)
	 B[d] = maxB / 2.0;
      osD << "DATE" << UtilIntToStr(d) << "\t"
	  << setw(10) << UtilDblToStr(B[d],0) << endl;
   }
 
   int * K    = new int[nAtms];
   int   maxK = 0;
   index = 0;
   for(a = 0; a < nAtms; a++){
      K[a] = 0;
      for(d = 0; d < nDates; d++){
	 K[a] += f[index] <= 0 ? 1 : 0;
	 index++;
      }
      if(K[a] > maxK) maxK=K[a];
   }
   //---
   //--- randomize it (and tighten constraint)
   //---
   osA << "a\tK\n";
   for(a = 0; a < nAtms; a++){
      //K[a] -= UtilURand(1, maxK/4);
      osA << "ATM" << UtilIntToStr(a) << "\t"
	  << setw(10) << K[a] << endl;
   }
   
   osAD.close();
   osA.close();
   osD.close();
   
   UTIL_DELARR(withdrawal);
   UTIL_DELARR(allocation);
   UTIL_DELARR(netimpactAve);
   UTIL_DELARR(netimpactStd);
   UTIL_DELARR(normalAve);
   UTIL_DELARR(normalStd);
   UTIL_DELARR(ts1);
   UTIL_DELARR(ts2);
   UTIL_DELARR(ca);
   UTIL_DELARR(cb);
   UTIL_DELARR(cc);
   UTIL_DELARR(cd);
   UTIL_DELARR(ce);   
   UTIL_DELARR(f);
   UTIL_DELARR(B);
   UTIL_DELARR(K);
}