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
1.4.5