예제 #1
0
//===========================================================================//
void GAP_Instance::readBestKnown(string& fileName,
                                 string& instanceName)
{
   ifstream is;
   string   instance;
   double   bestUpperBound;
   bool     isProvenOptimal;
   int      status  = 0;
   status = UtilOpenFile(is, fileName);

   if (status)
      throw UtilException("Failed to best-known file",
                          "readBestKnown", "GAP_Instance");

   while (!is.eof()) {
      is >> instance >> bestUpperBound >> isProvenOptimal;
      instance = UtilStrTrim(instance);

      if (instance == instanceName) {
         if (isProvenOptimal) {
            m_bestKnownLB = bestUpperBound;
         } else {
            m_bestKnownLB = -COIN_DBL_MAX;
         }

         m_bestKnownUB     = bestUpperBound;
         m_isProvenOptimal = isProvenOptimal;
         break;
      }
   }
}
예제 #2
0
//===========================================================================//
void MILPBlock_DecompApp::readBlockFile(){

   ifstream is;
   string   fileName = m_appParam.DataDir 
      + UtilDirSlash() + m_appParam.BlockFile;

   //---
   //--- is there a permutation file?
   //---  this file just remaps the row ids
   //--- (for use in submission of atm to MIPLIB2010 and debugging)
   //---
   map<int,int>           permute;
   map<int,int>::iterator mit;
   string       fileNameP = m_appParam.DataDir 
      + UtilDirSlash() + m_appParam.PermuteFile;
   
   if(m_appParam.PermuteFile.size() > 0){
      ifstream isP;
      int      rowIdOld, rowIdNew;
      //---
      //--- open file streams
      //---
      UtilOpenFile(isP, fileName.c_str());
      while(!isP.eof()){
	 if(isP.eof()) break;
	 isP >> rowIdOld >> rowIdNew;
	 permute.insert(make_pair(rowIdOld, rowIdNew));
      }
      isP.close();
   }
예제 #3
0
//===========================================================================//
void GAP_Instance::readInstance(string& fileName)
{
   int      i, j, n_ij, indexIJ;
   ifstream is;
   //---
   //--- File format (.../Decomp/data/GAP)
   //---
   //---   agents = machines (m, i index)
   //---   jobs   = tasks    (n, j index)
   //---
   //--- number of machines (m), number of tasks (n)
   //---   for each machine i (i=1,...,m) in turn:
   //---     cost of allocating task j to machine i (j=1,...,n)
   //---   for each machine i (i=1,...,m) in turn:
   //---     resource consumed in allocating task j to machine i (j=1,...,n)
   //--- resource capacity of machine j (j=1,...,m)
   //---
   UtilOpenFile(is, fileName.c_str());
   is >> m_nMachines
      >> m_nTasks;
   //---
   //--- allocate memory for capacity, value and weight
   //---
   n_ij = m_nMachines * m_nTasks;
   m_capacity = new int[m_nMachines];
   m_profit   = new int[n_ij];
   m_weight   = new int[n_ij];

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

   indexIJ = 0;

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

   indexIJ = 0;

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

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

   is.close();
}
예제 #4
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;
	      );
