/* nag_mip_handle_solve_minlp (h02ddc) Example Program.
*
* Copyright 2024 Numerical Algorithms Group.
*
* Mark 30.3, 2024.
*/
#include <math.h>
#include <nag.h>
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
static void NAG_CALL objfun(Integer nvar, const double x[], double *fx,
Integer *flag, Nag_Comm *comm);
static void NAG_CALL objgrd(Integer nvar, const double x[], Integer nnzfd,
double fdx[], Integer *flag, Nag_Comm *comm);
static void NAG_CALL confun(Integer nvar, const double x[], Integer ncnln,
double gx[], Integer *flag, Nag_Comm *comm);
static void NAG_CALL congrd(Integer nvar, const double x[], Integer nnzgd,
double gdx[], Integer *flag, Nag_Comm *comm);
#ifdef __cplusplus
}
#endif
int main(void) {
#define BIGBND 1.0E20
/* Scalars */
Integer exit_status = 0;
Integer p, i, idlc, nvar, nclin, ncnln, nnzfd, nnzgd, flag, lgourp = 4;
double rho;
/* Arrays */
double rinfo[100], stats[100], *x = 0;
double *fdx = 0, *gdx = 0;
Integer idxfd[4] = {1, 2, 3, 4};
double bl[8] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
double bu[8] = {BIGBND, BIGBND, BIGBND, BIGBND, 1.0, 1.0, 1.0, 1.0};
double linbl[5] = {1.0, 0.0, 0.0, 0.0, 0.0};
double linbu[5] = {1.0, BIGBND, BIGBND, BIGBND, BIGBND};
double nlnbl[2] = {0.0, 0.0};
double nlnbu[2] = {0.0, BIGBND};
Integer irowb[12] = {1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5};
Integer icolb[12] = {1, 2, 3, 4, 1, 5, 2, 6, 3, 7, 4, 8};
double b[12] = {1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0,};
Integer irowgd[4] = {1, 1, 1, 1};
Integer icolgd[4] = {1, 2, 3, 4};
Integer group[4] = {5, 6, 7, 8};
char ptype[] = "BINARY";
Integer iuser[1];
double ruser[1];
void *handle = 0;
/* Nag Types */
NagError fail;
Nag_FileID nout;
Nag_Comm comm;
/* Problem size */
nvar = 8;
/* Objective gradient nonzero elements quantity */
nnzfd = 4;
/* Constraint jacobian nonzero elements quantity */
nnzgd = 4;
printf("nag_mip_handle_solve_minlp (h02ddc) Example Program Results\n\n");
fflush(stdout);
/* nag_opt_handle_init (e04rac).
* Initialize an empty problem handle with NVAR variables.
*/
nag_opt_handle_init(&handle, nvar, NAGERR_DEFAULT);
/* nag_opt_handle_set_simplebounds (e04rhc).
* Define bounds on the variables
*/
nag_opt_handle_set_simplebounds(handle, nvar, bl, bu, NAGERR_DEFAULT);
/* nag_opt_handle_set_nlnobj (e04rgc).
* Define nonlinear objective
*/
nag_opt_handle_set_nlnobj(handle, nnzfd, idxfd, NAGERR_DEFAULT);
/* Add one linear constraint */
nclin = 5;
idlc = 0;
/* nag_opt_handle_set_linconstr (e04rjc).
* Define a block of linear constraints
*/
nag_opt_handle_set_linconstr(handle, nclin, linbl, linbu, 12, irowb,
icolb, b, &idlc, NAGERR_DEFAULT);
/* Add two nonlinear constraints */
ncnln = 2;
/* nag_opt_handle_set_nlnconstr (e04rkc).
* Define a block of nonlinear constraints
*/
nag_opt_handle_set_nlnconstr(handle, ncnln, nlnbl, nlnbu, nnzgd, irowgd,
icolgd, NAGERR_DEFAULT);
/* nag_opt_handle_set_property (e04rcc)
* Define integer variables */
nag_opt_handle_set_property(handle, ptype, lgourp, group, NAGERR_DEFAULT);
if (!(x = NAG_ALLOC(nvar, double))) {
printf("Allocation failure\n");
exit_status = -1;
goto END;
}
/* Initial estimate (binary variables need not be given) */
x[0] = x[1] = x[2] = x[3] = 1.0;
x[4] = x[5] = x[6] = x[7] = 0.0;
/* Disable printing */
nag_opt_handle_opt_set(handle, "Print Level = 0", NAGERR_DEFAULT);
/* Do not print options */
nag_opt_handle_opt_set(handle, "Print Options = No", NAGERR_DEFAULT);
/* Do not print solution, x and f(x) will be printed afterwards */
nag_opt_handle_opt_set(handle, "Print Solution = No", NAGERR_DEFAULT);
/* Portfolio parameters */
p = 3;
rho = 10.0;
iuser[0] = p;
comm.iuser = iuser;
ruser[0] = rho;
comm.user = ruser;
INIT_FAIL(fail);
/* nag_mip_handle_solve_minlp (h02ddc).
* Call the solver
*/
nag_mip_handle_solve_minlp(handle, objfun, objgrd, confun, congrd, NULLFN,
nvar, x, rinfo, stats, &comm, &fail);
if (fail.code == NE_NOERROR) {
NAG_FREE(fdx);
NAG_FREE(gdx);
/* Results */
printf("\nFinal estimate:");
for (i = 0; i < nvar; i++) {
printf("\nx[%4" NAG_IFMT "] = %12.4f", i + 1, x[i]);
}
printf("\n\nOptimised value = %12.4g\n", rinfo[0]);
} else {
printf("Error from nag_mip_handle_solve_minlp (h02ddc).\n%s\n",
fail.message);
exit_status = 1;
}
if (handle)
/* nag_opt_handle_free (e04rzc).
* Destroy the problem handle and deallocate all the memory used
*/
nag_opt_handle_free(&handle, NAGERR_DEFAULT);
NAG_FREE(x);
END:
return exit_status;
}
/* Subroutine */
static void NAG_CALL objfun(Integer nvar, const double x[], double *fx,
Integer *flag, Nag_Comm *comm) {
*flag = 0;
*fx = x[0] * (4.0 * x[0] + 3.0 * x[1] - x[2])
+ x[1] * (3.0 * x[0] + 6.0 * x[1] + x[2])
+ x[2] * (x[1] - x[0] + 10.0 * x[2]);
}
static void NAG_CALL objgrd(Integer nvar, const double x[], Integer nnzfd,
double fdx[], Integer *flag, Nag_Comm *comm) {
*flag = 0;
fdx[0] = 8.0 * x[0] + 6.0 * x[1] - 2.0 * x[2];
fdx[1] = 6.0 * x[0] + 12.0 * x[1] + 2.0 * x[2];
fdx[2] = 2.0 * (x[1] - x[0]) + 20.0 * x[2];
fdx[3] = 0.0;
}
static void NAG_CALL confun(Integer nvar, const double x[], Integer ncnln,
double gx[], Integer *flag, Nag_Comm *comm) {
*flag = 0;
Integer p = comm->iuser[0];
double rho = comm->user[0];
/* Mean return rho */
gx[0] = 8.0 * x[0] + 9.0 * x[1] + 12.0 * x[2] + 7.0 * x[3] - rho;
/* Maximum of p assets in portfolio */
gx[1] = (double)p - x[4] - x[5] - x[6] - x[7];
}
static void NAG_CALL congrd(Integer nvar, const double x[], Integer nnzgd,
double gdx[], Integer *flag, Nag_Comm *comm) {
*flag = 0;
gdx[0] = 8.0;
gdx[1] = 9.0;
gdx[2] = 12.0;
gdx[3] = 7.0;
}