Mercurial > octave
annotate src/DLD-FUNCTIONS/__glpk__.cc @ 10154:40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Wed, 20 Jan 2010 17:33:41 -0500 |
parents | 0631d397fbe0 |
children | 12884915a8e4 |
rev | line source |
---|---|
5234 | 1 /* |
2 | |
8920 | 3 Copyright (C) 2005, 2006, 2007, 2008 Nicolo' Giorgetti |
5234 | 4 |
5 This file is part of Octave. | |
6 | |
7 Octave is free software; you can redistribute it and/or modify it | |
8 under the terms of the GNU General Public License as published by the | |
7016 | 9 Free Software Foundation; either version 3 of the License, or (at your |
10 option) any later version. | |
5234 | 11 |
12 Octave is distributed in the hope that it will be useful, but WITHOUT | |
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 for more details. | |
16 | |
17 You should have received a copy of the GNU General Public License | |
7016 | 18 along with Octave; see the file COPYING. If not, see |
19 <http://www.gnu.org/licenses/>. | |
5234 | 20 |
21 */ | |
22 | |
23 #ifdef HAVE_CONFIG_H | |
24 #include <config.h> | |
25 #endif | |
5232 | 26 |
27 #include <cfloat> | |
28 #include <csetjmp> | |
29 #include <ctime> | |
30 | |
9003
0631d397fbe0
replace lo_ieee_isnan by xisnan, add missing includes
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
31 #include "lo-ieee.h" |
0631d397fbe0
replace lo_ieee_isnan by xisnan, add missing includes
Jaroslav Hajek <highegg@gmail.com>
parents:
8920
diff
changeset
|
32 |
5234 | 33 #include "defun-dld.h" |
34 #include "error.h" | |
5235 | 35 #include "gripes.h" |
36 #include "oct-map.h" | |
5234 | 37 #include "oct-obj.h" |
5235 | 38 #include "pager.h" |
39 | |
40 #if defined (HAVE_GLPK) | |
5232 | 41 |
6333 | 42 extern "C" |
43 { | |
6804 | 44 #if defined (HAVE_GLPK_GLPK_H) |
45 #include <glpk/glpk.h> | |
46 #else | |
5234 | 47 #include <glpk.h> |
6804 | 48 #endif |
6333 | 49 |
8275 | 50 #if 0 |
6381 | 51 #ifdef GLPK_PRE_4_14 |
6333 | 52 |
6287 | 53 #ifndef _GLPLIB_H |
54 #include <glplib.h> | |
55 #endif | |
56 #ifndef lib_set_fault_hook | |
57 #define lib_set_fault_hook lib_fault_hook | |
58 #endif | |
59 #ifndef lib_set_print_hook | |
60 #define lib_set_print_hook lib_print_hook | |
61 #endif | |
5232 | 62 |
6333 | 63 #else |
64 | |
65 void _glp_lib_print_hook (int (*func)(void *info, char *buf), void *info); | |
66 void _glp_lib_fault_hook (int (*func)(void *info, char *buf), void *info); | |
67 | |
68 #endif | |
8275 | 69 #endif |
6472 | 70 } |
6333 | 71 |
5232 | 72 #define NIntP 17 |
73 #define NRealP 10 | |
74 | |
5234 | 75 int lpxIntParam[NIntP] = { |
5240 | 76 0, |
5234 | 77 1, |
78 0, | |
79 1, | |
80 0, | |
81 -1, | |
82 0, | |
83 200, | |
84 1, | |
85 2, | |
86 0, | |
87 1, | |
88 0, | |
89 0, | |
90 2, | |
91 2, | |
92 1 | |
5232 | 93 }; |
94 | |
5234 | 95 int IParam[NIntP] = { |
96 LPX_K_MSGLEV, | |
97 LPX_K_SCALE, | |
98 LPX_K_DUAL, | |
99 LPX_K_PRICE, | |
100 LPX_K_ROUND, | |
101 LPX_K_ITLIM, | |
102 LPX_K_ITCNT, | |
103 LPX_K_OUTFRQ, | |
104 LPX_K_MPSINFO, | |
105 LPX_K_MPSOBJ, | |
106 LPX_K_MPSORIG, | |
107 LPX_K_MPSWIDE, | |
108 LPX_K_MPSFREE, | |
109 LPX_K_MPSSKIP, | |
110 LPX_K_BRANCH, | |
111 LPX_K_BTRACK, | |
112 LPX_K_PRESOL | |
5232 | 113 }; |
114 | |
115 | |
5234 | 116 double lpxRealParam[NRealP] = { |
117 0.07, | |
118 1e-7, | |
119 1e-7, | |
120 1e-9, | |
121 -DBL_MAX, | |
122 DBL_MAX, | |
123 -1.0, | |
124 0.0, | |
125 1e-6, | |
126 1e-7 | |
5232 | 127 }; |
128 | |
5234 | 129 int RParam[NRealP] = { |
130 LPX_K_RELAX, | |
131 LPX_K_TOLBND, | |
132 LPX_K_TOLDJ, | |
133 LPX_K_TOLPIV, | |
134 LPX_K_OBJLL, | |
135 LPX_K_OBJUL, | |
136 LPX_K_TMLIM, | |
137 LPX_K_OUTDLY, | |
138 LPX_K_TOLINT, | |
139 LPX_K_TOLOBJ | |
5232 | 140 }; |
141 | |
5241 | 142 static jmp_buf mark; //-- Address for long jump to jump to |
5232 | 143 |
8275 | 144 #if 0 |
5234 | 145 int |
5235 | 146 glpk_fault_hook (void * /* info */, char *msg) |
5234 | 147 { |
5240 | 148 error ("CRITICAL ERROR in GLPK: %s", msg); |
5234 | 149 longjmp (mark, -1); |
5232 | 150 } |
151 | |
5234 | 152 int |
5235 | 153 glpk_print_hook (void * /* info */, char *msg) |
5232 | 154 { |
5241 | 155 message (0, "%s", msg); |
5234 | 156 return 1; |
5232 | 157 } |
8275 | 158 #endif |
5232 | 159 |
5234 | 160 int |
161 glpk (int sense, int n, int m, double *c, int nz, int *rn, int *cn, | |
162 double *a, double *b, char *ctype, int *freeLB, double *lb, | |
163 int *freeUB, double *ub, int *vartype, int isMIP, int lpsolver, | |
164 int save_pb, double *xmin, double *fmin, double *status, | |
165 double *lambda, double *redcosts, double *time, double *mem) | |
5232 | 166 { |
5240 | 167 int errnum; |
5234 | 168 int typx = 0; |
169 int method; | |
170 | |
171 clock_t t_start = clock(); | |
172 | |
8275 | 173 #if 0 |
6381 | 174 #ifdef GLPK_PRE_4_14 |
6333 | 175 lib_set_fault_hook (0, glpk_fault_hook); |
176 #else | |
177 _glp_lib_fault_hook (glpk_fault_hook, 0); | |
178 #endif | |
5232 | 179 |
5234 | 180 if (lpxIntParam[0] > 1) |
6381 | 181 #ifdef GLPK_PRE_4_14 |
6333 | 182 lib_set_print_hook (0, glpk_print_hook); |
183 #else | |
184 _glp_lib_print_hook (glpk_print_hook, 0); | |
185 #endif | |
8275 | 186 #endif |
5234 | 187 |
188 LPX *lp = lpx_create_prob (); | |
189 | |
5232 | 190 |
5234 | 191 //-- Set the sense of optimization |
192 if (sense == 1) | |
193 lpx_set_obj_dir (lp, LPX_MIN); | |
194 else | |
195 lpx_set_obj_dir (lp, LPX_MAX); | |
196 | |
197 //-- If the problem has integer structural variables switch to MIP | |
198 if (isMIP) | |
199 lpx_set_class (lp, LPX_MIP); | |
5232 | 200 |
5234 | 201 lpx_add_cols (lp, n); |
202 for (int i = 0; i < n; i++) | |
203 { | |
5232 | 204 //-- Define type of the structural variables |
5234 | 205 if (! freeLB[i] && ! freeUB[i]) |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
206 { |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
207 if (lb[i] != ub[i]) |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
208 lpx_set_col_bnds (lp, i+1, LPX_DB, lb[i], ub[i]); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
209 else |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
210 lpx_set_col_bnds (lp, i+1, LPX_FX, lb[i], ub[i]); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
211 } |
5234 | 212 else |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
213 { |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
214 if (! freeLB[i] && freeUB[i]) |
5234 | 215 lpx_set_col_bnds (lp, i+1, LPX_LO, lb[i], ub[i]); |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
216 else |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
217 { |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
218 if (freeLB[i] && ! freeUB[i]) |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
219 lpx_set_col_bnds (lp, i+1, LPX_UP, lb[i], ub[i]); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
220 else |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
221 lpx_set_col_bnds (lp, i+1, LPX_FR, lb[i], ub[i]); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
222 } |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
223 } |
5234 | 224 |
225 // -- Set the objective coefficient of the corresponding | |
5232 | 226 // -- structural variable. No constant term is assumed. |
5234 | 227 lpx_set_obj_coef(lp,i+1,c[i]); |
5232 | 228 |
5234 | 229 if (isMIP) |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
230 lpx_set_col_kind (lp, i+1, vartype[i]); |
5234 | 231 } |
232 | |
233 lpx_add_rows (lp, m); | |
234 | |
235 for (int i = 0; i < m; i++) | |
236 { | |
5232 | 237 /* If the i-th row has no lower bound (types F,U), the |
238 corrispondent parameter will be ignored. | |
239 If the i-th row has no upper bound (types F,L), the corrispondent | |
240 parameter will be ignored. | |
241 If the i-th row is of S type, the i-th LB is used, but | |
242 the i-th UB is ignored. | |
243 */ | |
5234 | 244 |
245 switch (ctype[i]) | |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
246 { |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
247 case 'F': |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
248 typx = LPX_FR; |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
249 break; |
5234 | 250 |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
251 case 'U': |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
252 typx = LPX_UP; |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
253 break; |
5234 | 254 |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
255 case 'L': |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
256 typx = LPX_LO; |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
257 break; |
5232 | 258 |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
259 case 'S': |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
260 typx = LPX_FX; |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
261 break; |
5232 | 262 |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
263 case 'D': |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
264 typx = LPX_DB; |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
265 break; |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
266 } |
5234 | 267 |
268 lpx_set_row_bnds (lp, i+1, typx, b[i], b[i]); | |
269 | |
270 } | |
271 | |
272 lpx_load_matrix (lp, nz, rn, cn, a); | |
5232 | 273 |
5234 | 274 if (save_pb) |
275 { | |
6484 | 276 static char tmp[] = "outpb.lp"; |
277 if (lpx_write_cpxlp (lp, tmp) != 0) | |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
278 { |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
279 error ("__glpk__: unable to write problem"); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
280 longjmp (mark, -1); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
281 } |
5234 | 282 } |
283 | |
284 //-- scale the problem data (if required) | |
285 //-- if (scale && (!presol || method == 1)) lpx_scale_prob(lp); | |
286 //-- LPX_K_SCALE=IParam[1] LPX_K_PRESOL=IParam[16] | |
287 if (lpxIntParam[1] && (! lpxIntParam[16] || lpsolver != 1)) | |
288 lpx_scale_prob (lp); | |
289 | |
290 //-- build advanced initial basis (if required) | |
291 if (lpsolver == 1 && ! lpxIntParam[16]) | |
292 lpx_adv_basis (lp); | |
293 | |
294 for(int i = 0; i < NIntP; i++) | |
295 lpx_set_int_parm (lp, IParam[i], lpxIntParam[i]); | |
5232 | 296 |
5234 | 297 for (int i = 0; i < NRealP; i++) |
298 lpx_set_real_parm (lp, RParam[i], lpxRealParam[i]); | |
299 | |
300 if (lpsolver == 1) | |
301 method = 'S'; | |
302 else | |
303 method = 'T'; | |
5232 | 304 |
5234 | 305 switch (method) |
306 { | |
307 case 'S': | |
308 { | |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
309 if (isMIP) |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
310 { |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
311 method = 'I'; |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
312 errnum = lpx_simplex (lp); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
313 errnum = lpx_integer (lp); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
314 } |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
315 else |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
316 errnum = lpx_simplex(lp); |
5234 | 317 } |
5232 | 318 break; |
5234 | 319 |
320 case 'T': | |
5240 | 321 errnum = lpx_interior(lp); |
5234 | 322 break; |
323 | |
324 default: | |
8275 | 325 break; |
326 #if 0 | |
6381 | 327 #ifdef GLPK_PRE_4_14 |
5234 | 328 insist (method != method); |
6333 | 329 #else |
6484 | 330 static char tmp[] = "method != method"; |
331 glpk_fault_hook (0, tmp); | |
6333 | 332 #endif |
8275 | 333 #endif |
5234 | 334 } |
335 | |
5240 | 336 /* errnum assumes the following results: |
337 errnum = 0 <=> No errors | |
338 errnum = 1 <=> Iteration limit exceeded. | |
339 errnum = 2 <=> Numerical problems with basis matrix. | |
5234 | 340 */ |
5240 | 341 if (errnum == LPX_E_OK) |
5234 | 342 { |
343 if (isMIP) | |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
344 { |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
345 *status = lpx_mip_status (lp); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
346 *fmin = lpx_mip_obj_val (lp); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
347 } |
5234 | 348 else |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
349 { |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
350 if (lpsolver == 1) |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
351 { |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
352 *status = lpx_get_status (lp); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
353 *fmin = lpx_get_obj_val (lp); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
354 } |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
355 else |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
356 { |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
357 *status = lpx_ipt_status (lp); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
358 *fmin = lpx_ipt_obj_val (lp); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
359 } |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
360 } |
5232 | 361 |
5234 | 362 if (isMIP) |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
363 { |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
364 for (int i = 0; i < n; i++) |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
365 xmin[i] = lpx_mip_col_val (lp, i+1); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
366 } |
5234 | 367 else |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
368 { |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
369 /* Primal values */ |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
370 for (int i = 0; i < n; i++) |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
371 { |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
372 if (lpsolver == 1) |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
373 xmin[i] = lpx_get_col_prim (lp, i+1); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
374 else |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
375 xmin[i] = lpx_ipt_col_prim (lp, i+1); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
376 } |
5232 | 377 |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
378 /* Dual values */ |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
379 for (int i = 0; i < m; i++) |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
380 { |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
381 if (lpsolver == 1) |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
382 lambda[i] = lpx_get_row_dual (lp, i+1); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
383 else |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
384 lambda[i] = lpx_ipt_row_dual (lp, i+1); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
385 } |
5234 | 386 |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
387 /* Reduced costs */ |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
388 for (int i = 0; i < lpx_get_num_cols (lp); i++) |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
389 { |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
390 if (lpsolver == 1) |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
391 redcosts[i] = lpx_get_col_dual (lp, i+1); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
392 else |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
393 redcosts[i] = lpx_ipt_col_dual (lp, i+1); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
394 } |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
395 } |
5234 | 396 |
5241 | 397 *time = (clock () - t_start) / CLOCKS_PER_SEC; |
6333 | 398 |
6381 | 399 #ifdef GLPK_PRE_4_14 |
5241 | 400 *mem = (lib_env_ptr () -> mem_tpeak); |
6333 | 401 #else |
402 *mem = 0; | |
403 #endif | |
5234 | 404 |
405 lpx_delete_prob (lp); | |
406 return 0; | |
407 } | |
408 | |
409 lpx_delete_prob (lp); | |
410 | |
5241 | 411 *status = errnum; |
5234 | 412 |
5240 | 413 return errnum; |
5232 | 414 } |
415 | |
5235 | 416 #endif |
417 | |
5240 | 418 #define OCTAVE_GLPK_GET_REAL_PARAM(NAME, IDX) \ |
419 do \ | |
420 { \ | |
421 if (PARAM.contains (NAME)) \ | |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
422 { \ |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
423 Cell tmp = PARAM.contents (NAME); \ |
5240 | 424 \ |
425 if (! tmp.is_empty ()) \ | |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
426 { \ |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
427 lpxRealParam[IDX] = tmp(0).scalar_value (); \ |
5240 | 428 \ |
429 if (error_state) \ | |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
430 { \ |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
431 error ("glpk: invalid value in param." NAME); \ |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
432 return retval; \ |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
433 } \ |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
434 } \ |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
435 else \ |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
436 { \ |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
437 error ("glpk: invalid value in param." NAME); \ |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
438 return retval; \ |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
439 } \ |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
440 } \ |
5240 | 441 } \ |
442 while (0) | |
443 | |
444 #define OCTAVE_GLPK_GET_INT_PARAM(NAME, VAL) \ | |
445 do \ | |
446 { \ | |
447 if (PARAM.contains (NAME)) \ | |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
448 { \ |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
449 Cell tmp = PARAM.contents (NAME); \ |
5240 | 450 \ |
451 if (! tmp.is_empty ()) \ | |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
452 { \ |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
453 VAL = tmp(0).int_value (); \ |
5240 | 454 \ |
455 if (error_state) \ | |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
456 { \ |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
457 error ("glpk: invalid value in param." NAME); \ |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
458 return retval; \ |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
459 } \ |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
460 } \ |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
461 else \ |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
462 { \ |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
463 error ("glpk: invalid value in param." NAME); \ |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
464 return retval; \ |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
465 } \ |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
466 } \ |
5240 | 467 } \ |
468 while (0) | |
469 | |
5235 | 470 DEFUN_DLD (__glpk__, args, , |
5245 | 471 "-*- texinfo -*-\n\ |
472 @deftypefn {Loadable Function} {[@var{values}] =} __glpk__ (@var{args})\n\ | |
6945 | 473 Undocumented internal function.\n\ |
5245 | 474 @end deftypefn") |
5232 | 475 { |
5234 | 476 // The list of values to return. See the declaration in oct-obj.h |
477 octave_value_list retval; | |
5232 | 478 |
5235 | 479 #if defined (HAVE_GLPK) |
480 | |
5234 | 481 int nrhs = args.length (); |
482 | |
5240 | 483 if (nrhs != 9) |
5234 | 484 { |
5823 | 485 print_usage (); |
5232 | 486 return retval; |
5234 | 487 } |
488 | |
5237 | 489 //-- 1nd Input. A column array containing the objective function |
490 //-- coefficients. | |
5880 | 491 volatile int mrowsc = args(0).rows(); |
5234 | 492 |
5237 | 493 Matrix C (args(0).matrix_value ()); |
5240 | 494 |
495 if (error_state) | |
496 { | |
497 error ("__glpk__: invalid value of C"); | |
498 return retval; | |
499 } | |
500 | |
5234 | 501 double *c = C.fortran_vec (); |
5455 | 502 Array<int> rn; |
503 Array<int> cn; | |
504 ColumnVector a; | |
5515 | 505 volatile int mrowsA; |
5455 | 506 volatile int nz = 0; |
5232 | 507 |
5237 | 508 //-- 2nd Input. A matrix containing the constraints coefficients. |
5234 | 509 // If matrix A is NOT a sparse matrix |
5631 | 510 if (args(1).is_sparse_type ()) |
5455 | 511 { |
5603 | 512 SparseMatrix A = args(1).sparse_matrix_value (); // get the sparse matrix |
5455 | 513 |
514 if (error_state) | |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
515 { |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
516 error ("__glpk__: invalid value of A"); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
517 return retval; |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
518 } |
5234 | 519 |
5455 | 520 mrowsA = A.rows (); |
521 octave_idx_type Anc = A.cols (); | |
5604 | 522 octave_idx_type Anz = A.nzmax (); |
5455 | 523 rn.resize (Anz+1); |
524 cn.resize (Anz+1); | |
525 a.resize (Anz+1, 0.0); | |
526 | |
527 if (Anc != mrowsc) | |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
528 { |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
529 error ("__glpk__: invalid value of A"); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
530 return retval; |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
531 } |
5455 | 532 |
533 for (octave_idx_type j = 0; j < Anc; j++) | |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
534 for (octave_idx_type i = A.cidx(j); i < A.cidx(j+1); i++) |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
535 { |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
536 nz++; |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
537 rn(nz) = A.ridx(i) + 1; |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
538 cn(nz) = j + 1; |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
539 a(nz) = A.data(i); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
540 } |
5455 | 541 } |
5631 | 542 else |
543 { | |
544 Matrix A (args(1).matrix_value ()); // get the matrix | |
545 | |
546 if (error_state) | |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
547 { |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
548 error ("__glpk__: invalid value of A"); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
549 return retval; |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
550 } |
5631 | 551 |
552 mrowsA = A.rows (); | |
553 rn.resize (mrowsA*mrowsc+1); | |
554 cn.resize (mrowsA*mrowsc+1); | |
555 a.resize (mrowsA*mrowsc+1, 0.0); | |
556 | |
557 for (int i = 0; i < mrowsA; i++) | |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
558 { |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
559 for (int j = 0; j < mrowsc; j++) |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
560 { |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
561 if (A(i,j) != 0) |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
562 { |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
563 nz++; |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
564 rn(nz) = i + 1; |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
565 cn(nz) = j + 1; |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
566 a(nz) = A(i,j); |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
567 } |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
568 } |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
569 } |
5631 | 570 |
571 } | |
5232 | 572 |
5237 | 573 //-- 3rd Input. A column array containing the right-hand side value |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
574 // for each constraint in the constraint matrix. |
5237 | 575 Matrix B (args(2).matrix_value ()); |
5240 | 576 |
577 if (error_state) | |
578 { | |
579 error ("__glpk__: invalid value of b"); | |
580 return retval; | |
581 } | |
582 | |
5234 | 583 double *b = B.fortran_vec (); |
584 | |
5237 | 585 //-- 4th Input. An array of length mrowsc containing the lower |
5234 | 586 //-- bound on each of the variables. |
5237 | 587 Matrix LB (args(3).matrix_value ()); |
5240 | 588 |
8036
854683691d7a
fix invalid memory read in glpk
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
589 if (error_state || LB.length () < mrowsc) |
5240 | 590 { |
591 error ("__glpk__: invalid value of lb"); | |
592 return retval; | |
593 } | |
594 | |
5234 | 595 double *lb = LB.fortran_vec (); |
596 | |
597 //-- LB argument, default: Free | |
598 Array<int> freeLB (mrowsc); | |
599 for (int i = 0; i < mrowsc; i++) | |
600 { | |
5455 | 601 if (xisinf (lb[i])) |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
602 { |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
603 freeLB(i) = 1; |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
604 lb[i] = -octave_Inf; |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
605 } |
5234 | 606 else |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
607 freeLB(i) = 0; |
5234 | 608 } |
609 | |
5237 | 610 //-- 5th Input. An array of at least length numcols containing the upper |
5234 | 611 //-- bound on each of the variables. |
5237 | 612 Matrix UB (args(4).matrix_value ()); |
5234 | 613 |
8036
854683691d7a
fix invalid memory read in glpk
Jaroslav Hajek <highegg@gmail.com>
parents:
7017
diff
changeset
|
614 if (error_state || UB.length () < mrowsc) |
5240 | 615 { |
616 error ("__glpk__: invalid value of ub"); | |
617 return retval; | |
618 } | |
619 | |
5234 | 620 double *ub = UB.fortran_vec (); |
5232 | 621 |
5234 | 622 Array<int> freeUB (mrowsc); |
623 for (int i = 0; i < mrowsc; i++) | |
624 { | |
5455 | 625 if (xisinf (ub[i])) |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
626 { |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
627 freeUB(i) = 1; |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
628 ub[i] = octave_Inf; |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
629 } |
5234 | 630 else |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
631 freeUB(i) = 0; |
5234 | 632 } |
633 | |
5237 | 634 //-- 6th Input. A column array containing the sense of each constraint |
635 //-- in the constraint matrix. | |
636 charMatrix CTYPE (args(5).char_matrix_value ()); | |
5240 | 637 |
638 if (error_state) | |
639 { | |
640 error ("__glpk__: invalid value of ctype"); | |
641 return retval; | |
642 } | |
643 | |
5237 | 644 char *ctype = CTYPE.fortran_vec (); |
645 | |
646 //-- 7th Input. A column array containing the types of the variables. | |
647 charMatrix VTYPE (args(6).char_matrix_value ()); | |
5232 | 648 |
5240 | 649 if (error_state) |
650 { | |
651 error ("__glpk__: invalid value of vtype"); | |
652 return retval; | |
653 } | |
654 | |
5234 | 655 Array<int> vartype (mrowsc); |
5235 | 656 volatile int isMIP = 0; |
5234 | 657 for (int i = 0; i < mrowsc ; i++) |
658 { | |
659 if (VTYPE(i,0) == 'I') | |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
660 { |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
661 isMIP = 1; |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
662 vartype(i) = LPX_IV; |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
663 } |
5234 | 664 else |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
665 vartype(i) = LPX_CV; |
5234 | 666 } |
667 | |
5237 | 668 //-- 8th Input. Sense of optimization. |
669 volatile int sense; | |
670 double SENSE = args(7).scalar_value (); | |
5240 | 671 |
672 if (error_state) | |
673 { | |
674 error ("__glpk__: invalid value of sense"); | |
675 return retval; | |
676 } | |
677 | |
5237 | 678 if (SENSE >= 0) |
679 sense = 1; | |
680 else | |
681 sense = -1; | |
682 | |
5234 | 683 //-- 9th Input. A structure containing the control parameters. |
684 Octave_map PARAM = args(8).map_value (); | |
685 | |
5240 | 686 if (error_state) |
687 { | |
688 error ("__glpk__: invalid value of param"); | |
689 return retval; | |
690 } | |
691 | |
5234 | 692 //-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
693 //-- Integer parameters | |
694 //-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | |
695 | |
696 //-- Level of messages output by the solver | |
5240 | 697 OCTAVE_GLPK_GET_INT_PARAM ("msglev", lpxIntParam[0]); |
698 if (lpxIntParam[0] < 0 || lpxIntParam[0] > 3) | |
5234 | 699 { |
5240 | 700 error ("__glpk__: param.msglev must be 0 (no output [default]) or 1 (error messages only) or 2 (normal output) or 3 (full output)"); |
701 return retval; | |
702 } | |
5232 | 703 |
5234 | 704 //-- scaling option |
5240 | 705 OCTAVE_GLPK_GET_INT_PARAM ("scale", lpxIntParam[1]); |
706 if (lpxIntParam[1] < 0 || lpxIntParam[1] > 2) | |
5234 | 707 { |
5240 | 708 error ("__glpk__: param.scale must be 0 (no scaling) or 1 (equilibration scaling [default]) or 2 (geometric mean scaling)"); |
709 return retval; | |
5234 | 710 } |
5232 | 711 |
5234 | 712 //-- Dual dimplex option |
5240 | 713 OCTAVE_GLPK_GET_INT_PARAM ("dual", lpxIntParam[2]); |
714 if (lpxIntParam[2] < 0 || lpxIntParam[2] > 1) | |
5234 | 715 { |
5240 | 716 error ("__glpk__: param.dual must be 0 (do NOT use dual simplex [default]) or 1 (use dual simplex)"); |
717 return retval; | |
5234 | 718 } |
5232 | 719 |
5234 | 720 //-- Pricing option |
5240 | 721 OCTAVE_GLPK_GET_INT_PARAM ("price", lpxIntParam[3]); |
722 if (lpxIntParam[3] < 0 || lpxIntParam[3] > 1) | |
5234 | 723 { |
5240 | 724 error ("__glpk__: param.price must be 0 (textbook pricing) or 1 (steepest edge pricing [default])"); |
725 return retval; | |
726 } | |
5232 | 727 |
5234 | 728 //-- Solution rounding option |
5240 | 729 OCTAVE_GLPK_GET_INT_PARAM ("round", lpxIntParam[4]); |
730 if (lpxIntParam[4] < 0 || lpxIntParam[4] > 1) | |
5234 | 731 { |
5240 | 732 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)"); |
733 return retval; | |
5234 | 734 } |
735 | |
736 //-- Simplex iterations limit | |
5240 | 737 OCTAVE_GLPK_GET_INT_PARAM ("itlim", lpxIntParam[5]); |
5232 | 738 |
5234 | 739 //-- Simplex iterations count |
5240 | 740 OCTAVE_GLPK_GET_INT_PARAM ("itcnt", lpxIntParam[6]); |
5234 | 741 |
742 //-- Output frequency, in iterations | |
5240 | 743 OCTAVE_GLPK_GET_INT_PARAM ("outfrq", lpxIntParam[7]); |
5234 | 744 |
745 //-- Branching heuristic option | |
5240 | 746 OCTAVE_GLPK_GET_INT_PARAM ("branch", lpxIntParam[14]); |
747 if (lpxIntParam[14] < 0 || lpxIntParam[14] > 2) | |
5234 | 748 { |
5240 | 749 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]"); |
750 return retval; | |
751 } | |
5232 | 752 |
5234 | 753 //-- Backtracking heuristic option |
5240 | 754 OCTAVE_GLPK_GET_INT_PARAM ("btrack", lpxIntParam[15]); |
755 if (lpxIntParam[15] < 0 || lpxIntParam[15] > 2) | |
5234 | 756 { |
5240 | 757 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]"); |
758 return retval; | |
759 } | |
5232 | 760 |
5234 | 761 //-- Presolver option |
5240 | 762 OCTAVE_GLPK_GET_INT_PARAM ("presol", lpxIntParam[16]); |
763 if (lpxIntParam[16] < 0 || lpxIntParam[16] > 1) | |
5234 | 764 { |
5240 | 765 error ("__glpk__: param.presol must be 0 (do NOT use LP presolver) or 1 (use LP presolver [default])"); |
766 return retval; | |
5234 | 767 } |
768 | |
5237 | 769 //-- LPsolver option |
770 volatile int lpsolver = 1; | |
5240 | 771 OCTAVE_GLPK_GET_INT_PARAM ("lpsolver", lpsolver); |
772 if (lpsolver < 1 || lpsolver > 2) | |
5237 | 773 { |
5240 | 774 error ("__glpk__: param.lpsolver must be 1 (simplex method) or 2 (interior point method)"); |
775 return retval; | |
5237 | 776 } |
777 | |
778 //-- Save option | |
779 volatile int save_pb = 0; | |
5240 | 780 OCTAVE_GLPK_GET_INT_PARAM ("save", save_pb); |
781 save_pb = save_pb != 0; | |
5237 | 782 |
5234 | 783 //-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
784 //-- Real parameters | |
785 //-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | |
786 | |
787 //-- Ratio test option | |
5240 | 788 OCTAVE_GLPK_GET_REAL_PARAM ("relax", 0); |
5232 | 789 |
5234 | 790 //-- Relative tolerance used to check if the current basic solution |
791 //-- is primal feasible | |
5240 | 792 OCTAVE_GLPK_GET_REAL_PARAM ("tolbnd", 1); |
5234 | 793 |
794 //-- Absolute tolerance used to check if the current basic solution | |
795 //-- is dual feasible | |
5240 | 796 OCTAVE_GLPK_GET_REAL_PARAM ("toldj", 2); |
5232 | 797 |
5234 | 798 //-- Relative tolerance used to choose eligible pivotal elements of |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
799 //-- the simplex table in the ratio test |
5240 | 800 OCTAVE_GLPK_GET_REAL_PARAM ("tolpiv", 3); |
5234 | 801 |
5240 | 802 OCTAVE_GLPK_GET_REAL_PARAM ("objll", 4); |
5234 | 803 |
5240 | 804 OCTAVE_GLPK_GET_REAL_PARAM ("objul", 5); |
5232 | 805 |
5240 | 806 OCTAVE_GLPK_GET_REAL_PARAM ("tmlim", 6); |
5234 | 807 |
5240 | 808 OCTAVE_GLPK_GET_REAL_PARAM ("outdly", 7); |
5234 | 809 |
5240 | 810 OCTAVE_GLPK_GET_REAL_PARAM ("tolint", 8); |
5234 | 811 |
5240 | 812 OCTAVE_GLPK_GET_REAL_PARAM ("tolobj", 9); |
5234 | 813 |
814 //-- Assign pointers to the output parameters | |
8068
e3e3d12364b0
make glpk return NA values for unfeasible problems
Jaroslav Hajek <highegg@gmail.com>
parents:
8036
diff
changeset
|
815 ColumnVector xmin (mrowsc, octave_NA); |
e3e3d12364b0
make glpk return NA values for unfeasible problems
Jaroslav Hajek <highegg@gmail.com>
parents:
8036
diff
changeset
|
816 ColumnVector fmin (1, octave_NA); |
5234 | 817 ColumnVector status (1); |
8068
e3e3d12364b0
make glpk return NA values for unfeasible problems
Jaroslav Hajek <highegg@gmail.com>
parents:
8036
diff
changeset
|
818 ColumnVector lambda (mrowsA, octave_NA); |
e3e3d12364b0
make glpk return NA values for unfeasible problems
Jaroslav Hajek <highegg@gmail.com>
parents:
8036
diff
changeset
|
819 ColumnVector redcosts (mrowsc, octave_NA); |
5234 | 820 ColumnVector time (1); |
821 ColumnVector mem (1); | |
5232 | 822 |
5234 | 823 int jmpret = setjmp (mark); |
5235 | 824 |
5234 | 825 if (jmpret == 0) |
5235 | 826 glpk (sense, mrowsc, mrowsA, c, nz, rn.fortran_vec (), |
10154
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
827 cn.fortran_vec (), a.fortran_vec (), b, ctype, |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
828 freeLB.fortran_vec (), lb, freeUB.fortran_vec (), |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
829 ub, vartype.fortran_vec (), isMIP, lpsolver, |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
830 save_pb, xmin.fortran_vec (), fmin.fortran_vec (), |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
831 status.fortran_vec (), lambda.fortran_vec (), |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
832 redcosts.fortran_vec (), time.fortran_vec (), |
40dfc0c99116
DLD-FUNCTIONS/*.cc: untabify
John W. Eaton <jwe@octave.org>
parents:
9003
diff
changeset
|
833 mem.fortran_vec ()); |
5232 | 834 |
5234 | 835 Octave_map extra; |
836 | |
5238 | 837 if (! isMIP) |
838 { | |
839 extra.assign ("lambda", octave_value (lambda)); | |
840 extra.assign ("redcosts", octave_value (redcosts)); | |
841 } | |
842 | |
5234 | 843 extra.assign ("time", octave_value (time)); |
844 extra.assign ("mem", octave_value (mem)); | |
5232 | 845 |
5234 | 846 retval(3) = extra; |
847 retval(2) = octave_value(status); | |
848 retval(1) = octave_value(fmin); | |
849 retval(0) = octave_value(xmin); | |
850 | |
5235 | 851 #else |
852 | |
853 gripe_not_supported ("glpk"); | |
854 | |
855 #endif | |
856 | |
5234 | 857 return retval; |
5232 | 858 } |