reducemex(double M[], double costs[], double stats[], double ikeep[], double m[], int matbeg[], int matcnt[], int matind[], double matval[], char sense[], int objsen, double lb[], double ub[], int numrows, int numcols, double tol) { CPXENVptr env = NULL; CPXLPptr lp = NULL; int status; char probname[16]; double *pi; double *slack; double *dj; double *obj; int solstat; double objval; double *x; double newval; int *indices; int kc, i; obj = mxCalloc(numcols,sizeof(double)); x = mxCalloc(numcols,sizeof(double)); indices = mxCalloc(numcols,sizeof(int)); pi = mxCalloc(numrows,sizeof(double)); slack = mxCalloc(numrows,sizeof(double)); dj = mxCalloc(numcols,sizeof(double)); /* Initialize the CPLEX environment */ env = CPXopenCPLEX (&status); if ( env == NULL ) { char errmsg[1024]; fprintf (stderr, "Could not open CPLEX environment.\n"); CPXgeterrorstring (env, status, errmsg); fprintf (stderr, "%s", errmsg); goto TERMINATE; } /* Turn off output to the screen */ status = CPXsetintparam (env, CPX_PARAM_SCRIND, CPX_OFF); if ( status ) { fprintf (stderr, "Failure to turn on screen indicator, error %d.\n", status); goto TERMINATE; } /* Turn off pre-processor status = CPXsetintparam (env, CPX_PARAM_PREIND, CPX_OFF); if ( status ) { fprintf (stderr, "Failure to turn off pre-processor, error %d.\n", status); goto TERMINATE; } /* Turn off aggregator status = CPXsetintparam (env, CPX_PARAM_AGGIND, CPX_OFF); if ( status ) { fprintf (stderr, "Failure to turn of aggregator, error %d.\n", status); goto TERMINATE; }*/ /* Create the problem. */ strcpy(probname,"LPnoname"); lp = CPXcreateprob (env, &status, probname); if ( lp == NULL ) { fprintf (stderr, "Failed to create LP.\n"); goto TERMINATE; } /* Initialize data */ for (kc = 0; kc <= numcols-1; kc++) { indices[kc] = kc; } /* Now copy the problem data into the lp */ status = CPXcopylp (env, lp, numcols, numrows, objsen, obj, m, sense, matbeg, matcnt, matind, matval, lb, ub, NULL); if ( status ) { fprintf (stderr, "Failed to copy problem data.\n"); goto TERMINATE; } /**********MAIN LOOP************/ for(i = 0; i <= numrows-1; i++) { for (kc = 0; kc <= numcols-1; kc++) { obj[kc] = M[i+kc*numrows]; } CPXchgobj(env, lp, numcols, indices, obj); newval = m[i] + 10; CPXchgrhs(env, lp, 1, &i, &newval); /* Optimize the problem and obtain solution. */ status = CPXlpopt (env, lp); /*status = CPX[prim/dual]opt (env, lp);*/ if ( status ) { fprintf (stderr, "Failed to optimize LP.\n"); goto TERMINATE; } status = CPXsolution (env, lp, &solstat, &objval, x, pi, slack, dj); if ( status ) { fprintf (stderr, "Failed to obtain solution.\n"); goto TERMINATE; } ikeep[i] = 0; if (objval > m[i] + tol) /* keep row */ { ikeep[i] = 1; newval = m[i]; CPXchgrhs(env, lp, 1, &i, &newval); } /* Write the output to the screen. */ /* printf ("\nSolution status = %d\n", solstat); printf ("Solution value = %f\n\n", objval); */ costs[i] = objval; stats[i] = solstat; } TERMINATE: /* Free up the problem as allocated by CPXcreateprob, if necessary */ if ( lp != NULL ) { status = CPXfreeprob (env, &lp); if ( status ) { fprintf (stderr, "CPXfreeprob failed, error code %d.\n", status); } } /* Free up the CPLEX environment, if necessary */ if ( env != NULL ) { status = CPXcloseCPLEX (&env); if ( status ) { char errmsg[1024]; fprintf (stderr, "Could not close CPLEX environment.\n"); CPXgeterrorstring (env, status, errmsg); fprintf (stderr, "%s", errmsg); } } }
void DDSIP_DetEqu () { CPXLPptr det_equ; int status, scen, i, j, k; char probname[] = "sipout/det_equ.lp.gz"; double *obj_coef; double *scaled_obj_coef; char *sense; char **scen_spec_rowname; char **scen_spec_colname; char **rowname, *rownamestore; char **colname, *colnamestore; int rowstorespace, rowsurplus_p; int colstorespace, colsurplus_p; char *string1, *string2; double coef; double *lb, *lb_sorted; double *ub, *ub_sorted; char *vartype, *vartype_sorted; int *colindex_sorted, *colindex_revers, *matcol_sorted; double *value; double *det_equ_rhs = NULL; double *non_stoc_rhs = NULL; if (DDSIP_param->seccon) det_equ_rhs = (double *) DDSIP_Alloc(sizeof(double),DDSIP_param->seccon,"det_equ_rhs(DetEqu)"); else { fprintf (stderr,"XXX ERROR: no second stage contraints, got DDSIP_param->seccon=%d.\n",DDSIP_param->seccon); exit (1); } if (DDSIP_param->seccon - DDSIP_param->stocrhs>0) non_stoc_rhs = (double *) DDSIP_Alloc(sizeof(double),DDSIP_param->seccon - DDSIP_param->stocrhs,"non_stoc_rhs(DetEqu)"); fprintf (stderr, "\nBuilding deterministic equivalent. This may take some time.\nWorks only for expectation-based model so far.\n"); if (!(sense = (char *) calloc (DDSIP_param->seccon, sizeof (char)))) { fprintf (stderr, "Not enough memory for building deterministic equivalent\n"); return; } if (!(obj_coef = (double *) calloc (DDSIP_param->firstvar + DDSIP_param->secvar, sizeof (double))) || !(scaled_obj_coef = (double *) calloc (DDSIP_bb->secvar, sizeof (double)))) { fprintf (stderr, "Not enough memory for building deterministic equivalent\n"); return; } det_equ = CPXcloneprob (DDSIP_env, DDSIP_lp, &status); CPXchgprobname (DDSIP_env, det_equ, probname); if (!(rowname = (char **) calloc (DDSIP_param->seccon, sizeof (char *))) || !(scen_spec_rowname = (char **) calloc (DDSIP_param->seccon, sizeof (char *))) || !(rownamestore = (char *) calloc (DDSIP_param->seccon * 255, sizeof (char)))) { fprintf (stderr, "Not enough memory for building deterministic equivalent\n"); return; } rowstorespace = DDSIP_param->seccon * 255; status = CPXgetrowname (DDSIP_env, DDSIP_lp, rowname, rownamestore, rowstorespace, &rowsurplus_p, DDSIP_param->firstcon, DDSIP_param->firstcon + DDSIP_param->seccon - 1); if (!(colname = (char **) calloc (DDSIP_param->firstvar + DDSIP_param->secvar, sizeof (char *))) || !(scen_spec_colname = (char **) calloc (DDSIP_param->secvar, sizeof (char *))) || !(colnamestore = (char *) calloc (DDSIP_param->secvar * 255, sizeof (char)))) { fprintf (stderr, "Not enough memory for building deterministic equivalent\n"); return; } colstorespace = (DDSIP_param->firstvar + DDSIP_param->secvar) * 255; status = CPXgetcolname (DDSIP_env, DDSIP_lp, colname, colnamestore, colstorespace, &colsurplus_p, 0, DDSIP_param->firstvar + DDSIP_param->secvar - 1); /*____________________________________________________________________________________*/ status = CPXgetsense (DDSIP_env, DDSIP_lp, sense, DDSIP_param->firstcon, DDSIP_param->firstcon + DDSIP_param->seccon - 1); /*____________________________________________________________________________________*/ status = CPXgetrhs (DDSIP_env, DDSIP_lp, non_stoc_rhs, DDSIP_param->firstcon + DDSIP_param->stocrhs, DDSIP_param->firstcon + DDSIP_param->seccon - 1); /*____________________________________________________________________________________*/ status = CPXgetobj (DDSIP_env, DDSIP_lp, obj_coef, 0, DDSIP_param->firstvar + DDSIP_param->secvar - 1); /*____________________________________________________________________________________*/ //copy rownames scenario many times, append scenario index //and enter sense and rhs for (scen = 0; scen < DDSIP_param->scenarios; scen++) { for (j = 0; j < DDSIP_param->seccon; j++) { if (!(string2 = (char *) calloc (1, 255 * sizeof (char)))) { fprintf (stderr, "Not enough memory for building deterministic equivalent\n"); return; } string1 = rowname[j]; sprintf (string2, "%sSC%.3d", string1, scen); scen_spec_rowname[j] = string2; if (j < DDSIP_param->stocrhs) det_equ_rhs[j] = DDSIP_data->rhs[DDSIP_param->stocrhs * scen + j]; else det_equ_rhs[j] = non_stoc_rhs[j - DDSIP_param->stocrhs]; } status = CPXnewrows (DDSIP_env, det_equ, DDSIP_param->seccon, det_equ_rhs, sense, NULL, scen_spec_rowname); for (j = 0; j < DDSIP_param->seccon; j++) DDSIP_Free ((void **) &(scen_spec_rowname[j])); } //copy colnames scenario many times, append scenario index //and enter into constraint matrix if (!(lb = (double *) calloc (DDSIP_param->firstvar + DDSIP_param->secvar, sizeof (double))) || !(lb_sorted = (double *) calloc (DDSIP_param->secvar, sizeof (double))) || !(ub = (double *) calloc (DDSIP_param->firstvar + DDSIP_param->secvar, sizeof (double))) || !(ub_sorted = (double *) calloc (DDSIP_param->secvar, sizeof (double))) || !(vartype = (char *) calloc (DDSIP_param->firstvar + DDSIP_param->secvar, sizeof (char))) || !(vartype_sorted = (char *) calloc (DDSIP_param->secvar, sizeof (double))) || !(colindex_revers = (int *) calloc (DDSIP_param->firstvar + DDSIP_param->secvar, sizeof (int))) || !(colindex_sorted = (int *) calloc (DDSIP_param->firstvar + DDSIP_param->secvar, sizeof (int)))) { fprintf (stderr, "Not enough memory for building deterministic equivalent\n"); return; } status = CPXgetlb (DDSIP_env, det_equ, lb, 0, DDSIP_param->firstvar + DDSIP_param->secvar - 1); status = CPXgetub (DDSIP_env, det_equ, ub, 0, DDSIP_param->firstvar + DDSIP_param->secvar - 1); status = CPXgetctype (DDSIP_env, det_equ, vartype, 0, DDSIP_param->firstvar + DDSIP_param->secvar - 1); for (j = 0; j < DDSIP_param->secvar; j++) { vartype_sorted[j] = vartype[DDSIP_bb->secondindex[j]]; lb_sorted[j] = lb[DDSIP_bb->secondindex[j]]; ub_sorted[j] = ub[DDSIP_bb->secondindex[j]]; } for (scen = 0; scen < DDSIP_param->scenarios; scen++) { for (j = 0; j < DDSIP_param->secvar; j++) { if (!(string2 = (char *) calloc (1, 255 * sizeof (char)))) { fprintf (stderr, "Not enough memory for building deterministic equivalent\n"); return; } string1 = colname[DDSIP_bb->secondindex[j]]; sprintf (string2, "%sSC%.3d", string1, scen); scen_spec_colname[j] = string2; scaled_obj_coef[j] = DDSIP_data->prob[scen] * obj_coef[DDSIP_bb->secondindex[j]]; } status = CPXnewcols (DDSIP_env, det_equ, DDSIP_param->secvar, scaled_obj_coef, lb_sorted, ub_sorted, vartype_sorted, scen_spec_colname); for (j = 0; j < DDSIP_param->secvar; j++) DDSIP_Free ((void **) &(scen_spec_colname[j])); } ///////////////////////////////////////////////// for (j = 0; j < DDSIP_param->firstvar; j++) { colindex_sorted[j] = DDSIP_bb->firstindex[j]; } for (j = 0; j < DDSIP_param->secvar; j++) { colindex_sorted[DDSIP_param->firstvar + j] = DDSIP_bb->secondindex[j]; } for (j = 0; j < DDSIP_param->firstvar + DDSIP_param->secvar; j++) { colindex_revers[colindex_sorted[j]] = j; } k = DDSIP_param->seccon / 60; printf ("\n0%% 100%%\n"); for (i = 0; i < DDSIP_param->seccon; i++) { for (j = 0; j < DDSIP_param->firstvar; j++) { if ((status = CPXgetcoef (DDSIP_env, det_equ, DDSIP_param->firstcon + i, colindex_sorted[j], &coef))) { fprintf (stderr, " Build det. equivalent: Error retrieving coefficient of first-stage Variable %d.\n", j); exit (1); } if (coef) { for (scen = 0; scen < DDSIP_param->scenarios; scen++) { status = CPXchgcoef (DDSIP_env, det_equ, DDSIP_param->firstcon + DDSIP_bb->seccon + scen * DDSIP_param->seccon + i, colindex_sorted[j], coef); if (status) { fprintf (stderr, " Build det. equivalent: Error setting coefficient of first-stage Variable %d.\n", j); exit (1); } } } } for (j = DDSIP_param->firstvar; j < DDSIP_param->firstvar + DDSIP_param->secvar; j++) { if ((status = CPXgetcoef (DDSIP_env, det_equ, DDSIP_param->firstcon + i, colindex_sorted[j], &coef))) { fprintf (stderr, " Build det. equivalent: Error retrieving coefficient of second-stage Variable %d.\n", j - DDSIP_param->firstvar); exit (1); } if (coef) { for (scen = 0; scen < DDSIP_param->scenarios; scen++) { status = CPXchgcoef (DDSIP_env, det_equ, DDSIP_param->firstcon + DDSIP_bb->seccon + scen * DDSIP_param->seccon + i, (scen + 1) * DDSIP_param->secvar + j, coef); } if (status) { fprintf (stderr, " Build det. equivalent: Error setting coefficient of second-stage Variable %d.\n", j - DDSIP_param->firstvar); exit (1); } } } if (!k) { for (j = 0; j <= 60 / DDSIP_param->seccon; j++) printf ("#"); } else if (i % k == k - 1) printf ("#"); } printf ("\n\n"); ///////delete original second stage rows & cols //////////////////////////////////////////// status = CPXdelrows (DDSIP_env, det_equ, DDSIP_param->firstcon, DDSIP_param->firstcon + DDSIP_bb->seccon - 1); j = 0; for (i = 0; i < DDSIP_param->secvar; i++) { status = CPXdelcols (DDSIP_env, det_equ, DDSIP_bb->secondindex[i] - j, DDSIP_bb->secondindex[i] - j); j++; } ///////enter stochastic matrix entries////////////////////////////////////////////////////// if (DDSIP_param->stocmat) { if (!(value = (double *) calloc (DDSIP_param->stocmat, sizeof (double))) || !(matcol_sorted = (int *) calloc (DDSIP_param->stocmat, sizeof (int)))) { fprintf (stderr, "Not enough memory for building deterministic equivalent\n"); return; } for (j = 0; j < DDSIP_param->stocmat; j++) { matcol_sorted[j] = colindex_revers[DDSIP_data->matcol[j]]; } for (scen = 0; scen < DDSIP_param->scenarios; scen++) { for (j = 0; j < DDSIP_param->stocmat; j++) { value[j] = DDSIP_data->matval[scen * DDSIP_param->stocmat + j]; } status = CPXchgcoeflist (DDSIP_env, det_equ, DDSIP_param->stocmat, DDSIP_data->matrow, matcol_sorted, value); if (status) { char errmsg[1024]; CPXgeterrorstring (DDSIP_env, status, errmsg); fprintf (stderr, "in DetEqu: %s\n", errmsg); } for (j = 0; j < DDSIP_param->stocmat; j++) { DDSIP_data->matrow[j] += DDSIP_param->seccon; if (matcol_sorted[j] >= DDSIP_param->firstvar) matcol_sorted[j] += DDSIP_param->secvar; } } DDSIP_Free ((void **) &(value)); DDSIP_Free ((void **) &(matcol_sorted)); //set matrow to the old values for (j = 0; j < DDSIP_param->stocmat; j++) { DDSIP_data->matrow[j] -= DDSIP_param->scenarios * DDSIP_param->seccon; } } ///////enter stochastic cost coefficients ////////////////////////////////////////////////// if (DDSIP_param->stoccost) { if (!(value = (double *) calloc (DDSIP_param->stoccost, sizeof (double))) || !(matcol_sorted = (int *) calloc (DDSIP_param->stoccost, sizeof (int)))) { fprintf (stderr, "Not enough memory for building deterministic equivalent\n"); return; } for (j = 0; j < DDSIP_param->stoccost; j++) { value[j] = 0.0; matcol_sorted[j] = colindex_revers[DDSIP_data->costind[j]]; } for (scen = 0; scen < DDSIP_param->scenarios; scen++) { for (j = 0; j < DDSIP_param->stoccost; j++) { if (matcol_sorted[j] >= DDSIP_param->firstvar) value[j] = DDSIP_data->prob[scen] * DDSIP_data->cost[scen * DDSIP_param->stoccost + j]; else value[j] += DDSIP_data->prob[scen] * DDSIP_data->cost[scen * DDSIP_param->stoccost + j]; } status = CPXchgobj (DDSIP_env, det_equ, DDSIP_param->stoccost, matcol_sorted, value); if (status) { char errmsg[1024]; CPXgeterrorstring (DDSIP_env, status, errmsg); fprintf (stderr, "in DetEqu: %s\n", errmsg); } for (j = 0; j < DDSIP_param->stoccost; j++) { if (matcol_sorted[j] >= DDSIP_param->firstvar) matcol_sorted[j] += DDSIP_param->secvar; } } DDSIP_Free ((void **) &(value)); DDSIP_Free ((void **) &(matcol_sorted)); } //////////////////////////////////////////////////////////////////////////////////////////// status = CPXwriteprob (DDSIP_env, det_equ, probname, NULL); if (status) fprintf (DDSIP_outfile, " *** Deterministic equivalent not written successfully, status = %d\n", status); else fprintf (DDSIP_outfile, " *** Deterministic equivalent written successfully\n"); status = CPXfreeprob (DDSIP_env, &det_equ); DDSIP_Free ((void **) &(sense)); DDSIP_Free ((void **) &(vartype)); DDSIP_Free ((void **) &(rowname)); DDSIP_Free ((void **) &(rownamestore)); DDSIP_Free ((void **) &(colname)); DDSIP_Free ((void **) &(colnamestore)); DDSIP_Free ((void **) &(det_equ_rhs)); DDSIP_Free ((void **) &(non_stoc_rhs)); DDSIP_Free ((void **) &(lb)); DDSIP_Free ((void **) &(ub)); DDSIP_Free ((void **) &(vartype_sorted)); DDSIP_Free ((void **) &(lb_sorted)); DDSIP_Free ((void **) &(ub_sorted)); DDSIP_Free ((void **) &(obj_coef)); DDSIP_Free ((void **) &(scaled_obj_coef)); DDSIP_Free ((void **) &(colindex_sorted)); DDSIP_Free ((void **) &(colindex_revers)); DDSIP_Free ((void **) &(scen_spec_rowname)); DDSIP_Free ((void **) &(scen_spec_colname)); return; }
int main (void) { /* Declare variables and arrays where we will store the optimization results including the status, objective value, and variable values. */ int solstat; double objval; double x[2*NUMEDGES]; /* One flow variable and one fixed charge indicator for each edge */ CPXENVptr env = NULL; CPXLPptr lp = NULL; int status; int j; /* Initialize the CPLEX environment */ env = CPXopenCPLEX (&status); /* If an error occurs, the status value indicates the reason for failure. A call to CPXgeterrorstring will produce the text of the error message. Note that CPXopenCPLEX produces no output, so the only way to see the cause of the error is to use CPXgeterrorstring. For other CPLEX routines, the errors will be seen if the CPXPARAM_ScreenOutput indicator is set to CPX_ON. */ if ( env == NULL ) { char errmsg[CPXMESSAGEBUFSIZE]; fprintf (stderr, "Could not open CPLEX environment.\n"); CPXgeterrorstring (env, status, errmsg); fprintf (stderr, "%s", errmsg); goto TERMINATE; } /* Turn on output to the screen */ status = CPXsetintparam (env, CPXPARAM_ScreenOutput, CPX_ON); if ( status ) { fprintf (stderr, "Failure to turn on screen indicator, error %d.\n", status); goto TERMINATE; } /* Create the problem. */ lp = CPXcreateprob (env, &status, "fixnet"); /* A returned pointer of NULL may mean that not enough memory was available or there was some other problem. In the case of failure, an error message will have been written to the error channel from inside CPLEX. In this example, the setting of the parameter CPXPARAM_ScreenOutput causes the error message to appear on stdout. */ if ( lp == NULL ) { fprintf (stderr, "Failed to create LP.\n"); goto TERMINATE; } /* Build the fixed-charge network flow model using indicator constraints. */ status = buildnetwork (env, lp); if ( status ) { fprintf (stderr, "Failed to build network.\n"); goto TERMINATE; } /* Optimize the problem and obtain solution. */ status = CPXmipopt (env, lp); if ( status ) { fprintf (stderr, "Failed to optimize MIP.\n"); goto TERMINATE; } solstat = CPXgetstat (env, lp); /* Write solution status and objective to the screen. */ printf ("\nSolution status = %d\n", solstat); status = CPXgetobjval (env, lp, &objval); if ( status ) { fprintf (stderr, "No MIP objective value available. Exiting...\n"); goto TERMINATE; } printf ("Solution value = %f\n", objval); printf ("Solution vector:\n"); dumpx (env, lp); status = CPXgetx (env, lp, x, 0, 2*NUMEDGES-1); if ( status ) { fprintf (stderr, "Failed to get optimal integer x.\n"); goto TERMINATE; } /* Make sure flow satisfies fixed-charge constraints */ for (j = 0; j < NUMEDGES; j++) { if ( x[j] > 0.0001 && x[NUMEDGES+j] < 0.9999 ) { printf ("WARNING : Edge from %d to %d has non-zero flow %.3f\n", orig[j], dest[j], x[j]); printf (" : fixed-charge indicator has value %.6f.\n", x[NUMEDGES+j]); } } printf("\n"); /* Finally, write a copy of the problem to a file. */ status = CPXwriteprob (env, lp, "fixnet.lp", NULL); if ( status ) { fprintf (stderr, "Failed to write LP to disk.\n"); goto TERMINATE; } /* Free problem */ status = CPXfreeprob (env, &lp); if ( status ) { fprintf (stderr, "CPXfreeprob failed, error code %d.\n", status); goto TERMINATE; } TERMINATE: /* Free up the problem as allocated by CPXcreateprob, if necessary */ if ( lp != NULL ) { status = CPXfreeprob (env, &lp); if ( status ) { fprintf (stderr, "CPXfreeprob failed, error code %d.\n", status); } } /* Free up the CPLEX environment, if necessary */ if ( env != NULL ) { status = CPXcloseCPLEX (&env); /* Note that CPXcloseCPLEX produces no output, so the only way to see the cause of the error is to use CPXgeterrorstring. For other CPLEX routines, the errors will be seen if the CPXPARAM_ScreenOutput indicator is set to CPX_ON. */ if ( status ) { char errmsg[CPXMESSAGEBUFSIZE]; fprintf (stderr, "Could not close CPLEX environment.\n"); CPXgeterrorstring (env, status, errmsg); fprintf (stderr, "%s", errmsg); } } return (status); } /* END main */
long GenModelCplex::CreateModel() { if(!binit) return ThrowError("CreateModel() not available : Problem not initialized yet"); CplexData* d = (CplexData*)solverdata; int status = 0; d->nc = nc; d->nc = nc; d->onc = nc; d->onr = nr; if(boolParam.count("maximize") > 0 && boolParam["maximize"]) CPXchgobjsen (d->env, d->lp, CPX_MAX); else CPXchgobjsen (d->env, d->lp, CPX_MIN); d->lrhs = new double[nr]; d->urhs = new double[nr]; d->sense = new char[nr]; d->ub = new double[nc]; d->lb = new double[nc]; d->obj = new double[nc]; d->type = new char[nc]; d->mat_r = new int[nz]; d->mat_c = new int[nz]; d->mat_v = new double[nz]; d->cname = new char*[nc]; d->rname = new char*[nr]; nz=0; for(unsigned long i = 0; i < nr; i++) { d->rname[i] = new char[consts[i].name.length()+1]; snprintf(d->rname[i], consts[i].name.length()+1, "%s", consts[i].name.c_str()); //printf("%ld %s: ", i, consts[i].name.c_str()); for(unsigned long j = 0; j < consts[i].nz; j++) { d->mat_r[nz] = i; d->mat_c[nz] = consts[i].cols[j]; d->mat_v[nz] = consts[i].coefs[j]; //if(i >= 198) //printf("(%ld,%ld(%s),%f) ", d->mat_r[nz], d->mat_c[nz], vars.name[d->mat_c[nz]].c_str(), d->mat_v[nz]); nz++; } if(consts[i].lrhs == numeric_limits<double>::infinity()) d->lrhs[i] = CPX_INFBOUND; else if(consts[i].lrhs == -numeric_limits<double>::infinity()) d->lrhs[i] = -CPX_INFBOUND; else d->lrhs[i] = consts[i].lrhs; if(consts[i].urhs == numeric_limits<double>::infinity()) d->urhs[i] = CPX_INFBOUND; else if(consts[i].urhs == -numeric_limits<double>::infinity()) d->urhs[i] = -CPX_INFBOUND; else d->urhs[i] = consts[i].urhs-consts[i].lrhs; d->sense[i] = consts[i].sense; // printf("%ld/%ld -> %c\n", i, nr, d->sense[i]); } for(unsigned long i = 0; i < nc; i++) { d->cname[i] = new char[vars.name[i].length()+1]; snprintf(d->cname[i], vars.name[i].length()+1, "%s", vars.name[i].c_str()); d->obj[i] = vars.obj[i]; if(vars.ub[i] == numeric_limits<double>::infinity()) d->ub[i] = CPX_INFBOUND; else if(vars.ub[i] == -numeric_limits<double>::infinity()) d->ub[i] = -CPX_INFBOUND; else d->ub[i] = vars.ub[i]; if(vars.lb[i] == numeric_limits<double>::infinity()) d->lb[i] = CPX_INFBOUND; else if(vars.lb[i] == -numeric_limits<double>::infinity()) d->lb[i] = -CPX_INFBOUND; else d->lb[i] = vars.lb[i]; d->type[i] = vars.type[i]; //printf("%ld (%s) -> %f %f %f %c\n", i, vars.name[i].c_str(), d->obj[i], d->lb[i], d->ub[i], d->type[i]); } status = CPXnewrows (d->env, d->lp, nr, d->lrhs, d->sense, d->urhs, d->rname); if ( status ) { char errmsg[1024]; fprintf (stderr, "Could not create new rows.\n"); CPXgeterrorstring (d->env, status, errmsg); fprintf (stderr, "%s", errmsg); return 1; } //else //printf("Row added!\n"); if(boolParam.count("mip") > 0 && boolParam["mip"]) status = CPXnewcols (d->env, d->lp, nc, d->obj, d->lb, d->ub, d->type, d->cname); else status = CPXnewcols (d->env, d->lp, nc, d->obj, d->lb, d->ub, NULL, NULL); if ( status ) { char errmsg[1024]; fprintf (stderr, "Could not create new cols.\n"); CPXgeterrorstring (d->env, status, errmsg); fprintf (stderr, "%s", errmsg); return 1; } //status = CPXnewcols (env, lp, nc, obj, lb, ub, NULL, colname); if ( status ) return 1; //else //printf("Col added!\n"); status = CPXchgcoeflist (d->env, d->lp, nz, d->mat_r, d->mat_c, d->mat_v); if ( status ) return 1; vector<long>::iterator iti; vector<long>::iterator itj = vars.qj.begin(); vector<double>::iterator itv = vars.qobj.begin(); vector<vector<pair<int,double> > > qptemp; qptemp.resize(nc); int* qpbeg = NULL; int* qpnum = NULL; int* qpind = NULL; double* qpv = NULL; int qpnz = 0; if(!vars.qi.empty()) { boolParam["qp"] = true; qpbeg = new int[nc]; qpnum = new int[nc]; } if(boolParam.count("qp_mat") == 0 || boolParam["qp_mat"]) { for(iti = vars.qi.begin(); iti != vars.qi.end(); iti++, itj++, itv++) { qptemp[*iti].push_back(pair<int, double>(*itj,*itv)); qpnz++; if(*iti != *itj) { qptemp[*itj].push_back(pair<int, double>(*iti,*itv)); qpnz++; } } if(!vars.qi.empty()) { qpv = new double[qpnz]; qpind = new int[qpnz]; qpnz=0; for(int i = 0; i < int(nc); i++) { qpbeg[i] = qpnz; qpnum[i] = int(qptemp[i].size()); for(int j = 0; j < int(qptemp[i].size()); j++) { qpind[qpnz] = qptemp[i][j].first; qpv[qpnz] = 2.0*qptemp[i][j].second; qpnz++; } } status = CPXcopyquad(d->env, d->lp, qpbeg, qpnum, qpind, qpv); delete[] qpbeg; delete[] qpnum; delete[] qpind; delete[] qpv; } if ( status ) { printf("QP problem!\n"); return 1; } } //else //printf("Coefs added!\n"); bcreated = true; return 0; }
int main (void) { /* Declare variables and arrays where we will store the optimization results including the status, objective value, and variable values. */ int solstat; double objval; int colcnt = 0; double *x = NULL; CPXENVptr env = NULL; CPXLPptr lp = NULL; int status; int m, p; /* Initialize the CPLEX environment */ env = CPXopenCPLEX (&status); /* If an error occurs, the status value indicates the reason for failure. A call to CPXgeterrorstring will produce the text of the error message. Note that CPXopenCPLEX produces no output, so the only way to see the cause of the error is to use CPXgeterrorstring. For other CPLEX routines, the errors will be seen if the CPXPARAM_ScreenOutput indicator is set to CPX_ON. */ if ( env == NULL ) { char errmsg[CPXMESSAGEBUFSIZE]; fprintf (stderr, "Could not open CPLEX environment.\n"); CPXgeterrorstring (env, status, errmsg); fprintf (stderr, "%s", errmsg); goto TERMINATE; } /* Turn on output to the screen */ status = CPXsetintparam (env, CPXPARAM_ScreenOutput, CPX_ON); if ( status ) { fprintf (stderr, "Failure to turn on screen indicator, error %d.\n", status); goto TERMINATE; } /* Formulate and solve the problem */ lp = CPXcreateprob (env, &status, "food manufacturing"); /* A returned pointer of NULL may mean that not enough memory was available or there was some other problem. In the case of failure, an error message will have been written to the error channel from inside CPLEX. In this example, the setting of the parameter CPXPARAM_ScreenOutput causes the error message to appear on stdout. */ if ( lp == NULL ) { fprintf (stderr, "Failed to create LP.\n"); goto TERMINATE; } /* Build the model */ status = buildmodel (env, lp); if ( status ) { fprintf (stderr, "Failed to build model.\n"); goto TERMINATE; } /* Write a copy of the problem to a file. */ status = CPXwriteprob (env, lp, "foodmanu.lp", NULL); if ( status ) { fprintf (stderr, "Failed to write LP to disk.\n"); goto TERMINATE; } /* Optimize the problem and obtain solution. */ status = CPXmipopt (env, lp); if ( status ) { fprintf (stderr, "Failed to optimize MIP.\n"); goto TERMINATE; } solstat = CPXgetstat (env, lp); /* Write solution status, objective and solution vector to the screen. */ printf ("\nSolution status = %d\n", solstat); status = CPXgetobjval (env, lp, &objval); if ( status ) { fprintf (stderr,"No MIP objective value available. Exiting...\n"); goto TERMINATE; } printf ("Solution value (maximum profit) = %f\n\n", objval); colcnt = NUMVARS*NUMMONTHS*NUMPRODUCTS; x = (double *) malloc (colcnt * sizeof(double)); if ( x == NULL ) { status = CPXERR_NO_MEMORY; fprintf (stderr, "Could not allocate memory for solution.\n"); goto TERMINATE; } status = CPXgetx (env, lp, x, 0, colcnt - 1); if ( status ) { fprintf (stderr, "Failed to get optimal integer x.\n"); goto TERMINATE; } for (m = 0; m < NUMMONTHS; m++) { printf ("Month %d \n", m); printf (" . buy "); for (p = 0; p < NUMPRODUCTS; p++) printf ("%f\t", x[varindex(m, p, BUY)]); printf ("\n"); printf (" . use "); for (p = 0; p < NUMPRODUCTS; p++) printf ("%f\t", x[varindex (m, p, USE)]); printf ("\n"); printf (" . store "); for (p = 0; p < NUMPRODUCTS; p++) printf ("%f\t", x[varindex (m, p, STORE)]); printf ("\n"); } /* Free problem */ status = CPXfreeprob (env, &lp); if ( status ) { fprintf (stderr, "CPXfreeprob failed, error code %d.\n", status); goto TERMINATE; } TERMINATE: free_and_null ((char **) &x); /* Free up the problem as allocated by CPXcreateprob, if necessary */ if ( lp != NULL ) { status = CPXfreeprob (env, &lp); if ( status ) { fprintf (stderr, "CPXfreeprob failed, error code %d.\n", status); } } /* Free up the CPLEX environment, if necessary */ if ( env != NULL ) { status = CPXcloseCPLEX (&env); /* Note that CPXcloseCPLEX produces no output, so the only way to see the cause of the error is to use CPXgeterrorstring. For other CPLEX routines, the errors will be seen if the CPXPARAM_ScreenOutput indicator is set to CPX_ON. */ if ( status ) { char errmsg[CPXMESSAGEBUFSIZE]; fprintf (stderr, "Could not close CPLEX environment.\n"); CPXgeterrorstring (env, status, errmsg); fprintf (stderr, "%s", errmsg); } } return (status); } /* END main */
int main (int argc, char *argv[]) { /* Declare and allocate space for the variables and arrays where we will store the optimization results including the status, objective value, maximum bound violation, variable values, and basis. */ int solnstat, solnmethod, solntype; double objval, maxviol; double *x = NULL; CPXENVptr env = NULL; CPXLPptr lp = NULL; int status = 0; int j; int cur_numrows, cur_numcols; /* Check the command line arguments */ if (( argc != 2 )) { usage (argv[0]); goto TERMINATE; } /* Initialize the CPLEX environment */ env = CPXopenCPLEX (&status); /* If an error occurs, the status value indicates the reason for failure. A call to CPXgeterrorstring will produce the text of the error message. Note that CPXopenCPLEX produces no output, so the only way to see the cause of the error is to use CPXgeterrorstring. For other CPLEX routines, the errors will be seen if the CPXPARAM_ScreenOutput indicator is set to CPX_ON. */ if ( env == NULL ) { char errmsg[CPXMESSAGEBUFSIZE]; fprintf (stderr, "Could not open CPLEX environment.\n"); CPXgeterrorstring (env, status, errmsg); fprintf (stderr, "%s", errmsg); goto TERMINATE; } /* Turn on output to the screen */ status = CPXsetintparam (env, CPXPARAM_ScreenOutput, CPX_ON); if ( status ) { fprintf (stderr, "Failure to turn on screen indicator, error %d.\n", status); goto TERMINATE; } /* Create the problem, using the filename as the problem name */ lp = CPXcreateprob (env, &status, argv[1]); /* A returned pointer of NULL may mean that not enough memory was available or there was some other problem. In the case of failure, an error message will have been written to the error channel from inside CPLEX. In this example, the setting of the parameter CPXPARAM_ScreenOutput causes the error message to appear on stdout. Note that most CPLEX routines return an error code to indicate the reason for failure. */ if ( lp == NULL ) { fprintf (stderr, "Failed to create LP.\n"); goto TERMINATE; } /* Now read the file, and copy the data into the created lp */ status = CPXreadcopyprob (env, lp, argv[1], NULL); if ( status ) { fprintf (stderr, "Failed to read and copy the problem data.\n"); goto TERMINATE; } if ( CPXgetprobtype (env, lp) != CPXPROB_MIQP ) { fprintf (stderr, "Input file is not a MIQP. Exiting.\n"); goto TERMINATE; } /* Optimize the problem and obtain solution. */ status = CPXsetintparam (env, CPXPARAM_SolutionTarget, CPX_SOLUTIONTARGET_OPTIMALGLOBAL); if ( status ) goto TERMINATE; status = CPXmipopt (env, lp); if ( status ) { fprintf (stderr, "Failed to optimize nonconvex MIQP.\n"); goto TERMINATE; } solnstat = CPXgetstat (env, lp); if ( solnstat == CPXMIP_UNBOUNDED || solnstat == CPX_STAT_UNBOUNDED ) { printf ("Model is unbounded\n"); goto TERMINATE; } else if ( solnstat == CPXMIP_INFEASIBLE || solnstat == CPX_STAT_INFEASIBLE ) { printf ("Model is infeasible\n"); goto TERMINATE; } else if ( solnstat == CPX_STAT_INForUNBD ) { printf ("Model is infeasible or unbounded\n"); goto TERMINATE; } status = CPXsolninfo (env, lp, &solnmethod, &solntype, NULL, NULL); if ( status ) { fprintf (stderr, "Failed to obtain solution info.\n"); goto TERMINATE; } printf ("Solution status %d, solution method %d\n", solnstat, solnmethod); if ( solntype == CPX_NO_SOLN ) { fprintf (stderr, "Solution not available.\n"); goto TERMINATE; } status = CPXgetobjval (env, lp, &objval); if ( status ) { fprintf (stderr, "Failed to obtain objective value.\n"); goto TERMINATE; } printf ("Objective value %.10g.\n", objval); /* The size of the problem should be obtained by asking CPLEX what the actual size is. cur_numrows and cur_numcols store the current number of rows and columns, respectively. */ cur_numcols = CPXgetnumcols (env, lp); cur_numrows = CPXgetnumrows (env, lp); /* Retrieve solution vector */ x = (double *) malloc (cur_numcols*sizeof(double)); if ( x == NULL ) { fprintf (stderr, "No memory for solution.\n"); goto TERMINATE; } status = CPXgetx (env, lp, x, 0, cur_numcols-1); if ( status ) { fprintf (stderr, "Failed to obtain primal solution.\n"); goto TERMINATE; } /* Write out the solution */ for (j = 0; j < cur_numcols; j++) { printf ( "Column %d: Value = %17.10g", j, x[j]); printf ("\n"); } /* Display the maximum bound violation. */ status = CPXgetdblquality (env, lp, &maxviol, CPX_MAX_PRIMAL_INFEAS); if ( status ) { fprintf (stderr, "Failed to obtain bound violation.\n"); goto TERMINATE; } printf ("Maximum bound violation = %17.10g\n", maxviol); TERMINATE: /* Free up the basis and solution */ free_and_null ((char **) &x); /* Free up the problem, if necessary */ if ( lp != NULL ) { status = CPXfreeprob (env, &lp); if ( status ) { fprintf (stderr, "CPXfreeprob failed, error code %d.\n", status); } } /* Free up the CPLEX environment, if necessary */ if ( env != NULL ) { status = CPXcloseCPLEX (&env); /* Note that CPXcloseCPLEX produces no output, so the only way to see the cause of the error is to use CPXgeterrorstring. For other CPLEX routines, the errors will be seen if the CPXPARAM_ScreenOutput indicator is set to CPX_ON. */ if ( status ) { char errmsg[CPXMESSAGEBUFSIZE]; fprintf (stderr, "Could not close CPLEX environment.\n"); CPXgeterrorstring (env, status, errmsg); fprintf (stderr, "%s", errmsg); } } return (status); } /* END main */
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { int i, j; double *b=NULL, *A=NULL, *l=NULL, *u=NULL, *x=NULL, *lambda=NULL ; int *iA=NULL, *kA=NULL, nnz=0, neq=0, m=0, n=0, display=0; long *lpenv=NULL, *p_lp=NULL; char *Sense=NULL ; CPXENVptr env = NULL; CPXLPptr lp = NULL; int status, lpstat; double objval; #ifndef MX_COMPAT_32 long *iA_=NULL, *kA_=NULL ; #endif if (nrhs > 6 || nrhs < 1) { mexErrMsgTxt("Usage: [how] " "= lp_addrows(env,lp,A,b,neq,disp)"); return; } switch (nrhs) { case 6: if (mxGetM(prhs[5]) != 0 || mxGetN(prhs[5]) != 0) { if (!mxIsNumeric(prhs[5]) || mxIsComplex(prhs[5]) || mxIsSparse(prhs[5]) || !(mxGetM(prhs[5])==1 && mxGetN(prhs[5])==1)) { mexErrMsgTxt("6th argument (display) must be " "an integer scalar."); return; } display = *mxGetPr(prhs[5]); } case 5: if (mxGetM(prhs[4]) != 0 || mxGetN(prhs[4]) != 0) { if (!mxIsNumeric(prhs[4]) || mxIsComplex(prhs[4]) || mxIsSparse(prhs[4]) || !(mxGetM(prhs[4])==1 && mxGetN(prhs[4])==1)) { mexErrMsgTxt("5th argument (neq) must be " "an integer scalar."); return; } neq = *mxGetPr(prhs[4]); } case 4: if (mxGetM(prhs[3]) != 0 || mxGetN(prhs[3]) != 0) { if (!mxIsNumeric(prhs[3]) || mxIsComplex(prhs[3]) || mxIsSparse(prhs[3]) || !mxIsDouble(prhs[3]) || mxGetN(prhs[3])!=1 ) { mexErrMsgTxt("4rd argument (b) must be " "a column vector."); return; } if (m != 0 && m != mxGetM(prhs[3])) { mexErrMsgTxt("Dimension error (arg 4 and later)."); return; } b = mxGetPr(prhs[3]); m = mxGetM(prhs[3]); } case 3: if (mxGetM(prhs[2]) != 0 || mxGetN(prhs[2]) != 0) { if (!mxIsNumeric(prhs[2]) || mxIsComplex(prhs[2]) || !mxIsSparse(prhs[2]) ) { mexErrMsgTxt("3n argument (A) must be " "a sparse matrix."); return; } if (m != 0 && m != mxGetN(prhs[2])) { mexErrMsgTxt("Dimension error (arg 3 and later)."); return; } if (n != 0 && n != mxGetM(prhs[2])) { mexErrMsgTxt("Dimension error (arg 3 and later)."); return; } m = mxGetN(prhs[2]); n = mxGetM(prhs[2]); A = mxGetPr(prhs[2]); #ifdef MX_COMPAT_32 iA = mxGetIr(prhs[2]); kA = mxGetJc(prhs[2]); #else iA_ = mxGetIr(prhs[2]); kA_ = mxGetJc(prhs[2]); iA = myMalloc(mxGetNzmax(prhs[2])*sizeof(int)) ; for (i=0; i<mxGetNzmax(prhs[2]); i++) iA[i]=iA_[i] ; kA = myMalloc((n+1)*sizeof(int)) ; for (i=0; i<n+1; i++) kA[i]=kA_[i] ; #endif /*{ int k=0 ; mxArray* a = mxCreateDoubleMatrix(1, 1, mxREAL); for (; k<28; k++) printf("%i,", iA[k]) ; printf("\n") ; for (k=0; k<28; k++) printf("%i,", kA[k]) ; printf("\n") ; for (k=0; k<28; k++) printf("%f,", A[k]) ; printf("\n") ; }*/ /*nnz=mxGetNzmax(prhs[2]); */ nnz=kA[m] ; if (display>3) fprintf(STD_OUT, "nnz=%i\n", nnz) ; Sense=myMalloc((m+1)*sizeof(char)) ; for (i=0; i<m; i++) if (i<neq) Sense[i]='E' ; else Sense[i]='L' ; Sense[m]=0 ; if (display>3) fprintf(STD_OUT, "Sense=%s\n", Sense) ; } case 2: if (mxGetM(prhs[1]) != 0 || mxGetN(prhs[1]) != 0) { if (!mxIsNumeric(prhs[1]) || mxIsComplex(prhs[1]) || mxIsSparse(prhs[1]) || !mxIsDouble(prhs[1]) || mxGetN(prhs[1])!=1 ) { mexErrMsgTxt("2nd argument (p_lp) must be " "a column vector."); return; } if (1 != mxGetM(prhs[1])) { mexErrMsgTxt("Dimension error (arg 2)."); return; } p_lp = (long*) mxGetPr(prhs[1]); } case 1: if (mxGetM(prhs[0]) != 0 || mxGetN(prhs[0]) != 0) { if (!mxIsNumeric(prhs[0]) || mxIsComplex(prhs[0]) || mxIsSparse(prhs[0]) || !mxIsDouble(prhs[0]) || mxGetN(prhs[0])!=1 ) { mexErrMsgTxt("1st argument (lpenv) must be " "a column vector."); return; } if (1 != mxGetM(prhs[0])) { mexErrMsgTxt("Dimension error (arg 1)."); return; } lpenv = (long*) mxGetPr(prhs[0]); } } if (nlhs > 1 || nlhs < 1) { mexErrMsgTxt("Usage: [how] " "= lp_gen(lpenv,p_lp,A,b,neq,disp)"); return; } if (display>3) fprintf(STD_OUT, "(m=%i, n=%i, neq=%i, nnz=%i) \n", m, n, neq, nnz) ; /* Initialize the CPLEX environment */ env = (CPXENVptr) lpenv[0] ; lp=(CPXLPptr)p_lp[0] ; if (display>2) fprintf(STD_OUT, "calling CPXaddrows \n") ; status = CPXaddrows (env, lp, 0, m, nnz, b, Sense, kA, iA, A, NULL, NULL); if ( status ) { fprintf (STD_OUT,"CPXaddrows failed.\n"); goto TERMINATE; } TERMINATE: if (status) { char errmsg[1024]; CPXgeterrorstring (env, status, errmsg); fprintf (STD_OUT, "%s", errmsg); if (nlhs >= 1) plhs[0] = mxCreateString(errmsg) ; } else if (nlhs >= 1) plhs[0] = mxCreateString("OK") ; ; /* if (Sense) myFree(Sense) ;*/ #ifndef MX_COMPAT_32 if (iA) myFree(iA) ; if (kA) myFree(kA) ; #endif return ; }
// solver initialisation // requires the list of versioned packages and the total amount of variables (including additional ones) int cplex_solver::init_solver(PSLProblem *problem, int other_vars) { int status; _solutionCount = 0; _nodeCount = 0; _timeCount = 0; // Coefficient initialization initialize_coeffs(problem->rankCount() + other_vars); /* Initialize the CPLEX environment */ env = CPXopenCPLEX (&status); if ( env == NULL ) { char errmsg[1024]; fprintf (stderr, "Could not open CPLEX environment.\n"); CPXgeterrorstring (env, status, errmsg); fprintf (stderr, "%s", errmsg); exit(-1); } /* Set the value of the time limit*/ status = CPXsetdblparam (env, CPX_PARAM_TILIM, time_limit); if ( status ) { fprintf (stderr, "Failure to set the time limit, error %d.\n", status); exit(-1); } /* Enhance EPGAP to handle big values correctly */ status = CPXsetdblparam (env, CPX_PARAM_EPGAP, 0.0); if ( status ) { fprintf (stderr, "Failure to set EPGAP, error %d.\n", status); exit(-1); } /* Limit the number of thread to 1 */ status = CPXsetintparam (env, CPX_PARAM_THREADS, 1); if ( status ) { fprintf (stderr, "Failure to set thread limit to 1, error %d.\n", status); exit(-1); } if (verbosity >= DEFAULT) { /* Turn on output to the screen */ status = CPXsetintparam (env, CPX_PARAM_SCRIND, CPX_ON); if ( status ) { fprintf (stderr, "Failure to turn on screen indicator, error %d.\n", status); exit(-1); } /* MIP node log display information */ int verb = verbosity >= SEARCH ? 5 : verbosity >= VERBOSE ? 2 : 1; status = CPXsetintparam (env, CPX_PARAM_MIPDISPLAY, verb); // int val = -1; // CPXgetintparam (env, CPX_PARAM_MIPDISPLAY, &val); // cerr << val << endl; if ( status ) { fprintf (stderr, "Failure to turn off presolve, error %d.\n", status); exit(-1); } } /* Create the problem. */ lp = CPXcreateprob (env, &status, "lpex1"); /* A returned pointer of NULL may mean that not enough memory was available or there was some other problem. In the case of failure, an error message will have been written to the error channel from inside CPLEX. In this example, the setting of the parameter CPX_PARAM_SCRIND causes the error message to appear on stdout. */ if ( lp == NULL ) { fprintf (stderr, "Failed to create LP.\n"); exit(-1); } first_objective = 0; lb = (double *)malloc(nb_vars*sizeof(double)); ub = (double *)malloc(nb_vars*sizeof(double)); vartype = (char *)malloc(nb_vars*sizeof(char)); varname = (char **)malloc(nb_vars*sizeof(char *)); if ((lb == (double *)NULL) || (ub == (double *)NULL) || (vartype == (char *)NULL) || (varname == (char **)NULL)) { fprintf(stderr, "cplex_solver: initialization: not enough memory.\n"); exit(-1); } init_vars(problem, nb_vars); return 0; }
/* This routine initializes the cplex enviorement, sets screen as an output for cplex errors and notifications, and sets parameters for cplex. It calls for a mixed integer program solution and frees the environment. To Do: Declare the parameters for the problem and fill them accordingly. After creating the program thus, copy it into cplex. Define any integer or binary variables as needed, and change their type before the call to CPXmipopt to solve problem. Use CPXwriteprob to output the problem in lp format, in the name of cluster_editing.lp. Read solution (both objective function value and variables assignment). Communicate to pass the problem and the solution between the modules in the best way you see. */ int cluster() { /* Declare and allocate space for the variables and arrays where we will store the optimization results including the status, objective value and variable values. */ CPXENVptr p_env = NULL; CPXLPptr p_lp = NULL; int status; /* Initialize the CPLEX environment */ p_env = CPXopenCPLEX (&status); /* If an error occurs, the status value indicates the reason for failure. A call to CPXgeterrorstring will produce the text of the error message. Note that CPXopenCPLEX produces no output, so the only way to see the cause of the error is to use CPXgeterrorstring. For other CPLEX routines, the errors will be seen if the CPX_PARAM_SCRIND indicator is set to CPX_ON. */ if ( p_env == NULL ) { char errmsg[1024]; fprintf (stderr, "Error: Could not open CPLEX environment.\n"); CPXgeterrorstring (p_env, status, errmsg); fprintf (stderr, "%s", errmsg); goto TERMINATE; } /* Turn on output to the screen */ status = CPXsetintparam (p_env, CPX_PARAM_SCRIND, CPX_ON); if ( status ) { fprintf (stderr, "Error: Failure to turn on screen indicator, error %d.\n", status); goto TERMINATE; } /* Create the problem. */ p_lp = CPXcreateprob (p_env, &status, probname); /* A returned pointer of NULL may mean that not enough memory was available or there was some other problem. In the case of failure, an error message will have been written to the error channel from inside CPLEX. The setting of the parameter CPX_PARAM_SCRIND causes the error message to appear on stdout. */ if ( p_lp == NULL ) { fprintf (stderr, "Error: Failed to create problem.\n"); goto TERMINATE; } /* Use CPXcopylp to transfer the ILP part of the problem data into the cplex pointer lp */ CPXcopylp (p_env, p_lp, numcols, numrows, objsen, obj, rhs, sense, matbeg, matcnt, matind, matval, lb, ub, 0); CPXchgctype(p_env, p_lp, cnt, indices, ctype); /* Optimize the problem. */ status = CPXmipopt (p_env, p_lp); if ( status ) { fprintf (stderr, "Error: Failed to optimize problem.\n"); goto TERMINATE; } status = CPXsolution(p_env, p_lp, &solstat, &objval, x, NULL, NULL, NULL); if ( status ) { fprintf (stderr, "Error: Failed to get solution variables.\n"); goto TERMINATE; } /* Write a copy of the problem to a file. Please put into probname the following string: Output Directory + "clustering_solution.lp" to create clustering_solution.lp in your output directory */ status = CPXwriteprob (p_env, p_lp, probname, NULL); if ( status ) { fprintf (stderr, "Error: Failed to write LP to disk.\n"); goto TERMINATE; } TERMINATE: /* Free up the problem as allocated by CPXcreateprob, if necessary */ if ( p_lp != NULL ) { status = CPXfreeprob (p_env, &p_lp); if ( status ) { fprintf (stderr, "Error: CPXfreeprob failed, error code %d.\n", status); } } /* Free up the CPLEX environment, if necessary */ if ( p_env != NULL ) { status = CPXcloseCPLEX (&p_env); /* Note that CPXcloseCPLEX produces no output, so the only way to see the cause of the error is to use CPXgeterrorstring. For other CPLEX routines, the errors will be seen if the CPX_PARAM_SCRIND indicator is set to CPX_ON. */ if ( status ) { char errmsg[1024]; fprintf (stderr, "Could not close CPLEX environment.\n"); CPXgeterrorstring (p_env, status, errmsg); fprintf (stderr, "%s", errmsg); } } return (status); }
int main (void) { char probname[16]; /* Problem name is max 16 characters */ int cstat[NUMCOLS]; int rstat[NUMROWS]; /* Declare and allocate space for the variables and arrays where we will store the optimization results including the status, objective value, variable values, dual values, row slacks and variable reduced costs. */ int solstat; double objval; double x[NUMCOLS]; double pi[NUMROWS]; double slack[NUMROWS]; double dj[NUMCOLS]; CPXENVptr env = NULL; CPXLPptr lp = NULL; int status; int i, j; int cur_numrows, cur_numcols; /* Initialize the CPLEX environment */ env = CPXopenCPLEX (&status); /* If an error occurs, the status value indicates the reason for failure. A call to CPXgeterrorstring will produce the text of the error message. Note that CPXopenCPLEX produces no output, so the only way to see the cause of the error is to use CPXgeterrorstring. For other CPLEX routines, the errors will be seen if the CPXPARAM_ScreenOutput indicator is set to CPX_ON. */ if ( env == NULL ) { char errmsg[CPXMESSAGEBUFSIZE]; fprintf (stderr, "Could not open CPLEX environment.\n"); CPXgeterrorstring (env, status, errmsg); fprintf (stderr, "%s", errmsg); goto TERMINATE; } /* Turn on output to the screen */ status = CPXsetintparam (env, CPXPARAM_ScreenOutput, CPX_ON); if ( status ) { fprintf (stderr, "Failure to turn on screen indicator, error %d.\n", status); goto TERMINATE; } /* Create the problem. */ strcpy (probname, "example"); lp = CPXcreateprob (env, &status, probname); /* A returned pointer of NULL may mean that not enough memory was available or there was some other problem. In the case of failure, an error message will have been written to the error channel from inside CPLEX. In this example, the setting of the parameter CPXPARAM_ScreenOutput causes the error message to appear on stdout. */ if ( lp == NULL ) { fprintf (stderr, "Failed to create LP.\n"); goto TERMINATE; } /* Now populate the problem with the data. */ status = populatebycolumn (env, lp); if ( status ) { fprintf (stderr, "Failed to populate problem data.\n"); goto TERMINATE; } /* We assume we know the optimal basis. Variables 1 and 2 are basic, while variable 0 is at its upper bound */ cstat[0] = CPX_AT_UPPER; cstat[1] = CPX_BASIC; cstat[2] = CPX_BASIC; /* The row statuses are all nonbasic for this problem */ rstat[0] = CPX_AT_LOWER; rstat[1] = CPX_AT_LOWER; /* Now copy the basis */ status = CPXcopybase (env, lp, cstat, rstat); if ( status ) { fprintf (stderr, "Failed to copy the basis.\n"); goto TERMINATE; } /* Optimize the problem and obtain solution. */ status = CPXlpopt (env, lp); if ( status ) { fprintf (stderr, "Failed to optimize LP.\n"); goto TERMINATE; } status = CPXsolution (env, lp, &solstat, &objval, x, pi, slack, dj); if ( status ) { fprintf (stderr, "Failed to obtain solution.\n"); goto TERMINATE; } /* Write the output to the screen. */ printf ("\nSolution status = %d\n", solstat); printf ("Solution value = %f\n", objval); printf ("Iteration count = %d\n\n", CPXgetitcnt (env, lp)); /* The size of the problem should be obtained by asking CPLEX what the actual size is, rather than using sizes from when the problem was built. cur_numrows and cur_numcols store the current number of rows and columns, respectively. */ cur_numrows = CPXgetnumrows (env, lp); cur_numcols = CPXgetnumcols (env, lp); for (i = 0; i < cur_numrows; i++) { printf ("Row %d: Slack = %10f Pi = %10f\n", i, slack[i], pi[i]); } for (j = 0; j < cur_numcols; j++) { printf ("Column %d: Value = %10f Reduced cost = %10f\n", j, x[j], dj[j]); } /* Finally, write a copy of the problem to a file. */ status = CPXwriteprob (env, lp, "lpex6.sav", NULL); if ( status ) { fprintf (stderr, "Failed to write LP to disk.\n"); goto TERMINATE; } TERMINATE: /* Free up the problem as allocated by CPXcreateprob, if necessary */ if ( lp != NULL ) { status = CPXfreeprob (env, &lp); if ( status ) { fprintf (stderr, "CPXfreeprob failed, error code %d.\n", status); } } /* Free up the CPLEX environment, if necessary */ if ( env != NULL ) { status = CPXcloseCPLEX (&env); /* Note that CPXcloseCPLEX produces no output, so the only way to see the cause of the error is to use CPXgeterrorstring. For other CPLEX routines, the errors will be seen if the CPXPARAM_ScreenOutput indicator is set to CPX_ON. */ if ( status ) { char errmsg[CPXMESSAGEBUFSIZE]; fprintf (stderr, "Could not close CPLEX environment.\n"); CPXgeterrorstring (env, status, errmsg); fprintf (stderr, "%s", errmsg); } } return (status); } /* END main */
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { int i, j; double *c=NULL, *b=NULL, *A=NULL, *H=NULL, *l=NULL, *u=NULL, *x=NULL, *lambda=NULL ; int *nzA=NULL, *nzH=NULL ; int *iA=NULL, *kA=NULL ; int *iH=NULL, *kH=NULL ; #ifndef MX_COMPAT_32 long *iA_=NULL, *kA_=NULL ; long *iH_=NULL, *kH_=NULL ; #endif int neq=0, m=0, n=0, display=0; long *cpenv=NULL, *p_qp=NULL; char *Sense=NULL ; CPXENVptr env = NULL; CPXLPptr qp = NULL; int status, qpstat; double objval; double * p_qpstat ; char opt_method[128]="auto" ; if (nrhs > 10 || nrhs < 1) { mexErrMsgTxt("Usage: [x,lambda,how,p_qp] " "= qp_solve(cpenv,Q,c,A,b,l,u,neq,disp,method)"); return; } switch (nrhs) { case 10: if (mxGetM(prhs[9]) != 0 || mxGetN(prhs[9]) != 0) { if (mxIsNumeric(prhs[9]) || mxIsComplex(prhs[9]) || !mxIsChar(prhs[9]) || mxIsSparse(prhs[9]) || !(mxGetM(prhs[9])==1 && mxGetN(prhs[9])>=1)) { mexErrMsgTxt("10th argument (method) must be " "a string."); return; } mxGetString(prhs[9], opt_method, 128) ; } case 9: if (mxGetM(prhs[8]) != 0 || mxGetN(prhs[8]) != 0) { if (!mxIsNumeric(prhs[8]) || mxIsComplex(prhs[8]) || mxIsSparse(prhs[8]) || !(mxGetM(prhs[8])==1 && mxGetN(prhs[8])==1)) { mexErrMsgTxt("9th argument (display) must be " "an integer scalar."); return; } display = *mxGetPr(prhs[8]); } case 8: if (mxGetM(prhs[7]) != 0 || mxGetN(prhs[7]) != 0) { if (!mxIsNumeric(prhs[7]) || mxIsComplex(prhs[7]) || mxIsSparse(prhs[7]) || !(mxGetM(prhs[7])==1 && mxGetN(prhs[7])==1)) { mexErrMsgTxt("8th argument (neqcstr) must be " "an integer scalar."); return; } neq = *mxGetPr(prhs[7]); } case 7: if (mxGetM(prhs[6]) != 0 || mxGetN(prhs[6]) != 0) { if (!mxIsNumeric(prhs[6]) || mxIsComplex(prhs[6]) || mxIsSparse(prhs[6]) || !mxIsDouble(prhs[6]) || mxGetN(prhs[6])!=1 ) { mexErrMsgTxt("7th argument (u) must be " "a column vector."); return; } u = mxGetPr(prhs[6]); n = mxGetM(prhs[6]); } case 6: if (mxGetM(prhs[5]) != 0 || mxGetN(prhs[5]) != 0) { if (!mxIsNumeric(prhs[5]) || mxIsComplex(prhs[5]) || mxIsSparse(prhs[5]) || !mxIsDouble(prhs[5]) || mxGetN(prhs[5])!=1 ) { mexErrMsgTxt("6th argument (l) must be " "a column vector."); return; } if (n != 0 && n != mxGetM(prhs[5])) { mexErrMsgTxt("Dimension error (arg 6 and later)."); return; } l = mxGetPr(prhs[5]); n = mxGetM(prhs[5]); } case 5: if (mxGetM(prhs[4]) != 0 || mxGetN(prhs[4]) != 0) { if (!mxIsNumeric(prhs[4]) || mxIsComplex(prhs[4]) || mxIsSparse(prhs[4]) || !mxIsDouble(prhs[4]) || mxGetN(prhs[4])!=1 ) { mexErrMsgTxt("5th argument (b) must be " "a column vector."); return; } if (m != 0 && m != mxGetM(prhs[4])) { mexErrMsgTxt("Dimension error (arg 5 and later)."); return; } b = mxGetPr(prhs[4]); m = mxGetM(prhs[4]); } case 4: if (mxGetM(prhs[3]) != 0 || mxGetN(prhs[3]) != 0) { if (!mxIsNumeric(prhs[3]) || mxIsComplex(prhs[3]) || !mxIsSparse(prhs[3]) ) { mexErrMsgTxt("4th argument (A) must be " "a sparse matrix."); return; } if (m != 0 && m != mxGetM(prhs[3])) { mexErrMsgTxt("Dimension error (arg 4 and later)."); return; } if (n != 0 && n != mxGetN(prhs[3])) { mexErrMsgTxt("Dimension error (arg 4 and later)."); return; } m = mxGetM(prhs[3]); n = mxGetN(prhs[3]); A = mxGetPr(prhs[3]); #ifdef MX_COMPAT_32 iA = mxGetIr(prhs[3]); kA = mxGetJc(prhs[3]); #else iA_ = mxGetIr(prhs[3]); kA_ = mxGetJc(prhs[3]); iA = (int*)malloc(mxGetNzmax(prhs[3])*sizeof(int)) ; for (i=0; i<mxGetNzmax(prhs[3]); i++) iA[i]=iA_[i] ; kA = (int*)malloc((n+1)*sizeof(int)) ; for (i=0; i<n+1; i++) kA[i]=kA_[i] ; #endif nzA=myMalloc(n*sizeof(int)) ; for (i=0; i<n; i++) nzA[i]=kA[i+1]-kA[i] ; Sense=myMalloc((m+1)*sizeof(char)) ; for (i=0; i<m; i++) if (i<neq) Sense[i]='E' ; else Sense[i]='L' ; Sense[m]=0 ; } case 3: if (mxGetM(prhs[2]) != 0 || mxGetN(prhs[2]) != 0) { if (!mxIsNumeric(prhs[2]) || mxIsComplex(prhs[2]) || mxIsSparse(prhs[2]) || !mxIsDouble(prhs[2]) || mxGetN(prhs[2])!=1 ) { mexErrMsgTxt("3rd argument (c) must be " "a column vector."); return; } if (n != 0 && n != mxGetM(prhs[2])) { mexErrMsgTxt("Dimension error (arg 3 and later)."); return; } c = mxGetPr(prhs[2]); n = mxGetM(prhs[2]); } case 2: if (mxGetM(prhs[1]) != 0 || mxGetN(prhs[1]) != 0) { if (!mxIsNumeric(prhs[1]) || mxIsComplex(prhs[1]) || !mxIsSparse(prhs[1]) ) { mexErrMsgTxt("2nd argument (H) must be " "a sparse matrix."); return; } if (n != 0 && n != mxGetM(prhs[1])) { mexErrMsgTxt("Dimension error (arg 2 and later)."); return; } if (n != 0 && n != mxGetN(prhs[1])) { mexErrMsgTxt("Dimension error (arg 2 and later)."); return; } n = mxGetN(prhs[1]); H = mxGetPr(prhs[1]); #ifdef MX_COMPAT_32 iH = mxGetIr(prhs[1]); kH = mxGetJc(prhs[1]); #else iH_ = mxGetIr(prhs[1]); kH_ = mxGetJc(prhs[1]); iH = (int*)malloc(mxGetNzmax(prhs[1])*sizeof(int)) ; for (i=0; i<mxGetNzmax(prhs[1]); i++) iH[i]=iH_[i] ; kH = (int*)malloc((n+1)*sizeof(int)) ; for (i=0; i<n+1; i++) kH[i]=kH_[i] ; #endif nzH=myMalloc(n*sizeof(int)) ; for (i=0; i<n; i++) nzH[i]=kH[i+1]-kH[i] ; } case 1: if (mxGetM(prhs[0]) != 0 || mxGetN(prhs[0]) != 0) { if (!mxIsNumeric(prhs[0]) || mxIsComplex(prhs[0]) || mxIsSparse(prhs[0]) || !mxIsDouble(prhs[0]) || mxGetN(prhs[0])!=1 ) { mexErrMsgTxt("1st argument (cpenv) must be " "a column vector."); return; } if (1 != mxGetM(prhs[0])) { mexErrMsgTxt("Dimension error (arg 1)."); return; } cpenv = (long*) mxGetPr(prhs[0]); } } /*if (display>3) */ fprintf(STD_OUT,"argument processing finished") ; /* Initialize the CPLEX environment */ env = (CPXENVptr) cpenv[0] ; /* Turn on output to the screen */ if (display>0) status = CPXsetintparam (env, CPX_PARAM_SCRIND, CPX_ON); else status = CPXsetintparam (env, CPX_PARAM_SCRIND, CPX_OFF); if ( status ) { fprintf (STD_OUT, "Failure to turn on screen indicator, error %d.\n", status); goto TERMINATE; } status = CPXsetintparam (env, CPX_PARAM_SIMDISPLAY, display); if ( status ) { fprintf (STD_OUT,"Failed to turn up simplex display level.\n"); goto TERMINATE; } if (nlhs > 4 || nlhs < 1) { mexErrMsgTxt("Usage: [x,lambda,how,p_qp] " "= qp_solve(cpenv,H,c,A,b,l,u,neqcstr)"); return; } if (display>3) fprintf(STD_OUT, "(m=%i, n=%i, neq=%i) \n", m, n, neq) ; switch (nlhs) { case 4: plhs[3] = mxCreateDoubleMatrix(1, 1, mxREAL); p_qp = (long*) mxGetPr(plhs[3]); case 3: /* plhs[2] = mxCreateDoubleMatrix(1, 1, mxREAL); p_qpstat = mxGetPr(plhs[2]);*/ case 2: plhs[1] = mxCreateDoubleMatrix(m, 1, mxREAL); lambda = mxGetPr(plhs[1]); case 1: plhs[0] = mxCreateDoubleMatrix(n, 1, mxREAL); x = mxGetPr(plhs[0]); break; } if (display>2) fprintf(STD_OUT, "argument processing finished\n") ; if (strcmp(opt_method, "primal") && strcmp(opt_method, "dual") && strcmp(opt_method, "net") && strcmp(opt_method, "bar") && strcmp(opt_method, "sift") && strcmp(opt_method, "con") && strcmp(opt_method, "auto")) mexErrMsgTxt("method \\in " "{'auto','primal','dual','bar','net','sift','con'}\n") ; if (strcmp(opt_method, "primal")==0) status = CPXsetintparam (env, CPX_PARAM_QPMETHOD, 1); else if (strcmp(opt_method, "dual")==0) status = CPXsetintparam (env, CPX_PARAM_QPMETHOD, 2); else if (strcmp(opt_method, "net")==0) status = CPXsetintparam (env, CPX_PARAM_QPMETHOD, 3); else if (strcmp(opt_method, "bar")==0) status = CPXsetintparam (env, CPX_PARAM_QPMETHOD, 4); else if (strcmp(opt_method, "sift")==0) status = CPXsetintparam (env, CPX_PARAM_QPMETHOD, 5); else if (strcmp(opt_method, "con")==0) status = CPXsetintparam (env, CPX_PARAM_QPMETHOD, 6); else if (strcmp(opt_method, "auto")==0) status = CPXsetintparam (env, CPX_PARAM_QPMETHOD, 0); else status = 1 ; if ( status ) { fprintf (STD_OUT,"Failed to set QP method.\n"); goto TERMINATE; } /* Create the problem */ if (display>2) fprintf(STD_OUT, "calling CPXcreateprob \n") ; qp = CPXcreateprob (env, &status, "xxx"); if ( qp == NULL ) { fprintf (STD_OUT,"Failed to create subproblem\n"); status = 1; goto TERMINATE; } if (p_qp) *p_qp=(long) qp ; /* Copy network part of problem. */ /*if (display>2) */ fprintf(STD_OUT, "calling CPXcopylp (m=%i, n=%i) \n", m, n) ; status = CPXcopylp(env, qp, n, m, CPX_MIN, c, b, Sense, kA, nzA, iA, A, l, u, NULL); if ( status ) { fprintf (STD_OUT, "CPXcopylp failed.\n"); goto TERMINATE; } /*if (display>2) */ fprintf(STD_OUT, "calling CPXcopyquad \n") ; status = CPXcopyquad (env, qp, kH, nzH, iH, H); if ( status ) { fprintf (STD_OUT, "CPXcopyquad failed.\n"); goto TERMINATE; } /*if (display>2) */ fprintf(STD_OUT, "calling optimizer 'bar'\n") ; status = CPXqpopt (env, qp); if (display>3) fprintf(STD_OUT, "CPXbaropt=%i\n", status) ; if ( status ) { fprintf (STD_OUT,"CPXbaropt failed.\n"); goto TERMINATE; } if (display>2) fprintf(STD_OUT, "calling CPXsolution\n") ; status = CPXsolution (env, qp, &qpstat, &objval, x, lambda, NULL, NULL); if ( status ) { fprintf (STD_OUT,"CPXsolution failed.\n"); goto TERMINATE; } if (display>1) fprintf (STD_OUT, "Solution status: %i,%s\n", qpstat, err_str[qpstat]); if (display>2) fprintf (STD_OUT, "Objective value %g\n", objval); if (nlhs >= 3) if (qpstat==1) plhs[2] = mxCreateString(err_str[0]) ; else plhs[2] = mxCreateString(err_str[qpstat]) ; /* if (nlhs >= 3) if (qpstat==1) *p_qpstat = 0 ; else *p_qpstat = qpstat ;*/ TERMINATE: if (status) { char errmsg[1024]; CPXgeterrorstring (env, status, errmsg); fprintf (STD_OUT, "%s", errmsg); if (nlhs >= 3) plhs[2] = mxCreateString(errmsg) ; } ; if (nzA) myFree(nzA) ; if (nzH) myFree(nzH) ; if (Sense) myFree(Sense) ; #ifndef MX_COMPAT_32 if (iA) myFree(iA) ; if (kA) myFree(kA) ; if (iH) myFree(iH) ; if (kH) myFree(kH) ; #endif if (!p_qp) { if ( qp != NULL ) { if (display>2) fprintf(STD_OUT, "calling CPXfreeprob\n") ; status = CPXfreeprob (env, &qp); if ( status ) { fprintf (STD_OUT, "CPXfreeprob failed, error code %d.\n", status); } } } return ; }
int cg_solver(int m, MyRow* rows) { CPXENVptr env = NULL; CPXLPptr model = NULL; int status = 0; int error = 0; int i, j; int cur_numrows, cur_numcols; int n_cuts, cut; int solstat; double objval; double *x; double *z; int *cstat; int n0 = rows[0].n; int n1 = rows[0].n+m-1; /// One slack variable for constraint int h = (m-1)*n0 + m-1; /// Number of nonzeros double obj[n1]; double rhs[m-1]; /// The first row is for the cost vector char sense[m-1]; int jnd[h]; int ind[h]; double val[h]; int idx = 0; int* rmatbeg; int* rmatind; double* rmatval; double* b_bar; char* gc_sense; double* gc_rhs; /// Create environment env = CPXopenCPLEX (&status); if ( env == NULL ) { char errmsg[CPXMESSAGEBUFSIZE]; fprintf (stderr, "Could not open CPLEX environment. Status: %d\n", status); CPXgeterrorstring (env, status, errmsg); fprintf (stderr, "%s", errmsg); goto QUIT; } /// Disable presolve POST_CMD( CPXsetintparam (env, CPX_PARAM_PREIND, CPX_OFF) ); /// Create problem model = CPXcreateprob (env, &error, "gomory"); if (error) goto QUIT; /// Minimization problem POST_CMD( CPXchgobjsen (env, model, CPX_MIN) ); /// Add rows (remember first row is cost vector) for ( i = 0; i < m-1; ++i ) { sense[i]='E'; rhs[i] = rows[i+1].rhs; } POST_CMD( CPXnewrows(env, model, m-1, rhs, sense, NULL, NULL) ); /// Add problem variables for ( j = 0; j < n0; ++j ) obj[j] = rows[0].lhs[j]; /// Add slack variables for ( j = n0; j < n1; ++j ) obj[j] = 0; POST_CMD( CPXnewcols(env, model, n1, obj, NULL, NULL, NULL, NULL) ); /// Write the full matrix A into the LP (WARNING: should use only nonzeros entries) for ( i = 1; i < m; ++i ) { for ( j = 0; j < n0; ++j ) { jnd[idx] = i-1; ind[idx] = rows[i].ind[j]; val[idx] = rows[i].lhs[j]; idx++; } /// Add a slack variable per constraint jnd[idx] = i-1; ind[idx] = n0+i-1; val[idx] = 1.0; idx++; } POST_CMD( CPXchgcoeflist(env, model, idx, jnd, ind, val) ); /// Optimize the problem POST_CMD( CPXlpopt(env, model) ); /// Check the results cur_numrows = CPXgetnumrows (env, model); cur_numcols = CPXgetnumcols (env, model); x = (double *) malloc (cur_numcols * sizeof(double)); z = (double *) malloc (cur_numcols * sizeof(double)); cstat = (int *) malloc (cur_numcols * sizeof(int)); b_bar = (double *) malloc (cur_numrows * sizeof(double)); POST_CMD( CPXsolution (env, model, &solstat, &objval, x, NULL, NULL, NULL) ); if ( solstat != 1 ) { printf("The solver did not find an optimal solution\nSolver status code: %d\n",solstat); exit(0); } /// Write the output to the screen printf ("\nSolution status = %d\t\t", solstat); printf ("Solution value = %f\n\n", objval); /// If the solution is integer, is the optimum -> exit the loop if ( isInteger(cur_numcols, x) ) { fprintf(stdout,"The solution is already integer!\n"); goto QUIT; } /// Dump the problem model to 'gomory.lp' for debbuging POST_CMD( CPXwriteprob(env, model, "gomory.lp", NULL) ); /// Get the base statuses POST_CMD( CPXgetbase(env, model, cstat, NULL) ); print_solution(cur_numcols, x, cstat); printf("\nOptimal base inverted matrix:\n"); for ( i = 0; i < cur_numrows; ++i ) { b_bar[i] = 0; POST_CMD( CPXbinvrow(env, model, i, z) ); for ( j = 0; j < cur_numrows; ++j ) { printf("%.1f ", z[j]); b_bar[i] += z[j]*rhs[j]; } printf("\n"); } printf("\nOptimal solution (non basic variables are equal to zero):\n"); idx = 0; /// Compute the nonzeros n_cuts = 0; /// Number of fractional variables (cuts to be generated) for ( i = 0; i < m-1; ++i ) { POST_CMD( CPXbinvarow(env, model, i, z) ); for ( j = 0; j < n1; ++j ) { if ( z[j] >= 0 ) printf("+"); printf("%.1f x%d ", z[j], j+1); if ( floor(z[j]+0.5) != 0 ) idx++; } printf("= %.1f\n", b_bar[i]); /// Count the number of cuts to be generated if ( floor(b_bar[i]) != b_bar[i] ) n_cuts++; } /// Allocate memory for the new data structure gc_sense = (char*) malloc ( n_cuts * sizeof(char) ); gc_rhs = (double*) malloc ( n_cuts * sizeof(double) ); rmatbeg = (int*) malloc ( n_cuts * sizeof(int) ); rmatind = (int*) malloc ( idx * sizeof(int) ); rmatval = (double*) malloc ( idx * sizeof(double) ); printf("\nGenerate Gomory cuts:\n"); idx = 0; cut = 0; /// Index of cut to be added for ( i = 0; i < m-1; ++i ) if ( floor(b_bar[i]) != b_bar[i] ) { printf("Row %d gives cut -> ", i+1); POST_CMD( CPXbinvarow(env, model, i, z) ); rmatbeg[cut] = idx; for ( j = 0; j < n1; ++j ) { z[j] = floor(z[j]); /// DANGER! if ( z[j] != 0 ) { rmatind[idx] = j; rmatval[idx] = z[j]; idx++; } /// Print the cut if ( z[j] >= 0 ) printf("+"); printf("%.1f x%d ", z[j], j+1); } gc_rhs[cut] = floor(b_bar[i]); /// DANGER! gc_sense[cut] = 'L'; printf("<= %.1f\n", gc_rhs[cut]); cut++; } /// Add the new cuts POST_CMD( CPXaddrows (env, model, 0, n_cuts, idx, gc_rhs, gc_sense, rmatbeg, rmatind, rmatval, NULL, NULL) ); /// Solve the new LP POST_CMD( CPXlpopt(env, model) ); /// Check the results cur_numrows = CPXgetnumrows (env, model); cur_numcols = CPXgetnumcols (env, model); POST_CMD( CPXsolution (env, model, &solstat, &objval, x, NULL, NULL, NULL) ); if ( solstat != 1 ) { printf("The solver did not find an optimal solution\nSolver status code: %d\n",solstat); exit(0); } /// Write the output to the screen printf ("\nSolution status = %d\n", solstat); printf ("Solution value = %f\n\n", objval); POST_CMD( CPXgetbase(env, model, cstat, NULL) ); print_solution(cur_numcols, x, cstat); free_and_null ((char **) &x); free_and_null ((char **) &z); free_and_null ((char **) &cstat); free_and_null ((char **) &rmatbeg); free_and_null ((char **) &rmatind); free_and_null ((char **) &rmatval); QUIT: free_and_null ((char **) &x); free_and_null ((char **) &z); free_and_null ((char **) &cstat); if ( error ) { char errmsg[CPXMESSAGEBUFSIZE]; CPXgeterrorstring (env, error, errmsg); fprintf (stderr, "%s", errmsg); } /* Free up the problem as allocated by CPXcreateprob, if necessary */ if ( model != NULL ) { status = CPXfreeprob (env, &model); if ( status ) { fprintf (stderr, "CPXfreeprob failed, error code %d.\n", status); } } /* Free up the CPLEX environment, if necessary */ if ( env != NULL ) { status = CPXcloseCPLEX (&env); if ( error ) { char errmsg[CPXMESSAGEBUFSIZE]; fprintf (stderr, "Could not close CPLEX environment.\n"); CPXgeterrorstring (env, status, errmsg); fprintf (stderr, "%s", errmsg); } } return (status); }
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { int display=0, i=0; long *lpenv=NULL ; CPXENVptr env = NULL; int status ; double value ; char param_name[128] ; int param_code=-1, dblfound=0, strfound=0 ; if (nrhs > 7 || nrhs < 1) { mexErrMsgTxt("Usage: [how] " "= lp_set_param(lpenv, param_name, value, display)"); return; } switch (nrhs) { case 4: if (mxGetM(prhs[3]) != 0 || mxGetN(prhs[3]) != 0) { if (!mxIsNumeric(prhs[3]) || mxIsComplex(prhs[3]) || mxIsSparse(prhs[3]) || !(mxGetM(prhs[3])==1 && mxGetN(prhs[3])==1)) { mexErrMsgTxt("4th argument (display) must be " "an integer scalar."); return; } display = *mxGetPr(prhs[3]); } case 3: if (mxGetM(prhs[2]) != 0 || mxGetN(prhs[2]) != 0) { if (!mxIsNumeric(prhs[2]) || mxIsComplex(prhs[2]) || mxIsSparse(prhs[2]) || !(mxGetM(prhs[2])==1 && mxGetN(prhs[2])==1)) { mexErrMsgTxt("3rd argument (value) must be " "an integer scalar."); return; } value = *mxGetPr(prhs[2]); } case 2: if (mxGetM(prhs[1]) != 0 || mxGetN(prhs[1]) != 0) { if (mxIsNumeric(prhs[1]) || mxIsComplex(prhs[1]) || mxIsSparse(prhs[1]) || !mxIsChar(prhs[1]) || !(mxGetM(prhs[1])==1) && mxGetN(prhs[1])>=1) { mexErrMsgTxt("2nd argument (param) must be " "a string."); return; } mxGetString(prhs[1], param_name, 128); } case 1: if (mxGetM(prhs[0]) != 0 || mxGetN(prhs[0]) != 0) { if (!mxIsNumeric(prhs[0]) || mxIsComplex(prhs[0]) || mxIsSparse(prhs[0]) || !mxIsDouble(prhs[0]) || mxGetN(prhs[0])!=1 ) { mexErrMsgTxt("1st argument (lpenv) must be " "a column vector."); return; } if (1 != mxGetM(prhs[0])) { mexErrMsgTxt("Dimension error (arg 1)."); return; } lpenv = (long*) mxGetPr(prhs[0]); } } if (nlhs > 1 || nlhs < 1) { mexErrMsgTxt("Usage: [how] " "= lp_set_param(lpenv,param_name,value,disp)"); return; } if (display>2) fprintf(STD_OUT, "argument processing finished\n") ; /* Initialize the CPLEX environment */ env = (CPXENVptr) lpenv[0] ; for (i=0; i<NUM_PARAMS; i++) if (strcmp(param_info[i].name, param_name)==0) param_code=param_info[i].code ; if (display>3) fprintf(STD_OUT, "(param=%s(%i), value=%f) \n", param_name, param_code, value) ; if (param_code==-1) mxErrMsgTxt("illegal parameter name") ; for (i=0; i<NUM_DBLPARAMS; i++) if (param_code==dblParams[i]) dblfound=1 ; for (i=0; i<NUM_STRPARAMS; i++) if (param_code==strParams[i]) strfound=1 ; if (dblfound==1) { if (display>2) fprintf(STD_OUT, "calling CPXsetdblparam\n") ; status = CPXsetdblparam(env, param_code, value); if ( status ) { fprintf (STD_OUT, "CPXsetdblparam failed.\n"); goto TERMINATE; } } else if (strfound==1) { fprintf(STD_OUT, "sorry not implemented\n") ; } else { if (display>2) fprintf(STD_OUT, "calling CPXsetintparam\n") ; status = CPXsetintparam(env, param_code, (int)value); if ( status ) { fprintf (STD_OUT, "CPXsetintparam failed.\n"); goto TERMINATE; } } ; TERMINATE: if (status) { char errmsg[1024]; CPXgeterrorstring (env, status, errmsg); fprintf (STD_OUT, "%s", errmsg); if (nlhs >= 1) plhs[0] = mxCreateString(errmsg) ; } else if (nlhs >= 1) plhs[0] = mxCreateString("OK") ; ; return ; }
int main (void) { /* Declare pointers for the variables and arrays that will contain the data which define the LP problem. The setproblemdata() routine allocates space for the problem data. */ char *probname = NULL; int numcols; int numrows; int objsen; double *obj = NULL; double *rhs = NULL; char *sense = NULL; int *matbeg = NULL; int *matcnt = NULL; int *matind = NULL; double *matval = NULL; double *lb = NULL; double *ub = NULL; int *qmatbeg = NULL; int *qmatcnt = NULL; int *qmatind = NULL; double *qmatval = NULL; /* Declare and allocate space for the variables and arrays where we will store the optimization results including the status, objective value, variable values, dual values, row slacks and variable reduced costs. */ int solstat; double objval; double x[NUMCOLS]; double pi[NUMROWS]; double slack[NUMROWS]; double dj[NUMCOLS]; CPXENVptr env = NULL; CPXLPptr lp = NULL; int status; int i, j; int cur_numrows, cur_numcols; /* Initialize the CPLEX environment */ env = CPXopenCPLEX (&status); /* If an error occurs, the status value indicates the reason for failure. A call to CPXgeterrorstring will produce the text of the error message. Note that CPXopenCPLEX produces no output, so the only way to see the cause of the error is to use CPXgeterrorstring. For other CPLEX routines, the errors will be seen if the CPXPARAM_ScreenOutput indicator is set to CPX_ON. */ if ( env == NULL ) { char errmsg[CPXMESSAGEBUFSIZE]; fprintf (stderr, "Could not open CPLEX environment.\n"); CPXgeterrorstring (env, status, errmsg); fprintf (stderr, "%s", errmsg); goto TERMINATE; } /* Turn on output to the screen */ status = CPXsetintparam (env, CPXPARAM_ScreenOutput, CPX_ON); if ( status ) { fprintf (stderr, "Failure to turn on screen indicator, error %d.\n", status); goto TERMINATE; } /* Fill in the data for the problem. */ status = setproblemdata (&probname, &numcols, &numrows, &objsen, &obj, &rhs, &sense, &matbeg, &matcnt, &matind, &matval, &lb, &ub, &qmatbeg, &qmatcnt, &qmatind, &qmatval); if ( status ) { fprintf (stderr, "Failed to build problem data arrays.\n"); goto TERMINATE; } /* Create the problem. */ lp = CPXcreateprob (env, &status, probname); /* A returned pointer of NULL may mean that not enough memory was available or there was some other problem. In the case of failure, an error message will have been written to the error channel from inside CPLEX. In this example, the setting of the parameter CPXPARAM_ScreenOutput causes the error message to appear on stdout. */ if ( lp == NULL ) { fprintf (stderr, "Failed to create problem.\n"); goto TERMINATE; } /* Now copy the LP part of the problem data into the lp */ status = CPXcopylp (env, lp, numcols, numrows, objsen, obj, rhs, sense, matbeg, matcnt, matind, matval, lb, ub, NULL); if ( status ) { fprintf (stderr, "Failed to copy problem data.\n"); goto TERMINATE; } status = CPXcopyquad (env, lp, qmatbeg, qmatcnt, qmatind, qmatval); if ( status ) { fprintf (stderr, "Failed to copy quadratic matrix.\n"); goto TERMINATE; } /* Optimize the problem and obtain solution. */ status = CPXqpopt (env, lp); if ( status ) { fprintf (stderr, "Failed to optimize QP.\n"); goto TERMINATE; } status = CPXsolution (env, lp, &solstat, &objval, x, pi, slack, dj); if ( status ) { fprintf (stderr, "Failed to obtain solution.\n"); goto TERMINATE; } /* Write the output to the screen. */ printf ("\nSolution status = %d\n", solstat); printf ("Solution value = %f\n\n", objval); /* The size of the problem should be obtained by asking CPLEX what the actual size is, rather than using what was passed to CPXcopylp. cur_numrows and cur_numcols store the current number of rows and columns, respectively. */ cur_numrows = CPXgetnumrows (env, lp); cur_numcols = CPXgetnumcols (env, lp); for (i = 0; i < cur_numrows; i++) { printf ("Row %d: Slack = %10f Pi = %10f\n", i, slack[i], pi[i]); } for (j = 0; j < cur_numcols; j++) { printf ("Column %d: Value = %10f Reduced cost = %10f\n", j, x[j], dj[j]); } /* Finally, write a copy of the problem to a file. */ status = CPXwriteprob (env, lp, "qpex1.lp", NULL); if ( status ) { fprintf (stderr, "Failed to write LP to disk.\n"); goto TERMINATE; } TERMINATE: /* Free up the problem as allocated by CPXcreateprob, if necessary */ if ( lp != NULL ) { status = CPXfreeprob (env, &lp); if ( status ) { fprintf (stderr, "CPXfreeprob failed, error code %d.\n", status); } } /* Free up the CPLEX environment, if necessary */ if ( env != NULL ) { status = CPXcloseCPLEX (&env); /* Note that CPXcloseCPLEX produces no output, so the only way to see the cause of the error is to use CPXgeterrorstring. For other CPLEX routines, the errors will be seen if the CPXPARAM_ScreenOutput indicator is set to CPX_ON. */ if ( status ) { char errmsg[CPXMESSAGEBUFSIZE]; fprintf (stderr, "Could not close CPLEX environment.\n"); CPXgeterrorstring (env, status, errmsg); fprintf (stderr, "%s", errmsg); } } /* Free up the problem data arrays, if necessary. */ free_and_null ((char **) &probname); free_and_null ((char **) &obj); free_and_null ((char **) &rhs); free_and_null ((char **) &sense); free_and_null ((char **) &matbeg); free_and_null ((char **) &matcnt); free_and_null ((char **) &matind); free_and_null ((char **) &matval); free_and_null ((char **) &lb); free_and_null ((char **) &ub); free_and_null ((char **) &qmatbeg); free_and_null ((char **) &qmatcnt); free_and_null ((char **) &qmatind); free_and_null ((char **) &qmatval); return (status); } /* END main */
int main (void) { char probname[16]; /* Problem name is max 16 characters */ /* Declare and allocate space for the variables and arrays where we will store the optimization results including the status, objective value, variable values, dual values, row slacks and variable reduced costs. */ int solstat; double objval; double x[NUMCOLS]; double pi[NUMROWS]; double slack[NUMROWS]; double dj[NUMCOLS]; CPXENVptr env = NULL; CPXLPptr lp = NULL; int status; int i, j; int cur_numrows, cur_numcols; /* Initialize the CPLEX environment */ env = CPXopenCPLEX (&status); /* If an error occurs, the status value indicates the reason for failure. The error message will be printed at the end of the program. */ if ( env == NULL ) { fprintf (stderr, "Could not open CPLEX environment.\n"); goto TERMINATE; } /* Turn *off* output to the screen since we'll be producing it via the callback function. This also means we won't see any CPLEX generated errors, but we'll handle that at the end of the program. */ status = CPXsetintparam (env, CPXPARAM_ScreenOutput, CPX_OFF); if ( status ) { fprintf (stderr, "Failure to turn off screen indicator, error %d.\n", status); goto TERMINATE; } /* Create the problem. */ strcpy (probname, "example"); lp = CPXcreateprob (env, &status, probname); /* A returned pointer of NULL may mean that not enough memory was available or there was some other problem. In the case of failure, an error message will have been written to the error channel from inside CPLEX. In this example, we wouldn't see an error message from CPXcreateprob since we turned off the CPXPARAM_ScreenOutput parameter above. The only way to see this message would be to use the CPLEX message handler, but that clutters up the simplicity of this example, which has a point of illustrating the CPLEX callback functionality. */ if ( lp == NULL ) { fprintf (stderr, "Failed to create LP.\n"); goto TERMINATE; } /* Now populate the problem with the data. */ status = populatebycolumn (env, lp); if ( status ) { fprintf (stderr, "Failed to populate problem data.\n"); goto TERMINATE; } status = CPXsetlpcallbackfunc (env, mycallback, NULL); if ( status ) { fprintf (stderr, "Failed to set callback function.\n"); goto TERMINATE; } /* Optimize the problem and obtain solution. */ status = CPXsetintparam (env, CPXPARAM_LPMethod, CPX_ALG_PRIMAL); if ( status ) { fprintf (stderr, "Failed to set the optimization method, error %d.\n", status); goto TERMINATE; } status = CPXlpopt (env, lp); if ( status ) { fprintf (stderr, "Failed to optimize LP.\n"); goto TERMINATE; } /* Turn off the callback function. This isn't strictly necessary, but is good practice. Note that the cast in front of NULL is only necessary for some compilers. */ status = CPXsetlpcallbackfunc (env, (int (CPXPUBLIC *)(CPXCENVptr, void *, int, void *)) NULL, NULL); if ( status ) { fprintf (stderr, "Failed to turn off callback function.\n"); goto TERMINATE; } status = CPXsolution (env, lp, &solstat, &objval, x, pi, slack, dj); if ( status ) { fprintf (stderr, "Failed to obtain solution.\n"); goto TERMINATE; } /* Write the output to the screen. */ printf ("\nSolution status = %d\n", solstat); printf ("Solution value = %f\n\n", objval); /* The size of the problem should be obtained by asking CPLEX what the actual size is, rather than using sizes from when the problem was built. cur_numrows and cur_numcols store the current number of rows and columns, respectively. */ cur_numrows = CPXgetnumrows (env, lp); cur_numcols = CPXgetnumcols (env, lp); for (i = 0; i < cur_numrows; i++) { printf ("Row %d: Slack = %10f Pi = %10f\n", i, slack[i], pi[i]); } for (j = 0; j < cur_numcols; j++) { printf ("Column %d: Value = %10f Reduced cost = %10f\n", j, x[j], dj[j]); } /* Finally, write a copy of the problem to a file. */ status = CPXwriteprob (env, lp, "lpex4.lp", NULL); if ( status ) { fprintf (stderr, "Failed to write LP to disk.\n"); goto TERMINATE; } TERMINATE: /* Free up the problem as allocated by CPXcreateprob, if necessary */ if ( lp != NULL ) { int frstatus; frstatus = CPXfreeprob (env, &lp); if ( frstatus ) { fprintf (stderr, "CPXfreeprob failed, error code %d.\n", frstatus); if (( !status ) && frstatus ) status = frstatus; } } /* Free up the CPLEX environment, if necessary */ if ( env != NULL ) { int clstatus; clstatus = CPXcloseCPLEX (&env); if ( clstatus ) { fprintf (stderr, "CPXcloseCPLEX failed, error code %d.\n", clstatus); if (( !status ) && clstatus ) status = clstatus; } } if ( status ) { char errmsg[CPXMESSAGEBUFSIZE]; /* Note that since we have turned off the CPLEX screen indicator, we'll need to print the error message ourselves. */ CPXgeterrorstring (env, status, errmsg); fprintf (stderr, "%s", errmsg); } return (status); } /* END main */
int main (int argc, char *argv[]) { int status = 0; /* Declare and allocate space for the variables and arrays where we will store the optimization results, including the status, objective value, and variable values */ int solstat; double objval; double *x = NULL; CPXENVptr env = NULL; CPXLPptr lp = NULL; int j; int cur_numcols; CPXFILEptr logfile = NULL; int wantorig = 1; int nameind = 1; /* Check the command line arguments */ if ( argc != 2 ) { if ( argc != 3 || argv[1][0] != '-' || argv[1][1] != 'r' ) { usage (argv[0]); goto TERMINATE; } wantorig = 0; nameind = 2; } /* Initialize the CPLEX environment */ env = CPXopenCPLEX (&status); /* If an error occurs, the status value indicates the reason for failure. A call to CPXgeterrorstring will produce the text of the error message. Note that CPXopenCPLEX produces no output, so the only way to see the cause of the error is to use CPXgeterrorstring. For other CPLEX routines, the errors will be seen if the CPXPARAM_ScreenOutput parameter is set to CPX_ON */ if ( env == NULL ) { char errmsg[CPXMESSAGEBUFSIZE]; fprintf (stderr, "Could not open CPLEX environment.\n"); CPXgeterrorstring (env, status, errmsg); fprintf (stderr, "%s", errmsg); goto TERMINATE; } /* Turn on output to the screen */ status = CPXsetintparam (env, CPXPARAM_ScreenOutput, CPX_ON); if ( status != 0 ) { fprintf (stderr, "Failure to turn on screen indicator, error %d.\n", status); goto TERMINATE; } /* Set MIP parameters */ status = CPXsetintparam (env, CPXPARAM_MIP_Limits_Nodes, 10000); if ( status ) goto TERMINATE; /* Open a logfile */ logfile = CPXfopen ("admipex3.log", "a"); if ( logfile == NULL ) goto TERMINATE; status = CPXsetlogfile (env, logfile); if ( status ) goto TERMINATE; /* Create the problem, using the filename as the problem name */ lp = CPXcreateprob (env, &status, argv[nameind]); /* A returned pointer of NULL may mean that not enough memory was available or there was some other problem. In the case of failure, an error message will have been written to the error channel from inside CPLEX. In this example, the setting of the parameter CPXPARAM_ScreenOutput causes the error message to appear on stdout. Note that most CPLEX routines return an error code to indicate the reason for failure */ if ( lp == NULL ) { fprintf (stderr, "Failed to create LP.\n"); goto TERMINATE; } /* Now read the file, and copy the data into the created lp */ status = CPXreadcopyprob (env, lp, argv[nameind], NULL); if ( status ) { fprintf (stderr, "Failed to read and copy the problem data.\n"); goto TERMINATE; } /* Set up to use MIP callbacks */ status = CPXsetbranchcallbackfunc (env, usersetbranch, NULL); if ( status ) goto TERMINATE; if ( wantorig ) { /* Assure linear mappings between the presolved and original models */ status = CPXsetintparam (env, CPXPARAM_Preprocessing_Linear, 0); if ( status ) goto TERMINATE; /* Let MIP callbacks work on the original model */ status = CPXsetintparam (env, CPXPARAM_MIP_Strategy_CallbackReducedLP, CPX_OFF); if ( status ) goto TERMINATE; } /* Turn on traditional search for use with control callbacks */ status = CPXsetintparam (env, CPXPARAM_MIP_Strategy_Search, CPX_MIPSEARCH_TRADITIONAL); if ( status ) goto TERMINATE; /* Optimize the problem and obtain solution */ status = CPXmipopt (env, lp); if ( status ) { fprintf (stderr, "Failed to optimize MIP.\n"); goto TERMINATE; } solstat = CPXgetstat (env, lp); printf ("Solution status %d.\n", solstat); status = CPXgetobjval (env, lp, &objval); if ( status ) { fprintf (stderr,"Failed to obtain objective value.\n"); goto TERMINATE; } printf ("Objective value %.10g\n", objval); cur_numcols = CPXgetnumcols (env, lp); /* Allocate space for solution */ x = (double *) malloc (cur_numcols * sizeof (double)); if ( x == NULL ) { fprintf (stderr, "No memory for solution values.\n"); goto TERMINATE; } status = CPXgetx (env, lp, x, 0, cur_numcols-1); if ( status ) { fprintf (stderr, "Failed to obtain solution.\n"); goto TERMINATE; } /* Write out the solution */ for (j = 0; j < cur_numcols; j++) { if ( fabs (x[j]) > 1e-10 ) { printf ( "Column %d: Value = %17.10g\n", j, x[j]); } } TERMINATE: /* Free the solution vector */ free_and_null ((char **) &x); /* Free the problem as allocated by CPXcreateprob and CPXreadcopyprob, if necessary */ if ( lp != NULL ) { status = CPXfreeprob (env, &lp); if ( status ) { fprintf (stderr, "CPXfreeprob failed, error code %d.\n", status); } } /* Free the CPLEX environment, if necessary */ if ( env != NULL ) { status = CPXcloseCPLEX (&env); /* Note that CPXcloseCPLEX produces no output, so the only way to see the cause of the error is to use CPXgeterrorstring. For other CPLEX routines, the errors will be seen if the CPXPARAM_ScreenOutput parameter is set to CPX_ON */ if ( status ) { char errmsg[CPXMESSAGEBUFSIZE]; fprintf (stderr, "Could not close CPLEX environment.\n"); CPXgeterrorstring (env, status, errmsg); fprintf (stderr, "%s", errmsg); } } if ( logfile != NULL ) CPXfclose (logfile); return (status); } /* END main */
int main (int argc, char *argv[]) { /* Declare and allocate space for the variables and arrays where we will store the optimization results including the status, objective value, maximum bound violation, variable values, and basis. */ time_t start, end; /* returns elapsed time in sec */ // clock_t start, end; /* for elapsed CPU time */ double total_time; start = clock(); int solnstat, solnmethod, solntype; double objval, maxviol; double *x = NULL; int *cstat = NULL; int *rstat = NULL; CPXENVptr env = NULL; CPXLPptr lp = NULL; int status = 0; int j; int cur_numrows, cur_numcols; int method; char *basismsg; /* Check the command line arguments */ if (( argc != 4 ) || ( strchr ("podhbnsc", argv[2][0]) == NULL ) ) { usage (argv[0]); goto TERMINATE; } /* Initialize the CPLEX environment */ env = CPXopenCPLEX (&status); /* If an error occurs, the status value indicates the reason for failure. A call to CPXgeterrorstring will produce the text of the error message. Note that CPXopenCPLEX produces no output, so the only way to see the cause of the error is to use CPXgeterrorstring. For other CPLEX routines, the errors will be seen if the CPX_PARAM_SCRIND indicator is set to CPX_ON. */ if ( env == NULL ) { char errmsg[CPXMESSAGEBUFSIZE]; fprintf (stderr, "Could not open CPLEX environment.\n"); CPXgeterrorstring (env, status, errmsg); fprintf (stderr, "%s", errmsg); goto TERMINATE; } /* Turn on output to the screen */ status = CPXsetintparam (env, CPX_PARAM_SCRIND, CPX_ON); if ( status ) { fprintf (stderr, "Failure to turn on screen indicator, error %d.\n", status); goto TERMINATE; } /* Create the problem, using the filename as the problem name */ lp = CPXcreateprob (env, &status, argv[1]); /* A returned pointer of NULL may mean that not enough memory was available or there was some other problem. In the case of failure, an error message will have been written to the error channel from inside CPLEX. In this example, the setting of the parameter CPX_PARAM_SCRIND causes the error message to appear on stdout. Note that most CPLEX routines return an error code to indicate the reason for failure. */ if ( lp == NULL ) { fprintf (stderr, "Failed to create LP.\n"); goto TERMINATE; } /* Now read the file, and copy the data into the created lp */ status = CPXreadcopyprob (env, lp, argv[1], NULL); if ( status ) { fprintf (stderr, "Failed to read and copy the problem data.\n"); goto TERMINATE; } /* Optimize the problem and obtain solution. */ switch (argv[2][0]) { case 'o': method = CPX_ALG_AUTOMATIC; break; case 'p': method = CPX_ALG_PRIMAL; break; case 'd': method = CPX_ALG_DUAL; break; case 'n': method = CPX_ALG_NET; break; case 'h': method = CPX_ALG_BARRIER; break; case 'b': method = CPX_ALG_BARRIER; status = CPXsetintparam (env, CPX_PARAM_BARCROSSALG, CPX_ALG_NONE); if ( status ) { fprintf (stderr, "Failed to set the crossover method, error %d.\n", status); goto TERMINATE; } break; case 's': method = CPX_ALG_SIFTING; break; case 'c': method = CPX_ALG_CONCURRENT; break; default: method = CPX_ALG_NONE; break; } status = CPXsetintparam (env, CPX_PARAM_LPMETHOD, method); if ( status ) { fprintf (stderr, "Failed to set the optimization method, error %d.\n", status); goto TERMINATE; } status = CPXlpopt (env, lp); if ( status ) { fprintf (stderr, "Failed to optimize LP.\n"); goto TERMINATE; } solnstat = CPXgetstat (env, lp); if ( solnstat == CPX_STAT_UNBOUNDED ) { printf ("Model is unbounded\n"); goto TERMINATE; } else if ( solnstat == CPX_STAT_INFEASIBLE ) { printf ("Model is infeasible\n"); goto TERMINATE; } else if ( solnstat == CPX_STAT_INForUNBD ) { printf ("Model is infeasible or unbounded\n"); goto TERMINATE; } status = CPXsolninfo (env, lp, &solnmethod, &solntype, NULL, NULL); if ( status ) { fprintf (stderr, "Failed to obtain solution info.\n"); goto TERMINATE; } printf ("Solution status %d, solution method %d\n", solnstat, solnmethod); if ( solntype == CPX_NO_SOLN ) { fprintf (stderr, "Solution not available.\n"); goto TERMINATE; } status = CPXgetobjval (env, lp, &objval); if ( status ) { fprintf (stderr, "Failed to obtain objective value.\n"); goto TERMINATE; } printf ("Objective value %.10g.\n", objval); /* The size of the problem should be obtained by asking CPLEX what the actual size is. cur_numrows and cur_numcols store the current number of rows and columns, respectively. */ cur_numcols = CPXgetnumcols (env, lp); cur_numrows = CPXgetnumrows (env, lp); /* Retrieve basis, if one is available */ if ( solntype == CPX_BASIC_SOLN ) { cstat = (int *) malloc (cur_numcols*sizeof(int)); rstat = (int *) malloc (cur_numrows*sizeof(int)); if ( cstat == NULL || rstat == NULL ) { fprintf (stderr, "No memory for basis statuses.\n"); goto TERMINATE; } status = CPXgetbase (env, lp, cstat, rstat); if ( status ) { fprintf (stderr, "Failed to get basis; error %d.\n", status); goto TERMINATE; } } else { printf ("No basis available\n"); } /* Retrieve solution vector */ x = (double *) malloc (cur_numcols*sizeof(double)); if ( x == NULL ) { fprintf (stderr, "No memory for solution.\n"); goto TERMINATE; } status = CPXgetx (env, lp, x, 0, cur_numcols-1); if ( status ) { fprintf (stderr, "Failed to obtain primal solution.\n"); goto TERMINATE; } status = CPXsolwrite(env,lp,argv[3]); /* Write out the solution for (j = 0; j < cur_numcols; j++) { printf ( "Column %d: Value = %17.10g", j, x[j]); if ( cstat != NULL ) { switch (cstat[j]) { case CPX_AT_LOWER: basismsg = "Nonbasic at lower bound"; break; case CPX_BASIC: basismsg = "Basic"; break; case CPX_AT_UPPER: basismsg = "Nonbasic at upper bound"; break; case CPX_FREE_SUPER: basismsg = "Superbasic, or free variable at zero"; break; default: basismsg = "Bad basis status"; break; } printf (" %s",basismsg); } printf ("\n"); } */ /* Display the maximum bound violation. */ status = CPXgetdblquality (env, lp, &maxviol, CPX_MAX_PRIMAL_INFEAS); if ( status ) { fprintf (stderr, "Failed to obtain bound violation.\n"); goto TERMINATE; } printf ("Maximum bound violation = %17.10g\n", maxviol); TERMINATE: /* Free up the basis and solution */ free_and_null ((char **) &cstat); free_and_null ((char **) &rstat); free_and_null ((char **) &x); /* Free up the problem, if necessary */ if ( lp != NULL ) { status = CPXfreeprob (env, &lp); if ( status ) { fprintf (stderr, "CPXfreeprob failed, error code %d.\n", status); } } /* Free up the CPLEX environment, if necessary */ if ( env != NULL ) { status = CPXcloseCPLEX (&env); /* Note that CPXcloseCPLEX produces no output, so the only way to see the cause of the error is to use CPXgeterrorstring. For other CPLEX routines, the errors will be seen if the CPX_PARAM_SCRIND indicator is set to CPX_ON. */ if ( status ) { char errmsg[CPXMESSAGEBUFSIZE]; fprintf (stderr, "Could not close CPLEX environment.\n"); CPXgeterrorstring (env, status, errmsg); fprintf (stderr, "%s", errmsg); } } end = clock(); total_time = (double)( end - start )/(double)CLOCKS_PER_SEC ; printf( "\nElapsed time : %0.3f \n", total_time ); return (status); } /* END main */
extern int solve_allocation(int nodeSize, int windowSize, int timeout, sched_nodeinfo_t *node_array, solver_job_list_t *job_array) { solver_job_list_t *sjob_ptr; struct job_details *job_det_ptr; int solstat; int n = windowSize, m = nodeSize; double objval; double *x = NULL; double *pi = NULL; double *slack = NULL; double *dj = NULL; CPXENVptr env = NULL; CPXLPptr lp = NULL; int status = 0; int i, j, k; int cur_numrows, cur_numcols; char envstr[256]; sprintf(envstr,"ILOG_LICENSE_FILE=%s",get_cplex_license_address()); if ( envstr != NULL ) { CPXputenv (envstr); } env = CPXopenCPLEX (&status); if ( env == NULL ) { char errmsg[1024]; fatal ("Could not open CPLEX environment.\n"); CPXgeterrorstring (env, status, errmsg); fprintf (stderr, "%s", errmsg); goto TERMINATE; } status = CPXsetintparam (env, CPX_PARAM_SCRIND, CPX_ON); if (status) { fatal("Failure to turn on screen indicator, error %d.",status); goto TERMINATE; } status = CPXsetintparam (env, CPX_PARAM_DATACHECK, CPX_ON); if (status) { fatal("Failure to turn on data checking, error %d.", status); goto TERMINATE; } lp = CPXcreateprob (env, &status, "lpex1"); if (lp == NULL) { fatal("Failed to create LP."); goto TERMINATE; } status = CPXsetdblparam(env,CPX_PARAM_TILIM,timeout); status = populatebynonzero (env, lp, m, n, timeout, node_array, job_array); if ( status ) { fprintf (stderr, "Failed to populate problem."); goto TERMINATE; } status = CPXlpopt (env, lp); if ( status ) { fprintf (stderr, "Failed to optimize LP."); goto TERMINATE; } cur_numrows = CPXgetnumrows (env, lp); cur_numcols = CPXgetnumcols (env, lp); x = (double *) malloc (cur_numcols * sizeof(double)); slack = (double *) malloc (cur_numrows * sizeof(double)); dj = (double *) malloc (cur_numcols * sizeof(double)); pi = (double *) malloc (cur_numrows * sizeof(double)); if ( x == NULL || slack == NULL || dj == NULL || pi == NULL ) { status = CPXERR_NO_MEMORY; fatal ("Could not allocate memory for solution."); goto TERMINATE; } status = CPXsolution (env, lp, &solstat, &objval, x, pi, slack, dj); if ( status ) { fatal ("Failed to obtain solution."); goto TERMINATE; } for (j = 0; j < windowSize; j++) { if (x[j] > 0) { sjob_ptr = &job_array[j]; job_det_ptr = sjob_ptr->job_ptr->details; sjob_ptr->node_bitmap = (bitstr_t *) bit_alloc (node_record_count); job_det_ptr->req_node_bitmap = (bitstr_t *) bit_alloc (node_record_count); sjob_ptr->onnodes = (uint32_t *) xmalloc (sizeof(uint32_t) * node_record_count); job_det_ptr->req_node_layout = (uint16_t *) xmalloc (sizeof(uint16_t) * node_record_count); job_det_ptr->req_node_bitmap = (bitstr_t *) bit_alloc (node_record_count); for (i = 0; i < nodeSize; i++) { k = (1 + i) * windowSize + j; if (x[k] > 0) { bit_set (sjob_ptr->node_bitmap, (bitoff_t) (i)); bit_set (job_det_ptr->req_node_bitmap, (bitoff_t) (i)); node_array[i].rem_cpus -= x[k]; node_array[i].rem_gpus -= sjob_ptr->gpu; sjob_ptr->onnodes[i] = x[k]; job_det_ptr->req_node_layout[i] = sjob_ptr->onnodes[i]; sjob_ptr->alloc_total += x[k]; } } } else job_array[j].alloc_total = 0; } TERMINATE: free_and_null ((char **) &x); free_and_null ((char **) &slack); free_and_null ((char **) &dj); free_and_null ((char **) &pi); if (lp != NULL) { status = CPXfreeprob (env, &lp); if (status) { fatal("CPXfreeprob failed, error code %d.", status); } } if (env != NULL) { status = CPXcloseCPLEX (&env); if (status) { char errmsg[1024]; fatal("Could not close CPLEX environment."); CPXgeterrorstring (env, status, errmsg); fatal("%s", errmsg); } } return (status); }
int main (void) { char probname[16]; /* Problem name is max 16 characters */ /* Declare and allocate space for the variables and arrays where we will store the optimization results including the status, objective value, variable values, dual values, row slacks and variable reduced costs. */ int solstat; double objval; double x[NUMCOLS]; double pi[NUMROWS]; double slack[NUMROWS]; double dj[NUMCOLS]; CPXENVptr env = NULL; CPXLPptr lp = NULL; int status; int i, j; int cur_numrows, cur_numcols; char errmsg[CPXMESSAGEBUFSIZE]; CPXCHANNELptr cpxerror = NULL; CPXCHANNELptr cpxwarning = NULL; CPXCHANNELptr cpxresults = NULL; CPXCHANNELptr ourchannel = NULL; char errorlabel[] = "cpxerror"; char warnlabel[] = "cpxwarning"; char reslabel[] = "cpxresults"; char ourlabel[] = "Our Channel"; char ourmessage[] = "Our Message"; CPXFILEptr fpout = NULL; /* Initialize the CPLEX environment */ env = CPXopenCPLEX (&status); /* If an error occurs, the status value indicates the reason for failure. A call to CPXgeterrorstring will produce the text of the error message. Note that CPXopenCPLEX produces no output, so the only way to see the cause of the error is to use CPXgeterrorstring. For other CPLEX routines, the errors will be seen if the CPXPARAM_ScreenOutput indicator is set to CPX_ON. */ /* Since the message handler is yet to be set up, we'll call our messaging function directly to print out any errors */ if ( env == NULL ) { ourmsgfunc (ourmessage, "Could not open CPLEX environment.\n"); goto TERMINATE; } /* Now get the standard channels. If an error, just call our message function directly. */ status = CPXgetchannels (env, &cpxresults, &cpxwarning, &cpxerror, NULL); if ( status ) { ourmsgfunc (ourmessage, "Could not get standard channels.\n"); CPXgeterrorstring (env, status, errmsg); ourmsgfunc (ourmessage, errmsg); goto TERMINATE; } /* Now set up the error channel first. The label will be "cpxerror" */ status = CPXaddfuncdest (env, cpxerror, errorlabel, ourmsgfunc); if ( status ) { ourmsgfunc (ourmessage, "Could not set up error message handler.\n"); CPXgeterrorstring (env, status, errmsg); ourmsgfunc (ourmessage, errmsg); } /* Now that we have the error message handler set up, all CPLEX generated errors will go through ourmsgfunc. So we don't have to use CPXgeterrorstring to determine the text of the message. We can also use CPXmsg to do any other printing. */ status = CPXaddfuncdest (env, cpxwarning, warnlabel, ourmsgfunc); if ( status ) { CPXmsg (cpxerror, "Failed to set up handler for cpxwarning.\n"); goto TERMINATE; } status = CPXaddfuncdest (env, cpxresults, reslabel, ourmsgfunc); if ( status ) { CPXmsg (cpxerror, "Failed to set up handler for cpxresults.\n"); goto TERMINATE; } /* Now turn on the iteration display. */ status = CPXsetintparam (env, CPXPARAM_Simplex_Display, 2); if ( status ) { CPXmsg (cpxerror, "Failed to turn on simplex display level.\n"); goto TERMINATE; } /* Create the problem. */ strcpy (probname, "example"); lp = CPXcreateprob (env, &status, probname); /* A returned pointer of NULL may mean that not enough memory was available or there was some other problem. In the case of failure, an error message will have been written to the error channel from inside CPLEX. In this example, the setting of the parameter CPXPARAM_ScreenOutput causes the error message to appear on stdout. */ if ( lp == NULL ) { CPXmsg (cpxerror, "Failed to create LP.\n"); goto TERMINATE; } /* Now populate the problem with the data. */ status = populatebycolumn (env, lp); if ( status ) { CPXmsg (cpxerror, "Failed to populate problem data.\n"); goto TERMINATE; } /* Optimize the problem and obtain solution. */ status = CPXlpopt (env, lp); if ( status ) { CPXmsg (cpxerror, "Failed to optimize LP.\n"); goto TERMINATE; } status = CPXsolution (env, lp, &solstat, &objval, x, pi, slack, dj); if ( status ) { CPXmsg (cpxerror, "Failed to obtain solution.\n"); goto TERMINATE; } /* Write the output to the screen. We will also write it to a file as well by setting up a file destination and a function destination. */ ourchannel = CPXaddchannel (env); if ( ourchannel == NULL ) { CPXmsg (cpxerror, "Failed to set up our private channel.\n"); goto TERMINATE; } fpout = CPXfopen ("lpex5.msg", "w"); if ( fpout == NULL ) { CPXmsg (cpxerror, "Failed to open lpex5.msg file for output.\n"); goto TERMINATE; } status = CPXaddfpdest (env, ourchannel, fpout); if ( status ) { CPXmsg (cpxerror, "Failed to set up output file destination.\n"); goto TERMINATE; } status = CPXaddfuncdest (env, ourchannel, ourlabel, ourmsgfunc); if ( status ) { CPXmsg (cpxerror, "Failed to set up our output function.\n"); goto TERMINATE; } /* Now any message to channel ourchannel will go into the file and into the file opened above. */ CPXmsg (ourchannel, "\nSolution status = %d\n", solstat); CPXmsg (ourchannel, "Solution value = %f\n\n", objval); /* The size of the problem should be obtained by asking CPLEX what the actual size is, rather than using sizes from when the problem was built. cur_numrows and cur_numcols store the current number of rows and columns, respectively. */ cur_numrows = CPXgetnumrows (env, lp); cur_numcols = CPXgetnumcols (env, lp); for (i = 0; i < cur_numrows; i++) { CPXmsg (ourchannel, "Row %d: Slack = %10f Pi = %10f\n", i, slack[i], pi[i]); } for (j = 0; j < cur_numcols; j++) { CPXmsg (ourchannel, "Column %d: Value = %10f Reduced cost = %10f\n", j, x[j], dj[j]); } /* Finally, write a copy of the problem to a file. */ status = CPXwriteprob (env, lp, "lpex5.lp", NULL); if ( status ) { CPXmsg (cpxerror, "Failed to write LP to disk.\n"); goto TERMINATE; } TERMINATE: /* First check if ourchannel is open */ if ( ourchannel != NULL ) { int chanstat; chanstat = CPXdelfuncdest (env, ourchannel, ourlabel, ourmsgfunc); if ( chanstat ) { strcpy (errmsg, "CPXdelfuncdest failed.\n"); ourmsgfunc (ourmessage, errmsg); if (!status) status = chanstat; } if ( fpout != NULL ) { chanstat = CPXdelfpdest (env, ourchannel, fpout); if ( chanstat ) { strcpy (errmsg, "CPXdelfpdest failed.\n"); ourmsgfunc (ourmessage, errmsg); if (!status) status = chanstat; } CPXfclose (fpout); } chanstat = CPXdelchannel (env, &ourchannel); if ( chanstat ) { strcpy (errmsg, "CPXdelchannel failed.\n"); ourmsgfunc (ourmessage, errmsg); if (!status) status = chanstat; } } /* Free up the problem as allocated by CPXcreateprob, if necessary */ if ( lp != NULL ) { status = CPXfreeprob (env, &lp); if ( status ) { strcpy (errmsg, "CPXfreeprob failed.\n"); ourmsgfunc (ourmessage, errmsg); } } /* Now delete our function destinations from the 3 CPLEX channels. */ if ( cpxresults != NULL ) { int chanstat; chanstat = CPXdelfuncdest (env, cpxresults, reslabel, ourmsgfunc); if ( chanstat && !status ) { status = chanstat; strcpy (errmsg, "Failed to delete cpxresults function.\n"); ourmsgfunc (ourmessage, errmsg); } } if ( cpxwarning != NULL ) { int chanstat; chanstat = CPXdelfuncdest (env, cpxwarning, warnlabel, ourmsgfunc); if ( chanstat && !status ) { status = chanstat; strcpy (errmsg, "Failed to delete cpxwarning function.\n"); ourmsgfunc (ourmessage, errmsg); } } if ( cpxerror != NULL ) { int chanstat; chanstat = CPXdelfuncdest (env, cpxerror, errorlabel, ourmsgfunc); if ( chanstat && !status ) { status = chanstat; strcpy (errmsg, "Failed to delete cpxerror function.\n"); ourmsgfunc (ourmessage, errmsg); } } /* Free up the CPLEX environment, if necessary */ if ( env != NULL ) { status = CPXcloseCPLEX (&env); /* Note that CPXcloseCPLEX produces no output, so the only way to see the cause of the error is to use CPXgeterrorstring. For other CPLEX routines, the errors will be seen if the CPXPARAM_ScreenOutput indicator is set to CPX_ON. */ if ( status ) { strcpy (errmsg, "Could not close CPLEX environment.\n"); ourmsgfunc (ourmessage, errmsg); CPXgeterrorstring (env, status, errmsg); ourmsgfunc (ourmessage, errmsg); } } return (status); } /* END main */