double MtxLP::getRowLB(string name)const{ return get_row_lb(nrow(name)); }
void *lpx_create_cog(LPX *lp) { struct COG *cog = NULL; int m, n, nb, i, j, p, q, len, *ind, *vert, *orig; double L, U, lf_min, lf_max, *val; xprintf("Creating the conflict graph...\n"); m = lpx_get_num_rows(lp); n = lpx_get_num_cols(lp); /* determine which binary variables should be included in the conflict graph */ nb = 0; vert = xcalloc(1+n, sizeof(int)); for (j = 1; j <= n; j++) vert[j] = 0; orig = xcalloc(1+n, sizeof(int)); ind = xcalloc(1+n, sizeof(int)); val = xcalloc(1+n, sizeof(double)); for (i = 1; i <= m; i++) { L = get_row_lb(lp, i); U = get_row_ub(lp, i); if (L == -DBL_MAX && U == +DBL_MAX) continue; len = lpx_get_mat_row(lp, i, ind, val); if (len > MAX_ROW_LEN) continue; lf_min = eval_lf_min(lp, len, ind, val); lf_max = eval_lf_max(lp, len, ind, val); for (p = 1; p <= len; p++) { if (!is_binary(lp, ind[p])) continue; for (q = p+1; q <= len; q++) { if (!is_binary(lp, ind[q])) continue; if (probing(len, val, L, U, lf_min, lf_max, p, 0, q) || probing(len, val, L, U, lf_min, lf_max, p, 1, q)) { /* there is a logical relation */ /* include the first variable in the graph */ j = ind[p]; if (vert[j] == 0) nb++, vert[j] = nb, orig[nb] = j; /* incude the second variable in the graph */ j = ind[q]; if (vert[j] == 0) nb++, vert[j] = nb, orig[nb] = j; } } } } /* if the graph is either empty or has too many vertices, do not create it */ if (nb == 0 || nb > MAX_NB) { xprintf("The conflict graph is either empty or too big\n"); xfree(vert); xfree(orig); goto done; } /* create the conflict graph */ cog = xmalloc(sizeof(struct COG)); cog->n = n; cog->nb = nb; cog->ne = 0; cog->vert = vert; cog->orig = orig; len = nb + nb; /* number of vertices */ len = (len * (len - 1)) / 2; /* number of entries in triangle */ len = (len + (CHAR_BIT - 1)) / CHAR_BIT; /* bytes needed */ cog->a = xmalloc(len); memset(cog->a, 0, len); for (j = 1; j <= nb; j++) { /* add edge between variable and its complement */ lpx_add_cog_edge(cog, +orig[j], -orig[j]); } for (i = 1; i <= m; i++) { L = get_row_lb(lp, i); U = get_row_ub(lp, i); if (L == -DBL_MAX && U == +DBL_MAX) continue; len = lpx_get_mat_row(lp, i, ind, val); if (len > MAX_ROW_LEN) continue; lf_min = eval_lf_min(lp, len, ind, val); lf_max = eval_lf_max(lp, len, ind, val); for (p = 1; p <= len; p++) { if (!is_binary(lp, ind[p])) continue; for (q = p+1; q <= len; q++) { if (!is_binary(lp, ind[q])) continue; /* set x[p] to 0 and examine x[q] */ switch (probing(len, val, L, U, lf_min, lf_max, p, 0, q)) { case 0: /* no logical relation */ break; case 1: /* x[p] = 0 implies x[q] = 0 */ lpx_add_cog_edge(cog, -ind[p], +ind[q]); break; case 2: /* x[p] = 0 implies x[q] = 1 */ lpx_add_cog_edge(cog, -ind[p], -ind[q]); break; default: xassert(lp != lp); } /* set x[p] to 1 and examine x[q] */ switch (probing(len, val, L, U, lf_min, lf_max, p, 1, q)) { case 0: /* no logical relation */ break; case 1: /* x[p] = 1 implies x[q] = 0 */ lpx_add_cog_edge(cog, +ind[p], +ind[q]); break; case 2: /* x[p] = 1 implies x[q] = 1 */ lpx_add_cog_edge(cog, +ind[p], -ind[q]); break; default: xassert(lp != lp); } } } } xprintf("The conflict graph has 2*%d vertices and %d edges\n", cog->nb, cog->ne); done: xfree(ind); xfree(val); return cog; }