eg_aequiset.h

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 /* ========================================================================= */
00021 /* This is an implementation of the set's defined at 'Data Structures and
00022  * Network Algorithms' of Robert Endre Tarjan. This structures allow to work
00023  * with disjoint sets with a representant (thus an equivalence class) and ask 
00024  * the basic question of, given an elment, who is the representant in his 
00025  * class, make a set, link two sets (i.e. union of them) and given a 
00026  * representant link an element to that class. But this implementation instead 
00027  * of working with pointers works with arrays and index in such an array, the 
00028  * main advantage of this implementation is that copying this information is 
00029  * easier than in the linked-list implementation. the main drawback is that it 
00030  * is an static structure (in terms of the number of elements).
00031  *
00032  * - 2003-12-01
00033  *          - First Implementation.
00034  * 
00035  * */
00036 /* ========================================================================= */
00037 #ifndef __EG_AEQUISET_H__
00038 #define __EG_AEQUISET_H__
00039 #include <stdio.h>
00040 #include <stdlib.h>
00041 #include <string.h>
00042 #include "eg_config.h"
00043 #include "eg_macros.h"
00044 #include "eg_mempool.h"
00045 #ifndef EG_AEQUISET_DLEVEL
00046 #define EG_AEQUISET_DLEVEL 10
00047 #endif
00048 
00049 /* ========================================================================= */
00050 /* this structure holds an element of a set */
00051 typedef struct EGaequiSetElem_t
00052 {
00053   unsigned father;
00054   unsigned rank;
00055   void *this;
00056 }
00057 EGaequiSetElem_t;
00058 
00059 /* ========================================================================= */
00060 /* this structure holds a universe set. Note that this structure is mainly
00061  * static. */
00062 typedef struct EGaequiSet_t
00063 {
00064   unsigned size;
00065   EGaequiSetElem_t *set;
00066   EGmemPool_t *mem;
00067 }
00068 EGaequiSet_t;
00069 
00070 /* ========================================================================= */
00071 /*  this function copy one aequiset to another new set */
00072 extern inline EGaequiSet_t *EGaequiSetCopyMP (EGaequiSet_t * U,
00073                                               EGcopyMP_f data_copy,
00074                                               EGmemPool_t * mem)
00075 {
00076   /* local variables */
00077   EGaequiSet_t *orig = (EGaequiSet_t *) U,
00078    *copy;
00079   register unsigned i;
00080 
00081   /* create basic copy of the set */
00082   copy = EGmemPoolSMalloc (orig->mem, EGaequiSet_t, 1);
00083   copy->mem = orig->mem;
00084   copy->size = orig->size;
00085   copy->set = EGmemPoolSMalloc (mem, EGaequiSetElem_t, orig->size);
00086   memcpy (copy->set, orig->set, sizeof (EGaequiSetElem_t) * orig->size);
00087 
00088   /* if we have a copy function we use it */
00089   if (data_copy)
00090     for (i = copy->size; i--;)
00091       copy->set[i].this = data_copy (orig->set[i].this, mem);
00092 
00093   /* ending */
00094   return copy;
00095 }
00096 
00097 /* ========================================================================= */
00098 /*  this function copy one aequiset to another new set */
00099 extern inline EGaequiSet_t *EGaequiSetCopy (EGaequiSet_t * U,
00100                                             EGcopy_f data_copy)
00101 {
00102   /* local variables */
00103   EGaequiSet_t *orig = (EGaequiSet_t *) U,
00104    *copy;
00105   register unsigned i;
00106 
00107   /* create basic copy of the set */
00108   copy = EGmemPoolSMalloc (orig->mem, EGaequiSet_t, 1);
00109   copy->mem = orig->mem;
00110   copy->size = orig->size;
00111   copy->set = EGmemPoolSMalloc (orig->mem, EGaequiSetElem_t, orig->size);
00112   memcpy (copy->set, orig->set, sizeof (EGaequiSetElem_t) * orig->size);
00113 
00114   /* if we have a copy function we use it */
00115   if (data_copy)
00116     for (i = copy->size; i--;)
00117       copy->set[i].this = data_copy (orig->set[i].this);
00118 
00119   /* ending */
00120   return copy;
00121 }
00122 
00123 /* ========================================================================= */
00124 /* this procedure make a new set of size 'size' and with all elements as
00125  * singletons and without internal data. */
00126 extern inline EGaequiSet_t *EGnewAEquiSet (EGmemPool_t * mem,
00127                                            const unsigned size)
00128 {
00129   /* local variables */
00130   EGaequiSet_t *v;
00131   register unsigned i;
00132   EGaequiSetElem_t *elem;
00133 
00134   /* basic set-up */
00135   v = EGmemPoolSMalloc (mem, EGaequiSet_t, 1);
00136   v->mem = mem;
00137   v->size = size;
00138   v->set = EGmemPoolSMalloc (mem, EGaequiSetElem_t, size);
00139   for (elem = v->set + size, i = size; i--;)
00140   {
00141     elem--;
00142     elem->father = i;
00143     elem->this = 0;
00144     elem->rank = 0;
00145   }
00146 
00147   /* ending */
00148   return v;
00149 }
00150 
00151 /* ========================================================================= */
00152 /* this function find the representant of this element in his equivalence set */
00153 unsigned EGaequiSetFind (EGaequiSet_t * const s,
00154                          const unsigned elem);
00155 
00156 /* ========================================================================= */
00157 /* this functionlink two sets or equivalence clases */
00158 extern inline unsigned EGaequiSetLink (EGaequiSet_t * const U,
00159                                        const unsigned u,
00160                                        const unsigned v)
00161 {
00162   /* local variables */
00163   EGaequiSetElem_t *w,
00164    *uptr,
00165    *vptr;
00166 
00167   /* some tests */
00168   EXITL (EG_AEQUISET_DLEVEL, u >= U->size,
00169          "elem (%u) is out of range (size = %u)", u, U->size);
00170   EXITL (EG_AEQUISET_DLEVEL, v >= U->size,
00171          "elem (%u) is out of range (size = %u)", v, U->size);
00172   EXITL (EG_AEQUISET_DLEVEL, v != U->set[v].father,
00173          "v is not a representant for its class");
00174   EXITL (EG_AEQUISET_DLEVEL, u != U->set[u].father,
00175          "u is not a representant for its class");
00176 
00177   /* pick the biggest one */
00178   uptr = U->set + u;
00179   vptr = U->set + v;
00180   if (uptr->rank < vptr->rank)
00181   {
00182     w = uptr;
00183     uptr = vptr;
00184     vptr = w;
00185   }
00186 
00187   if (uptr->rank == vptr->rank)
00188   {
00189     uptr->rank++;
00190   }
00191 
00192   /* now we know that rank->u > rank->v */
00193   vptr->father = uptr - U->set;
00194 
00195   /* ending */
00196   return vptr->father;
00197 }
00198 
00199 /* ========================================================================= */
00200 /* this function reset a Universe set to all singleton-state */
00201 extern inline void EGaequiSetReset (EGaequiSet_t * const U)
00202 {
00203   unsigned register i;
00204   EGaequiSetElem_t *elem;
00205   for (i = U->size, elem = U->set + U->size; i--;)
00206   {
00207     elem--;
00208     elem->father = i;
00209     elem->this = 0;
00210     elem->rank = 0;
00211   }
00212   return;
00213 }
00214 
00215 /* ========================================================================= */
00216 /* destructor for the structure, note that his only eliminate the given element
00217  * in the set, but no the whole structure */
00218 extern inline void EGfreeAEquiSet (void *U)
00219 {
00220   EGmemPoolSFree (((EGaequiSet_t *) U)->set,
00221                   EGaequiSetElem_t,
00222                   ((EGaequiSet_t *) U)->size, ((EGaequiSet_t *) U)->mem);
00223   EGmemPoolSFree (((EGaequiSet_t *) U),
00224                   EGaequiSet_t, 1, ((EGaequiSet_t *) U)->mem);
00225   return;
00226 }
00227 
00228 /* ========================================================================= */
00229 
00230 /* end eg_aequiset.h */
00231 #endif

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