/* nag_opt_lp (e04mfc) Example Program. * * Copyright 1991 Numerical Algorithms Group. * * Mark 2, 1991. * Mark 6 revised, 2000. * Mark 8 revised, 2004. */ /* 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. */ #include #include #include #include #include #include #define A(I, J) a[(I) *tda + J] int main(int argc, char *argv[]) { FILE *fpout; char *optionsfile = 0; char *outfile = 0; Integer exit_status = 0; Nag_Boolean print; Integer n, nbnd, nclin, tda; Nag_E04_Opt options; double *a = 0, bigbnd, *bl = 0, *bu = 0, *cvec = 0, objf, *x = 0; NagError fail; INIT_FAIL(fail); /* Check for command-line IO options */ fpout = nag_example_file_io(argc, argv, "-results", NULL); (void) nag_example_file_io(argc, argv, "-options", &optionsfile); (void) nag_example_file_io(argc, argv, "-nag_write", &outfile); if (!outfile) { outfile = NAG_ALLOC(7, char); strcpy(outfile, "stdout"); } fprintf(fpout, "nag_opt_lp (e04mfc) Example Program Results\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))) { fprintf(fpout, "Allocation failure\n"); exit_status = -1; goto END; } tda = n; } else { fprintf(fpout, "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); strcpy(options.outfile, outfile); options.inf_bound = bigbnd; /* Solve the problem. */ /* nag_opt_lp (e04mfc), see above. */ if (strcmp(outfile, "stdout")) fclose(fpout); nag_opt_lp(n, nclin, a, tda, bl, bu, cvec, x, &objf, &options, NAGCOMM_NULL, &fail); if (strcmp(outfile, "stdout")) { fpout = fopen(outfile, "a"); } if (fail.code != NE_NOERROR) { fprintf(fpout, "Error from nag_opt_lp (e04mfc).\n%s\n", fail.message); exit_status = 1; goto END; } /* Re-solve the problem with some additonal options. */ fprintf(fpout, "Re-solve problem with output of iteration results"); fprintf(fpout, " 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 */ if (strcmp(outfile, "stdout")) fclose(fpout); nag_opt_read("e04mfc", optionsfile, &options, print, options.outfile, &fail); if (strcmp(outfile, "stdout")) { fpout = fopen(outfile, "a"); } if (fail.code != NE_NOERROR) { fprintf(fpout, "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. */ if (strcmp(outfile, "stdout")) fclose(fpout); nag_opt_lp(n, nclin, a, tda, bl, bu, cvec, x, &objf, &options, NAGCOMM_NULL, &fail); if (strcmp(outfile, "stdout")) { fpout = fopen(outfile, "a"); } if (fail.code != NE_NOERROR) { fprintf(fpout, "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) { fprintf(fpout, "Error from nag_opt_free (e04xzc).\n%s\n", fail.message); exit_status = 1; goto END; } END: if (fpout != stdout) fclose(fpout); 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); if (optionsfile) NAG_FREE(optionsfile); if (outfile) NAG_FREE(outfile); return exit_status; }