eg_aequiset.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_aequiset.h"
00021 /* ========================================================================= */
00022 /*  this function copy one aequiset to another new set */
00023 EGaequiSet_t *EGaequiSetCopyMP (EGaequiSet_t * U,
00024                                 EGcopyMP_f data_copy,
00025                                 EGmemPool_t * mem)
00026 {
00027   /* local variables */
00028   EGaequiSet_t *orig = (EGaequiSet_t *) U,
00029    *copy;
00030   register unsigned i;
00031 
00032   /* create basic copy of the set */
00033   copy = EGmemPoolSMalloc (orig->mem, EGaequiSet_t, 1);
00034   copy->mem = orig->mem;
00035   copy->size = orig->size;
00036   copy->set = EGmemPoolSMalloc (orig->mem, EGaequiSetElem_t, orig->size);
00037   memcpy (copy->set, orig->set, sizeof (EGaequiSetElem_t) * orig->size);
00038 
00039   /* if we have a copy function we use it */
00040   if (data_copy)
00041     for (i = copy->size; i--;)
00042       copy->set[i].this = data_copy (orig->set[i].this, mem);
00043 
00044   /* ending */
00045   return copy;
00046 }
00047 
00048 /* ========================================================================= */
00049 /*  this function copy one aequiset to another new set */
00050 EGaequiSet_t *EGaequiSetCopy (EGaequiSet_t * U,
00051                               EGcopy_f data_copy)
00052 {
00053   /* local variables */
00054   EGaequiSet_t *orig = (EGaequiSet_t *) U,
00055    *copy;
00056   register unsigned i;
00057 
00058   /* create basic copy of the set */
00059   copy = EGmemPoolSMalloc (orig->mem, EGaequiSet_t, 1);
00060   copy->mem = orig->mem;
00061   copy->size = orig->size;
00062   copy->set = EGmemPoolSMalloc (orig->mem, EGaequiSetElem_t, orig->size);
00063   memcpy (copy->set, orig->set, sizeof (EGaequiSetElem_t) * orig->size);
00064 
00065   /* if we have a copy function we use it */
00066   if (data_copy)
00067     for (i = copy->size; i--;)
00068       copy->set[i].this = data_copy (orig->set[i].this);
00069 
00070   /* ending */
00071   return copy;
00072 }
00073 
00074 /* ========================================================================= */
00075 /* this procedure make a new set of size 'size' and with all elements as
00076  * singletons and without internal data. */
00077 EGaequiSet_t *EGnewAEquiSet (EGmemPool_t * mem,
00078                              const unsigned size)
00079 {
00080   /* local variables */
00081   EGaequiSet_t *v;
00082   register unsigned i;
00083   EGaequiSetElem_t *elem;
00084 
00085   /* basic set-up */
00086   v = EGmemPoolSMalloc (mem, EGaequiSet_t, 1);
00087   v->mem = mem;
00088   v->size = size;
00089   v->set = EGmemPoolSMalloc (mem, EGaequiSetElem_t, size);
00090   for (elem = v->set + size, i = size; i--;)
00091   {
00092     elem--;
00093     elem->father = i;
00094     elem->this = 0;
00095     elem->rank = 0;
00096   }
00097 
00098   /* ending */
00099   return v;
00100 }
00101 
00102 /* ========================================================================= */
00103 /* this function find the representant of this element in his equivalence set */
00104 unsigned EGaequiSetFind (EGaequiSet_t * const s,
00105                          const unsigned elem)
00106 {
00107   /* local variables */
00108   unsigned father;
00109 
00110   /* some tests */
00111   EXITL (EG_AEQUISET_DLEVEL, elem >= s->size,
00112          "elem (%u) is out of range (size = %u)", elem, s->size);
00113 
00114   /* computing fahter */
00115   father = s->set[elem].father;
00116   return (father == elem) ? elem : (s->set[elem].father =
00117                                     EGaequiSetFind (s, father));
00118 }
00119 
00120 /* ========================================================================= */
00121 /* this functionlink two sets or equivalence clases */
00122 unsigned EGaequiSetLink (EGaequiSet_t * const U,
00123                          const unsigned u,
00124                          const unsigned v)
00125 {
00126   /* local variables */
00127   EGaequiSetElem_t *uptr,
00128    *vptr,
00129    *w;
00130 
00131   /* some tests */
00132   EXITL (EG_AEQUISET_DLEVEL, u >= U->size,
00133          "elem (%u) is out of range (size = %u)", u, U->size);
00134   EXITL (EG_AEQUISET_DLEVEL, v >= U->size,
00135          "elem (%u) is out of range (size = %u)", v, U->size);
00136   EXITL (EG_AEQUISET_DLEVEL, v != U->set[v].father,
00137          "v is not a representant for its class");
00138   EXITL (EG_AEQUISET_DLEVEL, u != U->set[u].father,
00139          "u is not a representant for its class");
00140 
00141   /* pick the biggest one */
00142   uptr = U->set + u;
00143   vptr = U->set + v;
00144   if (uptr->rank < vptr->rank)
00145   {
00146     w = uptr;
00147     uptr = vptr;
00148     vptr = w;
00149   }
00150 
00151   if (uptr->rank == vptr->rank)
00152   {
00153     uptr->rank++;
00154   }
00155 
00156   /* now we know that rank->u > rank->v */
00157   vptr->father = uptr - U->set;
00158 
00159   /* ending */
00160   return vptr->father;
00161 }
00162 
00163 /* ========================================================================= */
00164 /* this function reset a Universe set to all singleton-state */
00165 void EGaequiSetReset (EGaequiSet_t * const U)
00166 {
00167   unsigned register i;
00168   EGaequiSetElem_t *elem;
00169   for (i = U->size, elem = U->set + U->size; i--;)
00170   {
00171     elem--;
00172     elem->father = i;
00173     elem->this = 0;
00174     elem->rank = 0;
00175   }
00176   return;
00177 }
00178 
00179 /* ========================================================================= */
00180 /* destructor for the structure, note that his only eliminate the given element
00181  * in the set, but no the whole structure */
00182 void EGfreeAEquiSet (void *u)
00183 {
00184   EGmemPoolSFree (((EGaequiSet_t *) u)->set,
00185                   EGaequiSetElem_t,
00186                   ((EGaequiSet_t *) u)->size, ((EGaequiSet_t *) u)->mem);
00187   EGmemPoolSFree (((EGaequiSet_t *) u),
00188                   EGaequiSet_t, 1, ((EGaequiSet_t *) u)->mem);
00189   return;
00190 }
00191 
00192 /* ========================================================================= */
00193 
00194 /* end eg_equiset.c */

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