24 #if defined (HAVE_CONFIG_H) 46 #if defined (HAVE_GLPK) 50 #if defined (HAVE_GLPK_GLPK_H) 51 # include <glpk/glpk.h> 80 glpk (
int sense,
int n,
int m,
double *
c,
int nz,
int *rn,
int *cn,
81 double *
a,
double *
b,
char *ctype,
int *freeLB,
double *lb,
82 int *freeUB,
double *ub,
int *vartype,
int isMIP,
int lpsolver,
84 double *
xmin,
double *fmin,
int *status,
85 double *lambda,
double *redcosts,
double *time)
90 clock_t t_start = clock ();
92 glp_prob *lp = glp_create_prob ();
96 glp_set_obj_dir (lp, GLP_MIN);
98 glp_set_obj_dir (lp, GLP_MAX);
100 glp_add_cols (lp, n);
101 for (
int i = 0;
i < n;
i++)
104 if (! freeLB[
i] && ! freeUB[
i])
107 glp_set_col_bnds (lp,
i+1, GLP_DB, lb[
i], ub[
i]);
109 glp_set_col_bnds (lp,
i+1, GLP_FX, lb[
i], ub[
i]);
113 if (! freeLB[
i] && freeUB[
i])
114 glp_set_col_bnds (lp,
i+1, GLP_LO, lb[
i], ub[
i]);
117 if (freeLB[
i] && ! freeUB[
i])
118 glp_set_col_bnds (lp,
i+1, GLP_UP, lb[
i], ub[
i]);
120 glp_set_col_bnds (lp,
i+1, GLP_FR, lb[
i], ub[
i]);
126 glp_set_obj_coef(lp,
i+1,
c[
i]);
129 glp_set_col_kind (lp,
i+1, vartype[
i]);
132 glp_add_rows (lp, m);
134 for (
int i = 0;
i < m;
i++)
165 glp_set_row_bnds (lp,
i+1, typx,
b[
i],
b[
i]);
169 glp_load_matrix (lp, nz, rn, cn,
a);
173 static char tmp[] =
"outpb.lp";
174 if (glp_write_lp (lp,
nullptr,
tmp) != 0)
175 error (
"__glpk__: unable to write problem");
179 if (! par->
presol || lpsolver != 1)
180 glp_scale_prob (lp,
scale);
183 if (lpsolver == 1 && ! par->
presol)
184 glp_adv_basis (lp, 0);
188 if ((! isMIP && lpsolver == 1)
189 || (isMIP && ! par->
presol))
192 glp_init_smcp (&smcp);
193 smcp.msg_lev = par->
msglev;
194 smcp.meth = par->
dual;
195 smcp.pricing = par->
price;
196 smcp.r_test = par->
rtest;
197 smcp.tol_bnd = par->
tolbnd;
198 smcp.tol_dj = par->
toldj;
199 smcp.tol_piv = par->
tolpiv;
200 smcp.obj_ll = par->
objll;
201 smcp.obj_ul = par->
objul;
202 smcp.it_lim = par->
itlim;
203 smcp.tm_lim = par->
tmlim;
204 smcp.out_frq = par->
outfrq;
205 smcp.out_dly = par->
outdly;
206 smcp.presolve = par->
presol;
207 errnum = glp_simplex (lp, &smcp);
213 glp_init_iocp (&iocp);
214 iocp.msg_lev = par->
msglev;
215 iocp.br_tech = par->
branch;
216 iocp.bt_tech = par->
btrack;
217 iocp.tol_int = par->
tolint;
218 iocp.tol_obj = par->
tolobj;
219 iocp.tm_lim = par->
tmlim;
220 iocp.out_frq = par->
outfrq;
221 iocp.out_dly = par->
outdly;
222 iocp.presolve = par->
presol;
223 errnum = glp_intopt (lp, &iocp);
226 if (! isMIP && lpsolver == 2)
229 glp_init_iptcp (&iptcp);
230 iptcp.msg_lev = par->
msglev;
231 errnum = glp_interior (lp, &iptcp);
238 *status = glp_mip_status (lp);
239 *fmin = glp_mip_obj_val (lp);
245 *status = glp_get_status (lp);
246 *fmin = glp_get_obj_val (lp);
250 *status = glp_ipt_status (lp);
251 *fmin = glp_ipt_obj_val (lp);
257 for (
int i = 0;
i < n;
i++)
258 xmin[
i] = glp_mip_col_val (lp,
i+1);
263 for (
int i = 0;
i < n;
i++)
266 xmin[
i] = glp_get_col_prim (lp,
i+1);
268 xmin[
i] = glp_ipt_col_prim (lp,
i+1);
272 for (
int i = 0;
i < m;
i++)
275 lambda[
i] = glp_get_row_dual (lp,
i+1);
277 lambda[
i] = glp_ipt_row_dual (lp,
i+1);
281 for (
int i = 0;
i < glp_get_num_cols (lp);
i++)
284 redcosts[
i] = glp_get_col_dual (lp,
i+1);
286 redcosts[
i] = glp_ipt_col_dual (lp,
i+1);
290 *time = (clock () - t_start) / CLOCKS_PER_SEC;
293 glp_delete_prob (lp);
305 #define OCTAVE_GLPK_GET_REAL_PARAM(NAME, VAL) \ 308 octave_value tmp = PARAM.getfield (NAME); \ 310 if (tmp.is_defined ()) \ 312 if (! tmp.isempty ()) \ 313 VAL = tmp.xscalar_value ("glpk: invalid value in PARAM" NAME); \ 315 error ("glpk: invalid value in PARAM" NAME); \ 320 #define OCTAVE_GLPK_GET_INT_PARAM(NAME, VAL) \ 323 octave_value tmp = PARAM.getfield (NAME); \ 325 if (tmp.is_defined ()) \ 327 if (! tmp.isempty ()) \ 328 VAL = tmp.xint_value ("glpk: invalid value in PARAM" NAME); \ 330 error ("glpk: invalid value in PARAM" NAME); \ 341 #if defined (HAVE_GLPK) 344 if (args.length () != 9)
348 int mrowsc = args(0).rows ();
350 Matrix C = args(0).xmatrix_value (
"__glpk__: invalid value of C");
352 double *
c =
C.fortran_vec ();
361 if (args(1).issparse ())
363 SparseMatrix A = args(1).xsparse_matrix_value (
"__glpk__: invalid value of A");
370 a.resize (Anz+1, 0.0);
373 error (
"__glpk__: invalid value of A");
379 rn(nz) =
A.ridx (
i) + 1;
386 Matrix A = args(1).xmatrix_value (
"__glpk__: invalid value of A");
391 a.resize (mrowsA*mrowsc+1, 0.0);
393 for (
int i = 0;
i < mrowsA;
i++)
395 for (
int j = 0; j < mrowsc; j++)
411 Matrix B = args(2).xmatrix_value (
"__glpk__: invalid value of B");
413 double *
b =
B.fortran_vec ();
417 Matrix LB = args(3).xmatrix_value (
"__glpk__: invalid value of LB");
419 if (LB.
numel () < mrowsc)
420 error (
"__glpk__: invalid dimensions for LB");
426 for (
int i = 0;
i < mrowsc;
i++)
439 Matrix UB = args(4).xmatrix_value (
"__glpk__: invalid value of UB");
441 if (UB.
numel () < mrowsc)
442 error (
"__glpk__: invalid dimensions for UB");
447 for (
int i = 0;
i < mrowsc;
i++)
460 charMatrix CTYPE = args(5).xchar_matrix_value (
"__glpk__: invalid value of CTYPE");
465 charMatrix VTYPE = args(6).xchar_matrix_value (
"__glpk__: invalid value of VARTYPE");
469 for (
int i = 0;
i < mrowsc ;
i++)
471 if (VTYPE(
i,0) ==
'I')
482 double SENSE = args(7).xscalar_value (
"__glpk__: invalid value of SENSE");
490 octave_scalar_map PARAM = args(8).xscalar_map_value (
"__glpk__: invalid value of PARAM");
500 error (
"__glpk__: PARAM.msglev must be 0 (no output) or 1 (error and warning messages only [default]) or 2 (normal output) or 3 (full output)");
505 if (scale < 0 || scale > 128)
506 error (
"__glpk__: PARAM.scale must either be 128 (automatic selection of scaling options), or a bitwise or of: 1 (geometric mean scaling), 16 (equilibration scaling), 32 (round scale factors to power of two), 64 (skip if problem is well scaled");
512 error (
"__glpk__: PARAM.dual must be 1 (use two-phase primal simplex [default]) or 2 (use two-phase dual simplex) or 3 (use two-phase dual simplex, and if it fails, switch to the primal simplex)");
518 error (
"__glpk__: PARAM.price must be 17 (textbook pricing) or 34 (steepest edge pricing [default])");
532 error (
"__glpk__: PARAM.branch must be 1 (first fractional variable) or 2 (last fractional variable) or 3 (most fractional variable) or 4 (heuristic by Driebeck and Tomlin [default]) or 5 (hybrid pseudocost heuristic)");
538 error (
"__glpk__: PARAM.btrack must be 1 (depth first search) or 2 (breadth first search) or 3 (best local bound) or 4 (best projection heuristic [default]");
544 error (
"__glpk__: PARAM.presol must be 0 (do NOT use LP presolver) or 1 (use LP presolver [default])");
549 if (lpsolver < 1 || lpsolver > 2)
550 error (
"__glpk__: PARAM.lpsolver must be 1 (simplex method) or 2 (interior point method)");
556 error (
"__glpk__: PARAM.rtest must be 17 (standard ratio test) or 34 (Harris' two-pass ratio test [default])");
567 save_pb = save_pb != 0;
610 save_pb,
scale, &par,
xmin.fortran_vec (), &fmin,
618 extra.
assign (
"lambda", lambda);
619 extra.assign (
"redcosts", redcosts);
622 extra.assign (
"time", time);
623 extra.assign (
"status", status);
625 return ovl (
xmin, fmin, errnum, extra);
629 octave_unused_parameter (args);
F77_RET_T const F77_INT F77_CMPLX const F77_INT F77_CMPLX * B
OCTINTERP_API void print_usage(void)
const T * fortran_vec(void) const
int glpk(int sense, int n, int m, double *c, int nz, int *rn, int *cn, double *a, double *b, char *ctype, int *freeLB, double *lb, int *freeUB, double *ub, int *vartype, int isMIP, int lpsolver, int save_pb, int scale, const control_params *par, double *xmin, double *fmin, int *status, double *lambda, double *redcosts, double *time)
void error(const char *fmt,...)
nd example oindent opens the file binary numeric values will be read assuming they are stored in IEEE format with the least significant bit and then converted to the native representation Opening a file that is already open simply opens it again and returns a separate file id It is not an error to open a file several though writing to the same file through several different file ids may produce unexpected results The possible values of text mode reading and writing automatically converts linefeeds to the appropriate line end character for the you may append a you must also open the file in binary mode The parameter conversions are currently only supported for and permissions will be set to and then everything is written in a single operation This is very efficient and improves performance c
calling an anonymous function involves an overhead quite comparable to the overhead of an m file function Passing a handle to a built in function is because the interpreter is not involved in the internal loop For a
F77_RET_T const F77_INT F77_CMPLX * A
#define OCTAVE_GLPK_GET_INT_PARAM(NAME, VAL)
#define OCTAVE_GLPK_GET_REAL_PARAM(NAME, VAL)
void resize(const dim_vector &dv, const T &rfv)
Resizing (with fill).
octave_int< T > xmin(const octave_int< T > &x, const octave_int< T > &y)
charNDArray max(char d, const charNDArray &m)
OCTAVE_EXPORT octave_value_list isa nd deftypefn *return ovl(args(0).isinteger())
void assign(const std::string &k, const octave_value &val)
void scale(Matrix &m, double x, double y, double z)
#define DEFUN_DLD(name, args_name, nargout_name, doc)
Macro to define an at run time dynamically loadable builtin function.
octave_idx_type numel(void) const
Number of elements in the array.
Vector representing the dimensions (size) of an Array.
void err_disabled_feature(const std::string &fcn, const std::string &feature, const std::string &pkg)