static int makeusercuts (CPXENVptr env, CPXLPptr lp, CUTINFOptr usercutinfo) { int status = 0; CPXNNZ beg[] = {0, 2, 4, 6, 16, 26, 36, 46, 56}; double val[] = {1, -1, 1, -1, 1, -1, 2.08, 2.98, 3.47, 2.24, 2.08, 0.25, 0.25, 0.25, 0.25, 0.25, 2.08, 2.98, 3.47, 2.24, 2.08, 0.25, 0.25, 0.25, 0.25, 0.25, 2.08, 2.98, 3.47, 2.24, 2.08, 0.25, 0.25, 0.25, 0.25, 0.25, 2.08, 2.98, 3.47, 2.24, 2.08, 0.25, 0.25, 0.25, 0.25, 0.25, 2.08, 2.98, 3.47, 2.24, 2.08, 0.25, 0.25, 0.25, 0.25, 0.25}; char const *varname[] = {"X21", "X22", "X22", "X23", "X23", "X24", "X11", "X21", "X31", "X41", "X51", "W11", "W21", "W31", "W41", "W51", "X12", "X22", "X32", "X42", "X52", "W12", "W22", "W32", "W42", "W52", "X13", "X23", "X33", "X43", "X53", "W13", "W23", "W33", "W43", "W53", "X14", "X24", "X34", "X44", "X54", "W14", "W24", "W34", "W44", "W54", "X15", "X25", "X35", "X45", "X55", "W15", "W25", "W35", "W45", "W55"}; double rhs[] = {0, 0, 0, 20.25, 20.25, 20.25, 20.25, 16.25}; CPXNNZ *cutbeg = NULL; CPXDIM *cutind = NULL; double *cutval = NULL; double *cutrhs = NULL; CPXDIM i, varind; CPXNNZ nz = 56; CPXDIM cuts = 8; CPXDIM cur_numcols = CPXXgetnumcols (env, lp); usercutinfo->lp = lp; usercutinfo->numcols = cur_numcols; usercutinfo->x = malloc (cur_numcols * sizeof (*usercutinfo->x)); if ( usercutinfo->x == NULL ) { fprintf (stderr, "No memory for solution values.\n"); goto TERMINATE; } cutbeg = malloc ((cuts+1) * sizeof (*cutbeg)); cutind = malloc (nz * sizeof (*cutind)); cutval = malloc (nz * sizeof (*cutval)); cutrhs = malloc (cuts * sizeof (*cutrhs)); if ( cutbeg == NULL || cutind == NULL || cutval == NULL || cutrhs == NULL ) { fprintf (stderr, "No memory.\n"); status = CPXERR_NO_MEMORY; goto TERMINATE; } for (i = 0; i < nz; i++) { status = CPXXgetcolindex (env, lp, varname[i], &varind); if ( status ) { fprintf (stderr, "Failed to get index from variable name.\n"); goto TERMINATE; } cutind[i] = varind; cutval[i] = val[i]; } for (i = 0; i < cuts; i++) { cutbeg[i] = beg[i]; cutrhs[i] = rhs[i]; } cutbeg[cuts] = beg[cuts]; usercutinfo->num = cuts; usercutinfo->beg = cutbeg; usercutinfo->ind = cutind; usercutinfo->val = cutval; usercutinfo->rhs = cutrhs; TERMINATE: if ( status ) { free_and_null ((char **) &cutbeg); free_and_null ((char **) &cutind); free_and_null ((char **) &cutval); free_and_null ((char **) &cutrhs); } return (status); } /* END makeusercuts */
static int makelazyconstraint (CPXENVptr env, CPXLPptr lp, CUTINFOptr lazyconinfo) { int status = 0; CPXNNZ beg[] = {0, 5}; double val[] = {1, 1, 1, 1, 1}; char const *varname[] = { "W11", "W12", "W13", "W14", "W15" }; double rhs[] = {3}; CPXNNZ *cutbeg = NULL; CPXDIM *cutind = NULL; double *cutval = NULL; double *cutrhs = NULL; CPXDIM i, varind; CPXNNZ nz = 5; CPXDIM cuts = 1; CPXDIM cur_numcols = CPXXgetnumcols (env, lp); lazyconinfo->lp = lp; lazyconinfo->numcols = cur_numcols; lazyconinfo->x = malloc (cur_numcols * sizeof (*lazyconinfo->x)); if ( lazyconinfo->x == NULL ) { fprintf (stderr, "No memory for solution values.\n"); goto TERMINATE; } cutbeg = malloc ((cuts+1) * sizeof (*cutbeg)); cutind = malloc (nz * sizeof (*cutind)); cutval = malloc (nz * sizeof (*cutval)); cutrhs = malloc (cuts * sizeof (*cutrhs)); if ( cutbeg == NULL || cutind == NULL || cutval == NULL || cutrhs == NULL ) { fprintf (stderr, "No memory.\n"); status = CPXERR_NO_MEMORY; goto TERMINATE; } for (i = 0; i < nz; i++) { status = CPXXgetcolindex (env, lp, varname[i], &varind); if ( status ) { fprintf (stderr, "Failed to get index from variable name.\n"); goto TERMINATE; } cutind[i] = varind; cutval[i] = val[i]; } for (i = 0; i < cuts; i++) { cutbeg[i] = beg[i]; cutrhs[i] = rhs[i]; } cutbeg[cuts] = beg[cuts]; lazyconinfo->num = cuts; lazyconinfo->beg = cutbeg; lazyconinfo->ind = cutind; lazyconinfo->val = cutval; lazyconinfo->rhs = cutrhs; TERMINATE: if ( status ) { free_and_null ((char **) &cutbeg); free_and_null ((char **) &cutind); free_and_null ((char **) &cutval); free_and_null ((char **) &cutrhs); } return (status); } /* END makelazyconstraint */
static int addusercuts (CPXENVptr env, CPXLPptr lp) { int status = 0; CPXNNZ cutbeg[] = {0, 2, 4, 6, 16, 26, 36, 46, 56}; double cutval[] = {1, -1, 1, -1, 1, -1, 2.08, 2.98, 3.47, 2.24, 2.08, 0.25, 0.25, 0.25, 0.25, 0.25, 2.08, 2.98, 3.47, 2.24, 2.08, 0.25, 0.25, 0.25, 0.25, 0.25, 2.08, 2.98, 3.47, 2.24, 2.08, 0.25, 0.25, 0.25, 0.25, 0.25, 2.08, 2.98, 3.47, 2.24, 2.08, 0.25, 0.25, 0.25, 0.25, 0.25, 2.08, 2.98, 3.47, 2.24, 2.08, 0.25, 0.25, 0.25, 0.25, 0.25}; char const *varname[] = {"X21", "X22", "X22", "X23", "X23", "X24", "X11", "X21", "X31", "X41", "X51", "W11", "W21", "W31", "W41", "W51", "X12", "X22", "X32", "X42", "X52", "W12", "W22", "W32", "W42", "W52", "X13", "X23", "X33", "X43", "X53", "W13", "W23", "W33", "W43", "W53", "X14", "X24", "X34", "X44", "X54", "W14", "W24", "W34", "W44", "W54", "X15", "X25", "X35", "X45", "X55", "W15", "W25", "W35", "W45", "W55"}; double cutrhs[] = {0, 0, 0, 20.25, 20.25, 20.25, 20.25, 16.25}; char cutsens[] = "LLLLLLLL"; CPXDIM cutind[56]; CPXNNZ i; CPXDIM varind; CPXNNZ nz = 56; CPXDIM cuts = 8; for (i = 0; i < nz; i++) { status = CPXXgetcolindex (env, lp, varname[i], &varind); if ( status ) { fprintf (stderr, "Failed to get index from variable name.\n"); goto TERMINATE; } cutind[i] = varind; } status = CPXXaddusercuts (env, lp, cuts, nz, cutrhs, cutsens, cutbeg, cutind, cutval, NULL); /* Alternative approach: Replace CPXXaddusercuts() by the following CPXXaddrows() call, and delete the call to CPXXsetintparam (env, CPXPARAM_Preprocessing_Linear, 0) in main(). Note that in this example, we're adding a small number of cuts, so it is reasonable (preferable, in fact) to to add them directly to the model. If you have a large number of cuts, however, they can slow down the linear programming relaxations significantly, so placing them in the user cut table rather than in the model itself will usually be preferable. status = CPXXaddrows (env, lp, 0, cuts, nz, cutrhs, cutsens, cutbeg, cutind, cutval, NULL, NULL); */ TERMINATE: return (status); } /* END addusercuts */