Esempio n. 1
0
/**
 * APPheuristics callback
 *
 * Called by DIP, we interface with Python
 */
int DippyDecompApp::APPheuristics(const double* xhat, const double* origCost, vector<DecompSolution*>& xhatIPFeas)
{
   if (!m_pyHeuristics) {
      return 0;
   }

   PyObject* pSolution = pyTupleList_FromDoubleArray(xhat, m_colList);
   PyObject* pObjective = pyTupleList_FromDoubleArray(origCost, m_colList);
   PyObject* pSolList = PyObject_CallMethod(m_pProb, "solveHeuristics", "OO", pSolution, pObjective);

   if (pSolList == NULL) {
      throw UtilException("Error calling method prob.solveHeuristics()", "APPheuristics", "DippyDecompApp");
   }

   // This should never happen, pyHeuristics should be set to false in dippy.py
   if (pSolList == Py_None)
      // method exists, but is not implemented, return 0
   {
      return 0;
   }

   // APPheuristics returns dictionary of (variable, value) pairs
   const int len = PyObject_Length(pSolList);

   // loop through each solution
   for (int i = 0; i < len; i++) {
      pSolution = PyList_GetItem(pSolList, i);
      int*     varInds = NULL;
      double* varVals = NULL;
      int numPairs = pyColDict_AsPackedArrays(pSolution, m_colIndices, &varInds, &varVals);
      assert(numPairs == PyObject_Length(pSolution));
      double* sol = new double[m_numCols];
      UtilFillN(sol, m_numCols, 0.0);

      for (int j = 0; j < numPairs; j++) {
         sol[varInds[j]] = varVals[j];
      }

      xhatIPFeas.push_back(new DecompSolution(m_numCols, sol, origCost));
      delete [] sol;
      delete [] varInds;
      delete [] varVals;
   }

   return len;
}
Esempio n. 2
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;
}
Esempio n. 3
0
//===========================================================================//
void ATM_DecompApp::createModelColumns(DecompConstraintSet * model,
				       const int             atmIndex,
                                       const int             dateIndex){

   //---
   //--- Column bounds:
   //---    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] in [0,1], x3[a] >= 0
   //--- NOTE: x3 no UB causing unbounded subproblems? try <= 1000
   //---    for a in A, t in T
   //---       x1[a,t] in {0,1}, z[a,t] in [0,1]
   //---
   //---  If this is for block atmIndex(>=0), 
   //---      fix all a!=atmIndex in A columns to 0.
   //---
   //---  If this is for block dateIndex(>=0), 
   //---      fix all d!=dateIndex in D columns to 0.
   //---
   string    colName;
   const int nPairs     = m_instance.getNPairs();
   const int nAtms      = m_instance.getNAtms();
   const int nSteps     = m_appParam.NumSteps;
   const int nAtmsSteps = getNAtmsSteps();
   const int nCols      = numCoreCols();

   const double      * w_ad    = m_instance.get_w_ad(); //dense storage
   const vector<int> & pairsAD = m_instance.getPairsAD();   
   vector<int>::const_iterator vi;

   //---   
   //--- set the col upper and lower bounds
   //---
   UtilFillN(model->colLB, nCols,  0.0);
   UtilFillN(model->colUB, nCols,  1.0);

   int index;
   index = getColOffset_fm();
   for(vi = pairsAD.begin(); vi != pairsAD.end(); vi++){
      model->colUB[index] = w_ad[*vi];
      index++;
   }
   
   UtilFillN(&model->colUB[0] + getColOffset_fp(), nPairs, DecompInf);
   
   //Another case of needing extreme rays??
   //UtilFillN(&model->colUB[0] + getColOffset_x3(), nAtms,  DecompInf);
   UtilFillN(&model->colUB[0] + getColOffset_x3(), nAtms,  1000.0);

   //---
   //--- if this is for block a, fix all others to 0.
   //---
   if(atmIndex >= 0){
      int a, t;
      int index_x1 = getColOffset_x1();
      int index_z  = getColOffset_z();
      int index_x2 = getColOffset_x2();
      int index_x3 = getColOffset_x3();
      int end      = nSteps;
      if(m_appParam.UseTightModel)
	 end++;
      for(a = 0; a < nAtms; a++){
         if(a != atmIndex){
            model->colUB[index_x2] = 0.0;
            model->colUB[index_x3] = 0.0;
            for(t = 0; t < end; t++){
               model->colUB[index_x1++] = 0.0;
               model->colUB[index_z ++] = 0.0;
            }
         }
         else{
            for(t = 0; t < end; t++){
	       model->activeColumns.push_back(index_x1++);
	       model->activeColumns.push_back(index_z++);
	    }
	    model->activeColumns.push_back(index_x2);
	    model->activeColumns.push_back(index_x3);	    
         }
         index_x2++;
         index_x3++;
      }
      int index_fp = getColOffset_fp();
      int index_fm = getColOffset_fm();      
      int index_v  = getColOffset_v();
      for(vi = pairsAD.begin(); vi != pairsAD.end(); vi++){
	 a = m_instance.getIndexADInv(*vi).first; 
	 if(a != atmIndex){
            model->colUB[index_fp] = 0.0;
            model->colUB[index_fm] = 0.0;
            model->colUB[index_v]  = 0.0;
         }
	 else{
	    model->activeColumns.push_back(index_fp);	    
	    model->activeColumns.push_back(index_fm); 
            model->activeColumns.push_back(index_v);	    
	 }
	 index_fp++;
	 index_fm++;	 
         index_v++;
      }
   }

   if(dateIndex >= 0){
      int d;
      int index_fp = getColOffset_fm();
      int index_fm = getColOffset_fm();            
      int index_v  = getColOffset_v();
      for(vi = pairsAD.begin(); vi != pairsAD.end(); vi++){
	 d = m_instance.getIndexADInv(*vi).second; 
	 if(d != dateIndex){
            model->colUB[index_fp] = 0.0;
            model->colUB[index_fm] = 0.0;            
            model->colUB[index_v]  = 0.0;
         }
	 else{
	    model->activeColumns.push_back(index_fp);
	    model->activeColumns.push_back(index_fm); 
            model->activeColumns.push_back(index_v); 
	 } 
	 index_fp++;
	 index_fm++;	 
         index_v++;
      }
   }

   //---
   //--- set the indices of the integer variables of model: x1, v
   //---
   UtilIotaN(model->integerVars, nAtmsSteps, getColOffset_x1());
   UtilIotaN(model->integerVars, nPairs,     getColOffset_v());
   
   //---
   //--- set column names for debugging
   //---
   addColumnNamesAT(model, "x1", getColOffset_x1());
   addColumnNamesAT(model, "z",  getColOffset_z());
   addColumnNamesAD(model, "fp", getColOffset_fp());
   addColumnNamesAD(model, "fm", getColOffset_fm());
   addColumnNamesA (model, "x2", getColOffset_x2());
   addColumnNamesA (model, "x3", getColOffset_x3());
   addColumnNamesAD(model, "v",  getColOffset_v());

#if 0
   {
      int i;
      for(i = 0; i < static_cast<int>(model->colNames.size()); i++){
	 printf("COL[%4d] = %20s LB:%g UB:%g\n", 
		i, 
		model->colNames[i].c_str(),
		model->colLB[i],
		model->colUB[i]);
      }
   }
#endif
}
Esempio n. 4
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);
}
Esempio n. 5
0
// --------------------------------------------------------------------- //
int GAP_DecompApp::createModelPartAP(DecompConstraintSet* model)
{
   int             i, j, colIndex;
   int             status     = GAPStatusOk;
   int             nTasks     = m_instance.getNTasks();    //n
   int             nMachines  = m_instance.getNMachines(); //m
   int             nCols      = nTasks * nMachines;
   int             nRows      = nTasks;
   UtilPrintFuncBegin(m_osLog, m_classTag,
                      "createModelPartAP()", m_appParam.LogLevel, 2);
   //---
   //--- Build the core model constraints (AP = assignment problem).
   //---
   //--- m is number of machines (index i)
   //--- n is number of tasks    (index j)
   //---
   //--- sum{i in 1..m} x[i,j] = 1, j in 1..n
   //---
   //--- Example structure: m=3, n=4
   //---  x   x   x     = 1 [j=1]
   //---   x   x   x    = 1 [j=2]
   //---    x   x   x   = 1 [j=3]
   //---     x   x   x  = 1 [j=4]
   //---
   //---
   //--- Allocate an empty row-ordered CoinPackedMatrix. Since we plan
   //---   to add rows, set the column dimension and let the row dimension
   //---   be set dynamically.
   //---
   model->M = new CoinPackedMatrix(false, 0.0, 0.0);
   CoinAssertHint(model->M, "Error: Out of Memory");
   model->M->setDimensions(0, nCols);
   //---
   //--- we know the sizes needed, so reserve space for them (for efficiency)
   //---
   model->reserve(nRows, nCols);

   //---
   //--- create one row per task
   //---   rowNames are not needed, they are used for debugging
   //---
   for (j = 0; j < nTasks; j++) {
      CoinPackedVector row;
      string           rowName = "a(j_" + UtilIntToStr(j) + ")";

      for (i = 0; i < nMachines; i++) {
         colIndex = getIndexIJ(i, j);
         row.insert(colIndex, 1.0);
      }

      model->appendRow(row, 1.0, 1.0, rowName);
   }

   //---
   //--- set the col upper and lower bounds (all in [0,1])
   //---
   UtilFillN(model->colLB, nCols,  0.0);
   UtilFillN(model->colUB, nCols,  1.0);
   //---
   //--- set the indices of the integer variables of model
   //---   (all vars are binary)
   //---
   UtilIotaN(model->integerVars, nCols, 0);
   //---
   //--- set column names for debugging
   //---
   colIndex = 0;

   for (i = 0; i < nMachines; i++) {
      for (j = 0; j < nTasks; j++) {
         string colName = "x("
                          + UtilIntToStr(colIndex) + "_"
                          + UtilIntToStr(i) + "," + UtilIntToStr(j) + ")";
         model->colNames.push_back(colName);
         colIndex++;
      }
   }

   UtilPrintFuncEnd(m_osLog, m_classTag,
                    "createModelPartAP()", m_appParam.LogLevel, 2);
   return status;
}
Esempio n. 6
0
//===========================================================================//
int GAP_DecompApp::createModelPartKP(DecompConstraintSet* model,
                                     vector<int>&          whichKnaps)
{
   int          i, j, b, colIndex;
   int          status     = GAPStatusOk;
   int          nTasks     = m_instance.getNTasks();    //n
   int          nMachines  = m_instance.getNMachines(); //m
   int          nKnaps     = static_cast<int>(whichKnaps.size());
   const int*   weight     = m_instance.getWeight();
   const int*   capacity   = m_instance.getCapacity();
   int          nCols      = nTasks * nMachines;
   int          nRows      = nKnaps;
   UtilPrintFuncBegin(m_osLog, m_classTag,
                      "createModelPartKP()", m_appParam.LogLevel, 2);
   //---
   //--- Build the relax model constraints (KP = assignment problem).
   //---
   //--- m is number of machines (index i)
   //--- n is number of tasks    (index j)
   //---
   //--- sum{j in 1..n} w[i,j] x[i,j] <= b[i], i in 1..m
   //--- x[i,j] in {0,1}, i in 1..m, j in 1..n
   //---
   //--- Example structure: m=3, n=4
   //---  xxxx         <= b[i=1]
   //---      xxxx     <= b[i=2]
   //---          xxxx <= b[i=3]
   //---
   //---
   //--- Allocate an empty row-ordered CoinPackedMatrix. Since we plan
   //---   to add rows, set the column dimension and let the row dimension
   //---   be set dynamically.
   //---
   model->M = new CoinPackedMatrix(false, 0.0, 0.0);
   CoinAssertHint(model->M, "Error: Out of Memory");
   model->M->setDimensions(0, nCols);
   //---
   //--- we know the sizes needed, so reserve space for them (for efficiency)
   //---
   model->reserve(nRows, nCols);
   //---
   //--- create one row per knapsack
   //---   rowNames are not needed, they are used for debugging
   //---
   vector<int>::iterator it;

   for (it = whichKnaps.begin(); it != whichKnaps.end(); ++it) {
      i = *it;
      CoinPackedVector row;
      string           rowName = "k(i_" + UtilIntToStr(i) + ")";

      for (j = 0; j < nTasks; j++) {
         colIndex = getIndexIJ(i, j);
         row.insert(colIndex, weight[colIndex]);
      }

      model->appendRow(row, -m_infinity, capacity[i], rowName);
   }

   //---
   //--- set the col upper and lower bounds (all in [0,1])
   //---
   UtilFillN(model->colLB, nCols,  0.0);
   UtilFillN(model->colUB, nCols,  1.0);
   //---
   //--- set the indices of the integer variables of model
   //---
   UtilIotaN(model->integerVars, nCols, 0);

   //---
   //--- tell the solver which columns are active (in this block)
   //---
   for (it = whichKnaps.begin(); it != whichKnaps.end(); ++it) {
      b = *it;

      for (i = 0; i < nMachines; i++) {
         for (j = 0; j < nTasks; j++) {
            colIndex = getIndexIJ(i, j);

            if (i == b) {
               model->activeColumns.push_back(colIndex);
            }
         }
      }
   }

   //---
   //--- set column names for debugging
   //---
   colIndex = 0;

   for (i = 0; i < nMachines; i++) {
      for (j = 0; j < nTasks; j++) {
         string colName = "x("
                          + UtilIntToStr(colIndex) + "_"
                          + UtilIntToStr(i) + "," + UtilIntToStr(j) + ")";
         model->colNames.push_back(colName);
         colIndex++;
      }
   }

   UtilPrintFuncEnd(m_osLog, m_classTag,
                    "createModelPartKP()", m_appParam.LogLevel, 2);
   return status;
}
Esempio n. 7
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);
}
Esempio n. 8
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);
}
Esempio 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);
}
Esempio n. 10
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);
}
Esempio n. 11
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 ;
   //
   //}

}