Example #1
0
/*--------------------------------------------------------------------------*/
int TSP_DecompApp::generateCutsSubtour(DecompCutList & newCuts){

   UtilPrintFuncBegin(m_osLog, m_classTag,
		      "generateCutsSubtour()", m_param.LogDebugLevel, 2);
   
   //TODO: use access methods
   TSP_Concorde     & tspConcorde      = m_tsp.m_concorde;

   vector<ConcordeSubtourCut> subtourCuts;

   int c;
   int n_subtour  = tspConcorde.generateCutsSubtour(subtourCuts);
   int n_prevcuts = static_cast<int>(newCuts.size());
   
   for(c = 0; c < n_subtour; c++){
      vector<int>  & S   = subtourCuts[c].S;
      vector<bool> & inS = subtourCuts[c].inS;

      if(S.size() >= 2){
	 TSP_SubtourCut * sec_cut = new TSP_SubtourCut(inS, S, m_infinity);
	 
	 UTIL_DEBUG(m_param.LogDebugLevel, 3,
		    sec_cut->print(m_infinity);
		    );
	 newCuts.push_back(sec_cut);	 
      }
Example #2
0
//===========================================================================//
void GAP_DecompApp::initializeApp(UtilParameters& utilParam)
{
   UtilPrintFuncBegin(m_osLog, m_classTag,
                      "initializeApp()", m_appParam.LogLevel, 2);
   //---
   //--- get application parameters
   //---
   m_appParam.getSettings(utilParam);

   if (m_appParam.LogLevel >= 1) {
      m_appParam.dumpSettings(m_osLog);
   }

   //---
   //--- read instance
   //
   string instanceFile = m_appParam.DataDir
                         + UtilDirSlash() + m_appParam.Instance;
   m_instance.readInstance(instanceFile);
   //---
   //--- read best known lb/ub (for debugging)
   //---
   string bestKnownFile = m_appParam.DataDir + UtilDirSlash() + "gap.opt";
   m_instance.readBestKnown(bestKnownFile, m_appParam.Instance);
   setBestKnownLB(m_instance.getBestKnownLB());
   setBestKnownUB(m_instance.getBestKnownUB());
   //---
   //--- create models
   //---
   createModels();
   UtilPrintFuncEnd(m_osLog, m_classTag,
                    "initializeApp()", m_appParam.LogLevel, 2);
}
Example #3
0
//===========================================================================//
void ATM_DecompApp::initializeApp() {
   

   UtilPrintFuncBegin(m_osLog, m_classTag,
		      "initializeApp()", m_appParam.LogLevel, 2);
   
   //---
   //--- read instance
   //
   string fileNameA, fileNameD, fileNameAD;
   if (m_appParam.DataDir != "") {
      fileNameA = m_appParam.DataDir + UtilDirSlash() + m_appParam.DataAtm;
      fileNameD = m_appParam.DataDir + UtilDirSlash() + m_appParam.DataDate;
      fileNameAD = m_appParam.DataDir + UtilDirSlash() + m_appParam.DataAtmDate;
   } else {
      fileNameA = m_appParam.DataAtm;
      fileNameD = m_appParam.DataDate;
      fileNameAD = m_appParam.DataAtmDate;
   }
   m_instance.readInstance(fileNameA,
                           fileNameD,
                           fileNameAD);

   //---
   //--- create models
   //---
   createModels();

   UtilPrintFuncEnd(m_osLog, m_classTag,
                    "initializeApp()", m_appParam.LogLevel, 2);
}
Example #4
0
//===========================================================================//
DecompConstraintSet * ATM_DecompApp::createModelCoreCount(){

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

   int                 a, nRows;
   const int           nAtms      = m_instance.getNAtms();
   const int           nAtmsSteps = getNAtmsSteps();
   const int           nCols      = numCoreCols();
   if(m_appParam.UseTightModel)
      nRows = 3*nAtms +   nAtmsSteps;
   else
      nRows = 2*nAtms + 3*nAtmsSteps;
   int                 rowCnt     = 0;

   //---
   //--- A'' (core):
   //---    for a in A:
   //---       sum{d in D} v[a,d]  <= K[a]
   //---
   
   DecompConstraintSet * model = new DecompConstraintSet();
   CoinAssertHint(model, "Error: Out of Memory");

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

   //---
   //--- create model constraints
   //---
   for(a = 0; a < nAtms; a++){
      rowCnt += createConCount  (model, a);
      rowCnt += createConZtoX   (model, a);//OPT
      rowCnt += createConPickOne(model, a);//OPT
   }
   //THINK - add conZtoX to core and remove from relax?
   printf("nRows = %d, rowCnt = %d\n", nRows, rowCnt);
   assert(rowCnt == nRows);
   
   //---
   //--- create model variables/columns
   //---
   createModelColumns(model);

   UtilPrintFuncEnd(m_osLog, m_classTag,
		    "createModelCoreCount()", m_appParam.LogLevel, 2);
   
   return model;
}
Example #5
0
//===========================================================================//
DecompConstraintSet * ATM_DecompApp::createModelCore2(){

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

   int                 a;
   const int           nAtms   = m_instance.getNAtms();
   const int           nCols   = numCoreCols();
   const int           nRows   = (2*nAtms);
   int                 rowCnt  = 0;

   //---
   //--- A'' (core):
   //---    for a in A:
   //---       sum{t in T} x1[a,t] <= 1
   //---       sum{d in D} v[a,d]  <= K[a]
   //---    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.
   //---
   
   DecompConstraintSet * model = new DecompConstraintSet();
   CoinAssertHint(model, "Error: Out of Memory");

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

   //---
   //--- create model constraints
   //---
   for(a = 0; a < nAtms; a++){
      rowCnt += createConPickOne(model, a);
      rowCnt += createConCount  (model, a);
   }
   printf("nRows = %d, rowCnt = %d\n", nRows, rowCnt);
   assert(rowCnt == nRows);
   
   //---
   //--- create model variables/columns
   //---
   createModelColumns(model);

   UtilPrintFuncEnd(m_osLog, m_classTag,
		    "createModelCore2()", m_appParam.LogLevel, 2);
   
   return model;
}
Example #6
0
//===========================================================================//
void MILPBlock_DecompApp::initializeApp()  {
   
   UtilPrintFuncBegin(m_osLog, m_classTag,
		      "initializeApp()", m_appParam.LogLevel, 2);
   
   //---
   //--- read MILPBlock instance (mps format)
   //---
   string fileName;
   if (m_appParam.DataDir != "") {
      fileName = m_appParam.DataDir + UtilDirSlash() + m_param.Instance;
   } else {
      fileName = m_appParam.Instance;
   }

   m_mpsIO.messageHandler()->setLogLevel(m_param.LogLpLevel);

   int rstatus = m_mpsIO.readMps(fileName.c_str());   
   if(rstatus < 0){
      cerr << "Error: Filename = " << fileName << " failed to open." << endl;
      throw UtilException("I/O Error.", "initalizeApp", "MILPBlock_DecompApp");
   }
   if(m_appParam.LogLevel >= 2)
      (*m_osLog) << "Objective Offset = " 
                 << UtilDblToStr(m_mpsIO.objectiveOffset()) << endl;

   //---
   //--- set best known lb/ub
   //---
   double offset = m_mpsIO.objectiveOffset();
   setBestKnownLB(m_appParam.BestKnownLB + offset);
   setBestKnownUB(m_appParam.BestKnownUB + offset);

   //---
   //--- read block file
   //---
   readBlockFile();

   //---
   //--- create models
   //---
   createModels();

   UtilPrintFuncEnd(m_osLog, m_classTag,
		    "initializeApp()", m_appParam.LogLevel, 2);
}
Example #7
0
//===========================================================================//
void SDPUC_DecompApp::initializeApp() {
      
   UtilPrintFuncBegin(m_osLog, m_classTag,
                      "initializeApp()", m_appParam.LogLevel, 2);

   //---
   //--- read problem instance
   //---   
   string instanceFile   = m_appParam.DataDir 
      + UtilDirSlash() + m_appParam.Instance;
   int rc = m_instance.readInstance(instanceFile, false);
   if(rc)
      throw UtilException("Error in readInstance",
                          "initializeApp", "MCF_DecompApp");
   //---
   //--- create models
   //---
   createModels();
   
   UtilPrintFuncEnd(m_osLog, m_classTag,
                    "initializeApp()", m_appParam.LogLevel, 2);
}
Example #8
0
//===========================================================================//
void ATM_DecompApp::initializeApp(UtilParameters & utilParam) {
   

   UtilPrintFuncBegin(m_osLog, m_classTag,
		      "initializeApp()", m_appParam.LogLevel, 2);
   
   //---
   //--- get application parameters
   //---
   m_appParam.getSettings(utilParam);
   if(m_appParam.LogLevel >= 1)
      m_appParam.dumpSettings(m_osLog); 
   
   //---
   //--- read instance
   //
   string fileNameA, fileNameD, fileNameAD;
   if (m_appParam.DataDir != "") {
      fileNameA = m_appParam.DataDir + UtilDirSlash() + m_appParam.DataAtm;
      fileNameD = m_appParam.DataDir + UtilDirSlash() + m_appParam.DataDate;
      fileNameAD = m_appParam.DataDir + UtilDirSlash() + m_appParam.DataAtmDate;
   } else {
      fileNameA = m_appParam.DataAtm;
      fileNameD = m_appParam.DataDate;
      fileNameAD = m_appParam.DataAtmDate;
   }
   m_instance.readInstance(fileNameA,
                           fileNameD,
                           fileNameAD);

   //---
   //--- create models
   //---
   createModels();

   UtilPrintFuncEnd(m_osLog, m_classTag,
                    "initializeApp()", m_appParam.LogLevel, 2);
}
Example #9
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);
}
Example #10
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;
}
Example #11
0
// --------------------------------------------------------------------- //
int GAP_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);
   //---
   //--- Generalized Assignment Problem (GAP)
   //---   m is number of machines (index i)
   //---   n is number of tasks    (index j)
   //---
   //--- min  sum{i in 1..m, j in 1..n} p[i,j] x[i,j]
   //--- s.t. sum{           j in 1..n} w[i,j] x[i,j] <= b[i], i in 1..m
   //---      sum{i in 1..m           }        x[i,j]  = 1   , j in 1..n
   //---      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]
   //---  x   x   x     = 1 [j=1]
   //---   x   x   x    = 1 [j=2]
   //---    x   x   x   = 1 [j=3]
   //---     x   x   x  = 1 [j=4]
   //---
   //---
   //--- Get information about this problem instance.
   //--
   int          i;
   string       modelName;
   int          status     = GAPStatusOk;
   int          nTasks     = m_instance.getNTasks();    //n
   int          nMachines  = m_instance.getNMachines(); //m
   const int*   profit     = m_instance.getProfit();
   int          nCols      = nTasks * nMachines;
   //---
   //--- Construct the objective function (the original problem is
   //---  a maximization, so we flip the sign to make it minimization).
   //---
   m_objective = new double[nCols];
   assert(m_objective);

   if (!m_objective) {
      return GAPStatusOutOfMemory;
   }

   for (i = 0; i < nCols; i++) {
      m_objective[i] = profit[i];
   }

   //---
   //--- A'[i] for i=1..m: m independent knapsacks
   //---  sum{j in 1..n}  w[i,j] x[i,j] <= b[i]
   //---  x[i,j] in {0,1}, i in 1..m, j in 1..n
   //---
   //--- A'':
   //---  sum{i in 1..m} x[i,j] = 1, j in 1..n
   //---
   //--- Example structure: m=3, n=4
   //--- A'[i=1]:
   //---  xxxx         <= b[i=1]
   //--- A'[i=2]:
   //---      xxxx     <= b[i=2]
   //--- A'[i=3]:
   //---          xxxx <= b[i=3]
   //---
   //--- A'':
   //---  x   x   x     = 1 [j=1]
   //---   x   x   x    = 1 [j=2]
   //---    x   x   x   = 1 [j=3]
   //---     x   x   x  = 1 [j=4]
   //---
   setModelObjective(m_objective, nCols);
   DecompConstraintSet* modelCore = new DecompConstraintSet();
   status = createModelPartAP(modelCore);

   if (status) {
      return status;
   }

   setModelCore(modelCore, "AP");
   m_models.push_back(modelCore);

   for (i = 0; i < nMachines; i++) {
      DecompConstraintSet* modelRelax = new DecompConstraintSet();
      status = createModelPartKP(modelRelax, i);
      modelName = "KP" + UtilIntToStr(i);
      setModelRelax(modelRelax, modelName, i);
      m_models.push_back(modelRelax);
   }

   UtilPrintFuncEnd(m_osLog, m_classTag,
                    "createModels()", m_appParam.LogLevel, 2);
   return status;
}
Example #12
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);
}
Example #13
0
//===========================================================================//
DecompConstraintSet * ATM_DecompApp::createModelCore1(bool includeCount){

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

   int   a, d, pairIndex;

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

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

   if(includeCount)
      nRows += nAtms;

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

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

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

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

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

   return model;
}
Example #14
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);
}
Example #15
0
void OSDipApp::initializeApp(UtilParameters & utilParam) {

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

	//---
	//--- get application parameters
	//---
	m_appParam.getSettings(utilParam);
	if (m_appParam.LogLevel >= 1)
		m_appParam.dumpSettings(m_osLog);

	try {

		//---
		//--- read OSiL instance
		//
		if (m_appParam.OSiLFile.size() <= 1)
			throw ErrorClass("An OSiL file not specified in the paramater file");
		std::string osilFile = m_appParam.DataDir + UtilDirSlash()
				+ m_appParam.OSiLFile;
		m_osInterface.readOSiL( osilFile);

		//---
		//--- read OSoL instance --  it is not necessary, if not there
		//--  all constraints become block constraints
		//
		//if(m_appParam.OSoLFile.size() <=  1) throw ErrorClass("An OSoL file not specified in the paramater file");
		if (m_appParam.OSoLFile.size() > 0) {
			std::string osolFile = m_appParam.DataDir + UtilDirSlash()
					+ m_appParam.OSoLFile;
			m_osInterface.readOSoL( osolFile);
		}

		//---
		//--- create models
		//---
		createModels();
		
		
		//just temporary playing around
		/**
		std::cout  << std::endl << std::endl << std::endl;
		
		std::cout << "VARIABLE INDEX TESTING " <<std::endl;
		
		std::vector<std::set<int> >  blockVars;
		std::set<int>::iterator sit;
		
		blockVars = m_osInterface.getBlockVarIndexes();
		
		for(int i = 0; i < blockVars.size(); i++){
			
			std::cout << "INSIDE BLOCK " << i << std::endl;
			
			for (sit = blockVars[i].begin(); sit != blockVars[i].end(); sit++) {
				
				std::cout << "VARIABLE =  " << *sit << std::endl;
				
			}
		}
		//now test core constraints
		
		
		
		std::cout << "CORE CONSTRAINT TESTING " <<std::endl;
				
		std::set<int>  conIndexes;

				
		conIndexes = m_osInterface.getCoreConstraintIndexes();
				
					
		for (sit = conIndexes.begin(); sit != conIndexes.end(); sit++) {
						
			std::cout << "CORE INDEX  =  " << *sit << std::endl;
						
		}
		
		
		std::cout << "BLOCK CONSTRAINT INDEX TESTING " <<std::endl;

		std::vector<std::map<int, int> >  blockCons;
		std::map<int, int>::iterator mit;
		
		blockCons = m_osInterface.getBlockConstraintIndexes();
		
		for(int i = 0; i < blockCons.size(); i++){
			
			std::cout << "INSIDE BLOCK " << i << std::endl;
			
			for (mit = blockCons[i].begin(); mit != blockCons[i].end(); mit++) {
				
				std::cout << "CONSTRAINT INDEX =  " << mit->first << std::endl;
				
			}
		}
		*/
		
		m_blockOSInstances = m_osInterface.getBlockOSInstances();
		//loop over the instances and generate a solver
		std::vector<OSInstance* >::iterator vit1;
		
		OSDipBlockCoinSolver *coinSolver = NULL;
		
		for (vit1 = m_blockOSInstances.begin(); vit1 != m_blockOSInstances.end(); vit1++) {
			
			coinSolver = new OSDipBlockCoinSolver( *vit1)  ;			
			m_osDipBlockCoinSolver.push_back( coinSolver ) ;
			
		}
		
		std::vector<std::set<int> >::iterator vit2;
		std::set<int>::iterator sit;
		std::set<int> blockVar;
		std::vector<IndexValuePair*> solIndexValPair;
		std::vector<IndexValuePair*>::iterator vit3;
		double optVal;
		
		double *cost = NULL;
		int index;
		int whichBlock;
		
		m_blockVars = m_osInterface.getBlockVarIndexes();
		whichBlock = 0;
		
		for (vit2 = m_blockVars.begin(); vit2 != m_blockVars.end(); vit2++) {
			
			blockVar = *vit2;
			
			cost = new double[ blockVar.size() ];
			
			index = 0;
			
			for (sit = blockVar.begin(); sit != blockVar.end(); sit++) {
				
				cost[index] = m_objective[ *sit];
				index++;
			
			}
			
			m_osDipBlockCoinSolver[whichBlock++]->solve( cost, &solIndexValPair, &optVal);
			
			std::cout << "OPTIMAL VALUE  = " << optVal  << std::endl;
			
			std::cout << "solIndexValPair SIZE 2 = " << solIndexValPair.size()  << std::endl;
			
			for (vit3 = solIndexValPair.begin(); vit3 != solIndexValPair.end(); vit3++) {
				
				std::cout << "IDEX =  " << (*vit3)->idx << std::endl;
				std::cout << "VALUE =  " << (*vit3)->value << std::endl;
			}
			
			delete []cost;
			
			
		}
		
		
	} catch (const ErrorClass& eclass) {

		throw ErrorClass(eclass.errormsg);

	}

	UtilPrintFuncEnd(m_osLog, m_classTag, "initializeApp()",
			m_appParam.LogLevel, 2);

}//end initializeApp
Example #16
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);
}
Example #17
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);
}
Example #18
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);
}
Example #19
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);
}
Example #20
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;
}
Example #21
0
//===========================================================================//
DecompConstraintSet * ATM_DecompApp::createModelRelax2(const int d){
   
   UtilPrintFuncBegin(m_osLog, m_classTag,
		      "createModelRelax2()", m_appParam.LogLevel, 2);
   
   int                a, t, nRows, pairIndex, nRowsMax;
   double             rhs, coefA, coefC;
   pair<int,int>      adP;
   vector<int>::const_iterator vi;
   
   const int           nSteps    = m_appParam.NumSteps;
   const int           nAtms     = m_instance.getNAtms();
   const vector<int> & pairsAD   = m_instance.getPairsAD();   

   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
   const double      * w_ad      = m_instance.get_w_ad(); //dense storage
   const double      * B_d       = m_instance.get_B_d();

   const int           nCols     = numCoreCols();
   if(m_appParam.UseTightModel)
      nRowsMax  = 3*nAtms + 1 + getNAtmsSteps();
   else
      nRowsMax  = 2*nAtms + 1 + (3*getNAtmsSteps());

   //---
   //--- A'[d] for d in D (independent blocks)
   //---    for a in A
   //---       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{a in A} (f+[a,d] - f-[a,d]) <= B[d]
   //---    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.
   //---
   
   DecompConstraintSet * model = new DecompConstraintSet();
   CoinAssertHint(model, "Error: Out of Memory");

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

   CoinPackedVector rowBudget;
   nRows     = 0;
   pairIndex = 0;
   for(vi = pairsAD.begin(); vi != pairsAD.end(); vi++){
      adP = m_instance.getIndexADInv(*vi);
      if(d != adP.second){
	 pairIndex++;
	 continue;      
      }
      a = adP.first;

      //---
      //--- sum{a in A} (f+[a,d] - f-[a,d]) <= B[d]
      //---
      rowBudget.insert(getColOffset_fp() + pairIndex,  1.0);
      rowBudget.insert(getColOffset_fm() + pairIndex, -1.0);


      //---
      //---       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]
      //---
      CoinPackedVector row;
      string rowName = "demand_def(a_" 
	 + m_instance.getAtmName(a) + ",d_" 
	 + m_instance.getDateName(d) + ")";
      row.insert(colIndex_fp(pairIndex),  1.0);
      row.insert(colIndex_fm(pairIndex), -1.0);
      coefA = -a_ad[*vi] / nSteps;
      coefC = -c_ad[*vi] / nSteps;
      if(m_appParam.UseTightModel){
	 for(t = 0; t <= nSteps; t++){ 
	    row.insert(colIndex_x1(a,t), t * coefA);
	    row.insert(colIndex_z (a,t), t * coefC);
	 }
      }
      else{
	 for(t = 0; t < nSteps; t++){ 
	    row.insert(colIndex_x1(a,t), (t+1) * coefA);
	    row.insert(colIndex_z (a,t), (t+1) * coefC);
	 }
      }
      row.insert(colIndex_x2(a), -b_ad[*vi]);
      row.insert(colIndex_x3(a), -d_ad[*vi]);

      rhs = e_ad[*vi];
      model->appendRow(row, rhs, rhs, rowName);
      nRows++;

      //---
      //---       f-[a,d] <= w[a,d] * v[a,d]      
      //---      
      CoinPackedVector rowLink;
      string rowNameLink = "linkv(a_" 
         + m_instance.getAtmName(a) + ",d_" 
         + m_instance.getDateName(d) + ")";	 
      rowLink.insert(colIndex_fm(pairIndex), 1.0);
      rowLink.insert(colIndex_v (pairIndex), -w_ad[*vi]);
      model->appendRow(rowLink, -DecompInf, 0.0, rowNameLink);
      nRows++;	 
   
      pairIndex++;
   }
   
   string rowNameBudget = "budget(d_" + m_instance.getDateName(d) + ")";
   model->appendRow(rowBudget, -DecompInf, B_d[d], rowNameBudget);
   nRows++;

  for(a = 0; a < nAtms; a++)
     nRows += createConZtoX(model, a);
   assert(nRows <= nRowsMax);
   
   //---
   //--- create model columns
   //---
   createModelColumns(model, -1, d);
   
   UtilPrintFuncEnd(m_osLog, m_classTag,
		    "createModelRelax2()", m_appParam.LogLevel, 2);

   return model;
}
Example #22
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 ;
   //
   //}

}
Example #23
0
//===========================================================================//
void OSDipApp::createModels() {

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

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

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

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

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

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

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

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

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

}// end createModels()
Example #24
0
// --------------------------------------------------------------------- //
void MAD_DecompApp::initializeApp(UtilParameters & utilParam) {

   UtilPrintFuncBegin(m_osLog, m_classTag,
		      "initializeApp()", m_param.LogDebugLevel, 2);

  
   //---
   //--- get application parameters
   //---
   m_appParam.getSettings(utilParam);
   m_appParam.dumpSettings(m_osLog); //use message handler

   //---
   //--- read instance from lp file (from MADLIB)
   //---   http://elib.zib.de/pub/mp-testdata/madlib/index.html
   //---
   string lpFile  = m_appParam.DataDir    + UtilDirSlash();
   lpFile        += m_appParam.Instance;
   if(m_appParam.DataSubDir == "miplib"){
      lpFile     += ".p.lp";
   } else if(m_appParam.DataSubDir == "netlib"){
      lpFile     += ".ob4";
   }   
   m_instance.readLp(lpFile.c_str());
   
   m_nOrigRows = m_instance.getNumRows();   
   m_beta      = m_appParam.NumBlocks;

   //---
   //--- read best known lb/ub 
   //---
   string bestKnownFile  = m_appParam.DataDir + UtilDirSlash();
   bestKnownFile        += "madlib." + m_appParam.DataSubDir + ".opt";
   {
      ifstream is;
      string   instanceName;
      double   bestLB, bestUB;
      UtilOpenFile(is, bestKnownFile);
      while(!is.eof()){
         //---
         //--- these are the number of rows in the border (less is better)
         //---  
         is >> instanceName >> bestLB >> bestUB;
         //printf("Instance = %15s bestLB = %6g bestUB = %6g\n",
         //     instanceName.c_str(), bestLB, bestUB);
         
         instanceName = UtilStrTrim(instanceName);
         if(instanceName == m_appParam.Instance){
            //---
            //--- the paper solves z = max sum x,             
            //---    where x is an assignment to a block
            //---    so, nBorder = nRows - z
            //---    or, z       = nRows - nBorder
            //---
            //--- but we only do min, so we solve -z = min sum (-x)
            //----   so, -z      = nBorder - nRows
            //---    
            m_bestKnownLB = bestLB - m_nOrigRows;
            m_bestKnownUB = bestUB - m_nOrigRows;
            break;
         }
      }
   }


   //---
   //--- set capacity based on MADLIB study (if it is not set):
   //---  http://elib.zib.de/pub/mp-testdata/madlib/index.en.html
   //---
   if(m_appParam.Capacity != -1){
      m_kappa = m_appParam.Capacity;
   }
   else{
      m_kappa 
	 = static_cast<int>(ceil(static_cast<double>(m_nOrigRows)/m_beta));
      if(m_appParam.DataSubDir == "netlib" ||
	 m_appParam.DataSubDir == "equipart"){
	 m_kappa 
	    = static_cast<int>(ceil(static_cast<double>(m_nOrigRows)/m_beta));
      } else if(m_appParam.DataSubDir == "miplib" ||
		m_appParam.DataSubDir == "miplibT"){
	 m_kappa = static_cast<int>(ceil( 1.05 * m_nOrigRows / m_beta) ); 
      } else if(m_appParam.DataSubDir == "steiner"){
	 if(m_appParam.Instance[0] == 'g'){
	    m_kappa = 30;
	 } else if (m_appParam.Instance[0] == 'd'){
	    m_kappa = 50;
	 }
      }
   }

   UTIL_DEBUG(m_param.LogDebugLevel, 1,
	      (*m_osLog) 
              << "Instance = " << m_appParam.Instance << endl
              << "  nRows  = " << m_nOrigRows         << endl
              << "  bestLB = " << m_bestKnownLB       << endl
              << "  bestUB = " << m_bestKnownUB       << endl
              << "  Beta   = " << m_beta              << endl
              << "  Kappa  = " << m_kappa             << endl;
	      );
Example #25
0
//===========================================================================//
DecompConstraintSet * 
ATM_DecompApp::createModelRelax1(const int a,
				 bool      includeCount){
   
   UtilPrintFuncBegin(m_osLog, m_classTag,
		      "createModelRelax1()", m_appParam.LogLevel, 2);

   int                t, d, nRows, pairIndex;
   double             rhs, coefA, coefC;
   pair<int,int>      adP;
   vector<int>::const_iterator vi;
   
   const int           nSteps    = m_appParam.NumSteps;
   const int           nDates    = m_instance.getNDates();
   const vector<int> & pairsAD   = m_instance.getPairsAD();   

   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
   const double      * w_ad      = m_instance.get_w_ad(); //dense storage

   const int           nCols     = numCoreCols();
   int                 nRowsMax  = nDates + 1 + (3*nSteps);
   if(includeCount)
      nRowsMax += nDates + 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]  (for count)
   //---    for a in A:
   //---       sum{t in T} x1[a,t] <= 1
   //---       sum{d in D} v[a,d]  <= K[a] (for count) [OPT]

   //Probably not... 
   //THINK: can't we just post-process this? z=x1*x2
   //---    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.
   //---
   
   DecompConstraintSet * model = new DecompConstraintSet();
   CoinAssertHint(model, "Error: Out of Memory");

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

   //---
   //---    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 count)
   //---
   nRows     = 0;
   pairIndex = 0;
   for(vi = pairsAD.begin(); vi != pairsAD.end(); vi++){
      adP = m_instance.getIndexADInv(*vi);
      if(a != adP.first){
	 pairIndex++;
	 continue;      
      }
      d = adP.second;

      CoinPackedVector row;
      string rowName = "demand_def(a_" 
	 + m_instance.getAtmName(a) + ",d_" 
	 + m_instance.getDateName(d) + ")";

      row.insert(colIndex_fp(pairIndex),  1.0);
      row.insert(colIndex_fm(pairIndex), -1.0);
      coefA = -a_ad[*vi] / nSteps;
      coefC = -c_ad[*vi] / nSteps;
      if(m_appParam.UseTightModel){
	 for(t = 0; t <= nSteps; t++){ 
	    row.insert(colIndex_x1(a,t), t * coefA);
	    row.insert(colIndex_z (a,t), t * coefC);
	 }
      }
      else{
	 for(t = 0; t < nSteps; t++){ 
	    row.insert(colIndex_x1(a,t), (t+1) * coefA);
	    row.insert(colIndex_z (a,t), (t+1) * coefC);
	 }
      }
      row.insert(colIndex_x2(a), -b_ad[*vi]);
      row.insert(colIndex_x3(a), -d_ad[*vi]);

      rhs = e_ad[*vi];
      model->M->appendRow(row);
      model->rowLB.push_back(rhs);
      model->rowUB.push_back(rhs);
      model->rowNames.push_back(rowName);      
      nRows++;
      
      CoinPackedVector rowLink;
      string rowNameLink = "linkv(a_" 
         + m_instance.getAtmName(a) + ",d_" 
         + m_instance.getDateName(d) + ")";	 
      rowLink.insert(colIndex_fm(pairIndex), 1.0);
      rowLink.insert(colIndex_v (pairIndex), -w_ad[*vi]);
      model->M->appendRow(rowLink);
      model->rowLB.push_back(-DecompInf);
      model->rowUB.push_back(0.0);
      model->rowNames.push_back(rowNameLink);	 
      nRows++;	 
   
      pairIndex++;
   }

   //---
   //---    for a in A:
   //---       sum{t in T} x1[a,t] <= 1
   //---       sum{d in D} v[a,d]  <= K[a] (for count)
   //---
   nRows += createConPickOne(model, a);
   if(includeCount)
      nRows += createConCount(model, a);
   
   //---
   //---    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.
   //---
   nRows += createConZtoX(model, a);

   //---
   //--- create model columns
   //---
   createModelColumns(model, a);
   
   UtilPrintFuncEnd(m_osLog, m_classTag,
		    "createModelRelax1()", m_appParam.LogLevel, 2);
   
   return model;
}
Example #26
0
int OSDipApp::generateInitVars(DecompVarList & initVars) {

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

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

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

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

	UtilPrintFuncEnd(m_osLog, m_classTag, "generateInitVars()",
			m_appParam.LogLevel, 2);
	return static_cast<int> (initVars.size());
}
Example #27
0
//===========================================================================//
DecompConstraintSet * ATM_DecompApp::createModelRelaxCount(){
   
   UtilPrintFuncBegin(m_osLog, m_classTag,
		      "createModelRelaxCount()", m_appParam.LogLevel, 2);
   
   int                a, d, t, nRows, pairIndex, nRowsMax;
   double             rhs, coefA, coefC;
   pair<int,int>      adP;
   vector<int>::const_iterator vi;
   
   const int           nSteps     = m_appParam.NumSteps;
   const int           nAtms      = m_instance.getNAtms();
   const int           nDates     = m_instance.getNDates();
   const int           nPairs     = m_instance.getNPairs();
   const int           nAtmsSteps = getNAtmsSteps();
   const vector<int> & pairsAD    = m_instance.getPairsAD();   

   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
   const double      * w_ad      = m_instance.get_w_ad(); //dense storage
   const double      * B_d       = m_instance.get_B_d();

   const int           nCols     = numCoreCols();
   if(m_appParam.UseTightModel)
      nRowsMax  = nDates + 2*nAtms +   nAtmsSteps + 2*nPairs;
   else
      nRowsMax  = nDates +   nAtms + 3*nAtmsSteps + 2*nPairs;

   //TODO:
   // try the nested idea - so master has ConZtoX and we price without that
   //   but we solve with gap the harder oracle with those constraints

   //---
   //--- A' (relax):
   //---    for d in D:
   //---       sum{a in A} (f+[a,d] - f-[a,d]) <= B[d]  <---- makes it hard
   //OPT
   //---    for a in A:
   //---       sum{t in T}  x1[a,t] <= 1
   //OPT
   //---    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]
   //---
   
   DecompConstraintSet * model = new DecompConstraintSet();
   CoinAssertHint(model, "Error: Out of Memory");

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

   //---
   //--- create nDates empty rowBudget packed vectors
   //---
   vector<CoinPackedVector> rowBudget;
   for(d = 0; d < nDates; d++){
      CoinPackedVector row;
      rowBudget.push_back(row);
   }

   nRows     = 0;
   pairIndex = 0;
   for(vi = pairsAD.begin(); vi != pairsAD.end(); vi++){
      adP = m_instance.getIndexADInv(*vi);
      a = adP.first;
      d = adP.second;

      //---
      //--- sum{a in A} (f+[a,d] - f-[a,d]) <= B[d]
      //---
      rowBudget[d].insert(getColOffset_fp() + pairIndex,  1.0);
      rowBudget[d].insert(getColOffset_fm() + pairIndex, -1.0);


      //---
      //---       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]
      //---
      CoinPackedVector row;
      string rowName = "demand_def(a_" 
	 + m_instance.getAtmName(a) + ",d_" 
	 + m_instance.getDateName(d) + ")";
      row.insert(colIndex_fp(pairIndex),  1.0);
      row.insert(colIndex_fm(pairIndex), -1.0);
      coefA = -a_ad[*vi] / nSteps;
      coefC = -c_ad[*vi] / nSteps;
      if(m_appParam.UseTightModel){
	 for(t = 0; t <= nSteps; t++){ 
	    row.insert(colIndex_x1(a,t), t * coefA);
	    row.insert(colIndex_z (a,t), t * coefC);
	 }
      }
      else{
	 for(t = 0; t < nSteps; t++){ 
	    row.insert(colIndex_x1(a,t), (t+1) * coefA);
	    row.insert(colIndex_z (a,t), (t+1) * coefC);
	 }
      }
      row.insert(colIndex_x2(a), -b_ad[*vi]);
      row.insert(colIndex_x3(a), -d_ad[*vi]);
      
      rhs = e_ad[*vi];
      model->appendRow(row, rhs, rhs, rowName);
      nRows++;

      //---
      //---       f-[a,d] <= w[a,d] * v[a,d]      
      //---
      CoinPackedVector rowLink;
      string rowNameLink = "linkv(a_" 
         + m_instance.getAtmName(a) + ",d_" 
         + m_instance.getDateName(d) + ")";	 
      rowLink.insert(colIndex_fm(pairIndex), 1.0);
      rowLink.insert(colIndex_v (pairIndex), -w_ad[*vi]);
      model->appendRow(rowLink, -DecompInf, 0.0, rowNameLink);
      nRows++;	 

      pairIndex++;
   }

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

   //---
   //---    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.      
   //---   
   //THINK: if you use this, shouldn't we postprocess z=x1*x2?
   //  putting those constaints in master are unneccessary... 
   //  in fact, why not just do that in block version too... 
   //for(a = 0; a < nAtms; a++){
      //nRows += createConZtoX(model, a);
      //nRows += createConPickOne(model, a);
   //}
   assert(nRows <= nRowsMax);
   
   //---
   //--- create model columns
   //---
   createModelColumns(model);
   
   UtilPrintFuncEnd(m_osLog, m_classTag,
		    "createModelRelaxCount()", m_appParam.LogLevel, 2);

   return model;
}
Example #28
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;
}