int cfg_expand_clique(CFG *G, int c_len, int c_ind[]) { int nv = G->nv; int d_len, *d_ind, *d_pos, len, *ind; int k, v; xassert(0 <= c_len && c_len <= nv); /* allocate working arrays */ d_ind = talloc(1+nv, int); d_pos = talloc(1+nv, int); ind = talloc(1+nv, int); /* initialize C := 0, D := V */ d_len = nv; for (k = 1; k <= nv; k++) d_ind[k] = d_pos[k] = k; /* expand C by vertices of specified initial clique C0 */ for (k = 1; k <= c_len; k++) { /* v in C0 */ v = c_ind[k]; xassert(1 <= v && v <= nv); /* since C0 is clique, v should be in D */ xassert(d_pos[v] != 0); /* W := set of vertices adjacent to v */ len = cfg_get_adjacent(G, v, ind); /* D := D inter W */ d_len = intersection(d_len, d_ind, d_pos, len, ind); /* since v not in W, now v should be not in D */ xassert(d_pos[v] == 0); } /* expand C by some other vertices until D is empty */ while (d_len > 0) { /* v in D */ v = d_ind[1]; xassert(1 <= v && v <= nv); /* note that v is adjacent to all vertices in C (by design), * so add v to C */ c_ind[++c_len] = v; /* W := set of vertices adjacent to v */ len = cfg_get_adjacent(G, v, ind); /* D := D inter W */ d_len = intersection(d_len, d_ind, d_pos, len, ind); /* since v not in W, now v should be not in D */ xassert(d_pos[v] == 0); } /* free working arrays */ tfree(d_ind); tfree(d_pos); tfree(ind); /* bring maximal clique to calling routine */ return c_len; }
static int sub_adjacent(struct csa *csa, int i, int adj[]) { /* retrieve vertices of induced subgraph adjacent to specified * vertex */ CFG *G = csa->G; int nv = G->nv; int *ind = csa->ind; int nn = csa->nn; int *vtoi = csa->vtoi; int *itov = csa->itov; int j, k, v, w, len, len1; /* determine original vertex v corresponding to vertex i */ xassert(1 <= i && i <= nn); v = itov[i]; /* retrieve vertices adjacent to vertex v in original graph */ len1 = cfg_get_adjacent(G, v, ind); /* keep only adjacent vertices which are in induced subgraph and * change their numbers appropriately */ len = 0; for (k = 1; k <= len1; k++) { /* there exists edge (v, w) in original graph */ w = ind[k]; xassert(1 <= w && w <= nv && w != v); j = vtoi[w]; if (j != 0) { /* vertex w is vertex j in induced subgraph */ xassert(1 <= j && j <= nn && j != i); adj[++len] = j; } } return len; }
void cfg_check_clique(CFG *G, int c_len, const int c_ind[]) { int nv = G->nv; int k, kk, v, w, len, *ind; char *flag; ind = talloc(1+nv, int); flag = talloc(1+nv, char); memset(&flag[1], 0, nv); /* walk thru clique vertices */ xassert(c_len >= 0); for (k = 1; k <= c_len; k++) { /* get clique vertex v */ v = c_ind[k]; xassert(1 <= v && v <= nv); /* get vertices adjacent to vertex v */ len = cfg_get_adjacent(G, v, ind); for (kk = 1; kk <= len; kk++) { w = ind[kk]; xassert(1 <= w && w <= nv); xassert(w != v); flag[w] = 1; } /* check that all clique vertices other than v are adjacent to v */ for (kk = 1; kk <= c_len; kk++) { w = c_ind[kk]; xassert(1 <= w && w <= nv); if (w != v) xassert(flag[w]); } /* reset vertex flags */ for (kk = 1; kk <= len; kk++) flag[ind[kk]] = 0; } tfree(ind); tfree(flag); return; }
static void build_subgraph(struct csa *csa) { /* build induced subgraph */ glp_prob *P = csa->P; int n = P->n; CFG *G = csa->G; int *ind = csa->ind; int *pos = G->pos; int *neg = G->neg; int nv = G->nv; int *ref = G->ref; int *vtoi = csa->vtoi; int *itov = csa->itov; double *wgt = csa->wgt; int j, k, v, w, nn, len; double z, sum; /* initially induced subgraph is empty */ nn = 0; /* walk thru vertices of original conflict graph */ for (v = 1; v <= nv; v++) { /* determine value of binary variable z[j] that corresponds to * vertex v */ j = ref[v]; xassert(1 <= j && j <= n); if (pos[j] == v) { /* z[j] = x[j], where x[j] is original variable */ z = P->col[j]->prim; } else if (neg[j] == v) { /* z[j] = 1 - x[j], where x[j] is original variable */ z = 1.0 - P->col[j]->prim; } else xassert(v != v); /* if z[j] is close to zero, do not include v in the induced * subgraph */ if (z < 0.001) { vtoi[v] = 0; continue; } /* calculate cumulative weight of vertex v */ sum = z; /* walk thru all vertices adjacent to v */ len = cfg_get_adjacent(G, v, ind); for (k = 1; k <= len; k++) { /* there is an edge (v,w) in the conflict graph */ w = ind[k]; xassert(w != v); /* add value of z[j] that corresponds to vertex w */ j = ref[w]; xassert(1 <= j && j <= n); if (pos[j] == w) sum += P->col[j]->prim; else if (neg[j] == w) sum += 1.0 - P->col[j]->prim; else xassert(w != w); } /* cumulative weight of vertex v is an upper bound of weight * of any clique containing v; so if it not greater than 1, do * not include v in the induced subgraph */ if (sum < 1.010) { vtoi[v] = 0; continue; } /* include vertex v in the induced subgraph */ nn++; vtoi[v] = nn; itov[nn] = v; wgt[nn] = z; } /* induced subgraph has been built */ csa->nn = nn; return; }