eg_1pchecker.c

Go to the documentation of this file.
00001 #include "eg_1pchecker.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 EG1pChecker (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 n_dom,
00012                  int *const *const n_Aset,
00013                  int *const *const n_Bset,
00014                  int const *const n_handle,
00015                  int **const *const Aset,
00016                  int **const *const Bset,
00017                  int *const *const handle,
00018                  double *const violation,
00019                  int *const *const e_coeff)
00020 {
00021   /* local variables */
00022   register int i,
00023     j;
00024   int rval = 0,
00025     cur_const;
00026   unsigned char *node_marks = 0,
00027    *edge_parity = 0;
00028 
00029   /* basic tests */
00030   TESTG ((rval = !nnodes), CLEANUP, "nnodes is zero");
00031   TESTG ((rval = !nedges), CLEANUP, "nedges is zero");
00032 
00033   /* looking for memory */
00034   node_marks = EGsMalloc (unsigned char,
00035                           nnodes);
00036   edge_parity = EGsMalloc (unsigned char,
00037                            nedges);
00038 
00039   /* we loop through all inequalities */
00040   for (cur_const = n_ineq; cur_const--;)
00041   {
00042     /* reset the edges coefficients to zero */
00043     memset (e_coeff[cur_const], 0, sizeof (int) * nedges);
00044     memset (edge_parity, 0, sizeof (unsigned char) * nedges);
00045     violation[cur_const] = -1.0;
00046 
00047     /* loop through all dominoes and start setting coefficients of the edges
00048      * and count n_xdom */
00049     for (i = n_dom[cur_const]; i--;)
00050     {
00051 
00052       /* first set marks of nodes */
00053       memset (node_marks, 0, sizeof (unsigned char) * nnodes);
00054       violation[cur_const] -= 3.0;
00055       TESTG ((rval =
00056               ((!n_Aset[cur_const][i])
00057                && (!n_Bset[cur_const][i]))), CLEANUP,
00058              "domino %d of constraint %d is empty", i, cur_const);
00059 
00060       /* now set marks due to A-partition */
00061       if (n_Aset[cur_const][i])
00062       {
00063         for (j = n_Aset[cur_const][i]; j--;)
00064         {
00065           node_marks[Aset[cur_const][i][j]] |= 1U;
00066           node_marks[Aset[cur_const][i][j]] |= 2U;
00067         }
00068       }
00069 
00070       /* now set marks due to B-partition */
00071       if (n_Bset[cur_const][i])
00072       {
00073         for (j = n_Bset[cur_const][i]; j--;)
00074         {
00075           TESTG ((rval =
00076                   node_marks[Bset[cur_const][i][j]]), CLEANUP,
00077                  "domino %d of constraint %d is such that A and B are non-disjoint",
00078                  i, cur_const);
00079           node_marks[Bset[cur_const][i][j]] |= 1U;
00080           node_marks[Bset[cur_const][i][j]] |= 4U;
00081         }
00082       }
00083 
00084       /* now we loop through the edges and set up their coefficients and
00085        * parities accordingly, also update the violation */
00086       for (j = nedges; j--;)
00087       {
00088         /* edges in Delta(T) */
00089         if ((node_marks[edges[j << 1]] & 1U) !=
00090             (node_marks[edges[(j << 1) | 1]] & 1U))
00091         {
00092           violation[cur_const] += weight[j];
00093           e_coeff[cur_const][j] += 1;
00094         }
00095         /* edges in E(A:B) */
00096         if (((node_marks[edges[j << 1]] & 1U)
00097              && (node_marks[edges[(j << 1) | 1]] & 1U))
00098             && ((node_marks[edges[j << 1]] & 2U) !=
00099                 (node_marks[edges[(j << 1) | 1]] & 2U)))
00100         {
00101           violation[cur_const] += weight[j];
00102           e_coeff[cur_const][j] += 1;
00103           edge_parity[j] ^= 1U;
00104         }
00105       }                         /* end setting coefficients for this 2-pie */
00106     }                           /* end for 2pies of the inequalities */
00107 
00108     /* check parity of dominoes for both handles */
00109     TESTG ((rval =
00110             !(n_dom[cur_const] & 1U)), CLEANUP, "number of dominoes is even");
00111 
00112     /* now we set marks for handles in nodes */
00113     memset (node_marks, 0, sizeof (unsigned char) * nnodes);
00114 
00115     /*
00116      * WARNING((!n_handle[cur_const]), 
00117      * "Handle of constraint %d is empty", cur_const);
00118      */
00119 
00120     for (i = n_handle[cur_const]; i--;)
00121       node_marks[handle[cur_const][i]] |= 1U;
00122 
00123     /* now check parity of all edges in Delta(Handle_i) and add coefficients
00124      * accordingly */
00125     for (i = nedges; i--;)
00126     {
00127       /* check the parity for the handle */
00128       if (((node_marks[edges[i << 1]] & 1U) !=
00129            (node_marks[edges[(i << 1) | 1]] & 1U)) && !(edge_parity[i] & 1U))
00130       {
00131         violation[cur_const] += weight[i];
00132         e_coeff[cur_const][i] += 1;
00133       }
00134       if (((node_marks[edges[i << 1]] & 1U) ==
00135            (node_marks[edges[(i << 1) | 1]] & 1U)) && (edge_parity[i] & 1U))
00136       {
00137         violation[cur_const] += weight[i];
00138         e_coeff[cur_const][i] += 1;
00139       }
00140     }                           /* end loop through edges setting up parity for handles */
00141   }                             /* end loop through all inequalities */
00142 
00143   /* ending */
00144 CLEANUP:
00145   if (node_marks)
00146     EGfree (node_marks);
00147   if (edge_parity)
00148     EGfree (edge_parity);
00149   return rval;
00150 }

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