__glpk__.cc

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (C) 2005-2012 Nicolo' Giorgetti
00004 
00005 This file is part of Octave.
00006 
00007 Octave is free software; you can redistribute it and/or modify it
00008 under the terms of the GNU General Public License as published by the
00009 Free Software Foundation; either version 3 of the License, or (at your
00010 option) any later version.
00011 
00012 Octave is distributed in the hope that it will be useful, but WITHOUT
00013 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00015 for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Octave; see the file COPYING.  If not, see
00019 <http://www.gnu.org/licenses/>.
00020 
00021 */
00022 
00023 #ifdef HAVE_CONFIG_H
00024 #include <config.h>
00025 #endif
00026 
00027 #include <cfloat>
00028 #include <csetjmp>
00029 #include <ctime>
00030 
00031 #include "lo-ieee.h"
00032 
00033 #include "defun-dld.h"
00034 #include "error.h"
00035 #include "gripes.h"
00036 #include "oct-map.h"
00037 #include "oct-obj.h"
00038 #include "pager.h"
00039 
00040 #if defined (HAVE_GLPK)
00041 
00042 extern "C"
00043 {
00044 #if defined (HAVE_GLPK_GLPK_H)
00045 #include <glpk/glpk.h>
00046 #else
00047 #include <glpk.h>
00048 #endif
00049 
00050 #if 0
00051 #ifdef GLPK_PRE_4_14
00052 
00053 #ifndef _GLPLIB_H
00054 #include <glplib.h>
00055 #endif
00056 #ifndef lib_set_fault_hook
00057 #define lib_set_fault_hook lib_fault_hook
00058 #endif
00059 #ifndef lib_set_print_hook
00060 #define lib_set_print_hook lib_print_hook
00061 #endif
00062 
00063 #else
00064 
00065 void _glp_lib_print_hook (int (*func)(void *info, char *buf), void *info);
00066 void _glp_lib_fault_hook (int (*func)(void *info, char *buf), void *info);
00067 
00068 #endif
00069 #endif
00070 }
00071 
00072 #define NIntP 17
00073 #define NRealP 10
00074 
00075 int lpxIntParam[NIntP] = {
00076   0,
00077   1,
00078   0,
00079   1,
00080   0,
00081   -1,
00082   0,
00083   200,
00084   1,
00085   2,
00086   0,
00087   1,
00088   0,
00089   0,
00090   2,
00091   2,
00092   1
00093 };
00094 
00095 int IParam[NIntP] = {
00096   LPX_K_MSGLEV,
00097   LPX_K_SCALE,
00098   LPX_K_DUAL,
00099   LPX_K_PRICE,
00100   LPX_K_ROUND,
00101   LPX_K_ITLIM,
00102   LPX_K_ITCNT,
00103   LPX_K_OUTFRQ,
00104   LPX_K_MPSINFO,
00105   LPX_K_MPSOBJ,
00106   LPX_K_MPSORIG,
00107   LPX_K_MPSWIDE,
00108   LPX_K_MPSFREE,
00109   LPX_K_MPSSKIP,
00110   LPX_K_BRANCH,
00111   LPX_K_BTRACK,
00112   LPX_K_PRESOL
00113 };
00114 
00115 
00116 double lpxRealParam[NRealP] = {
00117   0.07,
00118   1e-7,
00119   1e-7,
00120   1e-9,
00121   -DBL_MAX,
00122   DBL_MAX,
00123   -1.0,
00124   0.0,
00125   1e-6,
00126   1e-7
00127 };
00128 
00129 int RParam[NRealP] = {
00130   LPX_K_RELAX,
00131   LPX_K_TOLBND,
00132   LPX_K_TOLDJ,
00133   LPX_K_TOLPIV,
00134   LPX_K_OBJLL,
00135   LPX_K_OBJUL,
00136   LPX_K_TMLIM,
00137   LPX_K_OUTDLY,
00138   LPX_K_TOLINT,
00139   LPX_K_TOLOBJ
00140 };
00141 
00142 static jmp_buf mark;  //-- Address for long jump to jump to
00143 
00144 #if 0
00145 int
00146 glpk_fault_hook (void * /* info */, char *msg)
00147 {
00148   error ("CRITICAL ERROR in GLPK: %s", msg);
00149   longjmp (mark, -1);
00150 }
00151 
00152 int
00153 glpk_print_hook (void * /* info */, char *msg)
00154 {
00155   message (0, "%s", msg);
00156   return 1;
00157 }
00158 #endif
00159 
00160 int
00161 glpk (int sense, int n, int m, double *c, int nz, int *rn, int *cn,
00162       double *a, double *b, char *ctype, int *freeLB, double *lb,
00163       int *freeUB, double *ub, int *vartype, int isMIP, int lpsolver,
00164       int save_pb, double *xmin, double *fmin, double *status,
00165       double *lambda, double *redcosts, double *time, double *mem)
00166 {
00167   int errnum;
00168   int typx = 0;
00169   int method;
00170 
00171   clock_t t_start = clock();
00172 
00173 #if 0
00174 #ifdef GLPK_PRE_4_14
00175   lib_set_fault_hook (0, glpk_fault_hook);
00176 #else
00177   _glp_lib_fault_hook (glpk_fault_hook, 0);
00178 #endif
00179 
00180   if (lpxIntParam[0] > 1)
00181 #ifdef GLPK_PRE_4_14
00182     lib_set_print_hook (0, glpk_print_hook);
00183 #else
00184     _glp_lib_print_hook (glpk_print_hook, 0);
00185 #endif
00186 #endif
00187 
00188   LPX *lp = lpx_create_prob ();
00189 
00190 
00191   //-- Set the sense of optimization
00192   if (sense == 1)
00193     lpx_set_obj_dir (lp, LPX_MIN);
00194   else
00195     lpx_set_obj_dir (lp, LPX_MAX);
00196 
00197   //-- If the problem has integer structural variables switch to MIP
00198   if (isMIP)
00199     lpx_set_class (lp, LPX_MIP);
00200 
00201   lpx_add_cols (lp, n);
00202   for (int i = 0; i < n; i++)
00203     {
00204       //-- Define type of the structural variables
00205       if (! freeLB[i] && ! freeUB[i])
00206         {
00207           if (lb[i] != ub[i])
00208             lpx_set_col_bnds (lp, i+1, LPX_DB, lb[i], ub[i]);
00209           else
00210             lpx_set_col_bnds (lp, i+1, LPX_FX, lb[i], ub[i]);
00211         }
00212       else
00213         {
00214           if (! freeLB[i] && freeUB[i])
00215             lpx_set_col_bnds (lp, i+1, LPX_LO, lb[i], ub[i]);
00216           else
00217             {
00218               if (freeLB[i] && ! freeUB[i])
00219                 lpx_set_col_bnds (lp, i+1, LPX_UP, lb[i], ub[i]);
00220               else
00221                 lpx_set_col_bnds (lp, i+1, LPX_FR, lb[i], ub[i]);
00222             }
00223         }
00224 
00225       // -- Set the objective coefficient of the corresponding
00226       // -- structural variable. No constant term is assumed.
00227       lpx_set_obj_coef(lp,i+1,c[i]);
00228 
00229       if (isMIP)
00230         lpx_set_col_kind (lp, i+1, vartype[i]);
00231     }
00232 
00233   lpx_add_rows (lp, m);
00234 
00235   for (int i = 0; i < m; i++)
00236     {
00237       /* If the i-th row has no lower bound (types F,U), the
00238          corrispondent parameter will be ignored.
00239          If the i-th row has no upper bound (types F,L), the corrispondent
00240          parameter will be ignored.
00241          If the i-th row is of S type, the i-th LB is used, but
00242          the i-th UB is ignored.
00243       */
00244 
00245       switch (ctype[i])
00246         {
00247         case 'F':
00248           typx = LPX_FR;
00249           break;
00250 
00251         case 'U':
00252           typx = LPX_UP;
00253           break;
00254 
00255         case 'L':
00256           typx = LPX_LO;
00257           break;
00258 
00259         case 'S':
00260           typx = LPX_FX;
00261           break;
00262 
00263         case 'D':
00264           typx = LPX_DB;
00265           break;
00266         }
00267 
00268       lpx_set_row_bnds (lp, i+1, typx, b[i], b[i]);
00269 
00270     }
00271 
00272   lpx_load_matrix (lp, nz, rn, cn, a);
00273 
00274   if (save_pb)
00275     {
00276       static char tmp[] = "outpb.lp";
00277       if (lpx_write_cpxlp (lp, tmp) != 0)
00278         {
00279           error ("__glpk__: unable to write problem");
00280           longjmp (mark, -1);
00281         }
00282     }
00283 
00284   //-- scale the problem data (if required)
00285   //-- if (scale && (!presol || method == 1)) lpx_scale_prob(lp);
00286   //-- LPX_K_SCALE=IParam[1]  LPX_K_PRESOL=IParam[16]
00287   if (lpxIntParam[1] && (! lpxIntParam[16] || lpsolver != 1))
00288     lpx_scale_prob (lp);
00289 
00290   //-- build advanced initial basis (if required)
00291   if (lpsolver == 1 && ! lpxIntParam[16])
00292     lpx_adv_basis (lp);
00293 
00294   for(int i = 0; i < NIntP; i++)
00295     lpx_set_int_parm (lp, IParam[i], lpxIntParam[i]);
00296 
00297   for (int i = 0; i < NRealP; i++)
00298     lpx_set_real_parm (lp, RParam[i], lpxRealParam[i]);
00299 
00300   if (lpsolver == 1)
00301     method = 'S';
00302   else
00303     method = 'T';
00304 
00305   switch (method)
00306     {
00307     case 'S':
00308       {
00309         if (isMIP)
00310           {
00311             method = 'I';
00312             errnum = lpx_simplex (lp);
00313             errnum = lpx_integer (lp);
00314           }
00315         else
00316           errnum = lpx_simplex(lp);
00317       }
00318      break;
00319 
00320     case 'T':
00321       errnum = lpx_interior(lp);
00322       break;
00323 
00324     default:
00325       break;
00326 #if 0
00327 #ifdef GLPK_PRE_4_14
00328       insist (method != method);
00329 #else
00330       static char tmp[] = "method != method";
00331       glpk_fault_hook (0, tmp);
00332 #endif
00333 #endif
00334     }
00335 
00336   /*  errnum assumes the following results:
00337       errnum = 0 <=> No errors
00338       errnum = 1 <=> Iteration limit exceeded.
00339       errnum = 2 <=> Numerical problems with basis matrix.
00340   */
00341   if (errnum == LPX_E_OK)
00342     {
00343       if (isMIP)
00344         {
00345           *status = lpx_mip_status (lp);
00346           *fmin = lpx_mip_obj_val (lp);
00347         }
00348       else
00349         {
00350           if (lpsolver == 1)
00351             {
00352               *status = lpx_get_status (lp);
00353               *fmin = lpx_get_obj_val (lp);
00354             }
00355           else
00356             {
00357               *status = lpx_ipt_status (lp);
00358               *fmin = lpx_ipt_obj_val (lp);
00359             }
00360         }
00361 
00362       if (isMIP)
00363         {
00364           for (int i = 0; i < n; i++)
00365             xmin[i] = lpx_mip_col_val (lp, i+1);
00366         }
00367       else
00368         {
00369           /* Primal values */
00370           for (int i = 0; i < n; i++)
00371             {
00372               if (lpsolver == 1)
00373                 xmin[i] = lpx_get_col_prim (lp, i+1);
00374               else
00375                 xmin[i] = lpx_ipt_col_prim (lp, i+1);
00376             }
00377 
00378           /* Dual values */
00379           for (int i = 0; i < m; i++)
00380             {
00381               if (lpsolver == 1)
00382                 lambda[i] = lpx_get_row_dual (lp, i+1);
00383               else
00384                 lambda[i] = lpx_ipt_row_dual (lp, i+1);
00385             }
00386 
00387           /* Reduced costs */
00388           for (int i = 0; i < lpx_get_num_cols (lp); i++)
00389             {
00390               if (lpsolver == 1)
00391                 redcosts[i] = lpx_get_col_dual (lp, i+1);
00392               else
00393                 redcosts[i] = lpx_ipt_col_dual (lp, i+1);
00394             }
00395         }
00396 
00397       *time = (clock () - t_start) / CLOCKS_PER_SEC;
00398 
00399 #ifdef GLPK_PRE_4_14
00400       *mem = (lib_env_ptr () -> mem_tpeak);
00401 #else
00402       *mem = 0;
00403 #endif
00404 
00405       lpx_delete_prob (lp);
00406       return 0;
00407     }
00408 
00409    lpx_delete_prob (lp);
00410 
00411    *status = errnum;
00412 
00413    return errnum;
00414 }
00415 
00416 #endif
00417 
00418 #define OCTAVE_GLPK_GET_REAL_PARAM(NAME, IDX) \
00419   do \
00420     { \
00421       octave_value tmp = PARAM.getfield (NAME); \
00422  \
00423       if (tmp.is_defined ()) \
00424         { \
00425           if (! tmp.is_empty ()) \
00426             { \
00427               lpxRealParam[IDX] = tmp.scalar_value (); \
00428  \
00429               if (error_state) \
00430                 { \
00431                   error ("glpk: invalid value in PARAM." NAME); \
00432                   return retval; \
00433                 } \
00434             } \
00435           else \
00436             { \
00437               error ("glpk: invalid value in PARAM." NAME); \
00438               return retval; \
00439             } \
00440         } \
00441     } \
00442   while (0)
00443 
00444 #define OCTAVE_GLPK_GET_INT_PARAM(NAME, VAL) \
00445   do \
00446     { \
00447       octave_value tmp = PARAM.getfield (NAME); \
00448  \
00449       if (tmp.is_defined ()) \
00450         { \
00451           if (! tmp.is_empty ()) \
00452             { \
00453               VAL = tmp.int_value (); \
00454  \
00455               if (error_state) \
00456                 { \
00457                   error ("glpk: invalid value in PARAM." NAME); \
00458                   return retval; \
00459                 } \
00460             } \
00461           else \
00462             { \
00463               error ("glpk: invalid value in PARAM." NAME); \
00464               return retval; \
00465             } \
00466         } \
00467     } \
00468   while (0)
00469 
00470 DEFUN_DLD (__glpk__, args, ,
00471   "-*- texinfo -*-\n\
00472 @deftypefn {Loadable Function} {[@var{values}] =} __glpk__ (@var{args})\n\
00473 Undocumented internal function.\n\
00474 @end deftypefn")
00475 {
00476   // The list of values to return.  See the declaration in oct-obj.h
00477   octave_value_list retval;
00478 
00479 #if defined (HAVE_GLPK)
00480 
00481   int nrhs = args.length ();
00482 
00483   if (nrhs != 9)
00484     {
00485       print_usage ();
00486       return retval;
00487     }
00488 
00489   //-- 1nd Input. A column array containing the objective function
00490   //--            coefficients.
00491   volatile int mrowsc = args(0).rows();
00492 
00493   Matrix C (args(0).matrix_value ());
00494 
00495   if (error_state)
00496     {
00497       error ("__glpk__: invalid value of C");
00498       return retval;
00499     }
00500 
00501   double *c = C.fortran_vec ();
00502   Array<int> rn;
00503   Array<int> cn;
00504   ColumnVector a;
00505   volatile int mrowsA;
00506   volatile int nz = 0;
00507 
00508   //-- 2nd Input. A matrix containing the constraints coefficients.
00509   // If matrix A is NOT a sparse matrix
00510   if (args(1).is_sparse_type ())
00511     {
00512       SparseMatrix A = args(1).sparse_matrix_value (); // get the sparse matrix
00513 
00514       if (error_state)
00515         {
00516           error ("__glpk__: invalid value of A");
00517           return retval;
00518         }
00519 
00520       mrowsA = A.rows ();
00521       octave_idx_type Anc = A.cols ();
00522       octave_idx_type Anz = A.nnz ();
00523       rn.resize (dim_vector (Anz+1, 1));
00524       cn.resize (dim_vector (Anz+1, 1));
00525       a.resize (Anz+1, 0.0);
00526 
00527       if (Anc != mrowsc)
00528         {
00529           error ("__glpk__: invalid value of A");
00530           return retval;
00531         }
00532 
00533       for (octave_idx_type j = 0; j < Anc; j++)
00534         for (octave_idx_type i = A.cidx(j); i < A.cidx(j+1); i++)
00535           {
00536             nz++;
00537             rn(nz) = A.ridx(i) + 1;
00538             cn(nz) = j + 1;
00539             a(nz) = A.data(i);
00540           }
00541     }
00542   else
00543     {
00544       Matrix A (args(1).matrix_value ()); // get the matrix
00545 
00546       if (error_state)
00547         {
00548           error ("__glpk__: invalid value of A");
00549           return retval;
00550         }
00551 
00552       mrowsA = A.rows ();
00553       rn.resize (dim_vector (mrowsA*mrowsc+1, 1));
00554       cn.resize (dim_vector (mrowsA*mrowsc+1, 1));
00555       a.resize (mrowsA*mrowsc+1, 0.0);
00556 
00557       for (int i = 0; i < mrowsA; i++)
00558         {
00559           for (int j = 0; j < mrowsc; j++)
00560             {
00561               if (A(i,j) != 0)
00562                 {
00563                   nz++;
00564                   rn(nz) = i + 1;
00565                   cn(nz) = j + 1;
00566                   a(nz) = A(i,j);
00567                 }
00568             }
00569         }
00570 
00571     }
00572 
00573   //-- 3rd Input. A column array containing the right-hand side value
00574   //               for each constraint in the constraint matrix.
00575   Matrix B (args(2).matrix_value ());
00576 
00577   if (error_state)
00578     {
00579       error ("__glpk__: invalid value of B");
00580       return retval;
00581     }
00582 
00583   double *b = B.fortran_vec ();
00584 
00585   //-- 4th Input. An array of length mrowsc containing the lower
00586   //--            bound on each of the variables.
00587   Matrix LB (args(3).matrix_value ());
00588 
00589   if (error_state || LB.length () < mrowsc)
00590     {
00591       error ("__glpk__: invalid value of LB");
00592       return retval;
00593     }
00594 
00595   double *lb = LB.fortran_vec ();
00596 
00597   //-- LB argument, default: Free
00598   Array<int> freeLB (dim_vector (mrowsc, 1));
00599   for (int i = 0; i < mrowsc; i++)
00600      {
00601        if (xisinf (lb[i]))
00602          {
00603            freeLB(i) = 1;
00604            lb[i] = -octave_Inf;
00605          }
00606        else
00607          freeLB(i) = 0;
00608      }
00609 
00610   //-- 5th Input. An array of at least length numcols containing the upper
00611   //--            bound on each of the variables.
00612   Matrix UB (args(4).matrix_value ());
00613 
00614   if (error_state || UB.length () < mrowsc)
00615     {
00616       error ("__glpk__: invalid value of UB");
00617       return retval;
00618     }
00619 
00620   double *ub = UB.fortran_vec ();
00621 
00622   Array<int> freeUB (dim_vector (mrowsc, 1));
00623   for (int i = 0; i < mrowsc; i++)
00624     {
00625       if (xisinf (ub[i]))
00626         {
00627           freeUB(i) = 1;
00628           ub[i] = octave_Inf;
00629         }
00630       else
00631         freeUB(i) = 0;
00632     }
00633 
00634   //-- 6th Input. A column array containing the sense of each constraint
00635   //--            in the constraint matrix.
00636   charMatrix CTYPE (args(5).char_matrix_value ());
00637 
00638   if (error_state)
00639     {
00640       error ("__glpk__: invalid value of CTYPE");
00641       return retval;
00642     }
00643 
00644   char *ctype = CTYPE.fortran_vec ();
00645 
00646   //-- 7th Input. A column array containing the types of the variables.
00647   charMatrix VTYPE (args(6).char_matrix_value ());
00648 
00649   if (error_state)
00650     {
00651       error ("__glpk__: invalid value of VARTYPE");
00652       return retval;
00653     }
00654 
00655   Array<int> vartype (dim_vector (mrowsc, 1));
00656   volatile int isMIP = 0;
00657   for (int i = 0; i < mrowsc ; i++)
00658     {
00659       if (VTYPE(i,0) == 'I')
00660         {
00661           isMIP = 1;
00662           vartype(i) = LPX_IV;
00663         }
00664       else
00665         vartype(i) = LPX_CV;
00666     }
00667 
00668   //-- 8th Input. Sense of optimization.
00669   volatile int sense;
00670   double SENSE = args(7).scalar_value ();
00671 
00672   if (error_state)
00673     {
00674       error ("__glpk__: invalid value of SENSE");
00675       return retval;
00676     }
00677 
00678   if (SENSE >= 0)
00679     sense = 1;
00680   else
00681     sense = -1;
00682 
00683   //-- 9th Input. A structure containing the control parameters.
00684   octave_scalar_map PARAM = args(8).scalar_map_value ();
00685 
00686   if (error_state)
00687     {
00688       error ("__glpk__: invalid value of PARAM");
00689       return retval;
00690     }
00691 
00692   //-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00693   //-- Integer parameters
00694   //-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00695 
00696   //-- Level of messages output by the solver
00697   OCTAVE_GLPK_GET_INT_PARAM ("msglev", lpxIntParam[0]);
00698   if (lpxIntParam[0] < 0 || lpxIntParam[0] > 3)
00699     {
00700       error ("__glpk__: PARAM.msglev must be 0 (no output [default]) or 1 (error messages only) or 2 (normal output) or 3 (full output)");
00701       return retval;
00702     }
00703 
00704   //-- scaling option
00705   OCTAVE_GLPK_GET_INT_PARAM ("scale", lpxIntParam[1]);
00706   if (lpxIntParam[1] < 0 || lpxIntParam[1] > 2)
00707     {
00708       error ("__glpk__: PARAM.scale must be 0 (no scaling) or 1 (equilibration scaling [default]) or 2 (geometric mean scaling)");
00709       return retval;
00710     }
00711 
00712   //-- Dual dimplex option
00713   OCTAVE_GLPK_GET_INT_PARAM ("dual", lpxIntParam[2]);
00714   if (lpxIntParam[2] < 0 || lpxIntParam[2] > 1)
00715     {
00716       error ("__glpk__: PARAM.dual must be 0 (do NOT use dual simplex [default]) or 1 (use dual simplex)");
00717       return retval;
00718     }
00719 
00720   //-- Pricing option
00721   OCTAVE_GLPK_GET_INT_PARAM ("price", lpxIntParam[3]);
00722   if (lpxIntParam[3] < 0 || lpxIntParam[3] > 1)
00723     {
00724       error ("__glpk__: PARAM.price must be 0 (textbook pricing) or 1 (steepest edge pricing [default])");
00725       return retval;
00726     }
00727 
00728   //-- Solution rounding option
00729   OCTAVE_GLPK_GET_INT_PARAM ("round", lpxIntParam[4]);
00730   if (lpxIntParam[4] < 0 || lpxIntParam[4] > 1)
00731     {
00732       error ("__glpk__: PARAM.round must be 0 (report all primal and dual values [default]) or 1 (replace tiny primal and dual values by exact zero)");
00733       return retval;
00734     }
00735 
00736   //-- Simplex iterations limit
00737   OCTAVE_GLPK_GET_INT_PARAM ("itlim", lpxIntParam[5]);
00738 
00739   //-- Simplex iterations count
00740   OCTAVE_GLPK_GET_INT_PARAM ("itcnt", lpxIntParam[6]);
00741 
00742   //-- Output frequency, in iterations
00743   OCTAVE_GLPK_GET_INT_PARAM ("outfrq", lpxIntParam[7]);
00744 
00745   //-- Branching heuristic option
00746   OCTAVE_GLPK_GET_INT_PARAM ("branch", lpxIntParam[14]);
00747   if (lpxIntParam[14] < 0 || lpxIntParam[14] > 2)
00748     {
00749       error ("__glpk__: PARAM.branch must be (MIP only) 0 (branch on first variable) or 1 (branch on last variable) or 2 (branch using a heuristic by Driebeck and Tomlin [default]");
00750       return retval;
00751     }
00752 
00753   //-- Backtracking heuristic option
00754   OCTAVE_GLPK_GET_INT_PARAM ("btrack", lpxIntParam[15]);
00755   if (lpxIntParam[15] < 0 || lpxIntParam[15] > 2)
00756     {
00757       error ("__glpk__: PARAM.btrack must be (MIP only) 0 (depth first search) or 1 (breadth first search) or 2 (backtrack using the best projection heuristic [default]");
00758       return retval;
00759     }
00760 
00761   //-- Presolver option
00762   OCTAVE_GLPK_GET_INT_PARAM ("presol", lpxIntParam[16]);
00763   if (lpxIntParam[16] < 0 || lpxIntParam[16] > 1)
00764     {
00765       error ("__glpk__: PARAM.presol must be 0 (do NOT use LP presolver) or 1 (use LP presolver [default])");
00766       return retval;
00767     }
00768 
00769   //-- LPsolver option
00770   volatile int lpsolver = 1;
00771   OCTAVE_GLPK_GET_INT_PARAM ("lpsolver", lpsolver);
00772   if (lpsolver < 1 || lpsolver > 2)
00773     {
00774       error ("__glpk__: PARAM.lpsolver must be 1 (simplex method) or 2 (interior point method)");
00775       return retval;
00776     }
00777 
00778   //-- Save option
00779   volatile int save_pb = 0;
00780   OCTAVE_GLPK_GET_INT_PARAM ("save", save_pb);
00781   save_pb = save_pb != 0;
00782 
00783   //-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00784   //-- Real parameters
00785   //-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00786 
00787   //-- Ratio test option
00788   OCTAVE_GLPK_GET_REAL_PARAM ("relax", 0);
00789 
00790   //-- Relative tolerance used to check if the current basic solution
00791   //-- is primal feasible
00792   OCTAVE_GLPK_GET_REAL_PARAM ("tolbnd", 1);
00793 
00794   //-- Absolute tolerance used to check if the current basic solution
00795   //-- is dual feasible
00796   OCTAVE_GLPK_GET_REAL_PARAM ("toldj", 2);
00797 
00798   //-- Relative tolerance used to choose eligible pivotal elements of
00799   //--  the simplex table in the ratio test
00800   OCTAVE_GLPK_GET_REAL_PARAM ("tolpiv", 3);
00801 
00802   OCTAVE_GLPK_GET_REAL_PARAM ("objll", 4);
00803 
00804   OCTAVE_GLPK_GET_REAL_PARAM ("objul", 5);
00805 
00806   OCTAVE_GLPK_GET_REAL_PARAM ("tmlim", 6);
00807 
00808   OCTAVE_GLPK_GET_REAL_PARAM ("outdly", 7);
00809 
00810   OCTAVE_GLPK_GET_REAL_PARAM ("tolint", 8);
00811 
00812   OCTAVE_GLPK_GET_REAL_PARAM ("tolobj", 9);
00813 
00814   //-- Assign pointers to the output parameters
00815   ColumnVector xmin (mrowsc, octave_NA);
00816   double fmin = octave_NA;
00817   double status;
00818   ColumnVector lambda (mrowsA, octave_NA);
00819   ColumnVector redcosts (mrowsc, octave_NA);
00820   double time;
00821   double mem;
00822 
00823   int jmpret = setjmp (mark);
00824 
00825   if (jmpret == 0)
00826     glpk (sense, mrowsc, mrowsA, c, nz, rn.fortran_vec (),
00827           cn.fortran_vec (), a.fortran_vec (), b, ctype,
00828           freeLB.fortran_vec (), lb, freeUB.fortran_vec (), ub,
00829           vartype.fortran_vec (), isMIP, lpsolver, save_pb,
00830           xmin.fortran_vec (), &fmin, &status, lambda.fortran_vec (),
00831           redcosts.fortran_vec (), &time, &mem);
00832 
00833   octave_scalar_map extra;
00834 
00835   if (! isMIP)
00836     {
00837       extra.assign ("lambda", lambda);
00838       extra.assign ("redcosts", redcosts);
00839     }
00840 
00841   extra.assign ("time", time);
00842   extra.assign ("mem", mem);
00843 
00844   retval(3) = extra;
00845   retval(2) = status;
00846   retval(1) = fmin;
00847   retval(0) = xmin;
00848 
00849 #else
00850 
00851   gripe_not_supported ("glpk");
00852 
00853 #endif
00854 
00855   return retval;
00856 }
00857 
00858 /*
00859 
00860 ## No test needed for internal helper function.
00861 %!assert (1)
00862 
00863 */
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines