eg_push_relabel.ex.c

This is a complete example for the min-cut max-flow problem using the push/relabel implementation offered in EGalgPR.

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 EGalgPushRelabel */
00022 /** @addtogroup EGalgPushRelabel */
00023 /** @{ */
00024 #include "eg_push_relabel.h"
00025 #include "eg_timer.h"
00026 #include <stdio.h>
00027 /* ========================================================================= */
00028 /** @brief display usage of this program */
00029 static inline void pr_usage (char **argv)
00030 {
00031   fprintf (stderr, "Usage: %s input_file\n", argv[0]);
00032 }
00033 
00034 /* ========================================================================= */
00035 /** @brief example of usage of the Preflow-Push algorithm as implemented in
00036  * (EGalgPushRelabel).
00037  * 
00038  * We read a file from the input whose two first numbers are the number of nodes
00039  * and edges (we assume that the graph is undirected ), and then a 3-tupla with
00040  * head tail capacity. we use the last field (capacity) as the capacity of the
00041  * algorithm, and compute the shortest path from node 0 to node 1. */
00042 int main (int argc,
00043           char **argv)
00044 {
00045   int rval = 0;
00046   FILE *in_file = 0;
00047   unsigned int n_nodes = 0;
00048   unsigned int n_edges = 0;
00049   unsigned int register i;
00050   unsigned int head,
00051     tail;
00052   EGlpNum_t cap;
00053   EGtimer_t cut_timer;
00054   EGalgPRgraph_t G;
00055   EGalgPRnode_t *nodes = 0,
00056    *node_pt;
00057   EGalgPRedge_t *edges = 0;
00058   EGeList_t *n_it;
00059   char l_str[1024];
00060   EGtimerReset (&cut_timer);
00061   EGlpNumStart ();
00062   EGalgPRgraphInit (&G);
00063   EGlpNumInitVar (cap);
00064   /* test we have an input file */
00065   if (argc < 2)
00066   {
00067     pr_usage (argv);
00068     rval = 1;
00069     goto CLEANUP;
00070   }
00071   in_file = fopen (argv[1], "r");
00072   if (!in_file)
00073   {
00074     fprintf (stderr, "Can't open file %s\n", argv[1]);
00075     pr_usage (argv);
00076     rval = 1;
00077     goto CLEANUP;
00078   }
00079   /* now we start reading the file */
00080   fscanf (in_file, "%u %u", &n_nodes, &n_edges);
00081   if (!n_nodes || !n_edges)
00082   {
00083     fprintf (stderr, "Problem is trivial with %u nodes and %u edges\n",
00084              n_nodes, n_edges);
00085     goto CLEANUP;
00086   }
00087   fprintf (stderr, "Reading graph on %u nodes and %u edges...", n_nodes,
00088            n_edges);
00089   nodes = EGsMalloc (EGalgPRnode_t, n_nodes);
00090   edges = EGsMalloc (EGalgPRedge_t, n_edges);
00091   for (i = n_nodes; i--;)
00092   {
00093     EGalgPRnodeInit (nodes + i);
00094     EGeDgraphAddNode (&(G.G), &(nodes[i].v));
00095   }
00096   for (i = n_edges; i--;)
00097   {
00098     EGalgPRedgeInit (edges + i);
00099     fscanf (in_file, "%u %u %s", &head, &tail, l_str);
00100     EGlpNumReadStr (cap, l_str);
00101     EGeDgraphAddEdge (&(G.G),
00102                       &(nodes[head].v), &(nodes[tail].v), &(edges[i].fw.e));
00103     EGeDgraphAddEdge (&(G.G),
00104                       &(nodes[tail].v), &(nodes[head].v), &(edges[i].bw.e));
00105     EGlpNumCopy (edges[i].fw.u, cap);
00106     EGlpNumCopy (edges[i].bw.u, cap);
00107   }
00108   fclose (in_file);
00109   in_file = 0;
00110   fprintf (stderr, "...done\nComputing Min Cut 0 %u:", n_nodes >> 1);
00111 
00112   /* now we call the min cut algorithm */
00113   EGtimerStart (&cut_timer);
00114   rval = EGalgPRminSTcut (&G, nodes, nodes + (n_nodes >> 1));
00115   EGtimerStop (&cut_timer);
00116   fprintf (stderr, "...done in %lf seconds\n", cut_timer.time);
00117   /* now display all nodes in the cut */
00118 #if 1
00119   fprintf (stderr, "Minimum Cut: ");
00120   for (n_it = G.G.nodes.next; n_it != &(G.G.nodes); n_it = n_it->next)
00121   {
00122     node_pt = EGcontainerOf (n_it, EGalgPRnode_t, v.node_cn);
00123     if (node_pt->d < G.G.n_nodes)
00124       fprintf (stderr, "%u ", (unsigned) (node_pt - nodes));
00125   }
00126   fprintf (stderr, "\n");
00127 #endif
00128   fprintf (stderr, "Computing max flow...");
00129   EGtimerReset (&cut_timer);
00130   EGtimerStart (&cut_timer);
00131   rval = EGalgPRmaxSTflow (&G, nodes, nodes + (n_nodes >> 1));
00132   EGtimerStop (&cut_timer);
00133   fprintf (stderr, "...done in %lf seconds\n", cut_timer.time);
00134   /* now we print the value of the cut */
00135   fprintf (stderr, "Minimum Cut Capacity %lf\n",
00136            EGlpNumToLf (nodes[n_nodes >> 1].e));
00137   /* check the solution */
00138   rval = EGalgPRoptimalityTest (&G, nodes, nodes + (n_nodes >> 1), &cap);
00139   TESTG (rval, CLEANUP, "Worst error %lg, standard expected error %lg,"
00140          " number of errors %d", EGlpNumToLf (cap), EGlpNumToLf (epsLpNum),
00141          rval);
00142   CHECKRVALG (rval, CLEANUP);
00143 
00144   /* ending */
00145 CLEANUP:
00146   if (in_file)
00147     fclose (in_file);
00148   EGlpNumClearVar (cap);
00149   EGalgPRgraphClear (&G);
00150   for (i = n_nodes; i--;)
00151     EGalgPRnodeClear (nodes + i);
00152   for (i = n_edges; i--;)
00153     EGalgPRedgeClear (edges + i);
00154   EGfree (nodes);
00155   EGfree (edges);
00156   EGlpNumExit ();
00157   EGalgPRprofile;
00158   return rval;
00159 }
00160 
00161 /* ========================================================================= */
00162 /** @} */

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