/* nag_opt_lp (e04mfc) Example Program. * * Copyright 1991 Numerical Algorithms Group. * * Mark 2, 1991. * Mark 6 revised, 2000. * Mark 8 revised, 2004. */ #include #include #include #include #include static int ex1(void); static int ex2(void); int main(void) { Integer exit_status_ex1=0; Integer exit_status_ex2=0; /* Two examples are called, ex1() uses the * default settings to solve a problem while * ex2() solves another problem with some * of the optional parameters set by the user. */ Vprintf("nag_opt_lp (e04mfc) Example Program Results.\n"); exit_status_ex1 = ex1(); exit_status_ex2 = ex2(); return exit_status_ex1 == 0 && exit_status_ex2 == 0 ? 0 : 1; } #define A(I,J) a[(I)*tda + J] static int ex1(void) { Integer exit_status=0, i, j, n, nbnd, nclin, tda; NagError fail; double *a=0, *bl=0, *bu=0, *cvec=0, objf, *x=0; INIT_FAIL(fail); Vprintf("\nExample 1: default options used.\n"); Vscanf(" %*[^\n]"); /* Skip headings in data file */ Vscanf(" %*[^\n]"); /* Set the actual problem dimensions. * n = the number of variables. * nclin = the number of general linear constraints (may be 0). * nbnd = the number of variables + linear constraints */ n = 7; nclin = 7; nbnd = n + nclin; /* cvec = the objective function coefficients. * a = the linear constraint matrix. * bl = the lower bounds on x and A*x. * bu = the upper bounds on x and A*x. * x = the initial estimate of the solution. */ if ( n>=1 && nclin>=0 ) { if ( !( x = NAG_ALLOC(n, double)) || !( cvec = NAG_ALLOC(n, double)) || !( a = NAG_ALLOC(nclin*n, double)) || !( bl = NAG_ALLOC(nbnd, double)) || !( bu = NAG_ALLOC(nbnd, double)) ) { Vprintf("Allocation failure\n"); exit_status = -1; goto END; } tda = n; } else { Vprintf("Invalid n or nclin.\n"); exit_status = 1; return exit_status; } /* Read the objective function coefficients */ Vscanf(" %*[^\n]"); /* Skip heading in data file */ for (i = 0; i < n; ++i) Vscanf("%lf",&cvec[i]); /* Read the linear constraint matrix A. */ Vscanf(" %*[^\n]"); /* Skip heading in data file */ for (i = 0; i < nclin; ++i) for (j = 0; j < n; ++j) Vscanf("%lf",&A(i,j)); /* Read the bounds. */ nbnd = n + nclin; Vscanf(" %*[^\n]"); /* Skip heading in data file */ for (i = 0; i < nbnd; ++i) Vscanf("%lf", &bl[i]); Vscanf(" %*[^\n]"); /* Skip heading in data file */ for (i = 0; i < nbnd; ++i) Vscanf("%lf", &bu[i]); /* Read the initial estimate of x. */ Vscanf(" %*[^\n]"); /* Skip heading in data file */ for (i = 0; i < n; ++i) Vscanf("%lf",&x[i]); /* Solve the problem. */ /* nag_opt_lp (e04mfc). * Linear programming */ nag_opt_lp(n, nclin, a, tda, bl, bu, cvec, x, &objf, E04_DEFAULT, NAGCOMM_NULL, &fail); if (fail.code != NE_NOERROR) { Vprintf("Error from nag_opt_lp (e04mfc).\n%s\n", fail.message); exit_status = 1; goto END; } END: if (x) NAG_FREE(x); if (cvec) NAG_FREE(cvec); if (a) NAG_FREE(a); if (bl) NAG_FREE(bl); if (bu) NAG_FREE(bu); return exit_status; } /* ex1 */ static int ex2(void) { /* This sample linear program (LP) is a portfolio investment problem * (see Chapter 7, pp 258--262 of ``Numerical Linear Algebra and * Optimization'', by Gill, Murray and Wright, Addison Wesley, 1991). * The problem involves the rearrangement of a portfolio of three * stocks, Glitter, Risky and Trusty, so that the net worth of the * investor is maximized. * The problem is characterized by the following data: * Glitter Risky Trusty * 1990 Holdings 75 1000 25 * 1990 Priceshare($) 20 2 100 * 2099 Priceshare($) 18 3 102 * 2099 Dividend 5 0 2 * * The variables x[0], x[1] and x[2] represent the change in each of * the three stocks. */ Nag_Boolean print; Integer exit_status=0, n, nbnd, nclin, tda; NagError fail; Nag_E04_Opt options; double *a=0, bigbnd, *bl=0, *bu=0, *cvec=0, objf, *x=0; INIT_FAIL(fail); Vprintf("\nExample 2: some optional parameters are set.\n"); /* Set the actual problem dimensions. * n = the number of variables. * nclin = the number of general linear constraints (may be 0). */ n = 3; nclin = 5; nbnd = n+nclin; if ( n>=1 && nclin>=0 ) { if ( !( x = NAG_ALLOC(n, double)) || !( cvec = NAG_ALLOC(n, double)) || !( a = NAG_ALLOC(nclin*n, double)) || !( bl = NAG_ALLOC(nbnd, double)) || !( bu = NAG_ALLOC(nbnd, double)) ) { Vprintf("Allocation failure\n"); exit_status = -1; goto END; } tda = n; } else { Vprintf("Invalid n or nclin.\n"); exit_status = 1; return exit_status; } /* Define the value used to denote ``infinite'' bounds. */ bigbnd = 1e+25; /* Objective function: maximize 5*X[0] + 2*X[2], or equivalently, * minimize -5*X[0] - 2*X[2]. */ cvec[0] = -5.0; cvec[1] = 0.0; cvec[2] = -2.0; /* a = the general constraint matrix. * bl = the lower bounds on x and A*x. * bu = the upper bounds on x and A*x. * x = the initial estimate of the solution. * * A nonnegative amount of stock must be present after rearrangement. * For Glitter: x[0] + 75 >= 0. */ bl[0] = -75.0; bu[0] = bigbnd; /* For Risky: x[1] + 1000 >= 0.0 */ bl[1] = -1000.0; bu[1] = bigbnd; /* For Trusty: x[2] + 25 >= 0.0 */ bl[2] = -25.0; bu[2] = bigbnd; /* The current value of the portfolio must be the same after * rearrangement, i.e., * 20*(75+x[0]) + 2*(1000+x[1]) + 100*(25+x[2]) = 6000, or * 20*x[0] + 2*x[1] + 100*x[2] = 0. */ A(0,0) = 20.0; A(0,1) = 2.0; A(0,2) = 100.0; bl[n] = 0.0; bu[n] = 0.0; /* The value of the portfolio must increase by at least 5 per cent * at the end of the year, i.e., * 18*(75+x[0]) + 3*(1000+x[1]) + 102*(25+x[2]) >= 6300, or * 18*x[0] + 3*x[1] + 102*x[2] >= -600. */ A(1,0) = 18.0; A(1,1) = 3.0; A(1,2) = 102.0; bl[n + 1] = -600.0; bu[n + 1] = bigbnd; /* There are three ``balanced portfolio'' constraints. The value of * a stock must constitute at least a quarter of the total final * value of the portfolio. After rearrangement, the value of the * portfolio after is 20*(75+x[0]) + 2*(1000+x[1]) + 100*(25+x[2]). * * If Glitter is to constitute at least a quarter of the final * portfolio, then 15*x[0] - 0.5*x[1] - 25*x[2] >= 0. */ A(2,0) = 15.0; A(2,1) = -0.5; A(2,2) = -25.0; bl[n + 2] = 0.0; bu[n + 2] = bigbnd; /* If Risky is to constitute at least a quarter of the final * portfolio, then -5*x[0] + 1.5*x[1] - 25*x[2] >= -500. */ A(3,0) = -5.0; A(3,1) = 1.5; A(3,2) = -25.0; bl[n + 3] = -500.0; bu[n + 3] = bigbnd; /* If Trusty is to constitute at least a quarter of the final * portfolio, then -5*x[0] - 0.5*x[1] + 75*x[2] >= -1000. */ A(4,0) = -5.0; A(4,1) = -0.5; A(4,2) = 75.0; bl[n + 4] = -1000.0; bu[n + 4] = bigbnd; /* Set the initial estimate of the solution. * This portfolio is infeasible. */ x[0] = 10.0; x[1] = 20.0; x[2] = 100.0; /* Initialise options structure to null values. */ /* nag_opt_init (e04xxc). * Initialization function for option setting */ nag_opt_init(&options); /* Set one option */ options.inf_bound = bigbnd; /* Solve the problem. */ /* nag_opt_lp (e04mfc), see above. */ nag_opt_lp(n, nclin, a, tda, bl, bu, cvec, x, &objf, &options, NAGCOMM_NULL, &fail); if (fail.code != NE_NOERROR) { Vprintf("Error from nag_opt_lp (e04mfc).\n%s\n", fail.message); exit_status = 1; goto END; } /* Re-solve the problem with some additonal options. */ Vprintf("Re-solve problem with output of iteration results"); Vprintf(" suppressed and ftol = 1.0e-10.\n"); /* Read additional options from a file. */ print = Nag_TRUE; /* nag_opt_read (e04xyc). * Read options from a text file */ nag_opt_read("e04mfc", "stdin", &options, print, "stdout", &fail); if (fail.code != NE_NOERROR) { Vprintf("Error from nag_opt_read (e04xyc).\n%s\n", fail.message); exit_status = 1; goto END; } /* Reset starting point */ x[0] = 0.0; x[1] = 0.0; x[2] = 0.0; /* Solve the problem again. */ /* nag_opt_lp (e04mfc), see above. */ nag_opt_lp(n, nclin, a, tda, bl, bu, cvec, x, &objf, &options, NAGCOMM_NULL, &fail); if (fail.code != NE_NOERROR) { Vprintf("Error from nag_opt_lp (e04mfc).\n%s\n", fail.message); exit_status = 1; goto END; } /* Free memory allocated by nag_opt_lp (e04mfc) to pointers in options. */ /* nag_opt_free (e04xzc). * Memory freeing function for use with option setting */ nag_opt_free(&options, "all", &fail); if (fail.code != NE_NOERROR) { Vprintf("Error from nag_opt_free (e04xzc).\n%s\n", fail.message); exit_status = 1; goto END; } END: if (x) NAG_FREE(x); if (cvec) NAG_FREE(cvec); if (a) NAG_FREE(a); if (bl) NAG_FREE(bl); if (bu) NAG_FREE(bu); return exit_status; } /* ex2 */