cookInterface.c

Go to the documentation of this file.
00001 /* Copyright (c) 2005 by John M. Boyer, All Rights Reserved.  Please see
00002  * License.txt for use and redistribution license. */
00003 #include "cookInterface.h"
00004 
00005 /* Load a graph in Cook Format */
00006 int loadCookGraph (char *file_name,
00007                    int *nnodes,
00008                    int *nedges,
00009                    int **edges,
00010                    double **weight)
00011 {
00012   int i,
00013     h,
00014     t;
00015   double w;
00016   FILE *file;
00017   file = fopen (file_name, "r");
00018   TEST (!file, "error opening file");
00019   fscanf (file, "%d %d", nnodes, nedges);
00020   (*edges) = (int *) malloc (sizeof (int) * (*nedges) * 2);
00021   TEST (!(*edges), "error allocating memory");
00022   if (weight)
00023     (*weight) = (double *) malloc (sizeof (double) * (*nedges));
00024   for (i = 0; i < *nedges; i++)
00025 
00026   {
00027     fscanf (file, "%d %d %lf", &h, &t, &w);
00028     (*edges)[2 * i] = h;
00029     (*edges)[2 * i + 1] = t;
00030     if (weight)
00031       (*weight)[i] = w;
00032   }
00033   fclose (file);
00034   return 0;
00035 }
00036 
00037 
00038 /* Input a graph in Bill Cook Format */
00039 int cook2boyerGraph (graphP bGraph,
00040                      int nnodes,
00041                      int nedges,
00042                      int *edges)
00043 {
00044   int i,
00045     rval = 0;
00046   rval = gp_InitGraph (bGraph, nnodes);
00047   for (i = 0; i < nedges && !rval; i++)
00048     if (!gp_IsNeighbor (bGraph, edges[2 * i], edges[2 * i + 1]))
00049 
00050     {
00051       rval = gp_AddEdgeWid (bGraph, edges[2 * i], 1, edges[2 * i + 1], 1, i);
00052       TEST (rval, "error converting graph");
00053     }
00054   return rval;
00055 }
00056 
00057 
00058 /********************************************************************
00059  gp_AddEdgeWid()
00060  Adds the undirected edge (u,v) to the graph by placing edge records
00061  representing u into v's circular edge record list and v into u's
00062  circular edge record list.
00063 
00064  upos receives the location in G where the u record in v's list will be
00065         placed, and vpos is the location in G of the v record we placed in
00066  u's list.  These are used to initialize the short circuit links.
00067 
00068  ulink (0|1) indicates whether the edge record to v in u's list should
00069         become adjacent to u by its 0 or 1 link, i.e. u[ulink] == vpos.
00070  vlink (0|1) indicates whether the edge record to u in v's list should
00071         become adjacent to v by its 0 or 1 link, i.e. v[vlink] == upos.
00072 
00073  ********************************************************************/
00074 int gp_AddEdgeWid (graphP theGraph,
00075                    int u,
00076                    int ulink,
00077                    int v,
00078                    int vlink,
00079                    int id)
00080 {
00081   int upos,
00082     vpos;
00083   if (theGraph == NULL || u < 0 || v < 0 || u >= 2 * theGraph->N
00084       || v >= 2 * theGraph->N)
00085 
00086   {
00087     __EG_PRINTLOC2__;
00088     return NOTOK;
00089   }
00090 
00091   /* We enforce the edge limit */
00092   if (theGraph->M >= EDGE_LIMIT * theGraph->N)
00093 
00094   {
00095     __EG_PRINTLOC2__;
00096     return NONEMBEDDABLE;
00097   }
00098   vpos = 2 * theGraph->N + 2 * theGraph->M;
00099   upos = gp_GetTwinArc (theGraph, vpos);
00100   _AddArcWid (theGraph, u, v, vpos, ulink, id);
00101   _AddArcWid (theGraph, v, u, upos, vlink, id);
00102   theGraph->M++;
00103   return OK;
00104 }
00105 
00106 
00107 /********************************************************************
00108  _AddArcWid()
00109  This routine adds arc (u,v) to u's edge list, storing the record for
00110  v at position arcPos.  The record is either added to the link[0] or
00111  link[1] side of vertex u, depending on the link parameter.
00112  The links of a vertex record can be viewed as previous (link[0]) and
00113  next (link[1]) pointers.  Thus, an edge record is appended to u's
00114  list by hooking it to u.link[0], and it is prepended by hooking it
00115  to u.link[1].  The use of exclusive-or (i.e. 1^link) is simply to get
00116  the other link (if link is 0 then 1^link is 1, and vice versa).
00117  ********************************************************************/
00118 void _AddArcWid (graphP theGraph,
00119                  int u,
00120                  int v,
00121                  int arcPos,
00122                  int link,
00123                  int id)
00124 {
00125   theGraph->G[arcPos].id = id;
00126   theGraph->G[arcPos].v = v;
00127   if (theGraph->G[u].link[0] == NIL)
00128 
00129   {
00130     theGraph->G[u].link[0] = theGraph->G[u].link[1] = arcPos;
00131     theGraph->G[arcPos].link[0] = theGraph->G[arcPos].link[1] = u;
00132   }
00133 
00134   else
00135 
00136   {
00137     int u0 = theGraph->G[u].link[link];
00138     theGraph->G[arcPos].link[link] = u0;
00139     theGraph->G[arcPos].link[1 ^ link] = u;
00140     theGraph->G[u].link[link] = arcPos;
00141     theGraph->G[u0].link[1 ^ link] = arcPos;
00142   }
00143 }
00144 
00145 
00146 /* */
00147 int extractCookEdgeIds (graphP theGraph,
00148                         int *nmnodes,
00149                         int *nmedges,
00150                         int *medges)
00151 {
00152   int I,
00153     J,
00154     cnt = 0;
00155   if (theGraph == NULL)
00156     return NOTOK;
00157   *nmnodes = theGraph->N;
00158   *nmedges = theGraph->M;
00159   for (I = 0; I < theGraph->N; I++)
00160 
00161   {
00162     J = theGraph->G[I].link[1];
00163     while (J >= theGraph->N)
00164 
00165     {
00166       if (theGraph->G[J].v > I)
00167         medges[cnt++] = theGraph->G[J].id;
00168       J = theGraph->G[J].link[1];
00169     }
00170   }
00171   return OK;
00172 }
00173 
00174 int DPprintEmbed (graphP theGraph,
00175                   FILE * file)
00176 {
00177 
00178   /* local variables */
00179   int I,
00180     J;
00181 
00182   /* check integrity */
00183   if (theGraph == NULL || file == NULL)
00184     return NOTOK;
00185 
00186   /* loop through the nodes and print the adjacency list for them (in embed
00187    * order if we have called gp_Embed and return OK ) */
00188   fprintf (file, "N=%d\n", theGraph->N);
00189   for (I = 0; I < theGraph->N; I++)
00190 
00191   {
00192     fprintf (file, "%d:", I);
00193     J = theGraph->G[I].link[1];
00194 
00195     /* print the adjcency list for the current node */
00196     while (J >= theGraph->N)
00197 
00198     {
00199       fprintf (file, " %d", theGraph->G[J].v);
00200       J = theGraph->G[J].link[1];
00201     }
00202     fprintf (file, " %d\n", NIL);
00203   }
00204   return OK;
00205 }

Generated on Thu Oct 20 14:58:40 2005 for DominoParitySeparator by  doxygen 1.4.5