eg_shrink_graph.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 /** @defgroup EGsrkGraph EGsrkGraph
00022  * This is a group of functions, macros and types designed to work with
00023  * graphs that are shrinkable, meaning that we can take two nodes in the
00024  * (current) graph, and shrink them into a single node, and at the same time
00025  * collapse all edges that become loops and if two edges are parallel, keep
00026  * just one (but keep a reference to the collapsed edge). At the same time the
00027  * shrunken nodes keep a list to the nodes 'embeded' or 'shrunken' into the
00028  * given node. More details in the structure definition and in the example.
00029  * Note that this implementation only support undirected graphs with actual
00030  * weights on the edges, the weights must be of type EGlpNum_t, and their
00031  * values are updated during the shrinking procedure, so if anyone want to
00032  * have the original values omewere else, they will have to keep an extra copy
00033  * outside. Most of the ideas used in this implementation come from CONCORDE.
00034  * 
00035  * @version 0.0.1
00036  * @par History:
00037  * - 2005-06-01
00038  *            - First Implementation.
00039  * */
00040 /** @file
00041  * @ingroup EGsrkGraph */
00042 /** @addtogroup EGsrkGraph */
00043 /** @{ */
00044 /** @example eg_shrink_graph.ex.c */
00045 /* ========================================================================= */
00046 
00047 #ifndef _EGshrinkGraph_h__
00048 #define _EGshrinkGraph_h__
00049 #include <stdio.h>
00050 #include <stddef.h>
00051 #include <stdlib.h>
00052 #include <limits.h>
00053 #include "eg_elist.h"
00054 #include "eg_eset.h"
00055 #include "eg_eugraph.h"
00056 #include "eg_lpnum.h"
00057 #ifndef EG_SRK_DEBUG
00058 /* ========================================================================= */
00059 /** @brief debuigging level, the lower the more debugging is carried out */
00060 #define EG_SRK_DEBUG 100
00061 #endif
00062 
00063 /* ========================================================================= */
00064 /** @brief Edge structure for shrinkable graphs */
00065 typedef struct EGsrkEdge_t
00066 {
00067   EGeUgraphEdge_t edge; /**< Actual edge structure for the graph */
00068   EGeList_t members;    /**< list of other edges shrunken within this edge */
00069   unsigned int mmb_sz;  /**< length of the members list (without including the 
00070                              edge itsself */
00071   EGlpNum_t weight;     /**< Weight for the edge */
00072 }
00073 EGsrkEdge_t;
00074 
00075 /* ========================================================================= */
00076 /** @brief Node structure for shrinkable graphs */
00077 typedef struct EGsrkNode_t
00078 {
00079   EGeUgraphNode_t node; /**< actual node structure for the graph */
00080   EGeList_t members;    /**< list of other nodes shrunken with this node */
00081   unsigned int mmb_sz;  /**< length of the members list (without including the
00082                              node itself */
00083   EGes_t parent;        /**< If this node is the representant for its class, 
00084                              then this is a 'parent' node, otherwise, is a 
00085                              shrunken node */
00086   EGlpNum_t weight;     /**< Weight of the @f$\delta(n)@f$ edges for this node
00087                              (in the shrunken graph), this should be 
00088                              initialized by the user. */
00089   EGsrkEdge_t *hit;     /**< used for internal purposes, in particular, while 
00090                              merging two adjacency lists, this field is used 
00091                              to store the first edge touching this node, and 
00092                              then used to retrieve that information. When we 
00093                              call #EGsrkIdentifyNodes this field is assumed 
00094                              to be NULL */
00095 }
00096 EGsrkNode_t;
00097 
00098 /* ========================================================================= */
00099 /** @brief Graph structure for shrinkable graphs */
00100 typedef struct EGsrkGraph_t
00101 {
00102   EGeUgraph_t G;          /**< Actual graph structure. */
00103   unsigned n_onodes;      /**< Number of original nodes */
00104   unsigned n_oedges;      /**< Number of original edges */
00105 }
00106 EGsrkGraph_t;
00107 
00108 /* ========================================================================= */
00109 /** @brief Initialize an edge structure.
00110  * @param e_edge */
00111 #define EGsrkEdgeInit(e_edge) ({\
00112   EGsrkEdge_t*const _EGsrkE = (e_edge);\
00113   EGeUgraphEdgeInit(&(_EGsrkE->edge));\
00114   EGeListInit(&(_EGsrkE->members));\
00115   _EGsrkE->mmb_sz = 0;\
00116   EGlpNumInitVar(_EGsrkE->weight);\
00117   EGlpNumZero(_EGsrkE->weight);})
00118 
00119 /* ========================================================================= */
00120 /** @brief Clear internal memory (not allocated by the user) of an edge
00121  * structure.
00122  * @param e_edge */
00123 #define EGsrkEdgeClear(e_edge) ({\
00124   EGeUgraphEdgeClear(&((e_edge)->edge));\
00125   EGlpNumClearVar((e_edge)->weight);})
00126 
00127 /* ========================================================================= */
00128 /** @brief Initialize a graph structure 
00129  * @param graph graph to be initialized */
00130 #define EGsrkGraphInit(graph) ({\
00131   EGsrkGraph_t*const _EGsrkG = (graph);\
00132   EGeUgraphInit(&(_EGsrkG->G));\
00133   _EGsrkG->n_onodes = _EGsrkG->n_oedges = 0;})
00134 
00135 /* ========================================================================= */
00136 /** @brief Clear internal memory (not allocated by the user) of a graph
00137  * structure.
00138  * @param graph */
00139 #define EGsrkGraphClear(graph) EGeUgraphClear(&((graph)->G))
00140 
00141 /* ========================================================================= */
00142 /** @brief Initialize a node structure.
00143  * @param e_node node to be initialized */
00144 #define EGsrkNodeInit(e_node) ({\
00145   EGsrkNode_t*const _EGsrkN = (e_node);\
00146   EGeUgraphNodeInit(&(_EGsrkN->node));\
00147   EGeListInit(&(_EGsrkN->members));\
00148   _EGsrkN->mmb_sz = 0;\
00149   _EGsrkN->hit = 0;\
00150   EGesInit(&(_EGsrkN->parent));\
00151   EGlpNumInitVar(_EGsrkN->weight);\
00152   EGlpNumZero(_EGsrkN->weight);})
00153 
00154 /* ========================================================================= */
00155 /** @brief Clear internal memory (not allocated by the user) of a node
00156  * structure.
00157  * @param e_node */
00158 #define EGsrkNodeClear(e_node) ({\
00159   EGeUgraphNodeClear(&((e_node)->node));\
00160   EGlpNumClearVar((e_node)->weight);})
00161 
00162 /* ========================================================================= */
00163 /** @brief Add a #EGsrkNode_t node to a #EGsrkGraph_t graph.
00164  * @param graph graph were to add the node.
00165  * @param N node to add to the graph.
00166  * @return zero on success, non-zero otherwise.
00167  * */
00168 #define EGsrkAddNode(graph,N) EGeUgraphAddNode(&((graph)->G),&((N)->node))
00169 
00170 /* ========================================================================= */
00171 /** @brief Add a #EGsrkEdge_t edge to a #EGsrkGraph_t graph.
00172  * @param lG graph were to add the edge.
00173  * @param head_pt head node of the edge.
00174  * @param tail_pt tail node of the edge.
00175  * @param E edge to be added with end-points head_pt and tail_pt.
00176  * Note that this function will update the accumulated weight of both
00177  * endpoints of the newly added edge according to the value stored in the
00178  * #EGsrkEdge_t::weight field.
00179  * */
00180 #define EGsrkAddEdge(lG,head_pt,tail_pt,E) ({\
00181   EGsrkNode_t*const _EGsrkH = (head_pt);\
00182   EGsrkNode_t*const _EGsrkT = (tail_pt);\
00183   EGsrkEdge_t*const _EGsrkE = (E);\
00184   EGlpNumAddTo(_EGsrkH->weight,_EGsrkE->weight);\
00185   EGlpNumAddTo(_EGsrkT->weight,_EGsrkE->weight);\
00186   EGeUgraphAddEdge(&((lG)->G),&(_EGsrkH->node),&(_EGsrkT->node),&(_EGsrkE->edge));})
00187 
00188 /* ========================================================================= */
00189 /** @brief Given two nodes in the current shrunken graph, shrunk them into one 
00190  * node.
00191  * @param G pointer to the graph where we are working
00192  * @param base first node.
00193  * @param srkN second node.
00194  * @return pointer to the new representing node.
00195  * @note We assume that the field EGsrkNode_t::hit is identically NULL for all
00196  * nodes currently in the shrunken graph (including base and srkN). 
00197  * @note We allways assume that N1 will be the representing node.
00198  * @note Take note that this structure can't get back the pointer to the srkN
00199  * node, the user should take care of that if needed.
00200  * */
00201 EGsrkNode_t *EGsrkIdentifyNodes (EGsrkGraph_t * const G,
00202                                  EGsrkNode_t * const base,
00203                                  EGsrkNode_t * const srkN);
00204 
00205 /* ========================================================================= */
00206 /** @} 
00207  * end of eg_shrink_graph.h */
00208 #endif

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