eg_2pchecker.c

Go to the documentation of this file.
00001 #include "eg_2pchecker.h"
00002 /* this function check a 2-Pie constraint, and return its violation (negative if
00003  * it is not violated) and the coefficient of each edges in each constraint in
00004  * the double array e_coeff (that should have been alocated before calling this
00005  * function */
00006 int EG2pChecker (int const nnodes,
00007                  int const nedges,
00008                  int const *const edges,
00009                  double const *const weight,
00010                  int const n_ineq,
00011                  int const *const n2_dom,
00012                  int **const n_Aset,
00013                  int **const n_Bset,
00014                  int **const n_Tset,
00015                  int const *const n_Ahandle,
00016                  int const *const n_Bhandle,
00017                  int ***const Aset,
00018                  int ***const Bset,
00019                  int ***const Tset,
00020                  int **const Ahandle,
00021                  int **const Bhandle,
00022                  double *const violation,
00023                  int **const e_coeff)
00024 {
00025   /* local variables */
00026   register int i,
00027     j;
00028   int rval = 0,
00029     cur_const;
00030   unsigned char *node_marks = 0,
00031    *edge_parity = 0;
00032   unsigned int n_adom,
00033     n_bdom;
00034   unsigned int values[8];
00035 
00036   /* basic tests */
00037   TESTG ((rval = !nnodes), CLEANUP, "nnodes is zero");
00038   TESTG ((rval = !nedges), CLEANUP, "nedges is zero");
00039 
00040   /* looking for memory */
00041   node_marks = EGsMalloc (unsigned char, nnodes);
00042   edge_parity = EGsMalloc (unsigned char, nedges);
00043 
00044   /* we loop through all inequalities */
00045   for (cur_const = n_ineq; cur_const--;)
00046   {
00047     /* reset the edges coefficients to zero */
00048     memset (e_coeff[cur_const], 0, sizeof (int) * nedges);
00049     memset (edge_parity, 0, sizeof (unsigned char) * nedges);
00050     n_bdom = n_adom = 0;
00051     violation[cur_const] = -2.0;
00052 
00053     /* loop through all 2-dominoes and start setting coefficients of the edges
00054      * and count n_xdom */
00055     for (i = n2_dom[cur_const]; i--;)
00056     {
00057       memset (node_marks, 0, sizeof (unsigned char) * nnodes);
00058       /* first set marks of nodes */
00059       violation[cur_const] -= 2.0;
00060       TESTG ((rval = (!n_Tset[cur_const][i])), CLEANUP,
00061              "2-pie %d of constraint %d is empty %d", i, cur_const,
00062              n_Tset[cur_const][i]);
00063       TESTG ((rval = (n_Tset[cur_const][i] == nnodes)), CLEANUP,
00064              "T_%u is not a propper set", i);
00065       TESTG ((rval = (n_Tset[cur_const][i] <= n_Aset[cur_const][i])),
00066              CLEANUP, "A_%u is not a propper set of T", i);
00067       TESTG ((rval = (n_Tset[cur_const][i] <= n_Bset[cur_const][i])),
00068              CLEANUP, "B_%u is not a propper set of T", i);
00069       for (j = n_Tset[cur_const][i]; j--;)
00070         node_marks[Tset[cur_const][i][j]] |= 1U;
00071       /* now set marks due to A-partition */
00072       if (n_Aset[cur_const][i])
00073       {
00074         n_adom++;
00075         violation[cur_const] -= 1.0;
00076         for (j = n_Aset[cur_const][i]; j--;)
00077         {
00078           TESTG ((rval = !(node_marks[Aset[cur_const][i][j]] & 1U)), CLEANUP,
00079                  "Node in Aset not in T");
00080           node_marks[Aset[cur_const][i][j]] |= 2U;
00081         }
00082       }
00083       /* now set marks due to B-partition */
00084       if (n_Bset[cur_const][i])
00085       {
00086         n_bdom++;
00087         violation[cur_const] -= 1.0;
00088         for (j = n_Bset[cur_const][i]; j--;)
00089         {
00090           TESTG ((rval = !(node_marks[Bset[cur_const][i][j]] & 1U)), CLEANUP,
00091                  "Node in Bset not in T");
00092           node_marks[Bset[cur_const][i][j]] |= 4U;
00093         }
00094       }
00095       /* now we check that if this is a 2-domino, we have a 3-partition */
00096       if (n_Aset[cur_const][i] && n_Bset[cur_const][i])
00097       {
00098         memset (values, 0, sizeof (values));
00099         for (j = n_Tset[cur_const][i]; j--;)
00100           values[node_marks[Tset[cur_const][i][j]]]++;
00101         for (j = 1; j < 8; j++)
00102           values[0] += values[j] ? 1U : 0U;
00103         TESTG ((rval = (values[0] < 3)), CLEANUP, "2-domino %u is only a %u"
00104                " partition", i, values[0]);
00105 
00106       }
00107       /* now we loop through the edges and set up their coefficients and
00108        * parities accordingly, also update the violation */
00109       for (j = nedges; j--;)
00110       {
00111         /* edges in Delta(T) */
00112         if ((node_marks[edges[j << 1]] & 1U) !=
00113             (node_marks[edges[(j << 1) | 1]] & 1U))
00114         {
00115           violation[cur_const] += weight[j];
00116           e_coeff[cur_const][j] += 1;
00117         }
00118         /* edges in E(A:T\A) */
00119         if (((node_marks[edges[j << 1]] & 1U)
00120              && (node_marks[edges[(j << 1) | 1]] & 1U))
00121             && ((node_marks[edges[j << 1]] & 2U) !=
00122                 (node_marks[edges[(j << 1) | 1]] & 2U)))
00123         {
00124           violation[cur_const] += weight[j];
00125           e_coeff[cur_const][j] += 1;
00126           edge_parity[j] ^= 1U;
00127         }
00128         /* edges in E(B:T\B) */
00129         if (((node_marks[edges[j << 1]] & 1U)
00130              && (node_marks[edges[(j << 1) | 1]] & 1U))
00131             && ((node_marks[edges[j << 1]] & 4U) !=
00132                 (node_marks[edges[(j << 1) | 1]] & 4U)))
00133         {
00134           violation[cur_const] += weight[j];
00135           e_coeff[cur_const][j] += 1;
00136           edge_parity[j] ^= 2U;
00137         }
00138       }                         /* end setting coefficients for this 2-pie */
00139     }                           /* end for 2pies of the inequalities */
00140 
00141     /* check parity of dominoes for both handles */
00142     TESTG ((rval = !(n_adom & 1U)), CLEANUP, "A-dominos is even, nadom %u, nbdom %u", n_adom, n_bdom);
00143     TESTG ((rval = !(n_bdom & 1U)), CLEANUP, "B-dominos is even, nbdom %u, nadom %u", n_bdom, n_adom);
00144     memset (node_marks, 0, sizeof (unsigned char) * nnodes);
00145 
00146     /* now we set marks for handles in nodes */
00147     
00148     WARNING((!n_Ahandle[cur_const] || (n_Ahandle[cur_const]==nnodes)), 
00149     "Handle A of constraint %d is empty", cur_const);
00150     for (i = n_Ahandle[cur_const]; i--;)
00151       node_marks[Ahandle[cur_const][i]] |= 1U;
00152     WARNING((!n_Bhandle[cur_const] || (n_Bhandle[cur_const]==nnodes)), 
00153     "Handle B of constraint %d is empty", cur_const);
00154     for (i = n_Bhandle[cur_const]; i--;)
00155       node_marks[Bhandle[cur_const][i]] |= 2U;
00156 
00157     /* now check parity of all edges in Delta(Handle_i) and add coefficients
00158      * accordingly */
00159     for (i = nedges; i--;)
00160     {
00161       /* check if the parity for handle A */
00162       if (((node_marks[edges[i << 1]] & 1U) !=
00163            (node_marks[edges[(i << 1) | 1]] & 1U)) && !(edge_parity[i] & 1U))
00164       {
00165         violation[cur_const] += weight[i];
00166         e_coeff[cur_const][i] += 1;
00167       }
00168       if (((node_marks[edges[i << 1]] & 1U) ==
00169            (node_marks[edges[(i << 1) | 1]] & 1U)) && (edge_parity[i] & 1U))
00170       {
00171         violation[cur_const] += weight[i];
00172         e_coeff[cur_const][i] += 1;
00173       }
00174       /* check if the parity for handle B */
00175       if (((node_marks[edges[i << 1]] & 2U) !=
00176            (node_marks[edges[(i << 1) | 1]] & 2U)) && !(edge_parity[i] & 2U))
00177       {
00178         violation[cur_const] += weight[i];
00179         e_coeff[cur_const][i] += 1;
00180       }
00181       if (((node_marks[edges[i << 1]] & 2U) ==
00182            (node_marks[edges[(i << 1) | 1]] & 2U)) && (edge_parity[i] & 2U))
00183       {
00184         violation[cur_const] += weight[i];
00185         e_coeff[cur_const][i] += 1;
00186       }
00187     }                           /* end loop through edges setting up parity for handles */
00188   }                             /* end loop through all inequalities */
00189 
00190   /* ending */
00191 CLEANUP:
00192   if (node_marks)
00193     EGfree (node_marks);
00194   if (edge_parity)
00195     EGfree (edge_parity);
00196   return rval;
00197 }

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