/* Name: simple.c ** Author: Leo Liberti ** Purpose: simple example illustrating CPLEX callable library ** Source: C ** History: 060220 work started */ // standard include files #include #include #include #include #include #include // maximum length of variable/constraint names #define MAXNAME 64 int main(int argc, char** argv) { // return code int ret = 0; // status code returned by cplex callable library functions int status = 0; // number of rows (constraints) int m = 0; // number of columns (variables) int n = 0; // cplex environment to pass to/from cplex callable library CPXENVptr env = NULL; // cplex linear program to pass to/from cplex callable library CPXLPptr lp = NULL; // use for storing error messages returned by CPLEX char errmsg[1024]; // counters int i, j; // try to initialize the CPLEX environment env = CPXopenCPLEX(&status); if (env == NULL) { fprintf(stderr, "%s: could not open CPLEX environment\n", argv[0]); CPXgeterrorstring (env, status, errmsg); fprintf (stderr, "%s", errmsg); exit(2); } // turn on output to screen status = CPXsetintparam(env, CPX_PARAM_SCRIND, CPX_ON); status = CPXsetintparam (env, CPX_PARAM_SIMDISPLAY, 2); if (status != 0) { fprintf(stderr, "%s: could not turn on screen indicator, error %d\n", argv[0], status); exit(3); } // create the problem max{x1+x2 | x1+2x2<=2, 2x1+x2<=2, x>= 0} lp = CPXcreateprob(env, &status, "simple"); if (lp == NULL) { fprintf(stderr, "%s: failed to create problem\n"); exit(4); } // two variables n = 2; // two constraints m = 2; // objective function coefficients double *c = (double*) malloc(n * sizeof(double)); c[0] = -1.0; c[1] = -1.0; // variable lower bounds double *xL = (double*) malloc(n * sizeof(double)); xL[0] = 0.0; xL[1] = 0.0; // variable upper bounds double *xU = (double*) malloc(n * sizeof(double)); xU[0] = CPX_INFBOUND; xU[1] = CPX_INFBOUND; // variable names char** xn = (char**) malloc(n * sizeof(char*)); for(j = 0; j < n; j++) { xn[j] = (char*) malloc(MAXNAME * sizeof(char)); } strncpy(xn[0], "x1", MAXNAME); strncpy(xn[1], "x2", MAXNAME); // create the variables status = CPXnewcols(env, lp, 2, c, xL, xU, NULL, xn); if (status != 0) { fprintf(stderr, "%s: could not create variables, error %d\n", argv[0], status); exit(3); } // add constraints in row-wise sparse format // number of nonzeroes in constraint matrix int nzcnt = 4; // rmatval = {1.0, 2.0, 2.0, 1.0}, rmatind = {1,2,1,2}, rmatbeg = {1,2,4} int* rmatbeg = (int*) malloc((m+1) * sizeof(int)); // first row, nonzeroes stored in rmatval starting at position: rmatbeg[0] = 0; // second row, nonzeroes stored in rmatval starting at position: rmatbeg[1] = 2; // nonzeroes in rmatval end at position: rmatbeg[2] = 4; // column indices of nonzero entries int* rmatind = (int*) malloc(nzcnt * sizeof(int)); // first entry, 1.0, is in column 1 rmatind[0] = 0; // second entry, 2.0, is in column 2 rmatind[1] = 1; // third entry, 2.0, is in column 1 rmatind[2] = 0; // fourth entry, 1.0, is in column 2 rmatind[3] = 1; // nonzero entries double* rmatval = (double*) malloc(nzcnt * sizeof(double)); // matrix is [ [1,2], [2,1] ] rmatval[0] = 1.0; rmatval[1] = 2.0; rmatval[2] = 2.0; rmatval[3] = 1.0; // constraint right-hand sides double* rhs = (double*) malloc(m * sizeof(double)); // rhs is [2,2] rhs[0] = 2; rhs[1] = 2; // constraint sense char* csense = (char*) malloc(m * sizeof(char)); // constraints are "less than or equal to" csense[0] = 'L'; csense[1] = 'L'; // create the constraints status = CPXaddrows(env, lp, 0, m, nzcnt, rhs, csense, rmatbeg, rmatind, rmatval, NULL, NULL); if (status != 0) { fprintf(stderr, "%s: could not create constraints, error %d\n", argv[0], status); exit(3); } // select the optimization algorithm status = CPXsetintparam(env, CPX_PARAM_LPMETHOD, CPX_ALG_AUTOMATIC); if (status != 0) { fprintf(stderr, "%s: could not select optimization algorithm, error %d\n", argv[0], status); exit(3); } // write the problem in .lp form status = CPXwriteprob(env, lp, "simple.lp", NULL); if (status != 0) { fprintf(stderr, "%s: could not write simple.lp\n", argv[0]); exit(6); } // optimize status = CPXlpopt(env, lp); if (status != 0) { fprintf(stderr, "%s: failed to call optimization algorithm\n", argv[0]); exit(10); } // get solution information // value of the objective function double objval = 0; // values of the primal problem variables double *x = (double*) malloc(n * sizeof(double)); for(j = 0; j < n; j++) { x[j] = 0.0; } // values of the dual problem variables double *y = (double*) malloc(m * sizeof(double)); for(i = 0; i < m; i++) { y[i] = 0.0; } // values of the slack variables double *s = (double*) malloc(m * sizeof(double)); for(i = 0; i < m; i++) { s[i] = 0.0; } // reduced costs double *rc = (double*) malloc(n * sizeof(double)); for(j = 0; j < n; j++) { rc[j] = 0.0; } CPXsolution(env, lp, &status, &objval, x, y, s, rc); // print solution printf("%s: solution of problem \"simple\":\n", argv[0]); printf(" solver return status = %d\n", status); printf(" optimal objective function value = %f\n", objval); printf(" optimal primal variables:\n ( "); for(j = 0; j < n; j++) { printf("%f ", x[j]); } printf(")\n"); printf(" optimal dual variables:\n ( "); for(i = 0; i < m; i++) { printf("%f ", y[i]); } printf(")\n"); printf(" optimal slack variables:\n ( "); for(i = 0; i < m; i++) { printf("%f ", y[i]); } printf(")\n"); // free storage CPXfreeprob(env, &lp); free(rc); free(s); free(y); free(x); free(csense); free(rhs); free(rmatval); free(rmatind); free(rmatbeg); for(j = n - 1; j >= 0; j--) { free(xn[j]); } free(xn); free(xU); free(xL); free(c); return ret; }