Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
0
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;
}