static void mod_funcdef_clear(struct py_function_def *def) { mod_objclear(&def->function); mod_objclear(&def->module); free_and_null(&def->function_name); free_and_null(&def->module_name); }
/*! free free resources associated with p_udf_dirent. */ bool udf_dirent_free(udf_dirent_t *p_udf_dirent) { if (p_udf_dirent) { p_udf_dirent->fid = NULL; free_and_null(p_udf_dirent->psz_name); free_and_null(p_udf_dirent->sector); free_and_null(p_udf_dirent); } return true; }
void sharpel1pca (double *points_XT, int *dataDim, int *q, double *PCs, double *objectives) { ENTITYINFO entityinfo; SOLVERINFO solverinfo; PROBLEMINFO probleminfo; probleminfo.status = 0; int status = probleminfo.status; solverinfo.model = NULL; probleminfo.obj = NULL; probleminfo.lb = NULL; probleminfo.ub = NULL; probleminfo.rhs = NULL; probleminfo.matbeg = NULL; probleminfo.matind = NULL; probleminfo.matval = NULL; probleminfo.colname = NULL; probleminfo.PCs = PCs; /*probleminfo.getScores = *getScores; probleminfo.scores = scores;*/ probleminfo.objectives = objectives; entityinfo.numentities_n = dataDim[1]; entityinfo.numattributes_m = dataDim[0]; entityinfo.points_XT = points_XT; /* transpose of data matrix */ probleminfo.q = *q; /* desired number of PCs */ status = allocateMemoryL1Line(&entityinfo, &probleminfo); if (status) { REprintf ("Unable to allocate memory\n"); goto TERMINATE; } status = solveSharpeL1PCA( &entityinfo, &solverinfo, &probleminfo); /* in l1line.c*/ if (status) { REprintf ("Unable to solve. Terminating...; or done\n"); goto TERMINATE; } TERMINATE: free_and_null ((char **) &probleminfo.ratios); free_and_null ((char **) &probleminfo.weights); free_and_null ((char **) &probleminfo.v); free_and_null ((char **) &probleminfo.tosort); } /* end l1line */
void destroy_separator(void *obj) { Separator *separator = (Separator *)obj; remove_area(&separator->area); free_area(&separator->area); free_and_null(separator); }
/* This is run automatically before leaving the program. Free allocated resources. */ static void cleanup (void) { if (p) paranoia_free(p); if (d) cdda_close(d); free_and_null(force_cdrom_device); free_and_null(span); if(logfile_open) { fclose(logfile); logfile = NULL; } if(reportfile_open) { fclose(reportfile); reportfile = NULL; } }
static int free_user_cbhandle (USER_CBHANDLE *user_cbhandle) { int status = 0; if (user_cbhandle == NULL) goto TERMINATE; free_and_null ((char **) &user_cbhandle->x); free_and_null ((char **) &user_cbhandle->indices); free_and_null ((char **) &user_cbhandle->ray); free_and_null ((char **) &user_cbhandle->cutval); free_and_null ((char **) &user_cbhandle->cutind); if ( user_cbhandle->lp != NULL ) { int local_status = CPXXfreeprob (user_cbhandle->env, &(user_cbhandle->lp) ); if ( local_status ) { fprintf (stderr, "CPXXfreeprob failed, error code %d.\n", status); status = local_status; } else user_cbhandle->lp = NULL; } if ( user_cbhandle->env != NULL ) { int local_status = CPXXcloseCPLEX ( &(user_cbhandle->env) ); if ( local_status ) { fprintf (stderr, "CPXXcloseCPLEX failed, error code %d.\n", status); status = local_status; } else user_cbhandle->env = NULL; } TERMINATE: return status; } /* END free_user_cbhandle */
/*! Close UDF and free resources associated with p_udf. */ bool udf_close (udf_t *p_udf) { if (!p_udf) return true; if (p_udf->b_stream) { cdio_stdio_destroy(p_udf->stream); } else { cdio_destroy(p_udf->cdio); } /* Get rid of root directory if allocated. */ free_and_null(p_udf); return true; }
static int populatebyrow (CPXENVptr env, CPXLPptr lp, int nfoods, double *cost, double *lb, double *ub, int nnutr, double *nutrmin, double *nutrmax, double **nutrper) { int status = 0; int zero = 0; int *ind = NULL; int i, j; ind = (int*) malloc(nfoods * sizeof(int)); if ( ind == NULL ) { status = CPXERR_NO_MEMORY; goto TERMINATE; } for (j = 0; j < nfoods; j++) { ind[j] = j; } status = CPXnewcols (env, lp, nfoods, cost, lb, ub, NULL, NULL); if ( status ) goto TERMINATE; for (i = 0; i < nnutr; i++) { double rng = nutrmax[i] - nutrmin[i]; status = CPXaddrows (env, lp, 0, 1, nfoods, nutrmin+i, "R", &zero, ind, nutrper[i], NULL, NULL); if ( status ) goto TERMINATE; status = CPXchgrngval (env, lp, 1, &i, &rng); if ( status ) goto TERMINATE; } TERMINATE: free_and_null ((char **)&ind); return (status); } /* END populatebyrow */
int exec_instr_pipe(s_instr *instr, s_list_dup *list_dup, int *error) { s_instr_pipe *instr_pipe = NULL; int filedes[2]; int res = 0; s_list_dup *dp = NULL; s_list_dup *dp2 = NULL; s_list_instr_item *list_instr = NULL; int fd_in = STDIN_FILENO; if (instr == NULL || instr->instr == NULL) return (-1); instr_pipe = instr->instr; list_instr = instr_pipe->list_instr->first; for (; list_instr != NULL; list_instr = list_instr->next) { if (list_instr->next != NULL) mpipe(filedes); if (list_instr->next != NULL) dp = list_dup_insert(list_dup, filedes[1], STDOUT_FILENO); if (list_instr != instr_pipe->list_instr->first) dp2 = list_dup_insert(dp == NULL ? list_dup : dp, fd_in, STDIN_FILENO); res = exec_instr(list_instr->elmt, dp2 == NULL ? dp : dp2, error); close_fds(&fd_in, filedes, list_instr->next); free_and_null(&dp, &dp2); CHECK_ERROR() } return (res); }
int main (int argc, char *argv[]) { /* Declare and allocate space for the variables and arrays where we will store the optimization results including the status, objective value, maximum bound violation, variable values, and basis. */ int solnstat, solnmethod, solntype; double objval, maxviol; double *x = NULL; int *cstat = NULL; int *rstat = NULL; CPXENVptr env = NULL; CPXLPptr lp = NULL; int status = 0; int j; int cur_numrows, cur_numcols; char *basismsg; /* Check the command line arguments */ if (( argc != 3 ) || ( strchr ("cfg", argv[2][0]) == NULL ) ) { usage (argv[0]); goto TERMINATE; } /* Initialize the CPLEX environment */ env = CPXopenCPLEX (&status); /* If an error occurs, the status value indicates the reason for failure. A call to CPXgeterrorstring will produce the text of the error message. Note that CPXopenCPLEX produces no output, so the only way to see the cause of the error is to use CPXgeterrorstring. For other CPLEX routines, the errors will be seen if the CPXPARAM_ScreenOutput indicator is set to CPX_ON. */ if ( env == NULL ) { char errmsg[CPXMESSAGEBUFSIZE]; fprintf (stderr, "Could not open CPLEX environment.\n"); CPXgeterrorstring (env, status, errmsg); fprintf (stderr, "%s", errmsg); goto TERMINATE; } /* Turn on output to the screen */ status = CPXsetintparam (env, CPXPARAM_ScreenOutput, CPX_ON); if ( status ) { fprintf (stderr, "Failure to turn on screen indicator, error %d.\n", status); goto TERMINATE; } /* Create the problem, using the filename as the problem name */ lp = CPXcreateprob (env, &status, argv[1]); /* A returned pointer of NULL may mean that not enough memory was available or there was some other problem. In the case of failure, an error message will have been written to the error channel from inside CPLEX. In this example, the setting of the parameter CPXPARAM_ScreenOutput causes the error message to appear on stdout. Note that most CPLEX routines return an error code to indicate the reason for failure. */ if ( lp == NULL ) { fprintf (stderr, "Failed to create LP.\n"); goto TERMINATE; } /* Now read the file, and copy the data into the created lp */ status = CPXreadcopyprob (env, lp, argv[1], NULL); if ( status ) { fprintf (stderr, "Failed to read and copy the problem data.\n"); goto TERMINATE; } if ( CPXgetprobtype (env, lp) != CPXPROB_QP ) { fprintf (stderr, "Input file is not a QP. Exiting.\n"); goto TERMINATE; } /* Optimize the problem and obtain solution. */ switch (argv[2][0]) { case 'c': status = CPXsetintparam (env, CPXPARAM_SolutionTarget, CPX_SOLUTIONTARGET_OPTIMALCONVEX); if ( status ) goto TERMINATE; status = CPXqpopt (env, lp); if ( status ) { if ( status == CPXERR_Q_NOT_POS_DEF ) printf ("Problem is not convex. Use argument f to get local optimum " "or g to get global optimum.\n"); else fprintf (stderr, "Failed to optimize QP.\n"); goto TERMINATE; } break; case 'f': status = CPXsetintparam (env, CPXPARAM_SolutionTarget, CPX_SOLUTIONTARGET_FIRSTORDER); if ( status ) goto TERMINATE; status = CPXqpopt (env, lp); if ( status ) { fprintf (stderr, "Failed to optimize QP.\n"); goto TERMINATE; } break; case 'g': status = CPXsetintparam (env, CPXPARAM_SolutionTarget, CPX_SOLUTIONTARGET_OPTIMALGLOBAL); if ( status ) goto TERMINATE; status = CPXqpopt (env, lp); if ( status ) { fprintf (stderr, "Failed to optimize noncvonex QP.\n"); goto TERMINATE; } break; default: break; } solnstat = CPXgetstat (env, lp); if ( solnstat == CPXMIP_UNBOUNDED || solnstat == CPX_STAT_UNBOUNDED ) { printf ("Model is unbounded\n"); goto TERMINATE; } else if ( solnstat == CPXMIP_INFEASIBLE || solnstat == CPX_STAT_INFEASIBLE ) { printf ("Model is infeasible\n"); goto TERMINATE; } else if ( solnstat == CPX_STAT_INForUNBD ) { printf ("Model is infeasible or unbounded\n"); goto TERMINATE; } status = CPXsolninfo (env, lp, &solnmethod, &solntype, NULL, NULL); if ( status ) { fprintf (stderr, "Failed to obtain solution info.\n"); goto TERMINATE; } printf ("Solution status %d, solution method %d\n", solnstat, solnmethod); if ( solntype == CPX_NO_SOLN ) { fprintf (stderr, "Solution not available.\n"); goto TERMINATE; } status = CPXgetobjval (env, lp, &objval); if ( status ) { fprintf (stderr, "Failed to obtain objective value.\n"); goto TERMINATE; } printf ("Objective value %.10g.\n", objval); /* The size of the problem should be obtained by asking CPLEX what the actual size is. cur_numrows and cur_numcols store the current number of rows and columns, respectively. */ cur_numcols = CPXgetnumcols (env, lp); cur_numrows = CPXgetnumrows (env, lp); /* Retrieve basis, if one is available */ if ( solntype == CPX_BASIC_SOLN ) { cstat = (int *) malloc (cur_numcols*sizeof(int)); rstat = (int *) malloc (cur_numrows*sizeof(int)); if ( cstat == NULL || rstat == NULL ) { fprintf (stderr, "No memory for basis statuses.\n"); goto TERMINATE; } status = CPXgetbase (env, lp, cstat, rstat); if ( status ) { fprintf (stderr, "Failed to get basis; error %d.\n", status); goto TERMINATE; } } else { printf ("No basis available\n"); } /* Retrieve solution vector */ x = (double *) malloc (cur_numcols*sizeof(double)); if ( x == NULL ) { fprintf (stderr, "No memory for solution.\n"); goto TERMINATE; } status = CPXgetx (env, lp, x, 0, cur_numcols-1); if ( status ) { fprintf (stderr, "Failed to obtain primal solution.\n"); goto TERMINATE; } /* Write out the solution */ for (j = 0; j < cur_numcols; j++) { printf ( "Column %d: Value = %17.10g", j, x[j]); if ( cstat != NULL ) { switch (cstat[j]) { case CPX_AT_LOWER: basismsg = "Nonbasic at lower bound"; break; case CPX_BASIC: basismsg = "Basic"; break; case CPX_AT_UPPER: basismsg = "Nonbasic at upper bound"; break; case CPX_FREE_SUPER: basismsg = "Superbasic, or free variable at zero"; break; default: basismsg = "Bad basis status"; break; } printf (" %s",basismsg); } printf ("\n"); } /* Display the maximum bound violation. */ status = CPXgetdblquality (env, lp, &maxviol, CPX_MAX_PRIMAL_INFEAS); if ( status ) { fprintf (stderr, "Failed to obtain bound violation.\n"); goto TERMINATE; } printf ("Maximum bound violation = %17.10g\n", maxviol); TERMINATE: /* Free up the basis and solution */ free_and_null ((char **) &cstat); free_and_null ((char **) &rstat); free_and_null ((char **) &x); /* Free up the problem, if necessary */ if ( lp != NULL ) { status = CPXfreeprob (env, &lp); if ( status ) { fprintf (stderr, "CPXfreeprob failed, error code %d.\n", status); } } /* Free up the CPLEX environment, if necessary */ if ( env != NULL ) { status = CPXcloseCPLEX (&env); /* Note that CPXcloseCPLEX produces no output, so the only way to see the cause of the error is to use CPXgeterrorstring. For other CPLEX routines, the errors will be seen if the CPXPARAM_ScreenOutput indicator is set to CPX_ON. */ if ( status ) { char errmsg[CPXMESSAGEBUFSIZE]; fprintf (stderr, "Could not close CPLEX environment.\n"); CPXgeterrorstring (env, status, errmsg); fprintf (stderr, "%s", errmsg); } } return (status); } /* END main */
int main (int argc, char *argv[]) { CPXENVptr env = NULL; CPXLPptr lp = NULL; int status = 0; int j; int numcols; double totinv; int solstat; double objval; double *x = NULL; double rrhs[1]; char rsense[1]; int rmatbeg[1]; int *indices = NULL; double *values = NULL; char *namestore = NULL; char **nameptr = NULL; int surplus, storespace; const char * datadir = argc <= 1 ? "../../../examples/data" : argv[1]; char *prod = NULL; prod = (char *) malloc (strlen (datadir) + 1 + strlen("prod.lp") + 1); sprintf (prod, "%s/prod.lp", datadir); /* Initialize the CPLEX environment */ env = CPXopenCPLEX (&status); /* If an error occurs, the status value indicates the reason for failure. A call to CPXgeterrorstring will produce the text of the error message. Note that CPXopenCPLEX produces no output, so the only way to see the cause of the error is to use CPXgeterrorstring. For other CPLEX routines, the errors will be seen if the CPXPARAM_ScreenOutput indicator is set to CPX_ON. */ if ( env == NULL ) { char errmsg[CPXMESSAGEBUFSIZE]; fprintf (stderr, "Could not open CPLEX environment.\n"); CPXgeterrorstring (env, status, errmsg); fprintf (stderr, "%s", errmsg); goto TERMINATE; } /* Turn on output to the screen */ status = CPXsetintparam (env, CPXPARAM_ScreenOutput, CPX_ON); if ( status ) { fprintf (stderr, "Failure to turn on screen indicator, error %d.\n", status); goto TERMINATE; } /* Create the problem, using the filename as the problem name */ lp = CPXcreateprob (env, &status, "prod.lp"); /* A returned pointer of NULL may mean that not enough memory was available or there was some other problem. In the case of failure, an error message will have been written to the error channel from inside CPLEX. In this example, the setting of the parameter CPXPARAM_ScreenOutput causes the error message to appear on stdout. Note that most CPLEX routines return an error code to indicate the reason for failure. */ if ( lp == NULL ) { fprintf (stderr, "Failed to create LP.\n"); goto TERMINATE; } /* Now read the file, and copy the data into the created lp */ status = CPXreadcopyprob (env, lp, prod, NULL); if ( status ) { fprintf (stderr, "Failed to read and copy the problem data.\n"); goto TERMINATE; } /* Tell presolve to do only primal reductions, turn off simplex logging */ status = CPXsetintparam (env, CPXPARAM_Preprocessing_Reduce, 1); if ( status ) { fprintf (stderr, "Failed to set CPXPARAM_Preprocessing_Reduce: %d\n", status); goto TERMINATE; } status = CPXsetintparam (env, CPXPARAM_Simplex_Display, 0); if ( status ) { fprintf (stderr, "Failed to set CPXPARAM_Simplex_Display: %d\n", status); goto TERMINATE; } if ( status ) { fprintf (stderr, "Failure to set parameters\n"); goto TERMINATE; } /* Optimize the problem and obtain solution. */ status = CPXlpopt (env, lp); if ( status ) { fprintf (stderr, "Failed to optimize profit LP.\n"); goto TERMINATE; } solstat = CPXgetstat (env, lp); status = CPXgetobjval (env, lp, &objval); if ( status || solstat != CPX_STAT_OPTIMAL ) { fprintf (stderr, "Solution failed. Status %d, solstat %d.\n", status, solstat); goto TERMINATE; } printf ("Profit objective value is %g\n", objval); /* Allocate space for column names */ numcols = CPXgetnumcols (env, lp); if ( !numcols ) { fprintf (stderr, "No columns in problem\n"); goto TERMINATE; } CPXgetcolname (env, lp, NULL, NULL, 0, &surplus, 0, numcols-1); storespace = - surplus; namestore = (char *) malloc (storespace * sizeof(char)); nameptr = (char **) malloc (numcols * sizeof(char *)); if ( namestore == NULL || nameptr == NULL ) { fprintf (stderr, "No memory for column names\n"); goto TERMINATE; } status = CPXgetcolname (env, lp, nameptr, namestore, storespace, &surplus, 0, numcols-1); if ( status ) { fprintf (stderr, "Failed to get column names\n"); goto TERMINATE; } /* Allocate space for solution */ x = (double *) malloc (numcols * sizeof(double)); if ( x == NULL ) { fprintf (stderr,"No memory for solution.\n"); goto TERMINATE; } status = CPXgetx (env, lp, x, 0, numcols-1); if ( status ) { fprintf (stderr, "Failed to obtain primal solution.\n"); goto TERMINATE; } totinv = 0; for (j = 0; j < numcols; j++) { if ( !strncmp (nameptr[j], "inv", 3) ) totinv += x[j]; } printf ("Inventory level under profit objective is %g\n", totinv); /* Allocate space for a constraint */ indices = (int *) malloc (numcols * sizeof (int)); values = (double *) malloc (numcols * sizeof (double)); if ( indices == NULL || values == NULL ) { fprintf (stderr, "No memory for constraint\n"); goto TERMINATE; } /* Get profit objective and add it as a constraint */ status = CPXgetobj (env, lp, values, 0, numcols-1); if ( status ) { fprintf (stderr, "Failed to get profit objective. Status %d\n", status); goto TERMINATE; } for (j = 0; j < numcols; j++) { indices[j] = j; } rrhs[0] = objval - fabs (objval) * 1e-6; rsense[0] = 'G'; rmatbeg[0] = 0; status = CPXpreaddrows (env, lp, 1, numcols, rrhs, rsense, rmatbeg, indices, values, NULL); if ( status ) { fprintf (stderr, "Failed to add objective as constraint. Status %d\n", status); goto TERMINATE; } /* Set up objective to maximize negative of sum of inventory */ totinv = 0; for (j = 0; j < numcols; j++) { if ( strncmp (nameptr[j], "inv", 3) ) { values[j] = 0.0; } else { values[j] = - 1.0; } } status = CPXprechgobj (env, lp, numcols, indices, values); if ( status ) { fprintf (stderr, "Failed to change to inventory objective. Status %d\n", status); goto TERMINATE; } status = CPXlpopt (env, lp); if ( status ) { fprintf (stderr, "Optimization on inventory level failed. Status %d.\n", status); goto TERMINATE; } solstat = CPXgetstat (env, lp); status = CPXgetobjval (env, lp, &objval); if ( status || solstat != CPX_STAT_OPTIMAL ) { fprintf (stderr, "Solution failed. Status %d, solstat %d.\n", status, solstat); goto TERMINATE; } printf("Solution status %d.\n", solstat); printf ("Inventory level after optimization is %g\n", -objval); status = CPXgetx (env, lp, x, 0, numcols-1); if ( status ) { fprintf (stderr, "Failed to obtain primal solution.\n"); goto TERMINATE; } printf("Found solution"); /* Write out the solution */ printf ("\n"); for (j = 0; j < numcols; j++) { printf ( "%s: Value = %17.10g\n", nameptr[j], x[j]); } TERMINATE: /* Free the filename */ free_and_null ((char **) &prod); /* Free up the basis and solution */ free_and_null ((char **) &indices); free_and_null ((char **) &values); free_and_null ((char **) &nameptr); free_and_null ((char **) &namestore); free_and_null ((char **) &x); /* Free up the problem, if necessary */ if ( lp != NULL ) { status = CPXfreeprob (env, &lp); if ( status ) { fprintf (stderr, "CPXfreeprob failed, error code %d.\n", status); } } /* Free up the CPLEX environment, if necessary */ if ( env != NULL ) { status = CPXcloseCPLEX (&env); /* Note that CPXcloseCPLEX produces no output, so the only way to see the cause of the error is to use CPXgeterrorstring. For other CPLEX routines, the errors will be seen if the CPXPARAM_ScreenOutput indicator is set to CPX_ON. */ if ( status ) { char errmsg[CPXMESSAGEBUFSIZE]; fprintf (stderr, "Could not close CPLEX environment.\n"); CPXgeterrorstring (env, status, errmsg); fprintf (stderr, "%s", errmsg); } } return (status); } /* END main */
static int CPXPUBLIC rounddownheur (CPXCENVptr env, void *cbdata, int wherefrom, void *cbhandle, double *objval_p, double *x, int *checkfeas_p, int *useraction_p) { int status = 0; int j, cols; double roundobjval; int *feas = NULL; CPXCLPptr lp; double *objcoefs = NULL; *useraction_p = CPX_CALLBACK_DEFAULT; /* Heuristic motivated by knapsack constrained problems. Rounding down all fractional values will give an integer solution that is feasible, since all constraints are <= with positive coefficients */ status = CPXgetcallbacklp (env, cbdata, wherefrom, &lp); if ( status ) { fprintf (stdout, "Can't get lp pointer."); goto TERMINATE; } cols = CPXgetnumcols (env, lp); if ( cols <= 0 ) { fprintf (stdout, "numcols = %d.", cols); status = CPXERR_CALLBACK; goto TERMINATE; } objcoefs = (double *) malloc (cols * sizeof (double)); feas = (int *) malloc (cols * sizeof (int)); if ( objcoefs == NULL || feas == NULL ) { fprintf (stdout, "Out of memory."); status = CPXERR_CALLBACK; goto TERMINATE; } status = CPXgetobj (env, lp, objcoefs, 0, cols-1); if ( status ) { fprintf (stdout, "Can't get objective."); goto TERMINATE; } status = CPXgetcallbacknodeintfeas (env, cbdata, wherefrom, feas, 0, cols-1); if ( status ) { fprintf (stdout, "Can't get variable feasible status for node."); goto TERMINATE; } roundobjval = *objval_p; for (j = 0; j < cols; j++) { /* Set the fractional variable to zero and update the objective value */ if ( feas[j] == CPX_INTEGER_INFEASIBLE ) { roundobjval -= x[j] * objcoefs[j]; x[j] = 0.0; } } *objval_p = roundobjval; /* Have CPLEX check the solution for integer feasibility */ *checkfeas_p = 1; /* Tell CPLEX that a solution is being returned */ *useraction_p = CPX_CALLBACK_SET; TERMINATE: free_and_null ((char **) &objcoefs); free_and_null ((char **) &feas); return (status); } /* END rounddown */
int main (int argc, char *argv[]) { int status = 0; /* Declare and allocate space for the variables and arrays where we will store the optimization results, including the status, objective value, and variable values */ int solstat; double objval; double *x = NULL; CPXENVptr env = NULL; CPXLPptr lp = NULL; int j; int cur_numcols; int wantorig = 1; int nameind = 1; /* Check the command line arguments */ if ( argc != 2 ) { if ( argc != 3 || argv[1][0] != '-' || argv[1][1] != 'r' ) { usage (argv[0]); goto TERMINATE; } wantorig = 0; nameind = 2; } /* Initialize the CPLEX environment */ env = CPXopenCPLEX (&status); /* If an error occurs, the status value indicates the reason for failure. A call to CPXgeterrorstring will produce the text of the error message. Note that CPXopenCPLEX produces no output, so the only way to see the cause of the error is to use CPXgeterrorstring. For other CPLEX routines, the errors will be seen if the CPXPARAM_ScreenOutput parameter is set to CPX_ON */ if ( env == NULL ) { char errmsg[CPXMESSAGEBUFSIZE]; fprintf (stderr, "Could not open CPLEX environment.\n"); CPXgeterrorstring (env, status, errmsg); fprintf (stderr, "%s", errmsg); goto TERMINATE; } /* Turn on output to the screen */ status = CPXsetintparam (env, CPXPARAM_ScreenOutput, CPX_ON); if ( status != 0 ) { fprintf (stderr, "Failure to turn on screen indicator, error %d.\n", status); goto TERMINATE; } /* Create the problem, using the filename as the problem name */ lp = CPXcreateprob (env, &status, argv[nameind]); /* A returned pointer of NULL may mean that not enough memory was available or there was some other problem. In the case of failure, an error message will have been written to the error channel from inside CPLEX. In this example, the setting of the parameter CPXPARAM_ScreenOutput causes the error message to appear on stdout. Note that most CPLEX routines return an error code to indicate the reason for failure */ if ( lp == NULL ) { fprintf (stderr, "Failed to create LP.\n"); goto TERMINATE; } /* Now read the file, and copy the data into the created lp */ status = CPXreadcopyprob (env, lp, argv[nameind], NULL); if ( status ) { fprintf (stderr, "Failed to read and copy the problem data.\n"); goto TERMINATE; } if ( CPXgetnumcols (env, lp) != CPXgetnumbin (env, lp) ) { fprintf (stderr, "Problem contains non-binary variables, exiting\n"); goto TERMINATE; } /* Set parameters */ if ( wantorig ) { /* Assure linear mappings between the presolved and original models */ status = CPXsetintparam (env, CPXPARAM_Preprocessing_Linear, 0); if ( status ) goto TERMINATE; /* Let MIP callbacks work on the original model */ status = CPXsetintparam (env, CPXPARAM_MIP_Strategy_CallbackReducedLP, CPX_OFF); if ( status ) goto TERMINATE; } status = CPXsetdblparam (env, CPXPARAM_MIP_Tolerances_MIPGap, (double) 1e-6); if ( status ) goto TERMINATE; /* Turn on traditional search for use with control callbacks */ status = CPXsetintparam (env, CPXPARAM_MIP_Strategy_Search, CPX_MIPSEARCH_TRADITIONAL); if ( status ) goto TERMINATE; /* Set up to use MIP callback */ status = CPXsetheuristiccallbackfunc (env, rounddownheur, NULL); if ( status ) goto TERMINATE; /* Optimize the problem and obtain solution */ status = CPXmipopt (env, lp); if ( status ) { fprintf (stderr, "Failed to optimize MIP.\n"); goto TERMINATE; } solstat = CPXgetstat (env, lp); printf ("Solution status %d.\n", solstat); status = CPXgetobjval (env, lp, &objval); if ( status ) { fprintf (stderr, "Failed to obtain objective value.\n"); goto TERMINATE; } printf ("Objective value %.10g\n", objval); cur_numcols = CPXgetnumcols (env, lp); /* Allocate space for solution */ x = (double *) malloc (cur_numcols * sizeof (double)); if ( x == NULL ) { fprintf (stderr, "No memory for solution values.\n"); goto TERMINATE; } status = CPXgetx (env, lp, x, 0, cur_numcols-1); if ( status ) { fprintf (stderr, "Failed to obtain solution.\n"); goto TERMINATE; } /* Write out the solution */ for (j = 0; j < cur_numcols; j++) { if ( fabs (x[j]) > 1e-10 ) { printf ( "Column %d: Value = %17.10g\n", j, x[j]); } } TERMINATE: /* Free the solution vector */ free_and_null ((char **) &x); /* Free the problem as allocated by CPXcreateprob and CPXreadcopyprob, if necessary */ if ( lp != NULL ) { status = CPXfreeprob (env, &lp); if ( status ) { fprintf (stderr, "CPXfreeprob failed, error code %d.\n", status); } } /* Free the CPLEX environment, if necessary */ if ( env != NULL ) { status = CPXcloseCPLEX (&env); /* Note that CPXcloseCPLEX produces no output, so the only way to see the cause of the error is to use CPXgeterrorstring. For other CPLEX routines, the errors will be seen if the CPXPARAM_ScreenOutput parameter is set to CPX_ON */ if ( status ) { char errmsg[CPXMESSAGEBUFSIZE]; fprintf (stderr, "Could not close CPLEX environment.\n"); CPXgeterrorstring (env, status, errmsg); fprintf (stderr, "%s", errmsg); } } return (status); } /* END main */
int main (int argc, char *argv[]) { int status = 0; int solstat; /* 17 city problem */ const char* filename = "../../../examples/data/atsp.dat"; /* ATSP instance */ double **arc_cost = NULL; CPXDIM num_nodes; /* data required to print the optimal ATSP tour */ double objval; CPXDIM num_x_cols; double *x = NULL; CPXDIM i, j; CPXDIM *succ = NULL; /* Cplex environment and master ILP */ CPXENVptr env = NULL; CPXLPptr lp = NULL; /* Decide when Benders' cuts are going to be separated: 0: only when a integer solution if found (i.e., wherefrom == CPX_CALLBACK_MIP_CUT_FEAS ) 1: even to cut-off fractional solutions, at the end of the cplex cut-loop (i.e., wherefrom == CPX_CALLBACK_MIP_CUT_LAST || wherefrom == CPX_CALLBACK_MIP_CUT_FEAS ) */ int separate_fractional_solutions; /* Cut callback data structure */ USER_CBHANDLE user_cbhandle; user_cbhandle.env = NULL; user_cbhandle.lp = NULL; user_cbhandle.x = NULL; user_cbhandle.indices = NULL; user_cbhandle.ray = NULL; user_cbhandle.cutval = NULL; user_cbhandle.cutind = NULL; /* Check the command line arguments */ if ( argc != 2 && argc != 3) { usage (argv[0]); goto TERMINATE; } if ( (argv[1][0] != '1' && argv[1][0] != '0') || argv[1][1] != '\0' ) { usage (argv[0]); goto TERMINATE; } separate_fractional_solutions = ( argv[1][0] == '0' ? 0 : 1 ); printf ("Benders' cuts separated to cut off: "); if ( separate_fractional_solutions ) { printf ("Integer and fractional infeasible solutions.\n"); } else { printf ("Only integer infeasible solutions.\n"); } fflush (stdout); if ( argc == 3 ) filename = argv[2]; /* Read the ATSP instance */ status = read_ATSP (filename, &arc_cost, &num_nodes); if ( status ) { fprintf (stderr, "Error in read_ATSP, status = %d\n", status); goto TERMINATE; } /* Init the CPLEX environment */ env = CPXXopenCPLEX (&status); if ( env == NULL ) { fprintf (stderr, "Failure in CPXXopenCPLEX, status = %d.\n", status); goto TERMINATE; } /* Turn on output to the screen */ status = CPXXsetintparam (env, CPXPARAM_ScreenOutput, CPX_ON); if ( status ) { fprintf (stderr, "Failed to turn on screen indicator, status = %d.\n", status); goto TERMINATE; } /* Set MIP log interval to 1 */ status = CPXXsetcntparam (env, CPXPARAM_MIP_Interval, 1); if ( status ) { fprintf (stderr, "Failed to set CPXPARAM_MIP_Interval, status = %d.\n", status); goto TERMINATE; } /* Create the master ILP */ lp = CPXXcreateprob (env, &status, "master_ILP.lp"); if ( lp == NULL ) { fprintf (stderr, "Failure in CPXXcreateprob, status = %d.\n", status); goto TERMINATE; } status = create_master_ILP (env, lp, arc_cost, num_nodes); if ( status ) { fprintf (stderr, "Failed to create the master ILP.\n"); goto TERMINATE; } /* Init the cut callback data structure */ status = init_user_cbhandle (&user_cbhandle, num_nodes, separate_fractional_solutions); if ( status ) { fprintf (stderr, "Failed to init the cut callback data structure, status = %d.\n", status); goto TERMINATE; } /* Set up environment parameters to use the function benders_callback as cut callback function */ status = set_benders_callback (env, &user_cbhandle); if ( status ) { fprintf (stderr, "Failure in function set_benders_callback: status = %d.\n", status); goto TERMINATE; } /* Optimize the problem and obtain solution status */ status = CPXXmipopt (env, lp); if ( status ) { fprintf (stderr, "Failed to optimize MIP, status = %d.\n", status); goto TERMINATE; } solstat = CPXXgetstat (env, lp); printf ("\nSolution status: %d\n", solstat); /* Write out the objective value */ if ( CPXXgetobjval (env, lp, &objval) ) { printf ("Failed to obtain objective value.\n"); } else { printf ("Objective value: %17.10e\n", objval); } if ( solstat == CPXMIP_OPTIMAL ) { /* Write out the optimal tour */ num_x_cols = CPXXgetnumcols (env, lp); x = malloc (num_x_cols * sizeof(*x)); if ( x == NULL ) { fprintf (stderr, "No memory for x array.\n"); status = -1; goto TERMINATE; } status = CPXXgetx (env, lp, x, 0, num_x_cols-1); if ( status ) { fprintf (stderr, "Failed to obtain solution, status = %d.\n", status); goto TERMINATE; } succ = malloc (num_nodes * sizeof(*succ)); if ( succ == NULL ) { fprintf (stderr, "No memory for succ array.\n"); status = -1; goto TERMINATE; } for (j = 0; j < num_nodes; ++j) succ[j] = -1; for (i = 0; i < num_nodes; ++i) { for (j = 0; j < num_nodes; ++j) { if ( fabs (x[i * num_nodes + j]) > 1e-03 ) succ[i] = j; } } printf ("Optimal tour:\n"); i = 0; while ( succ[i] != 0 ) { printf ("%d, ", i); i = succ[i]; } printf ("%d\n", i); } else { printf ("Solution status is not CPX_STAT_OPTIMAL\n"); } TERMINATE: /* Free the allocated memory if necessary */ free_and_null ((char **) &x); free_and_null ((char **) &succ); if ( arc_cost != NULL ) { for (i = 0; i < num_nodes; ++i) { free_and_null ((char **) &(arc_cost[i])); } } free_and_null ((char **) &arc_cost); status = free_user_cbhandle (&user_cbhandle); if ( status ) { fprintf (stderr, "free_user_cbhandle failed, status = %d.\n", status); } if ( lp != NULL ) { int local_status = CPXXfreeprob (env, &lp); if ( local_status ) { fprintf (stderr, "CPXXfreeprob failed, error code %d.\n", local_status); status = local_status; } } /* Free the CPLEX environment, if necessary */ if ( env != NULL ) { int local_status = CPXXcloseCPLEX (&env); if ( local_status ) { fprintf (stderr, "Could not close CPLEX environment, status = %d.\n", local_status); status = local_status; } } return status; } /* END main */
gboolean read_execp(void *obj) { Execp *execp = (Execp *)obj; if (execp->backend->child_pipe < 0) return FALSE; gboolean command_finished = FALSE; while (1) { // Make sure there is free space in the buffer if (execp->backend->buf_capacity - execp->backend->buf_length < 1024) { execp->backend->buf_capacity *= 2; execp->backend->buf_output = realloc(execp->backend->buf_output, execp->backend->buf_capacity); } ssize_t count = read(execp->backend->child_pipe, execp->backend->buf_output + execp->backend->buf_length, execp->backend->buf_capacity - execp->backend->buf_length - 1); if (count > 0) { // Successful read execp->backend->buf_length += count; execp->backend->buf_output[execp->backend->buf_length] = '\0'; continue; } else if (count == 0) { // End of file command_finished = TRUE; break; } else if (errno == EAGAIN || errno == EWOULDBLOCK) { // No more data available at the moment break; } else if (errno == EINTR) { // Harmless interruption by signal continue; } else { // Error command_finished = TRUE; break; } break; } if (command_finished) { execp->backend->child = 0; close(execp->backend->child_pipe); execp->backend->child_pipe = -1; if (execp->backend->interval) execp->backend->timer = add_timeout(execp->backend->interval * 1000, 0, execp_timer_callback, execp, &execp->backend->timer); } if (!execp->backend->continuous && command_finished) { free_and_null(execp->backend->text); free_and_null(execp->backend->icon_path); if (!execp->backend->has_icon) { execp->backend->text = strdup(execp->backend->buf_output); } else { char *text = strchr(execp->backend->buf_output, '\n'); if (text) { *text = '\0'; text++; execp->backend->text = strdup(text); } else { execp->backend->text = strdup(""); } execp->backend->icon_path = strdup(execp->backend->buf_output); } int len = strlen(execp->backend->text); if (len > 0 && execp->backend->text[len - 1] == '\n') execp->backend->text[len - 1] = '\0'; execp->backend->buf_length = 0; execp->backend->buf_output[execp->backend->buf_length] = '\0'; execp->backend->last_update_finish_time = time(NULL); execp->backend->last_update_duration = execp->backend->last_update_finish_time - execp->backend->last_update_start_time; return TRUE; } else if (execp->backend->continuous > 0) { // Count lines in buffer int num_lines = 0; char *last = execp->backend->buf_output; char *end = NULL; for (char *c = execp->backend->buf_output; *c; c++) { if (*c == '\n') { num_lines++; if (num_lines == execp->backend->continuous) end = c; } last = c; } if (*last && *last != '\n') num_lines++; if (num_lines >= execp->backend->continuous) { if (end) *end = '\0'; free_and_null(execp->backend->text); free_and_null(execp->backend->icon_path); if (!execp->backend->has_icon) { execp->backend->text = strdup(execp->backend->buf_output); } else { char *text = strchr(execp->backend->buf_output, '\n'); if (text) { *text = '\0'; text++; execp->backend->text = strdup(text); } else { execp->backend->text = strdup(""); } execp->backend->icon_path = strdup(execp->backend->buf_output); } int len = strlen(execp->backend->text); if (len > 0 && execp->backend->text[len - 1] == '\n') execp->backend->text[len - 1] = '\0'; if (end) { char *next = end + 1; int copied = next - execp->backend->buf_output; int remaining = execp->backend->buf_length - copied; if (remaining > 0) { memmove(execp->backend->buf_output, next, remaining); execp->backend->buf_length = remaining; execp->backend->buf_output[execp->backend->buf_length] = '\0'; } else { execp->backend->buf_length = 0; execp->backend->buf_output[execp->backend->buf_length] = '\0'; } } execp->backend->last_update_finish_time = time(NULL); execp->backend->last_update_duration = execp->backend->last_update_finish_time - execp->backend->last_update_start_time; return TRUE; } } return FALSE; }
static int populatebycolumn (CPXENVptr env, CPXLPptr lp, int nfoods, double *cost, double *lb, double *ub, int nnutr, double *nutrmin, double *nutrmax, double **nutrper) { int status = 0; int i, j; int zero = 0; int *ind = NULL; double *val = NULL; char *sense = NULL; double *rngval = NULL; sense = (char*)malloc(nnutr * sizeof(char)); if ( sense == NULL ) { status = CPXERR_NO_MEMORY; goto TERMINATE; } for (i = 0; i < nnutr; i++) { sense[i] = 'R'; } val = (double*)malloc(nnutr * sizeof(double)); if ( val == NULL ) { status = CPXERR_NO_MEMORY; goto TERMINATE; } rngval = (double*)malloc(nnutr * sizeof(double)); if ( rngval == NULL ) { status = CPXERR_NO_MEMORY; goto TERMINATE; } for (i = 0; i < nnutr; i++) { rngval[i] = nutrmax[i] - nutrmin[i]; } ind = (int*) malloc(nfoods * sizeof(int)); if ( ind == NULL ) { status = CPXERR_NO_MEMORY; goto TERMINATE; } for (i = 0; i < nnutr; i++) { ind[i] = i; } status = CPXnewrows (env, lp, nnutr, nutrmin, sense, rngval, NULL); if ( status ) goto TERMINATE; for (j = 0; j < nfoods; ++j) { for (i = 0; i < nnutr; i++) { val[i] = nutrper[i][j]; } status = CPXaddcols (env, lp, 1, nnutr, cost+j, &zero, ind, val, lb+j, ub+j, NULL); if ( status ) goto TERMINATE; } TERMINATE: free_and_null ((char **)&sense); free_and_null ((char **)&rngval); free_and_null ((char **)&ind); free_and_null ((char **)&val); return (status); } /* END populatebycolumn */
static int setproblemdata (char **probname_p, int *numcols_p, int *numrows_p, int *objsen_p, double **obj_p, double **rhs_p, char **sense_p, int **matbeg_p, int **matcnt_p, int **matind_p, double **matval_p, double **lb_p, double **ub_p) { char *zprobname = NULL; /* Problem name <= 16 characters */ double *zobj = NULL; double *zrhs = NULL; char *zsense = NULL; int *zmatbeg = NULL; int *zmatcnt = NULL; int *zmatind = NULL; double *zmatval = NULL; double *zlb = NULL; double *zub = NULL; int status = 0; zprobname = (char *) malloc (16 * sizeof(char)); zobj = (double *) malloc (NUMCOLS * sizeof(double)); zrhs = (double *) malloc (NUMROWS * sizeof(double)); zsense = (char *) malloc (NUMROWS * sizeof(char)); zmatbeg = (int *) malloc (NUMCOLS * sizeof(int)); zmatcnt = (int *) malloc (NUMCOLS * sizeof(int)); zmatind = (int *) malloc (NUMNZ * sizeof(int)); zmatval = (double *) malloc (NUMNZ * sizeof(double)); zlb = (double *) malloc (NUMCOLS * sizeof(double)); zub = (double *) malloc (NUMCOLS * sizeof(double)); if ( zprobname == NULL || zobj == NULL || zrhs == NULL || zsense == NULL || zmatbeg == NULL || zmatcnt == NULL || zmatind == NULL || zmatval == NULL || zlb == NULL || zub == NULL ) { status = 1; goto TERMINATE; } strcpy (zprobname, "example"); /* The code is formatted to make a visual correspondence between the mathematical linear program and the specific data items. */ zobj[0] = 1.0; zobj[1] = 2.0; zobj[2] = 3.0; zmatbeg[0] = 0; zmatbeg[1] = 2; zmatbeg[2] = 4; zmatcnt[0] = 2; zmatcnt[1] = 2; zmatcnt[2] = 2; zmatind[0] = 0; zmatind[2] = 0; zmatind[4] = 0; zsense[0] = 'L'; zmatval[0] = -1.0; zmatval[2] = 1.0; zmatval[4] = 1.0; zrhs[0] = 20.0; zmatind[1] = 1; zmatind[3] = 1; zmatind[5] = 1; zsense[1] = 'L'; zmatval[1] = 1.0; zmatval[3] = -3.0; zmatval[5] = 1.0; zrhs[1] = 30.0; zlb[0] = 0.0; zlb[1] = 0.0; zlb[2] = 0.0; zub[0] = 40.0; zub[1] = CPX_INFBOUND; zub[2] = CPX_INFBOUND; TERMINATE: if ( status ) { free_and_null ((char **) &zprobname); free_and_null ((char **) &zobj); free_and_null ((char **) &zrhs); free_and_null ((char **) &zsense); free_and_null ((char **) &zmatbeg); free_and_null ((char **) &zmatcnt); free_and_null ((char **) &zmatind); free_and_null ((char **) &zmatval); free_and_null ((char **) &zlb); free_and_null ((char **) &zub); } else { *numcols_p = NUMCOLS; *numrows_p = NUMROWS; *objsen_p = CPX_MAX; /* The problem is maximization */ *probname_p = zprobname; *obj_p = zobj; *rhs_p = zrhs; *sense_p = zsense; *matbeg_p = zmatbeg; *matcnt_p = zmatcnt; *matind_p = zmatind; *matval_p = zmatval; *lb_p = zlb; *ub_p = zub; } return (status); } /* END setproblemdata */
static int CPXPUBLIC usersetbranch (CPXCENVptr env, void *cbdata, int wherefrom, void *cbhandle, int brtype, CPXDIM sos, int nodecnt, CPXDIM bdcnt, const CPXDIM *nodebeg, const CPXDIM *indices, const char *lu, const double *bd, const double *nodeest, int *useraction_p) { int status = 0; CPXDIM j, bestj = -1; CPXDIM cols; double maxobj = -CPX_INFBOUND; double maxinf = -CPX_INFBOUND; double xj_inf; double xj_lo; double objval; double *x = NULL; double *obj = NULL; int *feas = NULL; char varlu[1]; double varbd[1]; CPXCNT seqnum1, seqnum2; CPXCLPptr lp; /* Initialize useraction to indicate no user action taken */ *useraction_p = CPX_CALLBACK_DEFAULT; /* If CPLEX is choosing an SOS branch, take it */ if ( sos >= 0 ) return (status); /* Get pointer to the problem */ status = CPXXgetcallbacklp (env, cbdata, wherefrom, &lp); if ( status ) { fprintf (stdout, "Can't get LP pointer.\n"); goto TERMINATE; } cols = CPXXgetnumcols (env, lp); if ( cols <= 0 ) { fprintf (stdout, "Can't get number of columns.\n"); status = CPXERR_CALLBACK; goto TERMINATE; } /* Get solution values and objective coefficients */ x = malloc (cols * sizeof (*x)); obj = malloc (cols * sizeof (*obj)); feas = malloc (cols * sizeof (*feas)); if ( x == NULL || obj == NULL || feas == NULL ) { fprintf (stdout, "Out of memory."); status = CPXERR_CALLBACK; goto TERMINATE; } status = CPXXgetcallbacknodex (env, cbdata, wherefrom, x, 0, cols-1); if ( status ) { fprintf (stdout, "Can't get node solution."); goto TERMINATE; } status = CPXXgetcallbacknodeobjval (env, cbdata, wherefrom, &objval); if ( status ) { fprintf (stdout, "Can't get node objective value."); goto TERMINATE; } status = CPXXgetobj (env, lp, obj, 0, cols-1); if ( status ) { fprintf (stdout, "Can't get obj."); goto TERMINATE; } status = CPXXgetcallbacknodeintfeas (env, cbdata, wherefrom, feas, 0, cols-1); if ( status ) { fprintf (stdout, "Can't get variable feasible status for node."); goto TERMINATE; } /* Branch on var with largest objective coefficient among those with largest infeasibility */ for (j = 0; j < cols; j++) { if ( feas[j] == CPX_INTEGER_INFEASIBLE ) { xj_inf = x[j] - floor (x[j]); if ( xj_inf > 0.5 ) xj_inf = 1.0 - xj_inf; if ( xj_inf >= maxinf && (xj_inf > maxinf || fabs (obj[j]) >= maxobj) ) { bestj = j; maxinf = xj_inf; maxobj = fabs (obj[j]); } } } /* If there weren't any eligible variables, take default branch */ if ( bestj < 0 ) { goto TERMINATE; } /* Now set up node descriptions */ xj_lo = floor (x[bestj]); /* Up node */ varlu[0] = 'L'; varbd[0] = xj_lo + 1; status = CPXXbranchcallbackbranchbds (env, cbdata, wherefrom, 1, &bestj, varlu, varbd, objval, NULL, &seqnum1); if ( status ) goto TERMINATE; /* Down node */ varlu[0] = 'U'; varbd[0] = xj_lo; status = CPXXbranchcallbackbranchbds (env, cbdata, wherefrom, 1, &bestj, varlu, varbd, objval, NULL, &seqnum2); if ( status ) goto TERMINATE; /* Set useraction to indicate a user-specified branch */ *useraction_p = CPX_CALLBACK_SET; TERMINATE: free_and_null ((char **) &x); free_and_null ((char **) &obj); free_and_null ((char **) &feas); return (status); } /* END usersetbranch */
static int setproblemdata (char **probname_p, CPXDIM *numcols_p, CPXDIM *numrows_p, int *objsen_p, double **obj_p, double **rhs_p, char **sense_p, CPXNNZ **matbeg_p, CPXDIM **matcnt_p, CPXDIM **matind_p, double **matval_p, double **lb_p, double **ub_p, CPXNNZ **qmatbeg_p, CPXDIM **qmatcnt_p, CPXDIM **qmatind_p, double **qmatval_p) { char *zprobname = NULL; /* Problem name <= 16 characters */ double *zobj = NULL; double *zrhs = NULL; char *zsense = NULL; CPXNNZ *zmatbeg = NULL; CPXDIM *zmatcnt = NULL; CPXDIM *zmatind = NULL; double *zmatval = NULL; double *zlb = NULL; double *zub = NULL; CPXNNZ *zqmatbeg = NULL; CPXDIM *zqmatcnt = NULL; CPXDIM *zqmatind = NULL; double *zqmatval = NULL; int status = 0; zprobname = malloc (16 * sizeof(*zprobname)); zobj = malloc (NUMCOLS * sizeof(*zobj)); zrhs = malloc (NUMROWS * sizeof(*zrhs)); zsense = malloc (NUMROWS * sizeof(*zsense)); zmatbeg = malloc (NUMCOLS * sizeof(*zmatbeg)); zmatcnt = malloc (NUMCOLS * sizeof(*zmatcnt)); zmatind = malloc (NUMNZ * sizeof(*zmatind)); zmatval = malloc (NUMNZ * sizeof(*zmatval)); zlb = malloc (NUMCOLS * sizeof(*zlb)); zub = malloc (NUMCOLS * sizeof(*zub)); zqmatbeg = malloc (NUMCOLS * sizeof(*zqmatbeg)); zqmatcnt = malloc (NUMCOLS * sizeof(*zqmatcnt)); zqmatind = malloc (NUMQNZ * sizeof(*zqmatind)); zqmatval = malloc (NUMQNZ * sizeof(*zqmatval)); if ( zprobname == NULL || zobj == NULL || zrhs == NULL || zsense == NULL || zmatbeg == NULL || zmatcnt == NULL || zmatind == NULL || zmatval == NULL || zlb == NULL || zub == NULL || zqmatbeg == NULL || zqmatcnt == NULL || zqmatind == NULL || zqmatval == NULL ) { status = 1; goto TERMINATE; } strcpy (zprobname, "example"); /* The code is formatted to make a visual correspondence between the mathematical linear program and the specific data items. */ zobj[0] = 1.0; zobj[1] = 2.0; zobj[2] = 3.0; zmatbeg[0] = 0; zmatbeg[1] = 2; zmatbeg[2] = 4; zmatcnt[0] = 2; zmatcnt[1] = 2; zmatcnt[2] = 2; zmatind[0] = 0; zmatind[2] = 0; zmatind[4] = 0; zsense[0] = 'L'; zmatval[0] = -1.0; zmatval[2] = 1.0; zmatval[4] = 1.0; zrhs[0] = 20.0; zmatind[1] = 1; zmatind[3] = 1; zmatind[5] = 1; zsense[1] = 'L'; zmatval[1] = 1.0; zmatval[3] = -3.0; zmatval[5] = 1.0; zrhs[1] = 30.0; zlb[0] = 0.0; zlb[1] = 0.0; zlb[2] = 0.0; zub[0] = 40.0; zub[1] = CPX_INFBOUND; zub[2] = CPX_INFBOUND; /* Now set up the Q matrix. Note that we set the values knowing that * we're doing a maximization problem, so negative values go on * the diagonal. Also, the off diagonal terms are each repeated, * by taking the algebraic term and dividing by 2 */ zqmatbeg[0] = 0; zqmatbeg[1] = 2; zqmatbeg[2] = 5; zqmatcnt[0] = 2; zqmatcnt[1] = 3; zqmatcnt[2] = 2; /* Matrix is set up visually. Note that the x1*x3 term is 0, and is * left out of the matrix. */ zqmatind[0] = 0; zqmatind[2] = 0; zqmatval[0] = -33.0; zqmatval[2] = 6.0; zqmatind[1] = 1; zqmatind[3] = 1; zqmatind[5] = 1; zqmatval[1] = 6.0; zqmatval[3] = -22.0; zqmatval[5] = 11.5; zqmatind[4] = 2; zqmatind[6] = 2; zqmatval[4] = 11.5; zqmatval[6] = -11.0; TERMINATE: if ( status ) { free_and_null ((char **) &zprobname); free_and_null ((char **) &zobj); free_and_null ((char **) &zrhs); free_and_null ((char **) &zsense); free_and_null ((char **) &zmatbeg); free_and_null ((char **) &zmatcnt); free_and_null ((char **) &zmatind); free_and_null ((char **) &zmatval); free_and_null ((char **) &zlb); free_and_null ((char **) &zub); free_and_null ((char **) &zqmatbeg); free_and_null ((char **) &zqmatcnt); free_and_null ((char **) &zqmatind); free_and_null ((char **) &zqmatval); } else { *numcols_p = NUMCOLS; *numrows_p = NUMROWS; *objsen_p = CPX_MAX; /* The problem is maximization */ *probname_p = zprobname; *obj_p = zobj; *rhs_p = zrhs; *sense_p = zsense; *matbeg_p = zmatbeg; *matcnt_p = zmatcnt; *matind_p = zmatind; *matval_p = zmatval; *lb_p = zlb; *ub_p = zub; *qmatbeg_p = zqmatbeg; *qmatcnt_p = zqmatcnt; *qmatind_p = zqmatind; *qmatval_p = zqmatval; } return (status); } /* END setproblemdata */
static int CPXPUBLIC logcallback (CPXCENVptr env, void *cbdata, int wherefrom, void *cbhandle) { int status = 0; LOGINFOptr info = (LOGINFOptr) cbhandle; int hasincumbent = 0; int newincumbent = 0; int nodecnt; int nodesleft; double objval; double bound; double *x = NULL; status = CPXgetcallbackinfo (env, cbdata, wherefrom, CPX_CALLBACK_INFO_NODE_COUNT, &nodecnt); if ( status ) goto TERMINATE; status = CPXgetcallbackinfo (env, cbdata, wherefrom, CPX_CALLBACK_INFO_NODES_LEFT, &nodesleft); if ( status ) goto TERMINATE; status = CPXgetcallbackinfo (env, cbdata, wherefrom, CPX_CALLBACK_INFO_MIP_FEAS, &hasincumbent); if ( status ) goto TERMINATE; if ( hasincumbent ) { status = CPXgetcallbackinfo (env, cbdata, wherefrom, CPX_CALLBACK_INFO_BEST_INTEGER, &objval); if ( status ) goto TERMINATE; if ( fabs(info->lastincumbent - objval) > 1e-5*(1.0 + fabs(objval)) ) { newincumbent = 1; info->lastincumbent = objval; } } if ( nodecnt >= info->lastlog + 100 || newincumbent ) { double walltime; double dettime; status = CPXgetcallbackinfo (env, cbdata, wherefrom, CPX_CALLBACK_INFO_BEST_REMAINING, &bound); if ( status ) goto TERMINATE; if ( !newincumbent ) info->lastlog = nodecnt; status = CPXgettime (env, &walltime); if ( status ) goto TERMINATE; status = CPXgetdettime (env, &dettime); if ( status ) goto TERMINATE; printf ("Time = %.2f Dettime = %.2f Nodes = %d(%d) Best objective = %g", walltime - info->timestart, dettime - info->dettimestart, nodecnt, nodesleft, bound); if ( hasincumbent ) printf (" Incumbent objective = %g\n", objval); else printf ("\n"); } if ( newincumbent ) { int j; int numcols = info->numcols; x = (double *) malloc (numcols*sizeof(double)); if ( x == NULL ) { status = CPXERR_NO_MEMORY; goto TERMINATE; } status = CPXgetcallbackincumbent (env, cbdata, wherefrom, x, 0, numcols-1); if ( status ) goto TERMINATE; printf ("New incumbent values:\n"); for (j = 0; j < numcols; j++) { if ( fabs(x[j]) > 1e-6 ) { printf (" Column %d: %g\n", j, x[j]); } } } TERMINATE: free_and_null ((char **) &x); return (status); } /* END logcallback */
int main (int argc, char *argv[]) { /* Declare and allocate space for the variables and arrays where we will store the optimization results including the status, objective value, maximum bound violation, variable values, and basis. */ int solnstat, solnmethod, solntype; double objval, maxviol; double *x = NULL; int *cstat = NULL; int *rstat = NULL; CPXENVptr env = NULL; CPXLPptr lp = NULL; int status = 0; int j; int cur_numrows, cur_numcols; char **cur_colname = NULL; char *cur_colnamestore = NULL; int cur_colnamespace; int surplus; int method; char *basismsg; /* Check the command line arguments */ if (( argc != 3 ) || ( strchr ("podhbnsc", argv[2][0]) == NULL ) ) { usage (argv[0]); goto TERMINATE; } /* Initialize the CPLEX environment */ env = CPXopenCPLEX (&status); /* If an error occurs, the status value indicates the reason for failure. A call to CPXgeterrorstring will produce the text of the error message. Note that CPXopenCPLEX produces no output, so the only way to see the cause of the error is to use CPXgeterrorstring. For other CPLEX routines, the errors will be seen if the CPXPARAM_ScreenOutput indicator is set to CPX_ON. */ if ( env == NULL ) { char errmsg[CPXMESSAGEBUFSIZE]; fprintf (stderr, "Could not open CPLEX environment.\n"); CPXgeterrorstring (env, status, errmsg); fprintf (stderr, "%s", errmsg); goto TERMINATE; } /* Turn on output to the screen */ status = CPXsetintparam (env, CPXPARAM_ScreenOutput, CPX_ON); if ( status ) { fprintf (stderr, "Failure to turn on screen indicator, error %d.\n", status); goto TERMINATE; } /* Create the problem, using the filename as the problem name */ lp = CPXcreateprob (env, &status, argv[1]); /* A returned pointer of NULL may mean that not enough memory was available or there was some other problem. In the case of failure, an error message will have been written to the error channel from inside CPLEX. In this example, the setting of the parameter CPXPARAM_ScreenOutput causes the error message to appear on stdout. Note that most CPLEX routines return an error code to indicate the reason for failure. */ if ( lp == NULL ) { fprintf (stderr, "Failed to create LP.\n"); goto TERMINATE; } /* Now read the file, and copy the data into the created lp */ status = CPXreadcopyprob (env, lp, argv[1], NULL); if ( status ) { fprintf (stderr, "Failed to read and copy the problem data.\n"); goto TERMINATE; } /* Optimize the problem and obtain solution. */ switch (argv[2][0]) { case 'o': method = CPX_ALG_AUTOMATIC; break; case 'p': method = CPX_ALG_PRIMAL; break; case 'd': method = CPX_ALG_DUAL; break; case 'n': method = CPX_ALG_NET; break; case 'h': method = CPX_ALG_BARRIER; break; case 'b': method = CPX_ALG_BARRIER; status = CPXsetintparam (env, CPXPARAM_Barrier_Crossover, CPX_ALG_NONE); if ( status ) { fprintf (stderr, "Failed to set the crossover method, error %d.\n", status); goto TERMINATE; } break; case 's': method = CPX_ALG_SIFTING; break; case 'c': method = CPX_ALG_CONCURRENT; break; default: method = CPX_ALG_NONE; break; } status = CPXsetintparam (env, CPXPARAM_LPMethod, method); if ( status ) { fprintf (stderr, "Failed to set the optimization method, error %d.\n", status); goto TERMINATE; } status = CPXlpopt (env, lp); if ( status ) { fprintf (stderr, "Failed to optimize LP.\n"); goto TERMINATE; } solnstat = CPXgetstat (env, lp); if ( solnstat == CPX_STAT_UNBOUNDED ) { printf ("Model is unbounded\n"); goto TERMINATE; } else if ( solnstat == CPX_STAT_INFEASIBLE ) { printf ("Model is infeasible\n"); goto TERMINATE; } else if ( solnstat == CPX_STAT_INForUNBD ) { printf ("Model is infeasible or unbounded\n"); goto TERMINATE; } status = CPXsolninfo (env, lp, &solnmethod, &solntype, NULL, NULL); if ( status ) { fprintf (stderr, "Failed to obtain solution info.\n"); goto TERMINATE; } printf ("Solution status %d, solution method %d\n", solnstat, solnmethod); if ( solntype == CPX_NO_SOLN ) { fprintf (stderr, "Solution not available.\n"); goto TERMINATE; } status = CPXgetobjval (env, lp, &objval); if ( status ) { fprintf (stderr, "Failed to obtain objective value.\n"); goto TERMINATE; } printf ("Objective value %.10g.\n", objval); /* The size of the problem should be obtained by asking CPLEX what the actual size is. cur_numrows and cur_numcols store the current number of rows and columns, respectively. */ cur_numcols = CPXgetnumcols (env, lp); cur_numrows = CPXgetnumrows (env, lp); /* Retrieve basis, if one is available */ if ( solntype == CPX_BASIC_SOLN ) { cstat = (int *) malloc (cur_numcols*sizeof(int)); rstat = (int *) malloc (cur_numrows*sizeof(int)); if ( cstat == NULL || rstat == NULL ) { fprintf (stderr, "No memory for basis statuses.\n"); goto TERMINATE; } status = CPXgetbase (env, lp, cstat, rstat); if ( status ) { fprintf (stderr, "Failed to get basis; error %d.\n", status); goto TERMINATE; } } else { printf ("No basis available\n"); } /* Retrieve solution vector */ x = (double *) malloc (cur_numcols*sizeof(double)); if ( x == NULL ) { fprintf (stderr, "No memory for solution.\n"); goto TERMINATE; } status = CPXgetx (env, lp, x, 0, cur_numcols-1); if ( status ) { fprintf (stderr, "Failed to obtain primal solution.\n"); goto TERMINATE; } /* Now get the column names for the problem. First we determine how much space is used to hold the names, and then do the allocation. Then we call CPXgetcolname() to get the actual names. */ status = CPXgetcolname (env, lp, NULL, NULL, 0, &surplus, 0, cur_numcols-1); if (( status != CPXERR_NEGATIVE_SURPLUS ) && ( status != 0 ) ) { fprintf (stderr, "Could not determine amount of space for column names.\n"); goto TERMINATE; } cur_colnamespace = - surplus; if ( cur_colnamespace > 0 ) { cur_colname = (char **) malloc (sizeof(char *)*cur_numcols); cur_colnamestore = (char *) malloc (cur_colnamespace); if ( cur_colname == NULL || cur_colnamestore == NULL ) { fprintf (stderr, "Failed to get memory for column names.\n"); status = -1; goto TERMINATE; } status = CPXgetcolname (env, lp, cur_colname, cur_colnamestore, cur_colnamespace, &surplus, 0, cur_numcols-1); if ( status ) { fprintf (stderr, "CPXgetcolname failed.\n"); goto TERMINATE; } } else { printf ("No names associated with problem. Using Fake names.\n"); } /* Write out the solution */ for (j = 0; j < cur_numcols; j++) { if ( cur_colnamespace > 0 ) { printf ("%-16s: ", cur_colname[j]); } else { printf ("Fake%-6.6d : ", j);; } printf ("%17.10g", x[j]); if ( cstat != NULL ) { switch (cstat[j]) { case CPX_AT_LOWER: basismsg = "Nonbasic at lower bound"; break; case CPX_BASIC: basismsg = "Basic"; break; case CPX_AT_UPPER: basismsg = "Nonbasic at upper bound"; break; case CPX_FREE_SUPER: basismsg = "Superbasic, or free variable at zero"; break; default: basismsg = "Bad basis status"; break; } printf (" %s",basismsg); } printf ("\n"); } /* Display the maximum bound violation. */ status = CPXgetdblquality (env, lp, &maxviol, CPX_MAX_PRIMAL_INFEAS); if ( status ) { fprintf (stderr, "Failed to obtain bound violation.\n"); goto TERMINATE; } printf ("Maximum bound violation = %17.10g\n", maxviol); TERMINATE: /* Free up the basis and solution */ free_and_null ((char **) &cstat); free_and_null ((char **) &rstat); free_and_null ((char **) &x); free_and_null ((char **) &cur_colname); free_and_null ((char **) &cur_colnamestore); /* Free up the problem, if necessary */ if ( lp != NULL ) { status = CPXfreeprob (env, &lp); if ( status ) { fprintf (stderr, "CPXfreeprob failed, error code %d.\n", status); } } /* Free up the CPLEX environment, if necessary */ if ( env != NULL ) { status = CPXcloseCPLEX (&env); /* Note that CPXcloseCPLEX produces no output, so the only way to see the cause of the error is to use CPXgeterrorstring. For other CPLEX routines, the errors will be seen if the CPXPARAM_ScreenOutput indicator is set to CPX_ON. */ if ( status ) { char errmsg[CPXMESSAGEBUFSIZE]; fprintf (stderr, "Could not close CPLEX environment.\n"); CPXgeterrorstring (env, status, errmsg); fprintf (stderr, "%s", errmsg); } } return (status); } /* END main */
static int create_master_ILP (CPXENVptr env, CPXLPptr lp, double **arc_cost, CPXDIM num_nodes) { CPXDIM i, j; int status = 0; char sense; char const *colname = NULL; CPXNNZ nzcnt, rmatbeg; CPXDIM *rmatind = NULL; double rhs, *rmatval = NULL; /* Change problem type */ status = CPXXchgprobtype (env, lp, CPXPROB_MILP); if ( status ) { fprintf (stderr, "Error in CPXXchgprobtype, status = %d.\n", status); goto TERMINATE; } /* Create arc variables x(i,j), one per time For simplicity, also dummy variables x(i,i) are created. Those variables are fixed to 0 and do not partecipate to the constraints */ colname = malloc (100 * sizeof(*colname)); if ( colname == NULL ) { fprintf (stderr, "No memory for colname array.\n"); status = -1; goto TERMINATE; } for (i = 0; i < num_nodes; ++i) { for (j = 0; j < num_nodes; ++j) { double cost = ( i == j ? 0. : arc_cost[i][j] ); double lb = 0.; double ub = ( i == j ? 0. : 1. ); char type = 'B'; sprintf ((char *)colname, "x.%d.%d", i, j); status = CPXXnewcols (env, lp, 1, &cost, &lb, &ub, &type, &colname); if ( status ) { fprintf (stderr, "Error in CPXXnewcols, status = %d.\n", status); goto TERMINATE; } } } /* Init data structures to add degree constraints */ rhs = 1.; sense = 'E'; rmatbeg = 0; rmatind = malloc ((num_nodes-1) * sizeof (*rmatind)); if ( rmatind == NULL ) { fprintf (stderr, "No memory for rmatind array.\n"); status = -1; goto TERMINATE; } rmatval = malloc ((num_nodes-1) * sizeof (*rmatval)); if ( rmatval == NULL ) { fprintf (stderr, "No memory for rmatval array.\n"); status = -1; goto TERMINATE; } /* Add the out degree constraints, one at a time: forall i in V: sum((i,j) in delta+(i)) x(i,j) = 1 */ for (i = 0; i < num_nodes; ++i) { nzcnt = 0; for (j = 0; j < num_nodes; ++j) { if ( i != j ) { rmatind[nzcnt] = i * num_nodes + j; rmatval[nzcnt++] = 1.; } } status = CPXXaddrows (env, lp, 0, 1, num_nodes-1, &rhs, &sense, &rmatbeg, rmatind, rmatval, NULL, NULL); if ( status ) { fprintf (stderr, "Error in CPXXaddrows, status = %d.\n", status); goto TERMINATE; } } /* Add the in degree constraints, one at a time: forall i in V: sum((j,i) in delta-(i)) x(j,i) = 1 */ for (i = 0; i < num_nodes; ++i) { nzcnt = 0; for (j = 0; j < num_nodes; ++j) { if (i != j ) { rmatind[nzcnt] = j * num_nodes + i; rmatval[nzcnt++] = 1.; } } status = CPXXaddrows (env, lp, 0, 1, num_nodes-1, &rhs, &sense, &rmatbeg, rmatind, rmatval, NULL, NULL); if ( status ) { fprintf (stderr, "Error in CPXXaddrows, status = %d.\n", status); goto TERMINATE; } } TERMINATE: free_and_null ((char **) &colname); free_and_null ((char **) &rmatind); free_and_null ((char **) &rmatval); return status; } /* END create_master_ILP */
static int buildmodel (CPXENVptr env, CPXLPptr lp) { CPXDIM colcnt = NUMVARS*NUMMONTHS*NUMPRODUCTS; double *obj = NULL; double *lb = NULL; double *ub = NULL; char *ctype = NULL; CPXDIM *rmatind = NULL; double *rmatval = NULL; CPXDIM indicator; CPXNNZ rmatbeg[1]; double rhs[1]; char sense[1]; int m, p; int status = 0; status = CPXXchgobjsen (env, lp, CPX_MAX); /* Maximization problem */ if ( status ) { fprintf (stderr, "Could not change objective sense.\n"); goto TERMINATE; } rmatbeg[0] = 0; /* Allocate colcnt-sized arrays */ obj = malloc (colcnt * sizeof(*obj)); lb = malloc (colcnt * sizeof(*lb)); ub = malloc (colcnt * sizeof(*ub)); ctype = malloc (colcnt * sizeof(*ctype)); rmatind = malloc (colcnt * sizeof(*rmatind)); rmatval = malloc (colcnt * sizeof(*rmatval)); if ( obj == NULL || lb == NULL || ub == NULL || ctype == NULL || rmatind == NULL || rmatval == NULL ) { fprintf (stderr, "Could not allocate colcnt arrays\n"); status = CPXERR_NO_MEMORY; goto TERMINATE; } /* Create variables. For each month and each product, we have 3 variables corresponding to the quantity used (semi-continuous), stored (continuous) and bought (continuous) and one binary variable indicating whether or not the product is used during this month. */ for (m = 0; m < NUMMONTHS; m++) { for (p = 0; p < NUMPRODUCTS; p++) { /* The quantity bought is a continuous variable. It has a cost */ obj[varindex(m, p, BUY)] = -cost[m*NUMPRODUCTS + p]; lb[varindex (m, p, BUY)] = 0.0; ub[varindex (m, p, BUY)] = CPX_INFBOUND; ctype[varindex (m, p, BUY)] = 'C'; /* When an oil is used, the quantity must be at least 20 tons. This is modeled as a semi-continuous variable. */ obj[varindex (m, p, USE)] = 0.0; lb[varindex (m, p, USE)] = 20.0; ub[varindex (m, p, USE)] = CPX_INFBOUND; ctype[varindex (m, p, USE)] = 'S'; /* It is possible to store up to 1000 tons of each product. There are storage costs. */ obj[varindex (m, p, STORE)] = -5.0; lb[varindex (m, p, STORE)] = 0.0; ub[varindex (m, p, STORE)] = 1000.0; ctype[varindex (m, p, STORE)] = 'C'; /* At the end, we must have exactly 500 tons of each product in storage. */ if ( m == NUMMONTHS - 1 ) { lb[varindex (m, p, STORE)] = 500.0; ub[varindex (m, p, STORE)] = 500.0; } /* The variable indicating whether or not a product is used during a month is a binary variable. */ obj[varindex (m, p, IS_USED)] = 0.0; lb[varindex (m, p, IS_USED)] = 0.0; ub[varindex (m, p, IS_USED)] = 1.0; ctype[varindex (m, p, IS_USED)] = 'B'; } } status = CPXXnewcols (env, lp, colcnt, obj, lb, ub, ctype, NULL); if ( status ) { fprintf (stderr, "Could not add new columns.\n"); goto TERMINATE; } /* Constraints for each month */ for (m = 0; m < NUMMONTHS; m++) { int totalindex; /* For each product, create an indicator constraint linking the quantity used and the binary variable indicating whether or not the product is used */ for (p = 0; p < NUMPRODUCTS; p++) { indicator = varindex (m, p, IS_USED); rmatind[0] = varindex (m, p, USE); rmatval[0] = 1.0; status = CPXXaddindconstr (env, lp, indicator, 1, 1, 0.0, 'L', rmatind, rmatval, NULL); if ( status ) { fprintf (stderr, "Could not add new indicator constraint.\n"); goto TERMINATE; } } /* Not more than 200 tons of vegetable oil can be refined */ rmatind[0] = varindex (m, VEGOIL1, USE); rmatind[1] = varindex (m, VEGOIL2, USE); rmatval[0] = 1.0; rmatval[1] = 1.0; rhs[0] = 200.0; sense[0] = 'L'; status = CPXXaddrows (env, lp, 0, 1, 2, rhs, sense, rmatbeg, rmatind, rmatval, NULL, NULL); /* Not more than 250 tons of non-vegetable oil can be refined */ rmatind[0] = varindex (m, OIL1, USE); rmatind[1] = varindex (m, OIL2, USE); rmatind[2] = varindex (m, OIL3, USE); rmatval[0] = 1.0; rmatval[1] = 1.0; rmatval[2] = 1.0; rhs[0] = 250.0; sense[0] = 'L'; status = CPXXaddrows (env, lp, 0, 1, 3, rhs, sense, rmatbeg, rmatind, rmatval, NULL, NULL); if ( status ) { fprintf (stderr, "Could not add new rows.\n"); goto TERMINATE; } /* Constraint on food composition */ /* Add a variable corresponding to total quantity produced in a month */ obj[0] = 150.0; lb[0] = 0.0; ub[0] = CPX_INFBOUND; ctype[0] = 'C'; status = CPXXnewcols (env, lp, 1, obj, lb, ub, ctype, NULL); if ( status ) { fprintf (stderr, "Could not add new columns.\n"); goto TERMINATE; } totalindex = CPXXgetnumcols (env, lp) - 1; /* Total quantity = sum (quantities) */ for (p = 0; p < NUMPRODUCTS; p++) { rmatind[p] = varindex (m, p, USE); rmatval[p] = 1.0; } rmatind[NUMPRODUCTS] = totalindex; rmatval[NUMPRODUCTS] = -1.0; rhs[0] = 0.0; sense[0] = 'E'; status = CPXXaddrows (env, lp, 0, 1, NUMPRODUCTS + 1, rhs, sense, rmatbeg, rmatind, rmatval, NULL, NULL); if ( status ) { fprintf (stderr, "Could not add new rows.\n"); goto TERMINATE; } /* Hardness constraints sum (quantity * hardness) >= 3 * total quantity sum (quantity * hardness) <= 6 * total quantity */ for (p = 0; p < NUMPRODUCTS; p++) { rmatind[p] = varindex (m, p, USE); rmatval[p] = hardness[p]; } rmatind[NUMPRODUCTS] = totalindex; rmatval[NUMPRODUCTS] = -3.0; rhs[0] = 0.0; sense[0] = 'G'; status = CPXXaddrows (env, lp, 0, 1, NUMPRODUCTS + 1, rhs, sense, rmatbeg, rmatind, rmatval, NULL, NULL); if ( status ) { fprintf (stderr, "Could not add new rows.\n"); goto TERMINATE; } rmatval[NUMPRODUCTS] = -6.0; sense[0] = 'L'; status = CPXXaddrows (env, lp, 0, 1, NUMPRODUCTS + 1, rhs, sense, rmatbeg, rmatind, rmatval, NULL, NULL); if ( status ) { fprintf (stderr, "Could not add new rows.\n"); goto TERMINATE; } /* The food may never be made up of more than three oils */ for (p = 0; p < NUMPRODUCTS; p++) { rmatind[p] = varindex (m, p, IS_USED); rmatval[p] = 1.0; } rhs[0] = 3.0; sense[0] = 'L'; status = CPXXaddrows (env, lp, 0, 1, NUMPRODUCTS, rhs, sense, rmatbeg, rmatind, rmatval, NULL, NULL); if ( status ) { fprintf (stderr, "Could not add new rows.\n"); goto TERMINATE; } /* If product veg 1 or veg 2 is used then oil 3 must be used */ indicator = varindex (m, VEGOIL1, IS_USED); rmatind[0] = varindex (m, OIL3, USE); rmatval[0] = 1.0; status = CPXXaddindconstr (env, lp, indicator, 0, 1, 20.0, 'G', rmatind, rmatval, NULL); indicator = varindex (m, VEGOIL2, IS_USED); status = CPXXaddindconstr (env, lp, indicator, 0, 1, 20.0, 'G', rmatind, rmatval, NULL); if ( status ) { fprintf (stderr, "Could not add new indicator constraint.\n"); goto TERMINATE; } /* We can store each product from one month to the next, starting with a stock of 500 tons */ for (p = 0; p < NUMPRODUCTS; p++) { CPXNNZ n = 0; if ( m != 0 ) { rmatind[n] = varindex (m-1, p, STORE); /* stored last month */ rmatval[n++] = 1.0; rmatind[n] = varindex (m, p, BUY); /* bought this month */ rmatval[n++] = 1.0; rmatind[n] = varindex (m, p, USE); /* used this month */ rmatval[n++] = -1.0; rmatind[n] = varindex (m, p, STORE); /* stored this month */ rmatval[n++] = -1.0; rhs[0] = 0.0; sense[0] = 'E'; } else { rmatind[n] = varindex (m, p, BUY); /* bought this month */ rmatval[n++] = 1.0; rmatind[n] = varindex (m, p, USE); /* used this month */ rmatval[n++] = -1.0; rmatind[n] = varindex (m, p, STORE); /* stored this month */ rmatval[n++] = -1.0; rhs[0] = -500.0; sense[0] = 'E'; } status = CPXXaddrows (env, lp, 0, 1, n, rhs, sense, rmatbeg, rmatind, rmatval, NULL, NULL); if ( status ) { fprintf (stderr, "Could not add new rows.\n"); goto TERMINATE; } } } TERMINATE: free_and_null ((char **)&obj); free_and_null ((char **)&lb); free_and_null ((char **)&ub); free_and_null ((char **)&ctype); free_and_null ((char **)&rmatind); free_and_null ((char **)&rmatval); return (status); } /* END buildmodel */
static int init_user_cbhandle (USER_CBHANDLE *user_cbhandle, CPXDIM num_nodes, int separate_fractional_solutions) { CPXDIM i, j, k; int status = 0; /* Data structures to create columns and add rows */ CPXDIM num_rows; CPXNNZ nzcnt; char *sense = NULL; double *rhs = NULL; CPXNNZ *rmatbeg = NULL; CPXDIM *rmatind = NULL; double *rmatval = NULL; char const *colname = NULL; /* Init user_cbhandle */ user_cbhandle->separate_fractional_solutions = separate_fractional_solutions; user_cbhandle->num_nodes = num_nodes; user_cbhandle->num_x_cols = num_nodes * num_nodes; user_cbhandle->num_v_cols = (num_nodes - 1) * user_cbhandle->num_x_cols; user_cbhandle->num_u_cols = (num_nodes - 1) * num_nodes; user_cbhandle->env = NULL; user_cbhandle->lp = NULL; user_cbhandle->x = NULL; user_cbhandle->indices = NULL; user_cbhandle->ray = NULL; user_cbhandle->cutval = NULL; user_cbhandle->cutind = NULL; user_cbhandle->x = malloc (user_cbhandle->num_x_cols * sizeof(*user_cbhandle->x)); if ( user_cbhandle->x == NULL ) { fprintf (stderr, "No memory for x array.\n"); goto TERMINATE; } user_cbhandle->indices = malloc (user_cbhandle->num_x_cols * sizeof(*user_cbhandle->indices)); if ( user_cbhandle->indices == NULL ) { fprintf (stderr, "No memory for indices array.\n"); goto TERMINATE; } user_cbhandle->ray = malloc ((user_cbhandle->num_v_cols + user_cbhandle->num_u_cols) * sizeof(*user_cbhandle->ray)); if ( user_cbhandle->ray == NULL ) { fprintf (stderr, "No memory for ray array.\n"); goto TERMINATE; } user_cbhandle->cutval = malloc (user_cbhandle->num_x_cols * sizeof(*user_cbhandle->cutval)); if ( user_cbhandle->cutval == NULL ) { fprintf (stderr, "No memory for cutval array.\n"); goto TERMINATE; } user_cbhandle->cutind = malloc (user_cbhandle->num_x_cols * sizeof(*user_cbhandle->cutind)); if ( user_cbhandle->cutind == NULL ) { fprintf (stderr, "No memory for cutind array.\n"); goto TERMINATE; } /* Create the environment for the worker LP */ user_cbhandle->env = CPXXopenCPLEX (&status); if ( user_cbhandle->env == NULL ) { fprintf (stderr, "Could not open CPLEX environment for the worker LP: status = %d.\n", status); goto TERMINATE; } /* Turn off the presolve reductions */ status = CPXXsetintparam (user_cbhandle->env, CPXPARAM_Preprocessing_Reduce, 0); if ( status ) { fprintf(stderr, "Failed to set CPXPARAM_Preprocessing_Reduce, status = %d.\n", status); goto TERMINATE; } /* Create the worker LP */ user_cbhandle->lp = CPXXcreateprob (user_cbhandle->env, &status, "atsp_worker.lp"); if ( user_cbhandle->lp == NULL ) { fprintf (stderr, "Failed to create the worker LP: status = %d\n", status); goto TERMINATE; } /* Allocate memory for column names */ colname = malloc (100 * sizeof(*colname)); if ( colname == NULL ) { fprintf (stderr, "No memory for colname array.\n"); status = -1; goto TERMINATE; } /* Create variables v(k,i,j), one per time For simplicity, also dummy variables v(k,i,i) are created. Those variables are fixed to 0 and do not partecipate to the constraints */ for (k = 1; k < num_nodes; ++k) { for (i = 0; i < num_nodes; ++i) { for (j = 0; j < num_nodes; ++j) { double ub = ( i == j ? 0. : CPX_INFBOUND ); sprintf ((char *)colname, "v.%d.%d.%d", k, i, j); status = CPXXnewcols (user_cbhandle->env, user_cbhandle->lp, 1, NULL, NULL, &ub, NULL, &colname); if ( status ) { fprintf (stderr, "Error in CPXXnewcols, status = %d.\n", status); goto TERMINATE; } } } } /* Create variables u(k,i), one per time */ for (k = 1; k < num_nodes; ++k) { for (i = 0; i < num_nodes; ++i) { double obj = 0.; double lb = -CPX_INFBOUND; double ub = CPX_INFBOUND; sprintf ((char *)colname, "u.%d.%d", k, i); if ( i == 0 ) obj = -1.; else if ( i == k ) obj = 1.; status = CPXXnewcols (user_cbhandle->env, user_cbhandle->lp, 1, &obj, &lb, &ub, NULL, &colname); if ( status ) { fprintf (stderr, "Error in CPXXnewcols, status = %d.\n", status); goto TERMINATE; } } } /* Init data structures for CPXaddrows */ num_rows = user_cbhandle->num_x_cols * (num_nodes - 1); rhs = malloc (num_rows * sizeof (*rhs)); if ( rhs == NULL ) { fprintf (stderr, "No memory for rhs array.\n"); status = -1; goto TERMINATE; } sense = malloc (num_rows * sizeof (*sense)); if ( sense == NULL ) { fprintf (stderr, "No memory for sense array.\n"); status = -1; goto TERMINATE; } rmatbeg = malloc ( (num_rows + 1) * sizeof (*rmatbeg)); if ( rmatbeg == NULL ) { fprintf (stderr, "No memory for rmatbeg array.\n"); status = -1; goto TERMINATE; } rmatind = malloc (3 * num_rows * sizeof (*rmatind)); if ( rmatind == NULL ) { fprintf (stderr, "No memory for rmatind array.\n"); status = -1; goto TERMINATE; } rmatval = malloc (3 * num_rows * sizeof (*rmatval)); if ( rmatval == NULL ) { fprintf (stderr, "No memory for rmatval array.\n"); status = -1; goto TERMINATE; } /* Populate data structures for CPXaddrows and add all the constraints: forall k in V0, forall (i,j) in A: u(k,i) - u(k,j) <= v(k,i,j) */ num_rows = 0; nzcnt = 0; for (k = 1; k < num_nodes; ++k) { for (i = 0; i < num_nodes; ++i) { for (j = 0; j < num_nodes; ++j) { if ( i != j ) { rhs[num_rows] = 0.; sense[num_rows] = 'L'; rmatbeg[num_rows] = nzcnt; rmatind[nzcnt] = (k-1) * user_cbhandle->num_x_cols + i * num_nodes + j; rmatval[nzcnt++] = -1.; rmatind[nzcnt] = user_cbhandle->num_v_cols + (k-1) * num_nodes + i; rmatval[nzcnt++] = 1.; rmatind[nzcnt] = user_cbhandle->num_v_cols + (k-1) * num_nodes + j; rmatval[nzcnt++] = -1.; ++num_rows; } } } } rmatbeg[num_rows] = nzcnt; status = CPXXaddrows (user_cbhandle->env, user_cbhandle->lp, 0, num_rows, nzcnt, rhs, sense, rmatbeg, rmatind, rmatval, NULL, NULL); if ( status ) { fprintf (stderr, "Error in CPXXaddrows: status = %d\n", status); goto TERMINATE; } TERMINATE: free_and_null ((char **) &colname); free_and_null ((char **) &sense); free_and_null ((char **) &rhs); free_and_null ((char **) &rmatbeg); free_and_null ((char **) &rmatind); free_and_null ((char **) &rmatval); return status; } /* END init_user_cbhandle */
static int CPXPUBLIC solvecallback (CPXCENVptr env, void *cbdata, int wherefrom, void *userinfo, int *useraction_p) { int status = 0; int lpstatus = 0; CPXLPptr nodelp = NULL; double *prex = NULL; MYCBptr mycbinfo = (MYCBptr) userinfo; CPXLPptr mip = mycbinfo->mip; double *relx = mycbinfo->relx; CPXDIM cols; int prestat; *useraction_p = CPX_CALLBACK_DEFAULT; /* Only use callback for solving the root relaxation (node 0) */ if ( mycbinfo->count > 0 ) { goto TERMINATE; } mycbinfo->count++; /* Extract the LP to be solved */ status = CPXXgetcallbacknodelp (env, cbdata, wherefrom, &nodelp); if ( status ) goto TERMINATE; cols = CPXXgetnumcols (env, nodelp); prex = malloc (cols * sizeof (*prex)); if ( prex == NULL ) { status = CPXERR_NO_MEMORY; goto TERMINATE; } /* Use MIP presolve to crush the original solution. Note that MIP presolve can only crush primal solutions */ status = CPXXgetprestat (env, mip, &prestat, NULL, NULL, NULL, NULL); if ( status ) goto TERMINATE; /* If a presolved model exists, then relx is crushed down to prex, the corresponding solution for the presolved model; otherwise, prex is just a copy of relx */ if ( prestat ) { status = CPXXcrushx (env, mip, relx, prex); if ( status ) goto TERMINATE; } else { memcpy (prex, relx, cols * sizeof (*relx)); } /* Feed the crushed solution into 'nodelp' */ status = CPXXcopystart (env, nodelp, NULL, NULL, prex, NULL, NULL, NULL); /* Use primal to reoptimize, since we only have a primal solution */ status = CPXXprimopt (env, nodelp); if ( status ) goto TERMINATE; lpstatus = CPXXgetstat (env, nodelp); if ( lpstatus == CPX_STAT_OPTIMAL || lpstatus == CPX_STAT_OPTIMAL_INFEAS || lpstatus == CPX_STAT_INFEASIBLE ) { *useraction_p = CPX_CALLBACK_SET; } TERMINATE: free_and_null ((char **) &prex); return (status); } /* END solvecallback */
int main (int argc, char *argv[]) { int status = 0; /* Declare and allocate space for the variables and arrays where we will store the optimization results, including the status, objective value, and variable values */ int solstat; double objval, relobj; double *x = NULL; MYCB info; CPXENVptr env = NULL; CPXLPptr lp = NULL; CPXLPptr lpclone = NULL; CPXDIM j; CPXDIM cur_numcols; /* Check the command line arguments */ if ( argc != 2 ) { usage (argv[0]); goto TERMINATE; } /* Initialize the CPLEX environment */ env = CPXXopenCPLEX (&status); /* If an error occurs, the status value indicates the reason for failure. A call to CPXXgeterrorstring will produce the text of the error message. Note that CPXXopenCPLEX produces no output, so the only way to see the cause of the error is to use CPXXgeterrorstring. For other CPLEX routines, the errors will be seen if the CPXPARAM_ScreenOutput parameter is set to CPX_ON */ if ( env == NULL ) { char errmsg[CPXMESSAGEBUFSIZE]; fprintf (stderr, "Could not open CPLEX environment.\n"); CPXXgeterrorstring (env, status, errmsg); fprintf (stderr, "%s", errmsg); goto TERMINATE; } /* Turn on output to the screen */ status = CPXXsetintparam (env, CPXPARAM_ScreenOutput, CPX_ON); if ( status ) { fprintf (stderr, "Failure to turn on screen indicator, error %d.\n", status); goto TERMINATE; } /* Turn on traditional search for use with control callbacks */ status = CPXXsetintparam (env, CPXPARAM_MIP_Strategy_Search, CPX_MIPSEARCH_TRADITIONAL); if ( status ) goto TERMINATE; /* Create the problem, using the filename as the problem name */ lp = CPXXcreateprob (env, &status, argv[1]); /* A returned pointer of NULL may mean that not enough memory was available or there was some other problem. In the case of failure, an error message will have been written to the error channel from inside CPLEX. In this example, the setting of the parameter CPXPARAM_ScreenOutput causes the error message to appear on stdout. Note that most CPLEX routines return an error code to indicate the reason for failure */ if ( lp == NULL ) { fprintf (stderr, "Failed to create LP.\n"); goto TERMINATE; } /* Now read the file, and copy the data into the created lp */ status = CPXXreadcopyprob (env, lp, argv[1], NULL); if ( status ) { fprintf (stderr, "Failed to read and copy the problem data.\n"); goto TERMINATE; } /* We transfer a problem with semi-continuous or semi-integer variables to a MIP problem by adding variables and constraints. So in MIP callbacks, the size of the problem is changed and this example won't work for such problems */ if ( CPXXgetnumsemicont (env, lp) + CPXXgetnumsemiint (env, lp) ) { fprintf (stderr, "Not for problems with semi-continuous or semi-integer variables.\n"); goto TERMINATE; } /* The size of the problem should be obtained by asking CPLEX what the actual size is. cur_numcols store the current number of columns */ cur_numcols = CPXXgetnumcols (env, lp); x = malloc (cur_numcols * sizeof (*x)); if ( x == NULL ) { fprintf (stderr, "Memory allocation failed.\n"); goto TERMINATE; } /* Solve relaxation of MIP */ /* Clone original model */ lpclone = CPXXcloneprob (env, lp, &status); if ( status ) { fprintf (stderr, "Failed to clone problem.\n"); goto TERMINATE; } /* Relax */ status = CPXXchgprobtype (env, lpclone, CPXPROB_LP); if ( status ) { fprintf (stderr, "Failed to relax problem.\n"); goto TERMINATE; } /* Solve LP relaxation of original model using "default" LP solver */ status = CPXXlpopt (env, lpclone); if ( status ) { fprintf (stderr, "Failed to solve relaxation.\n"); goto TERMINATE; } printf ("Solution status %d.\n", CPXXgetstat(env,lpclone)); status = CPXXsolution (env, lpclone, NULL, &relobj, x, NULL, NULL, NULL); if ( status ) { fprintf (stderr, "Failed to extract solution.\n"); goto TERMINATE; } printf ("\nLP relaxation objective: %.4e\n\n", relobj); /* Set up solve callback */ info.count = 0; info.mip = lp; info.relx = x; status = CPXXsetsolvecallbackfunc (env, &solvecallback, (void *) &info); if ( status ) { fprintf (stderr, "Failed to set solve callback.\n"); goto TERMINATE; } /* Optimize the problem and obtain solution */ status = CPXXmipopt (env, lp); if ( status ) { fprintf (stderr, "Failed to optimize MIP.\n"); goto TERMINATE; } solstat = CPXXgetstat (env, lp); printf ("Solution status %d.\n", solstat); status = CPXXgetobjval (env, lp, &objval); if ( status ) { fprintf (stderr,"Failed to obtain objective value.\n"); goto TERMINATE; } printf ("Objective value %.10g\n", objval); status = CPXXgetx (env, lp, x, 0, cur_numcols-1); if ( status ) { fprintf (stderr, "Failed to obtain solution.\n"); goto TERMINATE; } /* Write out the solution */ for (j = 0; j < cur_numcols; j++) { if ( fabs (x[j]) > 1e-10 ) { printf ( "Column %d: Value = %17.10g\n", j, x[j]); } } TERMINATE: /* Free the solution vector */ free_and_null ((char **) &x); /* Free the problem as allocated by CPXXcreateprob and CPXXreadcopyprob, if necessary */ if ( lp != NULL ) { status = CPXXfreeprob (env, &lp); if ( status ) { fprintf (stderr, "CPXXfreeprob failed, error code %d.\n", status); } } /* Free the cloned lp as allocated by CPXXcloneprob, if necessary */ if ( lpclone != NULL ) { status = CPXXfreeprob (env, &lpclone); if ( status ) { fprintf (stderr, "CPXXfreeprob failed, error code %d.\n", status); } } /* Free the CPLEX environment, if necessary */ if ( env != NULL ) { status = CPXXcloseCPLEX (&env); /* Note that CPXXcloseCPLEX produces no output, so the only way to see the cause of the error is to use CPXXgeterrorstring. For other CPLEX routines, the errors will be seen if the CPXPARAM_ScreenOutput parameter is set to CPX_ON */ if ( status ) { char errmsg[CPXMESSAGEBUFSIZE]; fprintf (stderr, "Could not close CPLEX environment.\n"); CPXXgeterrorstring (env, status, errmsg); fprintf (stderr, "%s", errmsg); } } return (status); } /* END main */
int main (int argc, char **argv) { int status = 0; int nfoods; int nnutr; double *cost = NULL; double *lb = NULL; double *ub = NULL; double *nutrmin = NULL; double *nutrmax = NULL; double **nutrper = NULL; double *x = NULL; double objval; int solstat; /* Declare and allocate space for the variables and arrays where we will store the optimization results including the status, objective value, variable values, dual values, row slacks and variable reduced costs. */ CPXENVptr env = NULL; CPXLPptr lp = NULL; int i, j; /* Check the command line arguments */ if (( argc != 3 ) || ( argv[1][0] != '-' ) || ( strchr ("rc", argv[1][1]) == NULL ) ) { usage (argv[0]); goto TERMINATE; } status = readdata(argv[2], &nfoods, &cost, &lb, &ub, &nnutr, &nutrmin, &nutrmax, &nutrper); if ( status ) goto TERMINATE; /* Initialize the CPLEX environment */ env = CPXopenCPLEX (&status); /* If an error occurs, the status value indicates the reason for failure. A call to CPXgeterrorstring will produce the text of the error message. Note that CPXopenCPLEX produces no output, so the only way to see the cause of the error is to use CPXgeterrorstring. For other CPLEX routines, the errors will be seen if the CPXPARAM_ScreenOutput indicator is set to CPX_ON. */ if ( env == NULL ) { char errmsg[CPXMESSAGEBUFSIZE]; fprintf (stderr, "Could not open CPLEX environment.\n"); CPXgeterrorstring (env, status, errmsg); fprintf (stderr, "%s", errmsg); goto TERMINATE; } /* Turn on output to the screen */ status = CPXsetintparam (env, CPXPARAM_ScreenOutput, CPX_ON); if ( status ) { fprintf (stderr, "Failure to turn on screen indicator, error %d.\n", status); goto TERMINATE; } /* Turn on data checking */ status = CPXsetintparam (env, CPXPARAM_Read_DataCheck, CPX_ON); if ( status ) { fprintf (stderr, "Failure to turn on data checking, error %d.\n", status); goto TERMINATE; } /* Create the problem. */ lp = CPXcreateprob (env, &status, "diet"); /* A returned pointer of NULL may mean that not enough memory was available or there was some other problem. In the case of failure, an error message will have been written to the error channel from inside CPLEX. In this example, the setting of the parameter CPXPARAM_ScreenOutput causes the error message to appear on stdout. */ if ( lp == NULL ) { fprintf (stderr, "Failed to create LP.\n"); goto TERMINATE; } /* Now populate the problem with the data. For building large problems, consider setting the row, column and nonzero growth parameters before performing this task. */ switch (argv[1][1]) { case 'r': status = populatebyrow (env, lp, nfoods, cost, lb, ub, nnutr, nutrmin, nutrmax, nutrper); break; case 'c': status = populatebycolumn (env, lp, nfoods, cost, lb, ub, nnutr, nutrmin, nutrmax, nutrper); break; } if ( status ) { fprintf (stderr, "Failed to populate problem.\n"); goto TERMINATE; } /* Optimize the problem and obtain solution. */ status = CPXlpopt (env, lp); if ( status ) { fprintf (stderr, "Failed to optimize LP.\n"); goto TERMINATE; } x = (double *) malloc (nfoods * sizeof(double)); if ( x == NULL ) { status = CPXERR_NO_MEMORY; fprintf (stderr, "Could not allocate memory for solution.\n"); goto TERMINATE; } status = CPXsolution (env, lp, &solstat, &objval, x, NULL, NULL, NULL); if ( status ) { fprintf (stderr, "Failed to obtain solution.\n"); goto TERMINATE; } /* Write the output to the screen. */ printf ("\nSolution status = %d\n", solstat); printf ("Solution value = %f\n\n", objval); for (j = 0; j < nfoods; j++) { printf ("Food %d: Buy = %10f\n", j, x[j]); } /* Finally, write a copy of the problem to a file. */ status = CPXwriteprob (env, lp, "diet.lp", NULL); if ( status ) { fprintf (stderr, "Failed to write LP to disk.\n"); goto TERMINATE; } TERMINATE: /* Free up the problem as allocated by CPXcreateprob, if necessary */ if ( lp != NULL ) { status = CPXfreeprob (env, &lp); if ( status ) { fprintf (stderr, "CPXfreeprob failed, error code %d.\n", status); } } /* Free up the CPLEX environment, if necessary */ if ( env != NULL ) { status = CPXcloseCPLEX (&env); /* Note that CPXcloseCPLEX produces no output, so the only way to see the cause of the error is to use CPXgeterrorstring. For other CPLEX routines, the errors will be seen if the CPXPARAM_ScreenOutput indicator is set to CPX_ON. */ if ( status > 0 ) { char errmsg[CPXMESSAGEBUFSIZE]; fprintf (stderr, "Could not close CPLEX environment.\n"); CPXgeterrorstring (env, status, errmsg); fprintf (stderr, "%s", errmsg); } } if ( nutrper != NULL ) { for (i = 0; i < nnutr; ++i) { free_and_null ((char **) &(nutrper[i])); } } free_and_null ((char **) &nutrper); free_and_null ((char **) &cost); free_and_null ((char **) &cost); free_and_null ((char **) &lb); free_and_null ((char **) &ub); free_and_null ((char **) &nutrmin); free_and_null ((char **) &nutrmax); free_and_null ((char **) &x); return (status); } /* END main */
void destroy_execp(void *obj) { Execp *execp = (Execp *)obj; if (execp->frontend) { // This is a frontend element execp->backend->instances = g_list_remove_all(execp->backend->instances, execp); free_and_null(execp->frontend); remove_area(&execp->area); free_area(&execp->area); free_and_null(execp); } else { // This is a backend element stop_timeout(execp->backend->timer); execp->backend->timer = NULL; if (execp->backend->icon) { imlib_context_set_image(execp->backend->icon); imlib_free_image(); execp->backend->icon = NULL; } free_and_null(execp->backend->buf_output); free_and_null(execp->backend->text); free_and_null(execp->backend->icon_path); if (execp->backend->child) { kill(-execp->backend->child, SIGHUP); execp->backend->child = 0; } if (execp->backend->child_pipe >= 0) { close(execp->backend->child_pipe); execp->backend->child_pipe = -1; } if (execp->backend->cmd_pids) { g_tree_destroy(execp->backend->cmd_pids); execp->backend->cmd_pids = NULL; } execp->backend->bg = NULL; pango_font_description_free(execp->backend->font_desc); execp->backend->font_desc = NULL; free_and_null(execp->backend->command); free_and_null(execp->backend->tooltip); free_and_null(execp->backend->lclick_command); free_and_null(execp->backend->mclick_command); free_and_null(execp->backend->rclick_command); free_and_null(execp->backend->dwheel_command); free_and_null(execp->backend->uwheel_command); if (execp->backend->instances) { fprintf(stderr, "Error: Attempt to destroy backend while there are still frontend instances!\n"); exit(-1); } free(execp->backend); free(execp); } }
int main (void) { /* Declare pointers for the variables and arrays that will contain the data which define the LP problem. The setproblemdata() routine allocates space for the problem data. */ char *probname = NULL; int numcols; int numrows; int objsen; double *obj = NULL; double *rhs = NULL; char *sense = NULL; int *matbeg = NULL; int *matcnt = NULL; int *matind = NULL; double *matval = NULL; double *lb = NULL; double *ub = NULL; /* Declare and allocate space for the variables and arrays where we will store the optimization results including the status, objective value, variable values, dual values, row slacks and variable reduced costs. */ int solstat; double objval; double x[NUMCOLS]; double pi[NUMROWS]; double slack[NUMROWS]; double dj[NUMCOLS]; CPXENVptr env = NULL; CPXLPptr lp = NULL; int status; int i, j; int cur_numrows, cur_numcols; /* Initialize the CPLEX environment */ env = CPXopenCPLEX (&status); /* If an error occurs, the status value indicates the reason for failure. A call to CPXgeterrorstring will produce the text of the error message. Note that CPXopenCPLEX produces no output, so the only way to see the cause of the error is to use CPXgeterrorstring. For other CPLEX routines, the errors will be seen if the CPXPARAM_ScreenOutput indicator is set to CPX_ON. */ if ( env == NULL ) { char errmsg[CPXMESSAGEBUFSIZE]; fprintf (stderr, "Could not open CPLEX environment.\n"); CPXgeterrorstring (env, status, errmsg); fprintf (stderr, "%s", errmsg); goto TERMINATE; } /* Turn on output to the screen */ status = CPXsetintparam (env, CPXPARAM_ScreenOutput, CPX_ON); if ( status ) { fprintf (stderr, "Failure to turn on screen indicator, error %d.\n", status); goto TERMINATE; } /* Allocate memory and fill in the data for the problem. */ status = setproblemdata (&probname, &numcols, &numrows, &objsen, &obj, &rhs, &sense, &matbeg, &matcnt, &matind, &matval, &lb, &ub); if ( status ) { fprintf (stderr, "Failed to build problem data arrays.\n"); goto TERMINATE; } /* Create the problem. */ lp = CPXcreateprob (env, &status, probname); /* A returned pointer of NULL may mean that not enough memory was available or there was some other problem. In the case of failure, an error message will have been written to the error channel from inside CPLEX. In this example, the setting of the parameter CPXPARAM_ScreenOutput causes the error message to appear on stdout. */ if ( lp == NULL ) { fprintf (stderr, "Failed to create LP.\n"); goto TERMINATE; } /* Now copy the problem data into the lp */ status = CPXcopylp (env, lp, numcols, numrows, objsen, obj, rhs, sense, matbeg, matcnt, matind, matval, lb, ub, NULL); if ( status ) { fprintf (stderr, "Failed to copy problem data.\n"); goto TERMINATE; } /* Optimize the problem and obtain solution. */ status = CPXlpopt (env, lp); if ( status ) { fprintf (stderr, "Failed to optimize LP.\n"); goto TERMINATE; } status = CPXsolution (env, lp, &solstat, &objval, x, pi, slack, dj); if ( status ) { fprintf (stderr, "Failed to obtain solution.\n"); goto TERMINATE; } /* Write the output to the screen. */ printf ("\nSolution status = %d\n", solstat); printf ("Solution value = %f\n\n", objval); /* The size of the problem should be obtained by asking CPLEX what the actual size is, rather than using what was passed to CPXcopylp. cur_numrows and cur_numcols store the current number of rows and columns, respectively. */ cur_numrows = CPXgetnumrows (env, lp); cur_numcols = CPXgetnumcols (env, lp); for (i = 0; i < cur_numrows; i++) { printf ("Row %d: Slack = %10f Pi = %10f\n", i, slack[i], pi[i]); } for (j = 0; j < cur_numcols; j++) { printf ("Column %d: Value = %10f Reduced cost = %10f\n", j, x[j], dj[j]); } /* Finally, write a copy of the problem to a file. */ status = CPXwriteprob (env, lp, "lpex1.lp", NULL); if ( status ) { fprintf (stderr, "Failed to write LP to disk.\n"); goto TERMINATE; } TERMINATE: /* Free up the problem as allocated by CPXcreateprob, if necessary */ if ( lp != NULL ) { status = CPXfreeprob (env, &lp); if ( status ) { fprintf (stderr, "CPXfreeprob failed, error code %d.\n", status); } } /* Free up the CPLEX environment, if necessary */ if ( env != NULL ) { status = CPXcloseCPLEX (&env); /* Note that CPXcloseCPLEX produces no output, so the only way to see the cause of the error is to use CPXgeterrorstring. For other CPLEX routines, the errors will be seen if the CPXPARAM_ScreenOutput indicator is set to CPX_ON. */ if ( status ) { char errmsg[CPXMESSAGEBUFSIZE]; fprintf (stderr, "Could not close CPLEX environment.\n"); CPXgeterrorstring (env, status, errmsg); fprintf (stderr, "%s", errmsg); } } /* Free up the problem data arrays, if necessary. */ free_and_null ((char **) &probname); free_and_null ((char **) &obj); free_and_null ((char **) &rhs); free_and_null ((char **) &sense); free_and_null ((char **) &matbeg); free_and_null ((char **) &matcnt); free_and_null ((char **) &matind); free_and_null ((char **) &matval); free_and_null ((char **) &lb); free_and_null ((char **) &ub); return (status); } /* END main */
int main (void) { /* Declare variables and arrays where we will store the optimization results including the status, objective value, and variable values. */ int solstat; double objval; CPXDIM colcnt = 0; double *x = NULL; CPXENVptr env = NULL; CPXLPptr lp = NULL; int status; int m, p; /* Initialize the CPLEX environment */ env = CPXXopenCPLEX (&status); /* If an error occurs, the status value indicates the reason for failure. A call to CPXXgeterrorstring will produce the text of the error message. Note that CPXXopenCPLEX produces no output, so the only way to see the cause of the error is to use CPXXgeterrorstring. For other CPLEX routines, the errors will be seen if the CPXPARAM_ScreenOutput indicator is set to CPX_ON. */ if ( env == NULL ) { char errmsg[CPXMESSAGEBUFSIZE]; fprintf (stderr, "Could not open CPLEX environment.\n"); CPXXgeterrorstring (env, status, errmsg); fprintf (stderr, "%s", errmsg); goto TERMINATE; } /* Turn on output to the screen */ status = CPXXsetintparam (env, CPXPARAM_ScreenOutput, CPX_ON); if ( status ) { fprintf (stderr, "Failure to turn on screen indicator, error %d.\n", status); goto TERMINATE; } /* Formulate and solve the problem */ lp = CPXXcreateprob (env, &status, "food manufacturing"); /* A returned pointer of NULL may mean that not enough memory was available or there was some other problem. In the case of failure, an error message will have been written to the error channel from inside CPLEX. In this example, the setting of the parameter CPXPARAM_ScreenOutput causes the error message to appear on stdout. */ if ( lp == NULL ) { fprintf (stderr, "Failed to create LP.\n"); goto TERMINATE; } /* Build the model */ status = buildmodel (env, lp); if ( status ) { fprintf (stderr, "Failed to build model.\n"); goto TERMINATE; } /* Write a copy of the problem to a file. */ status = CPXXwriteprob (env, lp, "foodmanu.lp", NULL); if ( status ) { fprintf (stderr, "Failed to write LP to disk.\n"); goto TERMINATE; } /* Optimize the problem and obtain solution. */ status = CPXXmipopt (env, lp); if ( status ) { fprintf (stderr, "Failed to optimize MIP.\n"); goto TERMINATE; } solstat = CPXXgetstat (env, lp); /* Write solution status, objective and solution vector to the screen. */ printf ("\nSolution status = %d\n", solstat); status = CPXXgetobjval (env, lp, &objval); if ( status ) { fprintf (stderr,"No MIP objective value available. Exiting...\n"); goto TERMINATE; } printf ("Solution value (maximum profit) = %f\n\n", objval); colcnt = NUMVARS*NUMMONTHS*NUMPRODUCTS; x = malloc (colcnt * sizeof(*x)); if ( x == NULL ) { status = CPXERR_NO_MEMORY; fprintf (stderr, "Could not allocate memory for solution.\n"); goto TERMINATE; } status = CPXXgetx (env, lp, x, 0, colcnt - 1); if ( status ) { fprintf (stderr, "Failed to get optimal integer x.\n"); goto TERMINATE; } for (m = 0; m < NUMMONTHS; m++) { printf ("Month %d \n", m); printf (" . buy "); for (p = 0; p < NUMPRODUCTS; p++) printf ("%f\t", x[varindex(m, p, BUY)]); printf ("\n"); printf (" . use "); for (p = 0; p < NUMPRODUCTS; p++) printf ("%f\t", x[varindex (m, p, USE)]); printf ("\n"); printf (" . store "); for (p = 0; p < NUMPRODUCTS; p++) printf ("%f\t", x[varindex (m, p, STORE)]); printf ("\n"); } /* Free problem */ status = CPXXfreeprob (env, &lp); if ( status ) { fprintf (stderr, "CPXXfreeprob failed, error code %d.\n", status); goto TERMINATE; } TERMINATE: free_and_null ((char **) &x); /* Free up the problem as allocated by CPXXcreateprob, if necessary */ if ( lp != NULL ) { status = CPXXfreeprob (env, &lp); if ( status ) { fprintf (stderr, "CPXXfreeprob failed, error code %d.\n", status); } } /* Free up the CPLEX environment, if necessary */ if ( env != NULL ) { status = CPXXcloseCPLEX (&env); /* Note that CPXXcloseCPLEX produces no output, so the only way to see the cause of the error is to use CPXXgeterrorstring. For other CPLEX routines, the errors will be seen if the CPXPARAM_ScreenOutput indicator is set to CPX_ON. */ if ( status ) { char errmsg[CPXMESSAGEBUFSIZE]; fprintf (stderr, "Could not close CPLEX environment.\n"); CPXXgeterrorstring (env, status, errmsg); fprintf (stderr, "%s", errmsg); } } return (status); } /* END main */