/* Name: diet.c ** Author: Leo Liberti ** Purpose: diet problem ** Source: C ** History: 060220 work started */ // standard include files #include #include #include #include #include #include // maximum length of variable/constraint names #define MAXNAME 64 void AddConstraint(CPXENVptr env, CPXLPptr lp, int nz, double* coeffs, int* ind, char sense, double rhs) { int status = 0; // add constraints in row-wise sparse format int rmatbeg[2]; // nonzeroes stored in rmatval starting at position: rmatbeg[0] = 0; // nonzeroes stored in rmatval ending at position: rmatbeg[1] = nz-1; // create the constraints status = CPXaddrows(env, lp, 0, 1, nz, &rhs, &sense, rmatbeg, ind, coeffs, NULL, NULL); if (status != 0) { fprintf(stderr, "api: could not create constraints, error %d\n", status); exit(3); } } 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, "diet"); if (lp == NULL) { fprintf(stderr, "%s: failed to create problem\n"); exit(4); } // size of the problem n = 9; m = 7; // constraint matrix double A[][9] = { { 510, 370, 500, 370, 400, 220, 345, 110, 80}, { 34, 35, 42, 38, 42, 26, 27, 12, 20}, { 28, 24, 25, 14, 31, 3, 15, 9, 1}, { 15, 15, 6, 2, 8 , 0, 4 , 10, 2}, { 6, 10, 2, 0, 15, 15, 0 , 4, 120}, { 30, 20, 25, 15, 15, 0, 20, 30, 2}, { 20, 20, 20, 10, 8 , 2, 15, 0, 2} } ; // food prices double c[9] = { 1.84, 2.19, 1.84, 1.44, 2.29, 0.77, 1.29, 0.60, 0.72 }; // nutrient requirements double b[7] = { 2000, 350, 55, 100, 100, 100, 100 }; // create the variables status = CPXnewcols(env, lp, n, c, NULL, NULL, NULL, NULL); if (status != 0) { fprintf(stderr, "%s: could not create variables, error %d\n", argv[0], status); exit(3); } // add constraints int theind[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; for(i = 0; i < m; i++) { AddConstraint(env, lp, n, A[i], theind, 'G', b[i]); } // 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); } // 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 \"diet\":\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); return ret; }