Ejemplo n.º 1
0
//===========================================================================//
void GAP_Instance::readInstance(string& fileName)
{
   int      i, j, n_ij, indexIJ;
   ifstream is;
   //---
   //--- File format (.../Decomp/data/GAP)
   //---
   //---   agents = machines (m, i index)
   //---   jobs   = tasks    (n, j index)
   //---
   //--- number of machines (m), number of tasks (n)
   //---   for each machine i (i=1,...,m) in turn:
   //---     cost of allocating task j to machine i (j=1,...,n)
   //---   for each machine i (i=1,...,m) in turn:
   //---     resource consumed in allocating task j to machine i (j=1,...,n)
   //--- resource capacity of machine j (j=1,...,m)
   //---
   UtilOpenFile(is, fileName.c_str());
   is >> m_nMachines
      >> m_nTasks;
   //---
   //--- allocate memory for capacity, value and weight
   //---
   n_ij = m_nMachines * m_nTasks;
   m_capacity = new int[m_nMachines];
   m_profit   = new int[n_ij];
   m_weight   = new int[n_ij];

   if (!(m_capacity && m_profit && m_weight)) {
      throw UtilExceptionMemory("readInstance", "GAP_Instance");
   }

   indexIJ = 0;

   for (i = 0; i < m_nMachines; i++) {
      for (j = 0; j < m_nTasks; j++) {
         is >> m_profit[indexIJ++];//TODO: bad name - since cost
      }
   }

   indexIJ = 0;

   for (i = 0; i < m_nMachines; i++) {
      for (j = 0; j < m_nTasks; j++) {
         is >> m_weight[indexIJ++];
      }
   }

   for (j = 0; j < m_nMachines; j++) {
      is >> m_capacity[j];
   }

   is.close();
}
Ejemplo n.º 2
0
//===========================================================================//
void ATM_DecompApp::createModels(){

   //---
   //--- This function does the work to create the different models 
   //---  that will be used. This memory is owned by the user. It will
   //---  be passed to the application interface and used by the algorithms.
   //---
   UtilPrintFuncBegin(m_osLog, m_classTag,
		      "APPcreateModel()", m_appParam.LogLevel, 2);
   
   //---
   //--- The original problem is in the form of a MINLP:
   //---    min  sum{a in A, d in D} | f[a,d] | 
   //---    s.t.
   //---    for a in A, d in D:
   //---       f[a,d] =  
   //---         a[a,d] x1[a]       +
   //---         b[a,d] x2[a]       +     
   //---         c[a,d] x1[a] x2[a] + 
   //---         d[a,d] x3[a]       +
   //---         e[a,d]
   //---    for d in D:
   //---       sum{a in A} f[a,d]      <= B[d]
   //---    for a in A:
   //---      |{d in D : f[a,d] < 0} | <= K[a] (notice strict ineq)
   //---    for a in A, d in D:
   //---      f[a,d] free
   //---    for a in A:
   //---      x1[a], x2[a] in [0,1], x3[a] >= 0
   //---

   //---
   //--- Discretization of continuous variable.
   //---      n     = number of steps
   //---      T     = {1, ..., n}
   //---      sum{t in T} (t/n) * x1[a,t]  = x1[a], for a in A
   //---      sum{t in T}         x1[a,t] <= 1    , for a in A
   //---   so, if n=10, x1[a] in {0,0.1,0.2,...,1.0}.
   //---

   //---
   //--- Linearization of product of a binary and a continuous.
   //---  For a in A, t in T:
   //---     z[a,t] = x1[a,t] * x2[a] 
   //---         <==>
   //---     z[a,t] >= 0 <= 1,                  
   //---     z[a,t] <= x1[a,t],            
   //---     z[a,t] <= x2[a],              
   //---     z[a,t] >= x1[a,t] + x2[a] - 1.
   //---

   //---
   //--- Linearization of the absolute value.
   //---  For a in A, d in D: 
   //---     f+[a,d], f-[a,d] >= 0
   //---     f[a,d] = f+[a,d] - f-[a,d]
   //---    |f[a,d]|= f+[a,d] + f-[a,d]
   //--- 

   //---
   //--- To model the count constraints.
   //---  For a in A:
   //---    |{d in D : f[a,d]            < 0}| <= K[a]
   //---      <==>
   //---    |{d in D : f+[a,d] - f-[a,d] < 0}| <= K[a]
   //---
   //---  At optimality, if f[a,d] != 0, then either
   //---    f+[a,d] > 0 and f-[a,d] = 0, or
   //---    f+[a,d] = 0 and f-[a,d] > 0.
   //---  So, to count the cases when f[a,d] < 0, we can restrict
   //---  attention to the cases where f-[a,d] > 0.
   //---
   //---  With some application specific stuff, 
   //---      we know that f-[a,d] <= w[a,d].
   //---
   //---  So, to count the number of cases we can use the following:
   //---      f-[a,d] >  0 ==> v[a,d] = 1
   //---      f-[a,d] <= 0 <== v[a,d] = 0
   //---        <==>
   //---      f-[a,d] <= w[a,d] * v[a,d]
   //---
   //---  and, then
   //---    |{d in D : f+[a,d] - f-[a,d] <  0}| <= K[a]
   //---        <==>
   //---    sum{d in D} v[a,d]                  <= K[a]
   //---

   //---
   //--- (Approximate) MILP Reformulation
   //---
   //---    min  sum{a in A, d in D} f+[a,d] + f-[a,d] 
   //---    s.t.
   //---    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]
   //---       f-[a,d] <= w[a,d] * v[a,d]
   //---    for a in A:
   //---       sum{t in T}  x1[a,t] <= 1
   //---    for a in A, t in T:
   //---       z[a,t] <= x1[a,t],            
   //---       z[a,t] <= x2[a],              
   //---       z[a,t] >= x1[a,t] + x2[a] - 1.
   //---    for d in D:
   //---       sum{a in A} (f+[a,d] - f-[a,d]) <= B[d]
   //---    for a in A:
   //---       sum{d in D} v[a,d]              <= K[a]
   //---    for a in A, d in D:
   //---       f+[a,d], f-[a,d] >= 0
   //---                f-[a,d] <= w[a,d]
   //---       v[a,d] in {0,1}
   //---    for a in A:
   //---       x2[a], x3[a] in [0,1]
   //---    for a in A, t in T
   //---       x1[a,t] in {0,1}, z[a,t] in [0,1]
   //---

   //---
   //--- UPDATE (April 2010). 
   //---
   //--- A tighter formulation of the 
   //---   linearization of product of a binary and a continuous 
   //---   is possible due to the constraint: sum{t in T}  x1[a,t] <= 1
   //---
   //---  For a in A, t in T:
   //---     z[a,t] = x1[a,t] * x2[a] 
   //---         <==>
   //--- OLD:
   //---  for a in A:
   //---     sum{t in T}  x1[a,t] <= 1 (where, T = 1..n)
   //---  for a in A, t in T:
   //---     z[a,t] >= 0 <= 1,                  
   //---     z[a,t] <= x1[a,t],            
   //---     z[a,t] <= x2[a],              
   //---     z[a,t] >= x1[a,t] + x2[a] - 1.
   //--- NEW: 
   //---  for a in A:
   //---     sum{t in T}  x1[a,t] = 1 (where, T = 0..n)
   //---     sum{t in T}   z[a,t] = x2[a]
   //---  for a in A, t in T:
   //---     z[a,t] >= 0 <= 1,                  
   //---     z[a,t] <= x1[a,t].
   //---


   //---
   //--- Columns
   //---   x1[a,t] (binary)
   //---   z [a,t]
   //---   f+[a,d] 
   //---   f-[a,d]
   //---   x2[a]
   //---   x3[a]
   //----  v[a,d] (binary)
   //---
   int i, a;
   int nAtms   = m_instance.getNAtms();
   int numCols = numCoreCols();

   //---
   //--- Construct the objective function.
   //---    Coefficients of f+ and f- are 1.0, the rest are 0.
   //---
   m_objective = new double[numCols];
   if(!m_objective)
      throw UtilExceptionMemory("createModels", "MMKP_DecompApp");
   UtilFillN(m_objective, numCols, 0.0);
   for(i = getColOffset_fp(); i < getColOffset_x2(); i++)
      m_objective[i] = 1.0;
   setModelObjective(m_objective, numCols);
   
   
   //---
   //--- A'' (core):
   //---    for d in D:
   //---       sum{a in A} (f+[a,d] - f-[a,d]) <= B[d]
   //---    for a in A: <--- option ( core or relax )
   //---       sum{d in D} v[a,d] <= K[a]
   //---
   //--- A'[a] for a in A (independent blocks)
   //---    for 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]
   //---       f-[a,d] <= w[a,d] * v[a,d]
   //---    sum{t in T}  x1[a,t] <= 1
   //---    for t in T:
   //---       z[a,t] <= x1[a,t],            
   //---       z[a,t] <= x2[a],              
   //---       z[a,t] >= x1[a,t] + x2[a] - 1.
   //---    sum{d in D} v[a,d] <= K[a] <--- option ( core or relax )
   //---
   if(m_appParam.ModelNameCore == "BUDGET"){
      DecompConstraintSet * modelCore = createModelCore1(false);
      m_models.push_back(modelCore);
      setModelCore(modelCore, "BUDGET");
   }
   if(m_appParam.ModelNameCore == "BUDGET_COUNT"){
      DecompConstraintSet * modelCore = createModelCore1();
      m_models.push_back(modelCore);
      setModelCore(modelCore, "BUDGET_COUNT");
   }   
   if(m_appParam.ModelNameRelax == "CASH"){
      for(a = 0; a < nAtms; a++){
	 DecompConstraintSet * modelRelax = createModelRelax1(a, false);
         m_models.push_back(modelRelax);
         setModelRelax(modelRelax, "CASH" + UtilIntToStr(a), a);
      }
   }
   if(m_appParam.ModelNameRelax == "CASH_COUNT"){
      for(a = 0; a < nAtms; a++){
	 DecompConstraintSet * modelRelax = createModelRelax1(a);
         m_models.push_back(modelRelax);
         setModelRelax(modelRelax, "CASH_COUNT" + UtilIntToStr(a), a);
      }
   }
   if(m_appParam.ModelNameRelaxNest == "CASH_COUNT"){
      for(a = 0; a < nAtms; a++){
	 DecompConstraintSet * modelRelax = createModelRelax1(a);
         m_models.push_back(modelRelax);
         setModelRelaxNest(modelRelax, "CASH_COUNT" + UtilIntToStr(a), a);
      }
   }


   //TODO: solve this A' with gap as relaxNest - but
   //  we are doing blocks - so find a column then break it out
   //  tell framework to do that? or do as user? show how we can 
   //  get stuff back from framework to setup and solve... 
   /*{
      //---
      //--- Version MODEL_MASTER_COUNT
      //---    is relaxation too hard?
      //---
      //--- A'' (core):
      //---    for a in A:
      //---       sum{d in D} v[a,d] <= K[a]
      //---
      //--- A' (relax):
      //---    for d in D:
      //---       sum{a in A} (f+[a,d] - f-[a,d]) <= B[d]
      //---    for a in A:
      //---       sum{t in T}  x1[a,t] <= 1
      //---    for a in A, t in T:
      //---       z[a,t] <= x1[a,t],            
      //---       z[a,t] <= x2[a],              
      //---       z[a,t] >= x1[a,t] + x2[a] - 1.      
      //---    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]
      //---       f-[a,d] <= w[a,d] * v[a,d]
      //---
     vector< DecompConstraintSet* > modelRelaxV;   
     DecompConstraintSet * modelCoreCount  = createModelCoreCount();
     DecompConstraintSet * modelRelaxCount = createModelRelaxCount();
     modelRelaxV.push_back(modelRelaxCount);   
     modelCore.insert (make_pair(MODEL_COUNT, modelCoreCount));
     modelRelax.insert(make_pair(MODEL_COUNT, modelRelaxV));
     }*/
   
   UtilPrintFuncEnd(m_osLog, m_classTag,
		    "APPcreateModel()", m_appParam.LogLevel, 2);
}
Ejemplo n.º 3
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);
	
}
Ejemplo n.º 4
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);
}
Ejemplo n.º 5
0
//===========================================================================//
void MCF_DecompApp::createModelRelaxSparse(DecompConstraintSet* model,
      int                   commId)
{
   //---
   //--- SUBPROBLEM (A'): (one block for each k in K)
   //---      sum{(j,i) in A} x[k,i,j] -
   //---         sum{(i,j) in A} x[k,i,j] = d[i,k], for all i in N
   //---      x[k,i,j] integer >= l[i,j] <= u[i,j], for all (i,j) in A
   //--- For k=(s,t) in K,
   //---    d[i,k] = -d[k] if i=s
   //---           =  d[k] if i=t
   //---           =  0, otherwise
   //---
   int         a, i, head, tail, origColIndex, source, sink;
   int         numArcs        = m_instance.m_numArcs;
   int         numNodes       = m_instance.m_numNodes;
   int         numCommodities = m_instance.m_numCommodities;
   int         numCols        = numArcs;
   int         numRows        = numNodes;
   int         numColsOrig    = numArcs * numCommodities;
   MCF_Instance::arc*        arcs        = m_instance.m_arcs;
   MCF_Instance::commodity* commodities = m_instance.m_commodities;
   UtilPrintFuncBegin(m_osLog, m_classTag,
                      "createModelRelaxSparse()", m_appParam.LogLevel, 2);
   //---
   //--- create space for the model matrix (row-majored)
   //---
   model->M = new CoinPackedMatrix(false, 0.0, 0.0);

   if (!model->M) {
      throw UtilExceptionMemory("createModelCore", "MCF_DecompApp");
   }

   model->M->setDimensions(0, numCols);
   model->reserve(numRows, numCols);
   model->setSparse(numColsOrig);
   //---
   //--- get this commodity's source and sink node
   //---
   source = commodities[commId].source;
   sink   = commodities[commId].sink;

   //---
   //--- create the rows
   //---   NOTE: this is somewhat inefficient (but simple)
   //---
   for (i = 0; i < numNodes; i++) {
      CoinPackedVector row;

      for (a = 0; a < numArcs; a++) {
         tail = arcs[a].tail;
         head = arcs[a].head;

         if (head == i) {
            row.insert(a, 1.0);
         } else if (tail == i) {
            row.insert(a, -1.0);
         }
      }

      if (i == source)
         model->appendRow(row,
                          -commodities[commId].demand,
                          -commodities[commId].demand);
      else if (i == sink)
         model->appendRow(row,
                          commodities[commId].demand,
                          commodities[commId].demand);
      else {
         model->appendRow(row, 0.0, 0.0);
      }
   }

   //---
   //--- set the colLB, colUB, integerVars and sparse mapping
   //---
   origColIndex = commId * numArcs;

   for (a = 0; a < numArcs; a++) {
      double           arcLB = arcs[a].lb;
      double           arcUB = arcs[a].ub;
      model->pushCol(arcLB, arcUB, true, origColIndex);
      origColIndex++;
   }

   UtilPrintFuncEnd(m_osLog, m_classTag,
                    "createModelRelaxSparse()", m_appParam.LogLevel, 2);
}
Ejemplo n.º 6
0
//===========================================================================//
void MCF_DecompApp::createModels()
{
   //---
   //--- This function does the work to create the different models
   //---  that will be used. This memory is owned by the user. It will
   //---  be passed to the application interface and used by the algorithms.
   //---
   UtilPrintFuncBegin(m_osLog, m_classTag,
                      "createModels()", m_appParam.LogLevel, 2);
   //---
   //--- (Integer) Multi-Commodity Flow Problem (MCF).
   //---
   //--- We are given:
   //---    (1) a directed graph G=(N,A),
   //---    (2) a set of commodities K, where each commodity is
   //---         a source-sink pair.
   //---
   //--- min  sum{k in K} sum{(i,j) in A} w[i,j] x[k,i,j]
   //--- s.t. sum{(j,i) in A} x[k,i,j] -
   //---        sum{(i,j) in A} x[k,i,j] = d[i,k],  for all i in N, k in K
   //---      sum{k in K} x[k,i,j] >= l[i,j],       for all (i,j) in A
   //---      sum{k in K} x[k,i,j] <= u[i,j],       for all (i,j) in A
   //---      x[k,i,j] integer >= l[i,j] <= u[i,j], for all (i,j) in A
   //--- For k=(s,t) in K,
   //---    d[i,k] = -d[k] if i=s
   //---           =  d[k] if i=t
   //---           =  0, otherwise
   //---
   //--- NOTE: to make sure the problem is always feasible, dummy arcs
   //---   have been added between all source-sink commodity pairs and have
   //---   been given a 'big' weight.
   //---
   //---
   //--- The decomposition is formed as:
   //---
   //--- MASTER (A''):
   //---      sum{k in K} x[k,i,j] >= l[i,j],       for all (i,j) in A
   //---      sum{k in K} x[k,i,j] <= u[i,j],       for all (i,j) in A
   //---      x[k,i,j] integer >= l[i,j] <= u[i,j], for all (i,j) in A
   //---
   //--- SUBPROBLEM (A'): (one block for each k in K)
   //---      sum{(j,i) in A} x[k,i,j] -
   //---         sum{(i,j) in A} x[k,i,j] = d[i,k], for all i in N
   //---      x[k,i,j] integer >= l[i,j] <= u[i,j], for all (i,j) in A
   //---
   //---
   //--- Get information about this problem instance.
   //---
   int   k, a, colIndex;
   int   numCommodities = m_instance.m_numCommodities;
   int   numArcs        = m_instance.m_numArcs;
   int   numCols        = numCommodities * numArcs;
   MCF_Instance::arc* arcs = m_instance.m_arcs;
   //---
   //--- Construct the objective function and set it
   //---    columns indexed as [k,a]= k*numArcs + a
   //---
   objective = new double[numCols];

   if (!objective) {
      throw UtilExceptionMemory("createModels", "MCF_DecompApp");
   }

   colIndex = 0;

   for (k = 0; k < numCommodities; k++)
      for (a = 0; a < numArcs; a++) {
         objective[colIndex++] = arcs[a].weight;
      }

   //---
   //--- set the objective
   //---
   setModelObjective(objective, numCols);
   //---
   //--- create the core/master model and set it
   //---
   modelCore = new DecompConstraintSet();
   createModelCore(modelCore);
   setModelCore(modelCore, "core");

   //---
   //--- create the relaxed/subproblem models and set them
   //---
   for (k = 0; k < numCommodities; k++) {
      modelRelax = new DecompConstraintSet();
      string                modelName  = "relax" + UtilIntToStr(k);

      if (m_appParam.UseSparse) {
         createModelRelaxSparse(modelRelax, k);
      } else {
         createModelRelax(modelRelax, k);
      }

      setModelRelax(modelRelax, modelName, k);
      m_models.push_back(modelRelax);
   }

   UtilPrintFuncEnd(m_osLog, m_classTag,
                    "createModels()", m_appParam.LogLevel, 2);
}
Ejemplo n.º 7
0
//===========================================================================//
void MCF_DecompApp::createModelCore(DecompConstraintSet* model)
{
   //---
   //--- MASTER (A''):
   //---      sum{k in K} x[k,i,j] >= l[i,j],       for all (i,j) in A
   //---      sum{k in K} x[k,i,j] <= u[i,j],       for all (i,j) in A
   //---      x[k,i,j] integer >= l[i,j] <= u[i,j], for all (i,j) in A
   //---
   int   k, a, colIndex;
   int   numCommodities = m_instance.m_numCommodities;
   int   numArcs        = m_instance.m_numArcs;
   int   numCols        = numCommodities * numArcs;
   int   numRows        = 2              * numArcs;
   MCF_Instance::arc* arcs = m_instance.m_arcs;
   UtilPrintFuncBegin(m_osLog, m_classTag,
                      "createModelCore()", m_appParam.LogLevel, 2);
   //---
   //--- create space for the model matrix (row-majored)
   //---
   model->M = new CoinPackedMatrix(false, 0.0, 0.0);

   if (!model->M) {
      throw UtilExceptionMemory("createModelCore", "MCF_DecompApp");
   }

   model->M->setDimensions(0, numCols);
   model->reserve(numRows, numCols);
   //---
   //--- create the rows and set the col/row bounds
   //---
   UtilFillN(model->colLB, numCols,  0.0);
   UtilFillN(model->colUB, numCols,  m_infinity);

   for (a = 0; a < numArcs; a++) {
      CoinPackedVector row;
      double           arcLB = arcs[a].lb;
      double           arcUB = arcs[a].ub;

      for (k = 0; k < numCommodities; k++) {
         colIndex = k * numArcs + a;
         model->colLB[colIndex] = arcLB;
         model->colUB[colIndex] = arcUB;
         row.insert(colIndex, 1.0);
      }

      //TODO: any issue with range constraints?
      model->appendRow(row, -m_infinity, arcUB);
      string rowNameUB = "capUB(" +
                         UtilIntToStr(a)            + "_" +
                         UtilIntToStr(arcs[a].tail) + "," +
                         UtilIntToStr(arcs[a].head) + ")";
      model->rowNames.push_back(rowNameUB);
      model->appendRow(row, arcLB,  m_infinity);
      string rowNameLB = "capLB(" +
                         UtilIntToStr(a)            + "_" +
                         UtilIntToStr(arcs[a].tail) + "," +
                         UtilIntToStr(arcs[a].head) + ")";
      model->rowNames.push_back(rowNameLB);
   }

   //---
   //--- create column names (helps with debugging)
   //---
   for (k = 0; k < numCommodities; k++) {
      for (a = 0; a < numArcs; a++) {
         string colName = "x(comm_" + UtilIntToStr(k) + "," +
                          UtilIntToStr(a)            + "_" +
                          UtilIntToStr(arcs[a].tail) + "," +
                          UtilIntToStr(arcs[a].head) + ")";
         model->colNames.push_back(colName);
      }
   }

   //---
   //--- set the indices of the integer variables of model
   //---
   UtilIotaN(model->integerVars, numCols, 0);
   UtilPrintFuncEnd(m_osLog, m_classTag,
                    "createModelCore()", m_appParam.LogLevel, 2);
}
Ejemplo n.º 8
0
//===========================================================================//
void MCF_DecompApp::createModelRelax(DecompConstraintSet* model,
                                     int                   commId)
{
   //---
   //--- SUBPROBLEM (A'): (one block for each k in K)
   //---      sum{(j,i) in A} x[k,i,j] -
   //---         sum{(i,j) in A} x[k,i,j] = d[i,k], for all i in N
   //---      x[k,i,j] integer >= l[i,j] <= u[i,j], for all (i,j) in A
   //--- For k=(s,t) in K,
   //---    d[i,k] = -d[k] if i=s
   //---           =  d[k] if i=t
   //---           =  0, otherwise
   //---
   int         a, i, head, tail, colIndex, source, sink;
   int         numCommodities = m_instance.m_numCommodities;
   int         numArcs        = m_instance.m_numArcs;
   int         numNodes       = m_instance.m_numNodes;
   int         numCols        = numCommodities * numArcs;
   int         numRows        = numNodes;
   MCF_Instance::arc*        arcs        = m_instance.m_arcs;
   MCF_Instance::commodity* commodities = m_instance.m_commodities;
   UtilPrintFuncBegin(m_osLog, m_classTag,
                      "createModelRelax()", m_appParam.LogLevel, 2);
   //---
   //--- create space for the model matrix (row-majored)
   //---
   model->M = new CoinPackedMatrix(false, 0.0, 0.0);

   if (!model->M) {
      throw UtilExceptionMemory("createModelCore", "MCF_DecompApp");
   }

   model->M->setDimensions(0, numCols);
   model->reserve(numRows, numCols);
   //---
   //--- get this commodity's source and sink node
   //---
   source = commodities[commId].source;
   sink   = commodities[commId].sink;

   //---
   //--- create the rows
   //---   NOTE: this is somewhat inefficient (but simple)
   //---
   for (i = 0; i < numNodes; i++) {
      CoinPackedVector row;

      for (a = 0; a < numArcs; a++) {
         tail = arcs[a].tail;
         head = arcs[a].head;

         if (head == i) {
            colIndex = commId * numArcs + a;
            row.insert(colIndex, 1.0);
         } else if (tail == i) {
            colIndex = commId * numArcs + a;
            row.insert(colIndex, -1.0);
         }
      }

      if (i == source)
         model->appendRow(row,
                          -commodities[commId].demand,
                          -commodities[commId].demand);
      else if (i == sink)
         model->appendRow(row,
                          commodities[commId].demand,
                          commodities[commId].demand);
      else {
         model->appendRow(row, 0.0, 0.0);
      }

      string rowName = "flow(" +
                       UtilIntToStr(commId) + "_" +
                       UtilIntToStr(i)      + "_" +
                       UtilIntToStr(source) + "," +
                       UtilIntToStr(sink)   + ")";
      model->rowNames.push_back(rowName);
   }

   //---
   //--- create a list of the "active" columns (those related
   //---   to this commmodity) all other columns are fixed to 0
   //---
   UtilFillN(model->colLB, numCols,  0.0);
   UtilFillN(model->colUB, numCols,  0.0);
   colIndex = commId * numArcs;

   for (a = 0; a < numArcs; a++) {
      double           arcLB = arcs[a].lb;
      double           arcUB = arcs[a].ub;
      model->colLB[colIndex] = arcLB;
      model->colUB[colIndex] = arcUB;
      model->activeColumns.push_back(colIndex);
      colIndex++;
   }

   //---
   //--- set the indices of the integer variables of model
   //---
   UtilIotaN(model->integerVars, numCols, 0);
   UtilPrintFuncEnd(m_osLog, m_classTag,
                    "createModelRelax()", m_appParam.LogLevel, 2);
}
Ejemplo n.º 9
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);
}
Ejemplo n.º 10
0
//===========================================================================//
void SDPUC_DecompApp::createModels(){

   //---
   //--- This function does the work to create the different models 
   //---  that will be used. This memory is owned by the user. It will
   //---  be passed to the application interface and used by the algorithms.
   //---
   UtilPrintFuncBegin(m_osLog, m_classTag,
		      "createModels()", m_appParam.LogLevel, 2);

   //---
   //---  Switched Dispatch Problem with Unit Commitment (SDPUC).
   //---
   //--- We are given: 
   //---    (1) a directed graph G=(N,A),
   //---    (2) a set of time periods T, 
   //---
   //--- min  sum{(i,j) in A} f1[i,j] y1[i,j] 
   //---		  + sum{t in T} sum{(i,j) in A} f2[i,j] y2[i,j,t] + c[i,j,t] x[i,j,t]
   //--- s.t. sum{(j,i) in A} x[i,j,t] - 
   //---        sum{(i,j) in A} x[i,j,t] = d[i,t],  for all i in N, t in T
   //---      x[i,j,t] >= l[i,j,t] z[i,j,t],       for all (i,j) in A, t in T
   //---      x[i,j,t] <= u[i,j,t] z[i,j,t],       for all (i,j) in A, t in T
   //---	  r[i,j] x[i,j,t] - theta[j] + theta[i] <=  M (1 - z[i,j,t]) for all i,j,t
   //---	  r[i,j] x[i,j,t] - theta[j] + theta[i] >= -M (1 - z[i,j,t]) for all i,j,t
   //---	  z[i,j,t] <= y1[i,j]  for all (i,j) in A, t in T				  //arc-investment
   //---	  z[i,j,t] - z[i,j,t-1] <= y2[i,j,t]  for all (i,j) in A, t in T  //arc(unit) commitment
   //---	  y[i,j] binary for all (i,j) in A
   //---
   //--- NOTE: to make sure the problem is always feasible, 
   //----      demand may have to be modelled as arcs with large negative costs
   //---
   //---
   //--- The decomposition is formed as:
   //---
   //--- MASTER (A''):
   //---	  z[i,j,t] <= y1[i,j]  for all (i,j) in A, t in T				  //arc-investment
   //---	  z[i,j,t] - z[i,j,t-1] <= y2[i,j,t]  for all (i,j) in A, t in T  //arc(unit) commitment
   //---	  y[i,j] binary for all (i,j) in A
   //---
   //--- SUBPROBLEM (A'): (one block for each t in T)
   //---     sum{(j,i) in A} x[i,j,t] - 
   //---        sum{(i,j) in A} x[i,j,t] = d[i,t],  for all i in N
   //---      x[i,j,t] >= l[i,j,t] z[i,j,t],       for all (i,j) in A
   //---      x[i,j,t] <= u[i,j,t] z[i,j,t],       for all (i,j) in A
   //---	  r[i,j] x[i,j,t] - theta[j] + theta[i] <=  M (1 - z[i,j,t]) for all i,j
   //---	  r[i,j] x[i,j,t] - theta[j] + theta[i] >= -M (1 - z[i,j,t]) for all i,j

   //---

   //---
   //--- Get information about this problem instance.
   //---
   int   i, t, a, colIndex;
   int   numTimeperiods = m_instance.m_numTimeperiods;
   int   numArcs        = m_instance.m_numArcs;
   int	 numNodes		= m_instance.m_numNodes;
   int   numCols        = numArcs							//y1-vars
      + 3 * numTimeperiods * numArcs	//y2-, z-, and x-vars
      + numTimeperiods * numNodes;		//theta-vars
   SDPUC_Instance::arc * arcs = m_instance.m_arcs;
   SDPUC_Instance::timeseries * ts = m_instance.m_timeseries;
   cout << "\nnumCols=" << numCols << " numTimePeriods=" << numTimeperiods;
   cout << "numNodes=" << numNodes << " numArcs=" << numArcs << endl;

   //---
   //--- Construct the objective function and set it
   //---    y1-var columns indexed as [a]   = a  in [0 ; numArcs-1]
   //---	y2-var columns indexed as [a,t]  = a + numArcs in [numArcs ; numArcs * (1 + numTimeperiods) - 1]
   //---	z-var columns indexed as [a,t] = t*numArcs + a +  numArcs * (1 + numTimeperiods) 
   //---										in [numArcs*(1+numTimeperiods); numArcs*(1 + 2*numTimeperiods) - 1]
   //---	x-var columns indexed as [a,t] = t*numArcs + a + numArcs*(1 + 2*numTimeperiods) , 
   //---										in [numArcs*(1 + 2*numTimeperiods) ; numArcs*(1 + 3*numTimeperiods) - 1]
   //---	theta-var columns indexed as [i,t] = t*numNodes + i + numArcs*(1 + 3*numTimeperiods) , 
   //---										   in [numArcs*(1 + 3*numTimeperiods) ; numArcs*(1 + 3*numTimeperiods) + numNodes*numTimeperiods - 1]
   //--
   m_objective = new double[numCols];
   //initialise to 0
   for(i = 0; i < numCols; i++){
      m_objective[i] = 0;
   }
   if(!m_objective)
      throw UtilExceptionMemory("createModels", "MCF_DecompApp");
   colIndex = 0;
   for(a = 0; a < numArcs; a++) {
      m_objective[colIndex++] = arcs[a].fcost1;  //fixed arc investment cost 
   }
   for(t = 0; t < numTimeperiods; t++) {
      for(a = 0; a < numArcs; a++) {
	 m_objective[colIndex++] = arcs[a].fcost2;  //fixed arc "start-up" cost 
      }
   }
   colIndex = numArcs*(1 + 2*numTimeperiods);  //start-index for x-vars
   for(t = 0; t < numTimeperiods; t++) {
      for(a = 0; a < numArcs; a++) {
         m_objective[colIndex++] = arcs[a].mcost * ts[0].values[t] ;  //arc cost * probability (assume ts[0] indicate timeperiod probabilities)
      }
   }	 
   //---
   //--- set the objective 
   //---        
   setModelObjective(m_objective, numCols);
   /*cout << "obj = " ;
     for(i = 0; i < numCols; i++){
     cout << m_objective[i] << " ";
     }
     cout << endl;*/
   
   //---
   //--- create the core/master model and set it
   //---
   DecompConstraintSet * modelCore = new DecompConstraintSet();      
   createModelCore(modelCore);
   setModelCore(modelCore, "core");

   //---
   //--- create the relaxed/subproblem models and set them
   //---
   for(t = 0; t < numTimeperiods; t++){
      DecompConstraintSet * modelRelax = new DecompConstraintSet();
      string                modelName  = "relax" + UtilIntToStr(t);
      if(m_appParam.UseSparse)
         createModelRelaxSparse(modelRelax, t);
      else
         createModelRelax(modelRelax, t);
      
      setModelRelax(modelRelax, modelName, t);
   }

   //---
   //--- 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
   //---
   
   UtilPrintFuncEnd(m_osLog, m_classTag,
                    "createModels()", m_appParam.LogLevel, 2);
}
Ejemplo n.º 11
0
//===========================================================================//
void SDPUC_DecompApp::createModelRelax(DecompConstraintSet * model,
				       int                   tpId){

   //---
   //--- SUBPROBLEM (A'): (one block for each k in K)
   //---      sum{(j,i) in A} x[k,i,j] - 
   //---         sum{(i,j) in A} x[k,i,j] = d[i,k], for all i in N
   //---      x[k,i,j] integer >= l[i,j] <= u[i,j], for all (i,j) in A
   //--- For k=(s,t) in K,
   //---    d[i,k] = -d[k] if i=s
   //---           =  d[k] if i=t
   //---           =  0, otherwise

   //--- SUBPROBLEM (A'): (one block for each t in T)
   //---     sum{(j,i) in A} x[i,j,t] - 
   //---        sum{(i,j) in A} x[i,j,t] = d[i,t],  for all i in N\{s}, where s is the super source
   //---      x[i,j,t] >= l[i,j,t] z[i,j,t],       for all (i,j) in A
   //---      x[i,j,t] <= u[i,j,t] z[i,j,t],       for all (i,j) in A
   //---	  r[i,j] x[i,j,t] - theta[j] + theta[i] <=  M (1 - z[i,j,t]) for all i,j in A
   //---	  r[i,j] x[i,j,t] - theta[j] + theta[i] >= -M (1 - z[i,j,t]) for all i,j in A
   //---
   int         a, i, j, head, tail, colIndex, source;
   int         numTimeperiods = m_instance.m_numTimeperiods;
   int         numArcs        = m_instance.m_numArcs;
   int		   numSwitchings  = m_instance.m_numSwitchings;
   int         numNodes       = m_instance.m_numNodes;   
   int         numCols        = numArcs						    //y1-vars
      + 3 * numTimeperiods * numArcs	//y2-, z-, and x-vars
      + numTimeperiods * numNodes;		//theta-vars

   SDPUC_Instance::arc        * arcs     = m_instance.m_arcs;
   SDPUC_Instance::node       * nodes    = m_instance.m_nodes;
   SDPUC_Instance::timeseries * ts		  = m_instance.m_timeseries;
  
   int		   numACArcs = 0;
   for(a = 0; a < numArcs; a++){
      if(arcs[a].acline == 1) { numACArcs++; }
   }

   int         numRows        = numNodes - 1    // balance
      + 2 * numArcs     // capacity 
      + 2 * numACArcs   // and kirchoffs constraints
      + 1;				// max. allowed no. of switches employed  sum{z} <= k

   int	 col_yStartIndex  =		 0;
   int	 col_zStartIndex  =		 numArcs*(1+numTimeperiods);
   int	 col_xStartIndex  =		 numArcs * (1 + 2*numTimeperiods);
   int	 col_thetaStartIndex  =	 numArcs*(1 + 3*numTimeperiods) ;

   double   bigM = 100;

  


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

  


   //---
   //--- create space for the model matrix (row-majored)
   //---
   model->M = new CoinPackedMatrix(false, 0.0, 0.0);
   if(!model->M)
      throw UtilExceptionMemory("createModelCore", "MCF_DecompApp");
   model->M->setDimensions(0, numCols);
   model->reserve(numRows, numCols);

   //---
   //--- set super source node
   //---
   source = 0;
   
   //---
   //--- create the rows 
   //---   NOTE: this is somewhat inefficient (but simple)
   //---
   int hej = 0;
   cout << "Generating sub-problem " << tpId << endl; hej++;
   //cout << "y_index = " << col_yStartIndex << endl;
   //cout << "z_index = " << col_zStartIndex << endl;
   //cout << "x_index = " << col_xStartIndex << endl;
   //cout << "theta_index = " << col_thetaStartIndex << endl;
   //--- create balance constraints
   for(i = 0; i < numNodes; i++){
      CoinPackedVector row;
      for(a = 0; a < numArcs; a++){
         tail = arcs[a].tail;
         head = arcs[a].head;
         if(head == i){
	    colIndex = col_xStartIndex + tpId * numArcs + a;
            row.insert(colIndex, 1.0);
         }
         else if(tail == i){
            colIndex = col_xStartIndex + tpId * numArcs + a;
            row.insert(colIndex, -1.0);
         }
      }

      //set demand d
      double d = nodes[i].demand * ts[nodes[i].tsdemand].values[tpId];
      std::string rowName = "balance_" + UtilIntToStr(i) + "_" + UtilIntToStr(tpId);
      if(i == source) {
         model->appendRow(row, -m_infinity, 0.0, rowName);
      }
      else {
         model->appendRow(row, d, d, rowName);
      }
   }

   //--- create capacity constraints and kirchoffs constraints
   for(a = 0; a < numArcs; a++){
      CoinPackedVector rowLB, rowUB; //lower-, and upperbound
      //for(a = 0; a < numArcs; a++){
      tail = arcs[a].tail;
      head = arcs[a].head;
      double lb = arcs[a].lb * ts[arcs[a].tscap].values[tpId];
      double ub = arcs[a].ub * ts[arcs[a].tscap].values[tpId];
      double reactance = arcs[a].weight;
      colIndex = col_zStartIndex + tpId * numArcs + a;		 
      rowLB.insert(colIndex, -lb);
      rowUB.insert(colIndex, -ub);
 		
      colIndex = col_xStartIndex + tpId * numArcs + a;
      rowLB.insert(colIndex, 1.0);
      rowUB.insert(colIndex, 1.0);
		 
		 
      //set flow lower and upperbound
      std::string rowNameLB = "lb_" + UtilIntToStr(a) + "_" + UtilIntToStr(tpId);
      std::string rowNameUB = "ub_" + UtilIntToStr(a) + "_" + UtilIntToStr(tpId);
      model->appendRow(rowLB, 0.0, m_infinity, rowNameLB);
      model->appendRow(rowUB, -m_infinity, 0.0, rowNameUB);

      //set kirchoffs voltage constraints for ac-arcs
      if(arcs[a].acline == 1) {
	 CoinPackedVector rowK1, rowK2; //Kirchoff1, and Kirchoff2
	 colIndex = col_zStartIndex + tpId * numArcs + a;
	 rowK1.insert(colIndex, bigM);
	 rowK2.insert(colIndex, -bigM);
	 colIndex = col_xStartIndex + tpId * numArcs + a;
	 rowK1.insert(colIndex, reactance);
	 rowK2.insert(colIndex, reactance);
	 for(i = 0; i < numNodes; i++){
	    if(head == i){
	       colIndex = col_thetaStartIndex + tpId * numNodes + i;
	       rowK1.insert(colIndex, -1.0);
	       rowK2.insert(colIndex, -1.0);
	    }
	    else if(tail == i){
	       colIndex = col_thetaStartIndex + tpId * numNodes + i;
	       rowK1.insert(colIndex, 1.0);
	       rowK2.insert(colIndex, 1.0);
	    }
	 }
         std::string rowNameK1 = "k1_" + UtilIntToStr(a) + "_" + UtilIntToStr(tpId);
         std::string rowNameK2 = "k2_" + UtilIntToStr(a) + "_" + UtilIntToStr(tpId);
	 model->appendRow(rowK1, -m_infinity, bigM, rowNameK1);
	 model->appendRow(rowK2, -bigM, m_infinity, rowNameK2);
      }

   }

   //--- create max. no. of switchings-constraint
   CoinPackedVector row;
   for(a = 0; a < numArcs; a++){
      colIndex = col_zStartIndex + tpId * numArcs + a;
      if(arcs[a].acline == 1) {  //only for arcs with voltage constraints
	 row.insert(colIndex, 1.0);
      }
   }
   //model->appendRow(row, numACArcs-numSwitchings, numACArcs, std::string("sum{1-z}<=k"));
   std::string rowNameSumK = "sumk_" + UtilIntToStr(tpId);
   model->appendRow(row, numACArcs-numSwitchings, numACArcs, rowNameSumK);


   //---
   //--- create a list of the "active" columns (those related 
   //---   to this commmodity) all other columns are fixed to 0
   //---
   UtilFillN(model->colLB, numCols,  0.0);
   UtilFillN(model->colUB, numCols,  0.0);
   colIndex = 0;
   for(a = 0; a < numArcs; a++){
      //set y-columns active
      //if(tpId == 0) {
      //colIndex = col_yStartIndex + a;
      //   model->colLB[colIndex] = 0;
      //   model->colUB[colIndex] = 1;
      //   model->activeColumns.push_back(colIndex);
      //cout << "" << colIndex << ", " ;
      //}
      //set z-columns active
      colIndex = col_zStartIndex + tpId * numArcs + a;
      model->colLB[colIndex] = 0; //1 - arcs[a].switchable;  //if arc not switchable then fix z=1
      model->colUB[colIndex] = 1;
      model->activeColumns.push_back(colIndex);
      //set x-columns active
      colIndex = col_xStartIndex + tpId * numArcs + a;
      double           arcLB = min(0.0, arcs[a].lb * ts[arcs[a].tscap].values[tpId]); //!!****
      double           arcUB = arcs[a].ub * ts[arcs[a].tscap].values[tpId];
      model->colLB[colIndex] = arcLB;
      model->colUB[colIndex] = arcUB;
      model->activeColumns.push_back(colIndex);
   }
   //set theta-columns active
   for(i = 0; i < numNodes; i++){
      colIndex = col_thetaStartIndex + tpId * numNodes + i;
      model->colLB[colIndex] = -m_infinity;
      model->colUB[colIndex] =  m_infinity;
      model->activeColumns.push_back(colIndex);
   }  

   //---
   //--- set the indices of the integer variables of model
   //---
   UtilIotaN(model->integerVars, col_xStartIndex, col_yStartIndex);
  
   ////Display problem
   //cout << "find: \nActive cols: ";
   //std::vector<int>::const_iterator it;
   //for(it = model->getActiveColumns().begin(); it < model->getActiveColumns().end(); it++){
   //cout << *it << " ";
   //}
   //cout << "\ns.t.\n";
   //for(j = 0; j < model->getNumRows(); j++){
   //cout << model->rowNames[j] << " : \t\t";
   //cout << model->rowLB[j] << " \t <= \t" ;
   //for (i = 0; i < model->getNumCols(); i++){
   ////cout << "numCols=" << model->getNumCols() << endl;
   //if(model->getMatrix()->getCoefficient(j,i) != 0) {
   ////cout << "i" << i << " ";
   //cout << " " << model->M->getCoefficient(j,i) << " (" << i << ") + ";
   ////cout << model->getColNames()[i] ;
   //}
   //else {cout << "" ;}
   //}
   //cout << " \t <= \t " << model->rowUB[j] << endl ;
   //
   //}

   UtilPrintFuncEnd(m_osLog, m_classTag,
                    "createModelRelax()", m_appParam.LogLevel, 2);
}
Ejemplo n.º 12
0
//===========================================================================//
void SDPUC_DecompApp::createModelCore(DecompConstraintSet * model){

   //---
   //--- MASTER (A''):
   //---	  z[i,j,t] <= y1[i,j]  for all (i,j) in A, t in T		  //arc-investment
   //---	  z[i,j,t] - z[i,j,t-1] <= y2[i,j,t]  for all (i,j) in A, t in T  //arc(unit) commitment
   //---	  y[i,j] binary for all (i,j) in A
   //---                                    
   int   i, t, a, colIndex;
   int   numTimeperiods =		 m_instance.m_numTimeperiods;
   int   numArcs        =		 m_instance.m_numArcs;
   int   numNodes		=		 m_instance.m_numNodes;
   int   numCols        =		 numArcs   //y1-vars
      + 3 * numTimeperiods * numArcs	           //y2-, z-, and x-vars
      + numTimeperiods * numNodes;		   //theta-vars
   int   numRows		  =		 numArcs * numTimeperiods;
   int	 col_yStartIndex  =		 0;
   int	 col_zStartIndex  =		 numArcs*(1+numTimeperiods);
   int	 col_xStartIndex  =		 numArcs * (1 + 2*numTimeperiods);
   int	 col_thetaStartIndex  =	 numArcs*(1 + 3*numTimeperiods) ;

   SDPUC_Instance::arc * arcs = m_instance.m_arcs;

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

   //---
   //--- create space for the model matrix (row-majored)
   //---
   model->M = new CoinPackedMatrix(false, 0.0, 0.0);
   if(!model->M)
      throw UtilExceptionMemory("createModelCore", "SDPUC_DecompApp");
   model->M->setDimensions(0, numCols);
   model->reserve(numRows, numCols);
   
   //---
   //--- create the rows and set the col/row bounds
   //---
   UtilFillN(model->colLB, numCols,  -m_infinity);
   UtilFillN(model->colUB, numCols,  m_infinity);
   
   for(a = 0; a < numArcs; a++){
      colIndex = a;
      //add y1-vars   
      model->colLB[colIndex] = 0;
      model->colUB[colIndex] = 1;
	 
      for(t = 0; t < numTimeperiods; t++){
	 int t_prev = 0;
	 if(t == 0) {
            t_prev = numTimeperiods - 1;
         }
	 else {
            t_prev = t - 1;
         }

	 colIndex = a + t * numArcs + numArcs;
	 //add y2-vars   
	 model->colLB[colIndex] = 0;
	 model->colUB[colIndex] = 1;

	 CoinPackedVector row1;        // 0 <= y1[i,j] - z[i,j,t]  for all (i,j) in A, t in T
	 CoinPackedVector row2;        // 0 <= y2[i,j,t] - z[i,j,t] + z[i,j,t-1]  for all (i,j) in A, t in T 
	 CoinPackedVector rowFix_y1;   //fix y1=1
	 CoinPackedVector y2upper1;   // y2(t) <= z(t)  : if off in t then we dont start-up
	 CoinPackedVector y2upper2;   // y2(t) <= 1-z(t-1)  : if on in t-1 then dont start up in t

	 //insert y1-var coefficient
	 row1.insert(a, 1.0);
	 rowFix_y1.insert(a, 1.0);
	 //insert y2-var coefficient
	 colIndex = t * numArcs + a + numArcs;
	 row2.insert(colIndex, 1.0);
	 y2upper1.insert(colIndex, -1.0);
	 y2upper2.insert(colIndex, -1.0);
	 //add z-vars   
	 colIndex = t * numArcs + a + col_zStartIndex;
	 model->colLB[colIndex] = 0;
	 model->colUB[colIndex] = 1;
	 //insert z-var coefficient
	 row1.insert(colIndex, -1.0);
	 row2.insert(colIndex, -1.0);
	 y2upper1.insert(colIndex, 1.0);
	 colIndex = t_prev * numArcs + a + col_zStartIndex;
	 row2.insert(colIndex, 1.0);
	 y2upper2.insert(colIndex, -1.0);

         std::string rowName1_1 = "MP1_1_" + UtilIntToStr(a) + "_" + UtilIntToStr(t);
         std::string rowName1_2 = "MP1_2_" + UtilIntToStr(a) + "_" + UtilIntToStr(t);
         std::string rowName2_1 = "MP2_1_" + UtilIntToStr(a) + "_" + UtilIntToStr(t);
         std::string rowName2_2 = "MP2_2_" + UtilIntToStr(a) + "_" + UtilIntToStr(t);
         std::string rowNameFix = "fix_y1_" + UtilIntToStr(a) + "_" + UtilIntToStr(t);
 
	 //TODO: any issue with range constraint
	 model->appendRow(row1, 0.0, m_infinity, rowName1_1);  //add MP1_constraints (arc investments)
         
         model->appendRow(row1, -m_infinity, 1.0, rowName1_2);  //add MP1_constraints (arc investments)
	 if(arcs[a].tail == 0) {   //ONLY for supply arcs (!!)
	    model->appendRow(row2, 0.0, m_infinity, rowName2_1);  //add MP2_constraints (arc commitment) 
	    model->appendRow(row2, -m_infinity, 1.0, rowName2_2);  //add MP2_constraints (arc commitment) 
	 }
	 model->appendRow(rowFix_y1, 1.0, m_infinity, rowNameFix);  //add fix y1 vars
	 //model->appendRow(y2upper1, 0.0, m_infinity, std::string("y2-upperbound-1"));  //add upperbounds on y2
	 //model->appendRow(y2upper2, -1.0, m_infinity, std::string("y2-upperbound-2"));  //..to strengthen formulation
      }
   }

   //---
   //--- create column names (helps with debugging)
   //---
   //y-vars
   for(a = 0; a < numArcs; a++){
      std::string colName = "y1(a" + UtilIntToStr(a) + "(" +
	 UtilIntToStr(arcs[a].tail) + "," +
	 UtilIntToStr(arcs[a].head) + "))";
      model->colNames.push_back(colName);
   }
   for(t = 0; t < numTimeperiods; t++){
      for(a = 0; a < numArcs; a++){
	 std::string colName = "y2(t" + UtilIntToStr(t) + ",a" + UtilIntToStr(a) + "(" +
            UtilIntToStr(arcs[a].tail) + "," +
            UtilIntToStr(arcs[a].head) + "))";
	 model->colNames.push_back(colName);
      }
   }
   //z-vars
   for(t = 0; t < numTimeperiods; t++){
      for(a = 0; a < numArcs; a++){
         std::string colName = "z(t" + UtilIntToStr(t) + ",a" + UtilIntToStr(a) + "(" +
            UtilIntToStr(arcs[a].tail) + "," +
            UtilIntToStr(arcs[a].head) + "))";
         model->colNames.push_back(colName);
      }
   }
   //x-vars
   for(t = 0; t < numTimeperiods; t++){
      for(a = 0; a < numArcs; a++){
         std::string colName = "x(t" + UtilIntToStr(t) + ",a" + UtilIntToStr(a) + "(" +
            UtilIntToStr(arcs[a].tail) + "," +
            UtilIntToStr(arcs[a].head) + "))";
         model->colNames.push_back(colName);
      }
   }
   //theta-vars
   for(t = 0; t < numTimeperiods; t++){
      for(i = 0; i < numNodes; i++){
         std::string colName = "theta(t" + UtilIntToStr(t) + ",n" + UtilIntToStr(i) + ")";
         model->colNames.push_back(colName);
      }
   }

   //---
   //--- create a list of the "active" columns (those related 
   //---   to this commmodity) all other columns are fixed to 0
   //---
   UtilFillN(model->colLB, numCols,  0.0);
   UtilFillN(model->colUB, numCols,  0.0);
   colIndex = 0;
   for(a = 0; a < numArcs; a++){
      //set y-columns active
	  
      //model->colLB[colIndex] = 0;
      //model->colUB[colIndex] = 1;
      //model->activeColumns.push_back(colIndex);
      //set y-columns as master-only columns
      colIndex = col_yStartIndex + a;
      model->masterOnlyCols.push_back(colIndex);  //y1-vars
      for(t = 0; t < numTimeperiods; t++){
	 colIndex = col_yStartIndex + t * numArcs + a + numArcs;
	 model->masterOnlyCols.push_back(colIndex);  //y2-vars
      }
   }

   if(m_appParam.LogLevel >= 3){
      (*m_osLog) << "Master only columns:" << endl;
      UtilPrintVector(model->masterOnlyCols, m_osLog);
      if(model->getColNames().size() > 0)
	 UtilPrintVector(model->masterOnlyCols, 
			 model->getColNames(), m_osLog);
   }
      
   //---
   //--- set the indices of the integer variables of model
   //---
   UtilIotaN(model->integerVars, col_xStartIndex, col_yStartIndex);
   UtilPrintFuncEnd(m_osLog, m_classTag,
                    "createModelCore()", m_appParam.LogLevel, 2);
   //---
   //--- display problem
   //---
   //int j = 0;
   //cout << "find: \nActive cols: ";
   //std::vector<int>::const_iterator it;
   //for(it = model->getActiveColumns().begin(); it != model->getActiveColumns().end(); it++){
   //cout << *it << " ";
   //}
   //
   //cout << "\ns.t.\n";
   //for(j = 0; j < model->getNumRows(); j++){
   //cout << model->rowNames[j] << " : \t\t";
   //cout << model->rowLB[j] << " \t <= \t" ;
   //for (i = 0; i < model->getNumCols(); i++){
   ////cout << "numCols=" << model->getNumCols() << endl;
   //if(model->getMatrix()->getCoefficient(j,i) != 0) {
   ////cout << "i" << i << " ";
   //cout << " " << model->M->getCoefficient(j,i) << " " ;
   //cout << model->getColNames()[i] ;
   //}
   //else {cout << "" ;}
   //}
   //cout << " \t <= \t " << model->rowUB[j] << endl ;
   //
   //}

}
Ejemplo n.º 13
0
//===========================================================================//
int SDPUC_Instance::readInstance(string & fileName,
                               bool     addDummyArcs){
   
   ifstream is;   
   int      status = UtilOpenFile(is, fileName.c_str());   
   if(status)
      throw UtilException("Failed to read instance",
                          "readInstance", "MCF_Instance");
   
   double sumweight        = 0;
   bool   size_read        = true;
   int    arcs_read        = 0;
   int    nodes_read	   = 0;
   int	  ts_read   = 0;
   int	  nt = 0;
   char   line[1000];
   char   name[1000];
   while(is.good()) {
      is.getline(line, 1000);
      if (is.gcount() >= 999) {
         cerr << "ERROR: Input file is incorrect. "
              << "A line more than 1000 characters is found." << endl;
         return 1;
      }
      switch (line[0]) {
      case 'p':
         if (sscanf(line, "p%s%i%i%i%i%i",
                    name, &m_numNodes, &m_numArcs, &m_numSwitchings, &m_numTimeseries, &m_numTimeperiods) != 6) {
            cerr << "ERROR: Input file is incorrect. (p line)" << endl;
            return 1;
         }
         m_problemName = name;
         m_arcs        = new arc[m_numArcs + (addDummyArcs ? 0 : 0)];
         if(!m_arcs)
            throw UtilExceptionMemory("readInstance", "MCF_DecompApp");
         m_nodes = new node[m_numNodes];
         if(!m_nodes)
            throw UtilExceptionMemory("readInstance", "MCF_DecompApp");
		 m_timeseries = new timeseries[m_numTimeseries];
         if(!m_timeseries)
            throw UtilExceptionMemory("readInstance", "MCF_DecompApp");

         break;
      case 'c':
         break;
	  case '#':
		 break;
      case 'n':
         if (sscanf(line, "n%i%lf%i",
                    &m_nodes[nodes_read].id,
                    &m_nodes[nodes_read].demand,
                    &m_nodes[nodes_read].tsdemand) != 3) {
            cerr << "ERROR: Input file is incorrect. (n line)" << endl;
            return 1;
         }
         ++nodes_read;
         break;
      case 'a':
         if (sscanf(line, "a%i%i%lf%lf%lf%lf%lf%lf%i%i%i%i",
                    &m_arcs[arcs_read].tail,
                    &m_arcs[arcs_read].head,
                    &m_arcs[arcs_read].lb,
                    &m_arcs[arcs_read].ub,
                    &m_arcs[arcs_read].weight,
					&m_arcs[arcs_read].mcost,
					&m_arcs[arcs_read].fcost1,
					&m_arcs[arcs_read].fcost2,
					&m_arcs[arcs_read].tscap,
					&m_arcs[arcs_read].tscost,
					&m_arcs[arcs_read].acline,
					&m_arcs[arcs_read].switchable
					) != 12) {
            cerr << "Input file is incorrect. (a line)" << endl;
            return 1;
         }
         sumweight += fabs(m_arcs[arcs_read].mcost);
         ++arcs_read;
         break;
	   case 't':
		  //cout << "ts_read=" << ts_read ;
		  //cout << " numTimeperiods=" << m_numTimeperiods << endl;
		  m_timeseries[ts_read].values = new double[m_numTimeperiods];
		/* if (sscanf(line, "t%i%lf%lf%lf%lf",
                    &m_timeseries[ts_read].id,
                    &m_timeseries[ts_read].values[0],
                    &m_timeseries[ts_read].values[1],
					&m_timeseries[ts_read].values[2],
					&m_timeseries[ts_read].values[3]
					) != 5) {
            cerr << "ERROR: Input file is incorrect. (t line) << " << line << endl;
            return 1;	
         }*/
		 
		 nt = 0;
		 char * pch;
		 //printf ("Splitting string \"%s\" into tokens:\n",line);
		 pch = strtok (line,"\t");  //stripping the initial 't'
		 //printf ("%s ",pch);
		 pch = strtok (NULL, "\t"); //timeseries id
		 m_timeseries[ts_read].id = atoi(pch);
		 //printf ("%s\n",pch);
		 while (pch != NULL && nt < m_numTimeperiods)
		 {
			
			pch = strtok (NULL, "\t");
			m_timeseries[ts_read].values[nt] = atof(pch);
			//printf ("%s\n",pch);
			nt++;
		 }



         ++ts_read;
         break;
      default:
         if (sscanf(line+1, "%s", name) <= 0) {
            cerr << "Input file is incorrect. (non-recognizable line)" << endl;
            return 1;
         }
         break;
      }
   }
   
   if (!size_read			    || 
       arcs_read  != m_numArcs  || 
       nodes_read != m_numNodes ||
	   ts_read	  != m_numTimeseries
	   ) {
      cerr << "Input file is incorrect."
           << " size_read=" << size_read 
           << " arcs_read=" << arcs_read
           << " nodes_read=" << nodes_read 
		   << " ts_read=" << ts_read << endl;
      return 1;
   }
   
   /*if (addDummyArcs) {
      for (int i = 0; i < m_numCommodities; ++i) {
         m_arcs[m_numArcs].tail   = m_commodities[i].source;
         m_arcs[m_numArcs].head   = m_commodities[i].sink;
         m_arcs[m_numArcs].lb     = 0;
         m_arcs[m_numArcs].ub     = m_commodities[i].demand;
         m_arcs[m_numArcs].weight = sumweight+1;
         ++m_numArcs;
      }
   }*/
   is.close();
   return 0;
}