eg_col.c

Go to the documentation of this file.
00001 /* EGlib "Efficient General Library" provides some basic structures and
00002  * algorithms commons in many optimization algorithms.
00003  *
00004  * Copyright (C) 2005 Daniel Espinoza and Marcos Goycoolea.
00005  * 
00006  * This library is free software; you can redistribute it and/or modify it
00007  * under the terms of the GNU Lesser General Public License as published by the
00008  * Free Software Foundation; either version 2.1 of the License, or (at your
00009  * option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful, but 
00012  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
00013  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
00014  * License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public License
00017  * along with this library; if not, write to the Free Software Foundation,
00018  * Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA 
00019  * */
00020 #include "eg_col.h"
00021 /* return a pointer to an initialized EGcol object */
00022 EGcol_t *EGnewCol (EGmemPool_t * mempool)
00023 {
00024 
00025   /* local variables */
00026   EGcol_t *res;
00027 
00028   /* looking for memory */
00029   res = (EGcol_t *) EGmemPoolMalloc (mempool, sizeof (EGcol_t));
00030   res->list = EGnewList (mempool);
00031   res->name = 0;
00032 
00033   /* ending */
00034   return res;
00035 }
00036 
00037 /* liberate the memory returned by EGnewCol, __NEVER__ liberate such a memory 
00038  * space with free */
00039 void EGfreeCol (void *col)
00040 {
00041 
00042   /* local variables */
00043   EGmemPool_t *mempool = ((EGcol_t *) col)->list->mempool;
00044   EGlistNode_t *cur,
00045    *next;
00046 
00047   /* we free the list, in order to be more inteligent we free everithing from
00048    * here, the disadvantage of this is that is __VERY__ implementation dependent */
00049   cur = ((EGcol_t *) col)->list->begin;
00050   while (cur)
00051   {
00052     next = cur->next;
00053     EGmemPoolFree (cur->this, sizeof (EGcplexData_t), mempool);
00054     EGmemPoolFree (cur, sizeof (EGlistNode_t), mempool);
00055     cur = next;
00056   }
00057 
00058   /* then we free everyithing else */
00059   EGmemPoolFree (((EGcol_t *) col)->list, sizeof (EGlist_t), mempool);
00060   if (((EGcol_t *) col)->name)
00061     EGmemPoolFree (((EGcol_t *) col)->name,
00062                    strlen (((EGcol_t *) col)->name) + 1, mempool);
00063   EGmemPoolFree (col, sizeof (EGcol_t), mempool);
00064 
00065   /* ending */
00066   return;
00067 }
00068 
00069 /* this function just add the pair (int,double) to the List in EGcol, but it does not 
00070  * check if there is another entry with the same integer, i.e. if you add a constrain 
00071  * twice you will have two entries for the same constrain, and this will lead to an 
00072  * error when we add the constraint or column to  */
00073 void EGcolAddCoeff (EGcol_t * col,
00074                     const int LPind,
00075                     const double coeff)
00076 {
00077 
00078   /* local variables */
00079   EGcplexData_t *data;
00080 
00081   /* looking for memory */
00082   data =
00083     (EGcplexData_t *) EGmemPoolMalloc (col->list->mempool,
00084                                        sizeof (EGcplexData_t));
00085   data->LPind = LPind;
00086   data->coeff = coeff;
00087 
00088   /* andd data to the end of the list */
00089   EGlistPushBack (col->list, data);
00090 
00091   /* ending */
00092   return;
00093 }
00094 
00095 /* change the name, objective lowe and upper bound of a column */
00096 void EGcolInit (EGcol_t * col,
00097                 const char *name,
00098                 const double obj,
00099                 const double lb,
00100                 const double ub)
00101 {
00102 
00103   /* we free the current name */
00104   if (col->name)
00105     EGmemPoolFree (col->name, strlen (col->name) + 1, col->list->mempool);
00106 
00107   /* and now we copy all information */
00108   if (name)
00109   {
00110     col->name =
00111       (char *) EGmemPoolMalloc (col->list->mempool, strlen (name) + 1);
00112     memcpy (col->name, name, strlen (name) + 1);
00113   }
00114   else
00115     col->name = 0;
00116   col->obj = obj;
00117   col->lb = lb;
00118   col->ub = ub;
00119 
00120   /* ending */
00121   return;
00122 }
00123 
00124 /* this is for testing purposes only, you should call this function before running just to be 
00125  * sure the structures are OK */
00126 void EGcolTest (void)
00127 {
00128   /* local variables */
00129 #if DEBUG > 2
00130   int i,
00131     j,
00132     size = 10;
00133   EGcol_t *mycols[10];
00134 #else
00135   int i,
00136     j,
00137     size = 1000;
00138   EGcol_t *mycols[1000];
00139 #endif
00140   EGmemPool_t *mempool;
00141 
00142   /* creating some columns,  */
00143   mempool = EGnewMemPool (100, EGmemPoolNewSize, EGmemPoolNewSize (1));
00144 #if DEBUG > 2
00145   fprintf (stdout, "Creating Cols");
00146   fflush (stdout);
00147 #endif
00148   for (i = 0; i < size; i++)
00149   {
00150 #if DEBUG > 2
00151     fprintf (stdout, ".");
00152     fflush (stdout);
00153 #endif
00154     mycols[i] = EGnewCol (mempool);
00155     EGcolInit (mycols[i], "X", 1.0, 1.0, 0.0);
00156     for (j = 0; j < size; j++)
00157     {
00158       EGcolAddCoeff (mycols[i], j, drand48 ());
00159     }
00160   }
00161 #if DEBUG > 2
00162   fprintf (stdout, "done\n");
00163   fflush (stdout);
00164 #endif
00165 
00166   /*erase them,  */
00167   for (i = 0; i < size; i++)
00168   {
00169     EGfreeCol ((void *) mycols[i]);
00170   }
00171 
00172   /* recreate them and exit */
00173   /* creating some columns,  */
00174 #if DEBUG > 2
00175   fprintf (stdout, "Creating Cols");
00176   fflush (stdout);
00177 #endif
00178   for (i = 0; i < size; i++)
00179   {
00180 #if DEBUG > 2
00181     fprintf (stdout, ".");
00182     fflush (stdout);
00183 #endif
00184     mycols[i] = EGnewCol (mempool);
00185     EGcolInit (mycols[i], "X", 1.0, 1.0, 0.0);
00186     for (j = 0; j < size; j++)
00187     {
00188       EGcolAddCoeff (mycols[i], j, drand48 ());
00189     }
00190   }
00191 #if DEBUG > 2
00192   fprintf (stdout, "done\n");
00193   fflush (stdout);
00194 #endif
00195 
00196   /*erase them,  */
00197 #if DEBUG > 2
00198   fprintf (stdout, "Erasing Cols");
00199   fflush (stdout);
00200 #endif
00201   for (i = 0; i < size; i++)
00202   {
00203 #if DEBUG > 2
00204     fprintf (stdout, ".");
00205     fflush (stdout);
00206 #endif
00207     EGfreeCol ((void *) mycols[i]);
00208   }
00209 #if DEBUG > 2
00210   fprintf (stdout, "done\n");
00211   fflush (stdout);
00212 #endif
00213   EGfreeMemPool (mempool);
00214 
00215   /* ending */
00216   return;
00217 }
00218 
00219 /* this function clear the internal coefficient data */
00220 int EGcolClear (EGcol_t * col)
00221 {
00222 
00223   /* local data */
00224   EGlistNode_t *cur,
00225    *next;
00226   EGmemPool_t *mempool = ((EGcol_t *) col)->list->mempool;
00227 
00228   /* we clear the list */
00229   cur = col->list->begin;
00230   while (cur)
00231   {
00232     next = cur->next;
00233     EGmemPoolFree (cur->this, sizeof (EGcplexData_t), mempool);
00234     EGmemPoolFree (cur, sizeof (EGlistNode_t), mempool);
00235     cur = next;
00236   }
00237   col->list->size = 0;
00238   col->list->begin = col->list->end = 0;
00239 
00240   /* ending */
00241   return 0;
00242 }
00243 
00244 /* ========================================================================= */
00245 /* given a column, and LP number and a coefficient, this function will try to
00246  * find if the LP number already have an entry in the column, if so, it will add
00247  * the given coefficient to the existing one, if the LP index is not in the 
00248  * column, it will add it to the column with the given coefficient. */
00249 /* ========================================================================= */
00250 void EGcolAddIncCoeff (EGcol_t * col,
00251                        const int LPind,
00252                        const double coeff)
00253 {
00254 
00255   /* local variables */
00256   EGlistNode_t *it;
00257 
00258   /* first, we try to find an entry with the given LP number */
00259   for (it = col->list->begin; it; it = it->next)
00260     if (((EGcplexData_t *) (it->this))->LPind == LPind)
00261     {
00262       ((EGcplexData_t *) (it->this))->coeff += coeff;
00263       return;
00264     }
00265 
00266   /* if we can't find the LP number in the column, we just add it to the end of
00267    * the column list of indices */
00268   EGcolAddCoeff (col, LPind, coeff);
00269 
00270   /* ending */
00271   return;
00272 }

Generated on Mon Jan 30 08:48:52 2006 for EGlib by  doxygen 1.4.5