00001 #include "eg_2pchecker.h"
00002
00003
00004
00005
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
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
00037 TESTG ((rval = !nnodes), CLEANUP, "nnodes is zero");
00038 TESTG ((rval = !nedges), CLEANUP, "nedges is zero");
00039
00040
00041 node_marks = EGsMalloc (unsigned char, nnodes);
00042 edge_parity = EGsMalloc (unsigned char, nedges);
00043
00044
00045 for (cur_const = n_ineq; cur_const--;)
00046 {
00047
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
00054
00055 for (i = n2_dom[cur_const]; i--;)
00056 {
00057 memset (node_marks, 0, sizeof (unsigned char) * nnodes);
00058
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
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
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
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
00108
00109 for (j = nedges; j--;)
00110 {
00111
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
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
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 }
00139 }
00140
00141
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
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
00158
00159 for (i = nedges; i--;)
00160 {
00161
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
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 }
00188 }
00189
00190
00191 CLEANUP:
00192 if (node_marks)
00193 EGfree (node_marks);
00194 if (edge_parity)
00195 EGfree (edge_parity);
00196 return rval;
00197 }