mt_tableau.c

Go to the documentation of this file.
00001 /* MTgomory "multi tableau gomory cut" provides an implementation for gomory
00002  * cuts derived from multiple tableau rows in the spirit of the work of
00003  * Andersen et al (IPCO 2007), Cornuejols (es presented in George Nemhauser
00004  * Birthday Conference in Atlanta 2007) and Gomory (presented in the same
00005  * conference).
00006  *
00007  * Copyright (C) 2007 Daniel Espinoza.
00008  * 
00009  * This library is free software; you can redistribute it and/or modify it
00010  * under the terms of the GNU Lesser General Public License as published by the
00011  * Free Software Foundation; either version 2.1 of the License, or (at your
00012  * option) any later version.
00013  *
00014  * This library is distributed in the hope that it will be useful, but 
00015  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
00016  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
00017  * License for more details.
00018  *
00019  * You should have received a copy of the GNU Lesser General Public License
00020  * along with this library; if not, write to the Free Software Foundation,
00021  * Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA 
00022  * */
00023 /* ========================================================================= */
00024 #include "mt_tableau.h"
00025 #include "EGlib.h"
00026 /** @file 
00027  * @ingroup MTgomory */
00028 /** @addtogroup MTgomory */
00029 /** @{ */
00030 
00031 /* ========================================================================= */
00032 int MTwriteRTableau(FILE*out,
00033                     const int nrows, 
00034                     const int ncols,
00035                     const double*const rowval,
00036                     const int*const rowind,
00037                     const int*const rowbeg,
00038                     const double*const f)
00039 {
00040   int i = 0;
00041   fprintf(out,"TYPE: ROW_TABLEAU\n");
00042   fprintf(out,"NROWS: %d #rows in the tableau\n",nrows);
00043   fprintf(out,"NCOLS: %d #columns in the tableau\n",ncols);
00044   fprintf(out,"NZ: %d #number of non-zeros in the description\n",
00045           rowbeg[nrows]);
00046   fprintf(out,"ROWVAL_SECTION\n#what follows is the index and value "
00047               "information in the format\n#row_ind row_val\n");
00048   for(i = 0 ; i < rowbeg[nrows] ; i++) 
00049     fprintf(out,"%d %.5lf\n",rowind[i], rowval[i]);
00050   fprintf(out,"ROWBEG_SECTION\n#what follows is the rowbeg and f_i "
00051           "value asociated with each tableau, in the format\n"
00052           "#row_beg f_i\n");
00053   for(i = 0 ; i < nrows ; i++)
00054     fprintf(out,"%d %.5lf\n",rowbeg[i],f[i]);
00055   return 0; 
00056 }
00057 
00058 /* ========================================================================= */
00059 int MTreadRTableau(FILE*input,
00060                     int*const nrows, 
00061                     int*const ncols,
00062                     double**const rowval,
00063                     int**const rowind,
00064                     int**const rowbeg,
00065                     double**const f)
00066 {
00067   const char delim[3] = " :";
00068   const char coment[3] = "%#";
00069   int rval = 0, has_nrows=0, has_ncols=0, has_type=0, has_val=0, has_beg=0, has_nz=0, todo=1, i, nz=0, argc;
00070   char str[2048],*argv[1024];
00071   /* basic set-up */
00072   *nrows = *ncols = 0;
00073   *rowind = *rowbeg = 0;
00074   *rowval = 0;
00075   /* start reading from file */
00076   while(todo)
00077   {
00078     rval = EGioReadLine(str, (size_t)2048, input);
00079     CHECKRVALG(rval,CLEANUP);
00080     TESTG((rval = feof(input)||ferror(input)), CLEANUP, 
00081           "File ended prematurelly, or has errors");
00082     EGioNParse(str, 1024, delim, coment, &argc, argv);
00083     /* skip empty lines */
00084     if(!argc) continue;
00085     /* process each key-word accorsingly */
00086     if(strncmp(argv[0],"TYPE", (size_t)33)==0)
00087     {
00088       TESTG((rval=has_type),CLEANUP,"TYPE keyword repeated in file");
00089       TESTG((rval=(argc!=2)),CLEANUP,"TYPE has not 2 tokens");
00090       TESTG((rval=(strncmp(argv[1],"ROW_TABLEAU", (size_t)33)!=0)),
00091             CLEANUP, "Unknown file type %s, expected ROW_TABLEAU",
00092             argv[1]);
00093       has_type = 1;
00094     }
00095     else if(strncmp(argv[0],"NCOLS", (size_t)33)==0)
00096     {
00097       TESTG((rval=has_ncols),CLEANUP,"NCOLS keyword repeated in file");
00098       TESTG((rval=(argc!=2)),CLEANUP,"NCOLS has not 2 tokens");
00099       *ncols = atoi(argv[1]);
00100       TESTG((rval=(*ncols < 1)),CLEANUP, "NCOLS should be positive,"
00101             " is %d\n", *ncols);
00102       has_ncols = 1;
00103     }
00104     else if(strncmp(argv[0],"NZ", (size_t)33)==0)
00105     {
00106       TESTG((rval=has_nz),CLEANUP,"NZ keyword repeated in file");
00107       TESTG((rval=(argc!=2)),CLEANUP,"NZ has not 2 tokens");
00108       nz = atoi(argv[1]);
00109       TESTG((rval=(nz < 1)),CLEANUP, "NZ should be positive,"
00110             " is %d\n", nz);
00111       has_nz = 1;
00112       *rowval = EGsMalloc(double,nz);
00113       *rowind = EGsMalloc(int,nz);
00114     }
00115     else if(strncmp(argv[0],"ROWVAL_SECTION", (size_t)33)==0)
00116     {
00117       TESTG((rval=has_val),CLEANUP,"ROWVAL_SECTION keyword repeated in file");
00118       TESTG((rval=(argc!=1)),CLEANUP,"ROWVAL_SECTION has not 1 token");
00119       TESTG((rval=!has_nz),CLEANUP, "ROWVAL_SECTION without NZ");
00120       TESTG((rval=!has_ncols),CLEANUP, "ROWVAL_SECTION without NCOLS");
00121       for( i = 0 ; i < nz ; i++)
00122       {
00123         do
00124         {
00125           rval = EGioReadLine(str,(size_t)2048,input);
00126           CHECKRVALG(rval,CLEANUP);
00127           TESTG((rval = feof(input)||ferror(input)), CLEANUP, 
00128                 "File ended prematurelly, or has errors");
00129           EGioNParse(str,1024,delim,coment,&argc,argv);
00130         }while(!argc);
00131         TESTG((rval=(argc!=2)),CLEANUP,"in ROWVAL_SECTION, line has "
00132               "not 2 tokens");
00133         (*rowind)[i] = atoi(argv[0]);
00134         (*rowval)[i] = strtod(argv[1],0);
00135       }
00136       has_val = 1;
00137     }
00138     else if(strncmp(argv[0],"ROWBEG_SECTION", (size_t)33)==0)
00139     {
00140       TESTG((rval=has_beg),CLEANUP,"ROWBEG_SECTION keyword repeated in file");
00141       TESTG((rval=(argc!=1)),CLEANUP,"ROWBEG_SECTION has not 1 token");
00142       TESTG((rval=!has_nrows),CLEANUP, "ROWBEG_SECTION without NROWS");
00143       for( i = 0 ; i < *nrows ; i++)
00144       {
00145         do
00146         {
00147           rval = EGioReadLine(str,(size_t)2048,input);
00148           CHECKRVALG(rval,CLEANUP);
00149           TESTG((rval = feof(input)||ferror(input)), CLEANUP, 
00150                 "File ended prematurelly, or has errors");
00151           EGioNParse(str,1024,delim,coment,&argc,argv);
00152         }while(!argc);
00153         TESTG((rval=(argc!=2)),CLEANUP,"in ROWBEG_SECTION, line has "
00154               "not 2 tokens");
00155         (*rowbeg)[i] = atoi(argv[0]);
00156         (*f)[i] = strtod(argv[1],0);
00157       }
00158       has_beg = 1;
00159     }
00160     else if(strncmp(argv[0],"NROWS", (size_t)33)==0)
00161     {
00162       TESTG((rval=has_nrows),CLEANUP,"NROWS keyword repeated in file");
00163       TESTG((rval=(argc!=2)),CLEANUP,"NROWS has not 2 tokens");
00164       *nrows = atoi(argv[1]);
00165       TESTG((rval=(*nrows < 1)),CLEANUP, "NROWS should be positive,"
00166             " is %d\n", *nrows);
00167       has_nrows = 1;
00168       *rowbeg = EGsMalloc(int,(*nrows)+1);
00169       *f = EGsMalloc(double,(*nrows));
00170     }
00171     /* update todo */
00172     todo = !( has_nz && has_ncols && has_nrows && has_type && 
00173               has_val && has_beg && has_nz); 
00174   }
00175   (*rowbeg)[(*nrows)]=nz;
00176   /* final set-up */
00177   CLEANUP:
00178   return rval;
00179 }
00180 
00181 /* ========================================================================= */
00182 /** @} */
00183 /* end of mt_tableau.h */

Generated on Mon Oct 26 09:16:29 2009 for MTgomory by  doxygen 1.4.6