eg_shrink_graph.ex.c

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 EGsrkGraph
00022  * */
00023 /** @addtogroup EGsrkGraph */
00024 /** @{ */
00025 #include "eg_shrink_graph.h"
00026 /* ========================================================================= */
00027 /** @brief display usage of this program */
00028 static inline void srk_usage (char **argv)
00029 {
00030   fprintf (stderr, "Usage: %s input_file\n", argv[0]);
00031 }
00032 
00033 /* ========================================================================= */
00034 /** @brief given a EGsrkGraph_t structure, display the current shrunken graph
00035  * and it's node weights */
00036 static inline void display_srkG (EGsrkGraph_t * G,
00037                                  EGsrkNode_t * const all_nodes,
00038                                  EGsrkEdge_t * const all_edges)
00039 {
00040   EGeList_t *n_it,
00041    *e_it,
00042    *n_end,
00043    *e_end,
00044    *ee_it,
00045    *ee_end;
00046   EGsrkNode_t *lcn,
00047    *onode;
00048   EGsrkEdge_t *ce,
00049    *cee;
00050   EGeUgraphEP_t *cep;
00051   fprintf (stderr, "Graph %p: (%u nodes, %u edges)\n", (void *) G,
00052            G->G.n_nodes, G->G.n_edges);
00053   n_end = &(G->G.nodes);
00054   if (!EGeListIsEmpty (n_end))
00055   {
00056     fprintf (stderr, "Nodes:\n");
00057     for (n_it = n_end->next; n_it != n_end; n_it = n_it->next)
00058     {
00059       lcn = EGcontainerOf (n_it, EGsrkNode_t, node.node_cn);
00060       fprintf (stderr, "\t%d (%lf): ", lcn - all_nodes,
00061                EGlpNumToLf (lcn->weight));
00062       e_end = &(lcn->members);
00063       if (!EGeListIsEmpty (e_end))
00064       {
00065         fprintf (stderr, "(embeded nodes) ");
00066         for (e_it = e_end->next; e_it != e_end; e_it = e_it->next)
00067         {
00068           onode = EGcontainerOf (e_it, EGsrkNode_t, members);
00069           fprintf (stderr, "%d ", onode - all_nodes);
00070         }
00071       }
00072       e_end = &(lcn->node.edges);
00073       if (!EGeListIsEmpty (e_end))
00074       {
00075         fprintf (stderr, "(edges) ");
00076         for (e_it = e_end->next; e_it != e_end; e_it = e_it->next)
00077         {
00078           cep = EGcontainerOf (e_it, EGeUgraphEP_t, cn);
00079           ce = EGcontainerOf (cep, EGsrkEdge_t, edge.ep[cep->type]);
00080           fprintf (stderr, "%d[%lf] ", ce - all_edges,
00081                    EGlpNumToLf (ce->weight));
00082           ee_end = &(ce->members);
00083           if (!EGeListIsEmpty (ee_end))
00084           {
00085             fprintf (stderr, "[(embeded edges) ");
00086             for (ee_it = ee_end->next; ee_it != ee_end; ee_it = ee_it->next)
00087             {
00088               cee = EGcontainerOf (ee_it, EGsrkEdge_t, members);
00089               fprintf (stderr, "%d ", cee - all_edges);
00090             }
00091             fprintf (stderr, "] ");
00092           }
00093         }
00094       }
00095       fprintf (stderr, "\n");
00096     }
00097   }
00098 }
00099 
00100 /* ========================================================================= */
00101 /** @brief This program read a graph a file from the input whose two first 
00102  * numbers are the number of nodes and edges (we assume that the graph is
00103  * undirected ), and then a 3-tupla with head tail capacity. we use the last 
00104  * field (capacity) as the capacity of the edge. Once this graph has been
00105  * read, we create a EGsrkGraph, and then we shrink the graph until two nodes
00106  * remain. printing the graph at every iteration. */
00107 int main (int argc,
00108           char **argv)
00109 {
00110   int rval = 0,
00111     n_read;
00112   FILE *in_file = 0;
00113   unsigned register i;
00114   unsigned int head,
00115     tail;
00116   EGlpNum_t cap;
00117   EGsrkGraph_t G;
00118   EGsrkNode_t *all_nodes = 0;
00119   EGsrkEdge_t *all_edges = 0;
00120   EGsrkNode_t *N1,
00121    *N2;
00122   char l_str[1024];
00123   /* basic initialization */
00124   EGlpNumStart ();
00125   EGlpNumInitVar (cap);
00126   EGsrkGraphInit (&G);
00127   /* test we have an input file */
00128   if (argc < 2)
00129   {
00130     srk_usage (argv);
00131     rval = 1;
00132     goto CLEANUP;
00133   }
00134   in_file = fopen (argv[1], "r");
00135   if (!in_file)
00136   {
00137     fprintf (stderr, "Can't open file %s\n", argv[1]);
00138     srk_usage (argv);
00139     rval = 1;
00140     goto CLEANUP;
00141   }
00142   /* now we start reading the file */
00143   n_read = fscanf (in_file, "%u %u", &G.n_onodes, &G.n_oedges);
00144   TESTG ((rval = (n_read != 2)), CLEANUP, "couldn't read the number of nodes "
00145          "and edges");
00146   if (!G.n_oedges || !G.n_onodes)
00147   {
00148     fprintf (stderr, "n_edges %u n_nodes %u should be more than zero",
00149              G.n_oedges, G.n_onodes);
00150     G.n_oedges = G.n_onodes = 0;
00151     goto CLEANUP;
00152   }
00153   fprintf (stderr, "Reading graph on %u nodes and %u edges...",
00154            G.n_onodes, G.n_oedges);
00155   /* create all nodes and edges */
00156   all_nodes = EGsMalloc (EGsrkNode_t, G.n_onodes);
00157   all_edges = EGsMalloc (EGsrkEdge_t, G.n_oedges);
00158   for (i = G.n_onodes; i--;)
00159   {
00160     EGsrkNodeInit (all_nodes + i);
00161     EGsrkAddNode (&G, all_nodes + i);
00162   }
00163   for (i = G.n_oedges; i--;)
00164   {
00165     EGsrkEdgeInit (all_edges + i);
00166     n_read = fscanf (in_file, "%u %u %s", &head, &tail, l_str);
00167     TESTG ((rval = (n_read != 3)), CLEANUP, "couldn't read three fields");
00168     EGlpNumReadStr (cap, l_str);
00169     EGlpNumCopy (all_edges[i].weight, cap);
00170     EGsrkAddEdge (&G, all_nodes + head, all_nodes + tail, all_edges + i);
00171   }
00172   fclose (in_file);
00173   in_file = 0;
00174   fprintf (stderr, "done\n");
00175 
00176   /* now we display the graph, and shrink the two first consecutive nodes
00177    * until only two nodes remain in the shrunken graph */
00178   while (G.G.n_nodes > 2)
00179   {
00180     display_srkG (&G, all_nodes, all_edges);
00181     N1 = EGcontainerOf (G.G.nodes.next, EGsrkNode_t, node.node_cn);
00182     N2 = EGcontainerOf (N1->node.node_cn.next, EGsrkNode_t, node.node_cn);
00183     EGsrkIdentifyNodes (&G, N1, N2);
00184   }
00185   display_srkG (&G, all_nodes, all_edges);
00186   /* ending */
00187 CLEANUP:
00188   if (in_file)
00189     fclose (in_file);
00190   EGlpNumClearVar (cap);
00191   for (i = G.n_onodes; i--;)
00192     EGsrkNodeClear (all_nodes + i);
00193   for (i = G.n_oedges; i--;)
00194     EGsrkEdgeClear (all_edges + i);
00195   if (all_nodes)
00196     EGfree (all_nodes);
00197   if (all_edges)
00198     EGfree (all_edges);
00199   EGsrkGraphClear (&G);
00200   EGlpNumExit ();
00201   return rval;
00202 }
00203 
00204 
00205 /* ========================================================================= */
00206 /** @} */

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