eg_eheap.ex.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 /** @file 
00021  * @ingroup EGeHeap */
00022 /** @addtogroup EGeHeap */
00023 /** @{ */
00024 /* ========================================================================= */
00025 /** @brief This program reads a list of double values from a text file and 
00026  * uses a heap to sort them. It also allows the user to change the value of 
00027  * one of the read numbers after they have been placed in the heap. The 
00028  * purpose of this program is to illustrate the use of the @ref EGeHeap 
00029  * structure and its associated functions. 
00030  * 
00031  * The input file format is: 
00032  * n
00033  * Value_0
00034  * Value_1
00035  * Value_2
00036  * Value_3
00037  *   ...  
00038  * Value_n 
00039  * */
00040 /* ========================================================================= */
00041 #include <stdio.h>
00042 #include <stdlib.h>
00043 #ifdef LINUX
00044 #include <getopt.h>
00045 #endif
00046 #include "eg_eheap.h"
00047 
00048 /* ========================================================================= */
00049 /** @brief display the usage message for this program */
00050 void eheap_usage (char *program)
00051 {
00052   fprintf (stdout, "Usage: %s [options]\n", program);
00053   fprintf (stdout, "Options:\n");
00054   fprintf (stdout, "     -d n   'd' value.\n");
00055   fprintf (stdout, "     -f n   file name.\n");
00056   fprintf (stdout, "     -c n   item whose value to change.\n");
00057   fprintf (stdout, "     -v n   new item value (0 by default).\n");
00058 
00059 }
00060 
00061 /* ========================================================================= */
00062 /** @brief parse the input argumenbts for the program */
00063 int eheap_parseargs (int argc,
00064                      char **argv,
00065                      unsigned int *d,
00066                      unsigned int *ch,
00067                      EGlpNum_t * v,
00068                      char **file_name)
00069 {
00070   int c;
00071   while ((c = getopt (argc, argv, "f:d:c:v:")) != EOF)
00072   {
00073     switch (c)
00074     {
00075     case 'f':
00076       *file_name = optarg;
00077       break;
00078     case 'd':
00079       *d = atoi (optarg);
00080       break;
00081     case 'c':
00082       *ch = atoi (optarg);
00083       break;
00084     case 'v':
00085       EGlpNumReadStr (*v, optarg);
00086       break;
00087     default:
00088       eheap_usage (argv[0]);
00089       return 1;
00090     }
00091   }
00092   /* reporting the options */
00093   if (!*file_name)
00094   {
00095     eheap_usage (argv[0]);
00096     return 1;
00097   }
00098   fprintf (stdout, "Parsed Options:\n");
00099   fprintf (stdout, "input         : %s\n", *file_name);
00100   fprintf (stdout, "d             : %u\n", *d);
00101   if (*ch != UINT_MAX)
00102   {
00103     fprintf (stdout, "c             : %u\n", *ch);
00104     fprintf (stdout, "v             : %lf\n", EGlpNumToLf (*v));
00105   }
00106   return 0;
00107 }
00108 
00109 /* ========================================================================= */
00110 /** @brief main function */
00111 int main (int argc,
00112           char **argv)
00113 {
00114 
00115   int rval = 0;
00116   unsigned int i,
00117     c = UINT_MAX,
00118     d = 2;
00119   char *file_name = 0,
00120     str1[1024];
00121   FILE *file;
00122   unsigned int nval;
00123   EGlpNum_t v;
00124   EGeHeap_t my_heap;
00125   EGeHeapCn_t *all_cn = 0,
00126    *ccn;
00127   EGlpNumStart ();
00128   EGlpNumInitVar (v);
00129   EGlpNumZero (v);
00130   EGeHeapInit (&my_heap);
00131   rval = EGeHeapCheck (&my_heap);
00132   CHECKRVALG (rval, CLEANUP);
00133 
00134   /* Parse command line input to get 'file name' and 'd'. */
00135   rval = eheap_parseargs (argc, argv, &d, &c, &v, &file_name);
00136   CHECKRVALG (rval, CLEANUP);
00137   EGeHeapChangeD (&my_heap, d);
00138   rval = EGeHeapCheck (&my_heap);
00139   CHECKRVALG (rval, CLEANUP);
00140 
00141   /* Read the objects to sort from the file */
00142   file = fopen (file_name, "r");
00143   TEST (!file, "unable to open file %s", file_name);
00144   fscanf (file, "%u", &nval);
00145   all_cn = EGsMalloc (EGeHeapCn_t, nval);
00146   EGeHeapResize (&my_heap, nval);
00147   rval = EGeHeapCheck (&my_heap);
00148   CHECKRVALG (rval, CLEANUP);
00149   MESSAGE (EG_EHEAP_DEBUG, "Inserting %u elements into the heap", nval);
00150   for (i = 0; i < nval; i++)
00151   {
00152     EGeHeapCnInit (all_cn + i);
00153     fscanf (file, "%s", str1);
00154     EGlpNumReadStr (all_cn[i].val, str1);
00155     MESSAGE (EG_EHEAP_DEBUG, "Adding value (%s,%lf) to the heap", str1,
00156              EGlpNumToLf (all_cn[i].val));
00157     rval = EGeHeapAdd (&my_heap, all_cn + i);
00158     CHECKRVALG (rval, CLEANUP);
00159     rval = EGeHeapCheck (&my_heap);
00160     CHECKRVALG (rval, CLEANUP);
00161   }
00162   fclose (file);
00163 
00164   /* Check if change value is in range */
00165   TESTG (c != UINT_MAX && c >= nval, CLEANUP,
00166          "Change item (%u) is out of range (only %u objects)", c, nval);
00167 
00168   /* Popping the values from the heap */
00169   fprintf (stderr, "\nRemoving:\n\n");
00170   for (i = 0; i < nval; i++)
00171   {
00172     ccn = EGeHeapGetMin (&my_heap);
00173     MESSAGE (EG_EHEAP_DEBUG, "%u: item %d : %lf", i, ccn - all_cn,
00174              EGlpNumToLf (ccn->val));
00175     EGeHeapDel (&my_heap, ccn);
00176     rval = EGeHeapCheck (&my_heap);
00177     CHECKRVALG (rval, CLEANUP);
00178   }
00179 
00180   if (c == UINT_MAX)
00181     goto CLEANUP;
00182 
00183   /* Re-inserting the values into the heap */
00184   fprintf (stderr, "\nRe-Inserting.\n\n");
00185   for (i = 0; i < nval; i++)
00186   {
00187     rval = EGeHeapAdd (&my_heap, all_cn + i);
00188     CHECKRVALG (rval, CLEANUP);
00189     rval = EGeHeapCheck (&my_heap);
00190     CHECKRVALG (rval, CLEANUP);
00191   }
00192 
00193   /* Changing value of an item */
00194   fprintf (stderr, "Changing value of item %u from %lf to %lf.\n", c,
00195            EGlpNumToLf (all_cn[c].val), EGlpNumToLf (v));
00196   rval = EGeHeapChangeVal (&my_heap, all_cn + c, v);
00197   CHECKRVALG (rval, CLEANUP);
00198   rval = EGeHeapCheck (&my_heap);
00199   CHECKRVALG (rval, CLEANUP);
00200 
00201   /* Popping the values from the heap */
00202   fprintf (stderr, "\nRemoving:\n\n");
00203   for (i = 0; i < nval; i++)
00204   {
00205     ccn = EGeHeapGetMin (&my_heap);
00206     MESSAGE (EG_EHEAP_DEBUG, "%u: item %d : %lf", i, ccn - all_cn,
00207              EGlpNumToLf (ccn->val));
00208     EGeHeapDel (&my_heap, ccn);
00209     rval = EGeHeapCheck (&my_heap);
00210     CHECKRVALG (rval, CLEANUP);
00211   }
00212 
00213   /* Liberating allocated memory */
00214 CLEANUP:
00215   if (all_cn)
00216     EGfree (all_cn);
00217   EGeHeapResize (&my_heap, 0);
00218   EGeHeapClear (&my_heap);
00219   EGlpNumClearVar (v);
00220   EGlpNumExit ();
00221   return rval;
00222 }
00223 
00224 /* ========================================================================= */
00225 /** @} */

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