예제 #5
0
//===========================================================================//
void ATM_Instance::readInstance(string & fileNameA,
				string & fileNameD,
				string & fileNameAD){

   string   atm, date;
   int      a, d, ad, n_ad;
   double   K, B;
   
   ifstream isA, isD, isAD;
   ifstream isA2, isD2; //MSVS bug?
   char      dummy[10000];
   const int maxLine = 10000;

   //---
   //--- File format (.../Decomp/data/ATM)
   //---
   //--- dataA.txt:
   //---    a K[a]
   //--- dataD.txt:
   //---    d B[d]
   //--- dataAD.txt:
   //---    a d a[a,d] b[a,d] c[a,d] d[a,d] e[a,d]
   //---
   
   //---
   //--- open file streams
   //---
   UtilOpenFile(isA, fileNameA.c_str());
   UtilOpenFile(isD, fileNameD.c_str());
   UtilOpenFile(isAD, fileNameAD.c_str());

   //---
   //--- get number of atms
   //---
   printf("Reading %s\n", fileNameA.c_str());
   m_nAtms = 0;
   isA.getline(dummy, maxLine);
   while(!isA.eof()){
      isA >> atm;
      if(isA.eof())
	 break;
      isA >> K;
      m_nAtms++;
   }
   isA.close();

   //---
   //--- get number of dates
   //---
   printf("Reading %s\n", fileNameD.c_str());
   m_nDates = 0;
   isD.getline(dummy, maxLine);
   while(!isD.eof()){
      isD >> date;
      if(isD.eof())
	 break;
      isD >> B;
      m_nDates++;
   }
   isD.close();
   
   //---
   //--- allocate memory for storage of coefficients
   //---   open enough space as if dense
   //---
   n_ad   = m_nAtms * m_nDates;
   m_a_ad = new double[n_ad];
   m_b_ad = new double[n_ad];
   m_c_ad = new double[n_ad]; //(=-b)
   m_d_ad = new double[n_ad];
   m_e_ad = new double[n_ad];
   m_w_ad = new double[n_ad];
   m_B_d  = new double[m_nDates];
   m_K_a  = new double[m_nAtms];
   assert(m_a_ad && 
          m_b_ad && 
          m_c_ad && 
          m_d_ad && 
          m_e_ad &&
          m_w_ad &&
          m_B_d  && 
          m_K_a);
   
   //---
   //--- get data for atms
   //---
   UtilOpenFile(isA2, fileNameA.c_str());
   UtilOpenFile(isD2, fileNameD.c_str());
   m_nAtms = 0;
   isA2.getline(dummy, maxLine);
   while(!isA2.eof()){
      isA2 >> atm;
      if(isA2.eof())
	 break;
      m_strToIntAtms.insert(make_pair(atm, m_nAtms));
      m_intToStrAtms.push_back(atm);
      isA2 >> m_K_a[m_nAtms];
      m_nAtms++;
   }
   isA2.close();

   //---
   //--- get data for dates
   //---
   m_nDates = 0;
   isD2.getline(dummy, maxLine);
   while(!isD2.eof()){
      isD2 >> date;
      if(isD2.eof())
	 break;
      m_strToIntDates.insert(make_pair(date, m_nDates));
      m_intToStrDates.push_back(date);
      isD2 >> m_B_d[m_nDates];
      m_nDates++;
   }
   isD2.close();

   //---
   //--- get data for ATMS x DATES (we don't have data for all pairs)
   //---   
   printf("Reading %s\n", fileNameAD.c_str());
   map<string,int>::iterator mi;
   isAD.getline(dummy, maxLine);
   while(!isAD.eof()){
      isAD >> atm >> date;
      if(isAD.eof())
	 break;

      //get a,d index for this pair
      mi = m_strToIntAtms.find(atm);
      if(mi == m_strToIntAtms.end()){
	 printf("ERROR atm not found: %s\n", atm.c_str());
      }
      assert(mi != m_strToIntAtms.end());
      a = mi->second;

      mi = m_strToIntDates.find(date);
      if(mi == m_strToIntDates.end()){
	 printf("ERROR dates not found: %s\n", date.c_str());
      }
      assert(mi != m_strToIntDates.end());
      d = mi->second;

      ad = getIndexAD(a,d);
      m_pairsAD.push_back(ad);

      isAD >> m_a_ad[ad];
      isAD >> m_b_ad[ad];
      isAD >> m_c_ad[ad];
      isAD >> m_d_ad[ad];
      isAD >> m_e_ad[ad];
      isAD >> m_w_ad[ad];

      //printf("ad=%d atm=%s date=%s a=%g b=%g c=%g d=%g e=%g w=%g\n",
      //	     ad, atm.c_str(), date.c_str(), 
      //     m_a_ad[ad],
      //     m_b_ad[ad],
      //     m_c_ad[ad],
      //     m_d_ad[ad],
      //     m_e_ad[ad],
      //     m_w_ad[ad]);
   }
   isAD.close();

   printf("Number of ATMS  = %d\n", getNAtms());
   printf("Number of Dates = %d\n", getNDates());
   printf("Number of Pairs = %d\n", getNPairs());
   
}
예제 #6
0
//===========================================================================//
void ATM_Instance::generateRandom(const int nAtms,
				  const int nDates,
				  const int seed){

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

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

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

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


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

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

   //---
   //--- generate B and K
   //---
   //--- f(a,d) = ca*x1[a] + cb*x2[a] + cc*x1[a]*x2[a] + cd*x3[a] + ce
   //---      x1,x2 in {0,1}, x3 >= 0
   //---
   //--- sum{a} f(a,d)           <= B[d], for d
   //--- |{d in D | f(a,d) <= 0} <= K[a], for a
   //---
   double x01, x1, x2, x3;
   double * f = new double[nAD];
   assert(f);
   index = 0;
   for(a = 0; a < nAtms; a++){
      x01 = UtilURand(0.0,1.0);
      x1  = x01 >= 0.5 ? 1 : 0;
      x01 = UtilURand(0.0,1.0);
      x2  = x01 >= 0.5 ? 1 : 0;
      x3 = UtilURand(0.0,1.0);
      printf("x1=%g x2=%g x3=%g\n", x1, x2, x3);
      for(d = 0; d < nDates; d++){
	 f[index]  = ca[index] * x1;
	 f[index] += cb[index] * x2;
	 f[index] += cc[index] * x1 * x2;
	 f[index] += cd[index] * x3;
	 f[index] += ce[index];	    
	 index++;
      }
   }   
   
   double * B    = new double[nDates];
   double   maxB = -1e20;
   for(d = 0; d < nDates; d++){
      B[d] = 0;
      for(a = 0; a < nAtms; a++){
	 B[d] += f[a * nDates + d];
      }
      if(B[d] > maxB) maxB=B[d];
   }
   //---
   //--- B=budget for cash flow
   //---   if negative does not make sense
   //---   protect against this
   //---
   osD << "d\tB\n";
   for(d = 0; d < nDates; d++){
      if(B[d] < 0)
	 B[d] = maxB / 2.0;
      osD << "DATE" << UtilIntToStr(d) << "\t"
	  << setw(10) << UtilDblToStr(B[d],0) << endl;
   }
 
   int * K    = new int[nAtms];
   int   maxK = 0;
   index = 0;
   for(a = 0; a < nAtms; a++){
      K[a] = 0;
      for(d = 0; d < nDates; d++){
	 K[a] += f[index] <= 0 ? 1 : 0;
	 index++;
      }
      if(K[a] > maxK) maxK=K[a];
   }
   //---
   //--- randomize it (and tighten constraint)
   //---
   osA << "a\tK\n";
   for(a = 0; a < nAtms; a++){
      //K[a] -= UtilURand(1, maxK/4);
      osA << "ATM" << UtilIntToStr(a) << "\t"
	  << setw(10) << K[a] << endl;
   }
   
   osAD.close();
   osA.close();
   osD.close();
   
   UTIL_DELARR(withdrawal);
   UTIL_DELARR(allocation);
   UTIL_DELARR(netimpactAve);
   UTIL_DELARR(netimpactStd);
   UTIL_DELARR(normalAve);
   UTIL_DELARR(normalStd);
   UTIL_DELARR(ts1);
   UTIL_DELARR(ts2);
   UTIL_DELARR(ca);
   UTIL_DELARR(cb);
   UTIL_DELARR(cc);
   UTIL_DELARR(cd);
   UTIL_DELARR(ce);   
   UTIL_DELARR(f);
   UTIL_DELARR(B);
   UTIL_DELARR(K);
}
예제 #7
0
//===========================================================================//
int SDPUC_Instance::readInstance(string & fileName,
                               bool     addDummyArcs){
   
   ifstream is;   
   int      status = UtilOpenFile(is, fileName.c_str());   
   if(status)
      throw UtilException("Failed to read instance",
                          "readInstance", "MCF_Instance");
   
   double sumweight        = 0;
   bool   size_read        = true;
   int    arcs_read        = 0;
   int    nodes_read	   = 0;
   int	  ts_read   = 0;
   int	  nt = 0;
   char   line[1000];
   char   name[1000];
   while(is.good()) {
      is.getline(line, 1000);
      if (is.gcount() >= 999) {
         cerr << "ERROR: Input file is incorrect. "
              << "A line more than 1000 characters is found." << endl;
         return 1;
      }
      switch (line[0]) {
      case 'p':
         if (sscanf(line, "p%s%i%i%i%i%i",
                    name, &m_numNodes, &m_numArcs, &m_numSwitchings, &m_numTimeseries, &m_numTimeperiods) != 6) {
            cerr << "ERROR: Input file is incorrect. (p line)" << endl;
            return 1;
         }
         m_problemName = name;
         m_arcs        = new arc[m_numArcs + (addDummyArcs ? 0 : 0)];
         if(!m_arcs)
            throw UtilExceptionMemory("readInstance", "MCF_DecompApp");
         m_nodes = new node[m_numNodes];
         if(!m_nodes)
            throw UtilExceptionMemory("readInstance", "MCF_DecompApp");
		 m_timeseries = new timeseries[m_numTimeseries];
         if(!m_timeseries)
            throw UtilExceptionMemory("readInstance", "MCF_DecompApp");

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



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