alpar@1
|
1 |
/* glpapi19.c (stand-alone LP/MIP solver) */
|
alpar@1
|
2 |
|
alpar@1
|
3 |
/***********************************************************************
|
alpar@1
|
4 |
* This code is part of GLPK (GNU Linear Programming Kit).
|
alpar@1
|
5 |
*
|
alpar@1
|
6 |
* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
|
alpar@1
|
7 |
* 2009, 2010 Andrew Makhorin, Department for Applied Informatics,
|
alpar@1
|
8 |
* Moscow Aviation Institute, Moscow, Russia. All rights reserved.
|
alpar@1
|
9 |
* E-mail: <mao@gnu.org>.
|
alpar@1
|
10 |
*
|
alpar@1
|
11 |
* GLPK is free software: you can redistribute it and/or modify it
|
alpar@1
|
12 |
* under the terms of the GNU General Public License as published by
|
alpar@1
|
13 |
* the Free Software Foundation, either version 3 of the License, or
|
alpar@1
|
14 |
* (at your option) any later version.
|
alpar@1
|
15 |
*
|
alpar@1
|
16 |
* GLPK is distributed in the hope that it will be useful, but WITHOUT
|
alpar@1
|
17 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
alpar@1
|
18 |
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
alpar@1
|
19 |
* License for more details.
|
alpar@1
|
20 |
*
|
alpar@1
|
21 |
* You should have received a copy of the GNU General Public License
|
alpar@1
|
22 |
* along with GLPK. If not, see <http://www.gnu.org/licenses/>.
|
alpar@1
|
23 |
***********************************************************************/
|
alpar@1
|
24 |
|
alpar@1
|
25 |
#include "glpapi.h"
|
alpar@1
|
26 |
#include "glpgmp.h"
|
alpar@1
|
27 |
|
alpar@1
|
28 |
struct csa
|
alpar@1
|
29 |
{ /* common storage area */
|
alpar@1
|
30 |
glp_prob *prob;
|
alpar@1
|
31 |
/* LP/MIP problem object */
|
alpar@1
|
32 |
glp_bfcp bfcp;
|
alpar@1
|
33 |
/* basis factorization control parameters */
|
alpar@1
|
34 |
glp_smcp smcp;
|
alpar@1
|
35 |
/* simplex method control parameters */
|
alpar@1
|
36 |
glp_iptcp iptcp;
|
alpar@1
|
37 |
/* interior-point method control parameters */
|
alpar@1
|
38 |
glp_iocp iocp;
|
alpar@1
|
39 |
/* integer optimizer control parameters */
|
alpar@1
|
40 |
glp_tran *tran;
|
alpar@1
|
41 |
/* model translator workspace */
|
alpar@1
|
42 |
glp_graph *graph;
|
alpar@1
|
43 |
/* network problem object */
|
alpar@1
|
44 |
int format;
|
alpar@1
|
45 |
/* problem file format: */
|
alpar@1
|
46 |
#define FMT_MPS_DECK 1 /* fixed MPS */
|
alpar@1
|
47 |
#define FMT_MPS_FILE 2 /* free MPS */
|
alpar@1
|
48 |
#define FMT_LP 3 /* CPLEX LP */
|
alpar@1
|
49 |
#define FMT_GLP 4 /* GLPK LP/MIP */
|
alpar@1
|
50 |
#define FMT_MATHPROG 5 /* MathProg */
|
alpar@1
|
51 |
#define FMT_MIN_COST 6 /* DIMACS min-cost flow */
|
alpar@1
|
52 |
#define FMT_MAX_FLOW 7 /* DIMACS maximum flow */
|
alpar@1
|
53 |
const char *in_file;
|
alpar@1
|
54 |
/* name of input problem file */
|
alpar@1
|
55 |
#define DATA_MAX 10
|
alpar@1
|
56 |
/* maximal number of input data files */
|
alpar@1
|
57 |
int ndf;
|
alpar@1
|
58 |
/* number of input data files specified */
|
alpar@1
|
59 |
const char *in_data[1+DATA_MAX];
|
alpar@1
|
60 |
/* name(s) of input data file(s) */
|
alpar@1
|
61 |
const char *out_dpy;
|
alpar@1
|
62 |
/* name of output file to send display output; NULL means the
|
alpar@1
|
63 |
display output is sent to the terminal */
|
alpar@1
|
64 |
int seed;
|
alpar@1
|
65 |
/* seed value to be passed to the MathProg translator; initially
|
alpar@1
|
66 |
set to 1; 0x80000000 means the value is omitted */
|
alpar@1
|
67 |
int solution;
|
alpar@1
|
68 |
/* solution type flag: */
|
alpar@1
|
69 |
#define SOL_BASIC 1 /* basic */
|
alpar@1
|
70 |
#define SOL_INTERIOR 2 /* interior-point */
|
alpar@1
|
71 |
#define SOL_INTEGER 3 /* mixed integer */
|
alpar@1
|
72 |
const char *in_res;
|
alpar@1
|
73 |
/* name of input solution file in raw format */
|
alpar@1
|
74 |
int dir;
|
alpar@1
|
75 |
/* optimization direction flag:
|
alpar@1
|
76 |
0 - not specified
|
alpar@1
|
77 |
GLP_MIN - minimization
|
alpar@1
|
78 |
GLP_MAX - maximization */
|
alpar@1
|
79 |
int scale;
|
alpar@1
|
80 |
/* automatic problem scaling flag */
|
alpar@1
|
81 |
const char *out_sol;
|
alpar@1
|
82 |
/* name of output solution file in printable format */
|
alpar@1
|
83 |
const char *out_res;
|
alpar@1
|
84 |
/* name of output solution file in raw format */
|
alpar@1
|
85 |
const char *out_ranges;
|
alpar@1
|
86 |
/* name of output file to write sensitivity analysis report */
|
alpar@1
|
87 |
int check;
|
alpar@1
|
88 |
/* input data checking flag; no solution is performed */
|
alpar@1
|
89 |
const char *new_name;
|
alpar@1
|
90 |
/* new name to be assigned to the problem */
|
alpar@1
|
91 |
const char *out_mps;
|
alpar@1
|
92 |
/* name of output problem file in fixed MPS format */
|
alpar@1
|
93 |
const char *out_freemps;
|
alpar@1
|
94 |
/* name of output problem file in free MPS format */
|
alpar@1
|
95 |
const char *out_cpxlp;
|
alpar@1
|
96 |
/* name of output problem file in CPLEX LP format */
|
alpar@1
|
97 |
const char *out_glp;
|
alpar@1
|
98 |
/* name of output problem file in GLPK format */
|
alpar@1
|
99 |
const char *out_pb;
|
alpar@1
|
100 |
/* name of output problem file in OPB format */
|
alpar@1
|
101 |
const char *out_npb;
|
alpar@1
|
102 |
/* name of output problem file in normalized OPB format */
|
alpar@1
|
103 |
const char *log_file;
|
alpar@1
|
104 |
/* name of output file to hardcopy terminal output */
|
alpar@1
|
105 |
int crash;
|
alpar@1
|
106 |
/* initial basis option: */
|
alpar@1
|
107 |
#define USE_STD_BASIS 1 /* use standard basis */
|
alpar@1
|
108 |
#define USE_ADV_BASIS 2 /* use advanced basis */
|
alpar@1
|
109 |
#define USE_CPX_BASIS 3 /* use Bixby's basis */
|
alpar@1
|
110 |
#define USE_INI_BASIS 4 /* use initial basis from ini_file */
|
alpar@1
|
111 |
const char *ini_file;
|
alpar@1
|
112 |
/* name of input file containing initial basis */
|
alpar@1
|
113 |
int exact;
|
alpar@1
|
114 |
/* flag to use glp_exact rather than glp_simplex */
|
alpar@1
|
115 |
int xcheck;
|
alpar@1
|
116 |
/* flag to check final basis with glp_exact */
|
alpar@1
|
117 |
int nomip;
|
alpar@1
|
118 |
/* flag to consider MIP as pure LP */
|
alpar@1
|
119 |
};
|
alpar@1
|
120 |
|
alpar@1
|
121 |
static void print_help(const char *my_name)
|
alpar@1
|
122 |
{ /* print help information */
|
alpar@1
|
123 |
xprintf("Usage: %s [options...] filename\n", my_name);
|
alpar@1
|
124 |
xprintf("\n");
|
alpar@1
|
125 |
xprintf("General options:\n");
|
alpar@1
|
126 |
xprintf(" --mps read LP/MIP problem in fixed MPS fo"
|
alpar@1
|
127 |
"rmat\n");
|
alpar@1
|
128 |
xprintf(" --freemps read LP/MIP problem in free MPS for"
|
alpar@1
|
129 |
"mat (default)\n");
|
alpar@1
|
130 |
xprintf(" --lp read LP/MIP problem in CPLEX LP for"
|
alpar@1
|
131 |
"mat\n");
|
alpar@1
|
132 |
xprintf(" --glp read LP/MIP problem in GLPK format "
|
alpar@1
|
133 |
"\n");
|
alpar@1
|
134 |
xprintf(" --math read LP/MIP model written in GNU Ma"
|
alpar@1
|
135 |
"thProg modeling\n");
|
alpar@1
|
136 |
xprintf(" language\n");
|
alpar@1
|
137 |
xprintf(" -m filename, --model filename\n");
|
alpar@1
|
138 |
xprintf(" read model section and optional dat"
|
alpar@1
|
139 |
"a section from\n");
|
alpar@1
|
140 |
xprintf(" filename (same as --math)\n");
|
alpar@1
|
141 |
xprintf(" -d filename, --data filename\n");
|
alpar@1
|
142 |
xprintf(" read data section from filename (fo"
|
alpar@1
|
143 |
"r --math only);\n");
|
alpar@1
|
144 |
xprintf(" if model file also has data section"
|
alpar@1
|
145 |
", it is ignored\n");
|
alpar@1
|
146 |
xprintf(" -y filename, --display filename\n");
|
alpar@1
|
147 |
xprintf(" send display output to filename (fo"
|
alpar@1
|
148 |
"r --math only);\n");
|
alpar@1
|
149 |
xprintf(" by default the output is sent to te"
|
alpar@1
|
150 |
"rminal\n");
|
alpar@1
|
151 |
xprintf(" --seed value initialize pseudo-random number gen"
|
alpar@1
|
152 |
"erator used in\n");
|
alpar@1
|
153 |
xprintf(" MathProg model with specified seed "
|
alpar@1
|
154 |
"(any integer);\n");
|
alpar@1
|
155 |
xprintf(" if seed value is ?, some random see"
|
alpar@1
|
156 |
"d will be used\n");
|
alpar@1
|
157 |
xprintf(" --mincost read min-cost flow problem in DIMAC"
|
alpar@1
|
158 |
"S format\n");
|
alpar@1
|
159 |
xprintf(" --maxflow read maximum flow problem in DIMACS"
|
alpar@1
|
160 |
" format\n");
|
alpar@1
|
161 |
xprintf(" --simplex use simplex method (default)\n");
|
alpar@1
|
162 |
xprintf(" --interior use interior point method (LP only)"
|
alpar@1
|
163 |
"\n");
|
alpar@1
|
164 |
xprintf(" -r filename, --read filename\n");
|
alpar@1
|
165 |
xprintf(" read solution from filename rather "
|
alpar@1
|
166 |
"to find it with\n");
|
alpar@1
|
167 |
xprintf(" the solver\n");
|
alpar@1
|
168 |
xprintf(" --min minimization\n");
|
alpar@1
|
169 |
xprintf(" --max maximization\n");
|
alpar@1
|
170 |
xprintf(" --scale scale problem (default)\n");
|
alpar@1
|
171 |
xprintf(" --noscale do not scale problem\n");
|
alpar@1
|
172 |
xprintf(" -o filename, --output filename\n");
|
alpar@1
|
173 |
xprintf(" write solution to filename in print"
|
alpar@1
|
174 |
"able format\n");
|
alpar@1
|
175 |
xprintf(" -w filename, --write filename\n");
|
alpar@1
|
176 |
xprintf(" write solution to filename in plain"
|
alpar@1
|
177 |
" text format\n");
|
alpar@1
|
178 |
xprintf(" --ranges filename\n");
|
alpar@1
|
179 |
xprintf(" write sensitivity analysis report t"
|
alpar@1
|
180 |
"o filename in\n");
|
alpar@1
|
181 |
xprintf(" printable format (simplex only)\n");
|
alpar@1
|
182 |
xprintf(" --tmlim nnn limit solution time to nnn seconds "
|
alpar@1
|
183 |
"\n");
|
alpar@1
|
184 |
xprintf(" --memlim nnn limit available memory to nnn megab"
|
alpar@1
|
185 |
"ytes\n");
|
alpar@1
|
186 |
xprintf(" --check do not solve problem, check input d"
|
alpar@1
|
187 |
"ata only\n");
|
alpar@1
|
188 |
xprintf(" --name probname change problem name to probname\n");
|
alpar@1
|
189 |
xprintf(" --wmps filename write problem to filename in fixed "
|
alpar@1
|
190 |
"MPS format\n");
|
alpar@1
|
191 |
xprintf(" --wfreemps filename\n");
|
alpar@1
|
192 |
xprintf(" write problem to filename in free M"
|
alpar@1
|
193 |
"PS format\n");
|
alpar@1
|
194 |
xprintf(" --wlp filename write problem to filename in CPLEX "
|
alpar@1
|
195 |
"LP format\n");
|
alpar@1
|
196 |
xprintf(" --wglp filename write problem to filename in GLPK f"
|
alpar@1
|
197 |
"ormat\n");
|
alpar@1
|
198 |
#if 0
|
alpar@1
|
199 |
xprintf(" --wpb filename write problem to filename in OPB fo"
|
alpar@1
|
200 |
"rmat\n");
|
alpar@1
|
201 |
xprintf(" --wnpb filename write problem to filename in normal"
|
alpar@1
|
202 |
"ized OPB format\n");
|
alpar@1
|
203 |
#endif
|
alpar@1
|
204 |
xprintf(" --log filename write copy of terminal output to fi"
|
alpar@1
|
205 |
"lename\n");
|
alpar@1
|
206 |
xprintf(" -h, --help display this help information and e"
|
alpar@1
|
207 |
"xit\n");
|
alpar@1
|
208 |
xprintf(" -v, --version display program version and exit\n")
|
alpar@1
|
209 |
;
|
alpar@1
|
210 |
xprintf("\n");
|
alpar@1
|
211 |
xprintf("LP basis factorization options:\n");
|
alpar@1
|
212 |
xprintf(" --luf LU + Forrest-Tomlin update\n");
|
alpar@1
|
213 |
xprintf(" (faster, less stable; default)\n");
|
alpar@1
|
214 |
xprintf(" --cbg LU + Schur complement + Bartels-Gol"
|
alpar@1
|
215 |
"ub update\n");
|
alpar@1
|
216 |
xprintf(" (slower, more stable)\n");
|
alpar@1
|
217 |
xprintf(" --cgr LU + Schur complement + Givens rota"
|
alpar@1
|
218 |
"tion update\n");
|
alpar@1
|
219 |
xprintf(" (slower, more stable)\n");
|
alpar@1
|
220 |
xprintf("\n");
|
alpar@1
|
221 |
xprintf("Options specific to simplex solver:\n");
|
alpar@1
|
222 |
xprintf(" --primal use primal simplex (default)\n");
|
alpar@1
|
223 |
xprintf(" --dual use dual simplex\n");
|
alpar@1
|
224 |
xprintf(" --std use standard initial basis of all s"
|
alpar@1
|
225 |
"lacks\n");
|
alpar@1
|
226 |
xprintf(" --adv use advanced initial basis (default"
|
alpar@1
|
227 |
")\n");
|
alpar@1
|
228 |
xprintf(" --bib use Bixby's initial basis\n");
|
alpar@1
|
229 |
xprintf(" --ini filename use as initial basis previously sav"
|
alpar@1
|
230 |
"ed with -w\n");
|
alpar@1
|
231 |
xprintf(" (disables LP presolver)\n");
|
alpar@1
|
232 |
xprintf(" --steep use steepest edge technique (defaul"
|
alpar@1
|
233 |
"t)\n");
|
alpar@1
|
234 |
xprintf(" --nosteep use standard \"textbook\" pricing\n"
|
alpar@1
|
235 |
);
|
alpar@1
|
236 |
xprintf(" --relax use Harris' two-pass ratio test (de"
|
alpar@1
|
237 |
"fault)\n");
|
alpar@1
|
238 |
xprintf(" --norelax use standard \"textbook\" ratio tes"
|
alpar@1
|
239 |
"t\n");
|
alpar@1
|
240 |
xprintf(" --presol use presolver (default; assumes --s"
|
alpar@1
|
241 |
"cale and --adv)\n");
|
alpar@1
|
242 |
xprintf(" --nopresol do not use presolver\n");
|
alpar@1
|
243 |
xprintf(" --exact use simplex method based on exact a"
|
alpar@1
|
244 |
"rithmetic\n");
|
alpar@1
|
245 |
xprintf(" --xcheck check final basis using exact arith"
|
alpar@1
|
246 |
"metic\n");
|
alpar@1
|
247 |
xprintf("\n");
|
alpar@1
|
248 |
xprintf("Options specific to interior-point solver:\n");
|
alpar@1
|
249 |
xprintf(" --nord use natural (original) ordering\n");
|
alpar@1
|
250 |
xprintf(" --qmd use quotient minimum degree orderin"
|
alpar@1
|
251 |
"g\n");
|
alpar@1
|
252 |
xprintf(" --amd use approximate minimum degree orde"
|
alpar@1
|
253 |
"ring (default)\n");
|
alpar@1
|
254 |
xprintf(" --symamd use approximate minimum degree orde"
|
alpar@1
|
255 |
"ring\n");
|
alpar@1
|
256 |
xprintf("\n");
|
alpar@1
|
257 |
xprintf("Options specific to MIP solver:\n");
|
alpar@1
|
258 |
xprintf(" --nomip consider all integer variables as c"
|
alpar@1
|
259 |
"ontinuous\n");
|
alpar@1
|
260 |
xprintf(" (allows solving MIP as pure LP)\n");
|
alpar@1
|
261 |
xprintf(" --first branch on first integer variable\n")
|
alpar@1
|
262 |
;
|
alpar@1
|
263 |
xprintf(" --last branch on last integer variable\n");
|
alpar@1
|
264 |
xprintf(" --mostf branch on most fractional variable "
|
alpar@1
|
265 |
"\n");
|
alpar@1
|
266 |
xprintf(" --drtom branch using heuristic by Driebeck "
|
alpar@1
|
267 |
"and Tomlin\n");
|
alpar@1
|
268 |
xprintf(" (default)\n");
|
alpar@1
|
269 |
xprintf(" --pcost branch using hybrid pseudocost heur"
|
alpar@1
|
270 |
"istic (may be\n");
|
alpar@1
|
271 |
xprintf(" useful for hard instances)\n");
|
alpar@1
|
272 |
xprintf(" --dfs backtrack using depth first search "
|
alpar@1
|
273 |
"\n");
|
alpar@1
|
274 |
xprintf(" --bfs backtrack using breadth first searc"
|
alpar@1
|
275 |
"h\n");
|
alpar@1
|
276 |
xprintf(" --bestp backtrack using the best projection"
|
alpar@1
|
277 |
" heuristic\n");
|
alpar@1
|
278 |
xprintf(" --bestb backtrack using node with best loca"
|
alpar@1
|
279 |
"l bound\n");
|
alpar@1
|
280 |
xprintf(" (default)\n");
|
alpar@1
|
281 |
xprintf(" --intopt use MIP presolver (default)\n");
|
alpar@1
|
282 |
xprintf(" --nointopt do not use MIP presolver\n");
|
alpar@1
|
283 |
xprintf(" --binarize replace general integer variables b"
|
alpar@1
|
284 |
"y binary ones\n");
|
alpar@1
|
285 |
xprintf(" (assumes --intopt)\n");
|
alpar@1
|
286 |
xprintf(" --fpump apply feasibility pump heuristic\n")
|
alpar@1
|
287 |
;
|
alpar@1
|
288 |
xprintf(" --gomory generate Gomory's mixed integer cut"
|
alpar@1
|
289 |
"s\n");
|
alpar@1
|
290 |
xprintf(" --mir generate MIR (mixed integer roundin"
|
alpar@1
|
291 |
"g) cuts\n");
|
alpar@1
|
292 |
xprintf(" --cover generate mixed cover cuts\n");
|
alpar@1
|
293 |
xprintf(" --clique generate clique cuts\n");
|
alpar@1
|
294 |
xprintf(" --cuts generate all cuts above\n");
|
alpar@1
|
295 |
xprintf(" --mipgap tol set relative mip gap tolerance to t"
|
alpar@1
|
296 |
"ol\n");
|
alpar@1
|
297 |
xprintf("\n");
|
alpar@1
|
298 |
xprintf("For description of the MPS and CPLEX LP formats see Refe"
|
alpar@1
|
299 |
"rence Manual.\n");
|
alpar@1
|
300 |
xprintf("For description of the modeling language see \"GLPK: Mod"
|
alpar@1
|
301 |
"eling Language\n");
|
alpar@1
|
302 |
xprintf("GNU MathProg\". Both documents are included in the GLPK "
|
alpar@1
|
303 |
"distribution.\n");
|
alpar@1
|
304 |
xprintf("\n");
|
alpar@1
|
305 |
xprintf("See GLPK web page at <http://www.gnu.org/software/glpk/g"
|
alpar@1
|
306 |
"lpk.html>.\n");
|
alpar@1
|
307 |
xprintf("\n");
|
alpar@1
|
308 |
xprintf("Please report bugs to <bug-glpk@gnu.org>.\n");
|
alpar@1
|
309 |
return;
|
alpar@1
|
310 |
}
|
alpar@1
|
311 |
|
alpar@1
|
312 |
static void print_version(int briefly)
|
alpar@1
|
313 |
{ /* print version information */
|
alpar@1
|
314 |
xprintf("GLPSOL: GLPK LP/MIP Solver, v%s\n", glp_version());
|
alpar@1
|
315 |
if (briefly) goto done;
|
alpar@1
|
316 |
xprintf("\n");
|
alpar@1
|
317 |
xprintf("Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, "
|
alpar@1
|
318 |
"2007, 2008,\n");
|
alpar@1
|
319 |
xprintf("2009, 2010 Andrew Makhorin, Department for Applied Infor"
|
alpar@1
|
320 |
"matics, Moscow\n");
|
alpar@1
|
321 |
xprintf("Aviation Institute, Moscow, Russia. All rights reserved."
|
alpar@1
|
322 |
"\n");
|
alpar@1
|
323 |
xprintf("\n");
|
alpar@1
|
324 |
xprintf("This program has ABSOLUTELY NO WARRANTY.\n");
|
alpar@1
|
325 |
xprintf("\n");
|
alpar@1
|
326 |
xprintf("This program is free software; you may re-distribute it "
|
alpar@1
|
327 |
"under the terms\n");
|
alpar@1
|
328 |
xprintf("of the GNU General Public License version 3 or later.\n")
|
alpar@1
|
329 |
;
|
alpar@1
|
330 |
done: return;
|
alpar@1
|
331 |
}
|
alpar@1
|
332 |
|
alpar@1
|
333 |
static int parse_cmdline(struct csa *csa, int argc, const char *argv[])
|
alpar@1
|
334 |
{ /* parse command-line parameters */
|
alpar@1
|
335 |
int k;
|
alpar@1
|
336 |
#define p(str) (strcmp(argv[k], str) == 0)
|
alpar@1
|
337 |
for (k = 1; k < argc; k++)
|
alpar@1
|
338 |
{ if (p("--mps"))
|
alpar@1
|
339 |
csa->format = FMT_MPS_DECK;
|
alpar@1
|
340 |
else if (p("--freemps"))
|
alpar@1
|
341 |
csa->format = FMT_MPS_FILE;
|
alpar@1
|
342 |
else if (p("--lp") || p("--cpxlp"))
|
alpar@1
|
343 |
csa->format = FMT_LP;
|
alpar@1
|
344 |
else if (p("--glp"))
|
alpar@1
|
345 |
csa->format = FMT_GLP;
|
alpar@1
|
346 |
else if (p("--math") || p("-m") || p("--model"))
|
alpar@1
|
347 |
csa->format = FMT_MATHPROG;
|
alpar@1
|
348 |
else if (p("-d") || p("--data"))
|
alpar@1
|
349 |
{ k++;
|
alpar@1
|
350 |
if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
|
alpar@1
|
351 |
{ xprintf("No input data file specified\n");
|
alpar@1
|
352 |
return 1;
|
alpar@1
|
353 |
}
|
alpar@1
|
354 |
if (csa->ndf == DATA_MAX)
|
alpar@1
|
355 |
{ xprintf("Too many input data files\n");
|
alpar@1
|
356 |
return 1;
|
alpar@1
|
357 |
}
|
alpar@1
|
358 |
csa->in_data[++(csa->ndf)] = argv[k];
|
alpar@1
|
359 |
}
|
alpar@1
|
360 |
else if (p("-y") || p("--display"))
|
alpar@1
|
361 |
{ k++;
|
alpar@1
|
362 |
if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
|
alpar@1
|
363 |
{ xprintf("No display output file specified\n");
|
alpar@1
|
364 |
return 1;
|
alpar@1
|
365 |
}
|
alpar@1
|
366 |
if (csa->out_dpy != NULL)
|
alpar@1
|
367 |
{ xprintf("Only one display output file allowed\n");
|
alpar@1
|
368 |
return 1;
|
alpar@1
|
369 |
}
|
alpar@1
|
370 |
csa->out_dpy = argv[k];
|
alpar@1
|
371 |
}
|
alpar@1
|
372 |
else if (p("--seed"))
|
alpar@1
|
373 |
{ k++;
|
alpar@1
|
374 |
if (k == argc || argv[k][0] == '\0' ||
|
alpar@1
|
375 |
argv[k][0] == '-' && !isdigit((unsigned char)argv[k][1]))
|
alpar@1
|
376 |
{ xprintf("No seed value specified\n");
|
alpar@1
|
377 |
return 1;
|
alpar@1
|
378 |
}
|
alpar@1
|
379 |
if (strcmp(argv[k], "?") == 0)
|
alpar@1
|
380 |
csa->seed = 0x80000000;
|
alpar@1
|
381 |
else if (str2int(argv[k], &csa->seed))
|
alpar@1
|
382 |
{ xprintf("Invalid seed value `%s'\n", argv[k]);
|
alpar@1
|
383 |
return 1;
|
alpar@1
|
384 |
}
|
alpar@1
|
385 |
}
|
alpar@1
|
386 |
else if (p("--mincost"))
|
alpar@1
|
387 |
csa->format = FMT_MIN_COST;
|
alpar@1
|
388 |
else if (p("--maxflow"))
|
alpar@1
|
389 |
csa->format = FMT_MAX_FLOW;
|
alpar@1
|
390 |
else if (p("--simplex"))
|
alpar@1
|
391 |
csa->solution = SOL_BASIC;
|
alpar@1
|
392 |
else if (p("--interior"))
|
alpar@1
|
393 |
csa->solution = SOL_INTERIOR;
|
alpar@1
|
394 |
#if 1 /* 28/V-2010 */
|
alpar@1
|
395 |
else if (p("--alien"))
|
alpar@1
|
396 |
csa->iocp.alien = GLP_ON;
|
alpar@1
|
397 |
#endif
|
alpar@1
|
398 |
else if (p("-r") || p("--read"))
|
alpar@1
|
399 |
{ k++;
|
alpar@1
|
400 |
if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
|
alpar@1
|
401 |
{ xprintf("No input solution file specified\n");
|
alpar@1
|
402 |
return 1;
|
alpar@1
|
403 |
}
|
alpar@1
|
404 |
if (csa->in_res != NULL)
|
alpar@1
|
405 |
{ xprintf("Only one input solution file allowed\n");
|
alpar@1
|
406 |
return 1;
|
alpar@1
|
407 |
}
|
alpar@1
|
408 |
csa->in_res = argv[k];
|
alpar@1
|
409 |
}
|
alpar@1
|
410 |
else if (p("--min"))
|
alpar@1
|
411 |
csa->dir = GLP_MIN;
|
alpar@1
|
412 |
else if (p("--max"))
|
alpar@1
|
413 |
csa->dir = GLP_MAX;
|
alpar@1
|
414 |
else if (p("--scale"))
|
alpar@1
|
415 |
csa->scale = 1;
|
alpar@1
|
416 |
else if (p("--noscale"))
|
alpar@1
|
417 |
csa->scale = 0;
|
alpar@1
|
418 |
else if (p("-o") || p("--output"))
|
alpar@1
|
419 |
{ k++;
|
alpar@1
|
420 |
if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
|
alpar@1
|
421 |
{ xprintf("No output solution file specified\n");
|
alpar@1
|
422 |
return 1;
|
alpar@1
|
423 |
}
|
alpar@1
|
424 |
if (csa->out_sol != NULL)
|
alpar@1
|
425 |
{ xprintf("Only one output solution file allowed\n");
|
alpar@1
|
426 |
return 1;
|
alpar@1
|
427 |
}
|
alpar@1
|
428 |
csa->out_sol = argv[k];
|
alpar@1
|
429 |
}
|
alpar@1
|
430 |
else if (p("-w") || p("--write"))
|
alpar@1
|
431 |
{ k++;
|
alpar@1
|
432 |
if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
|
alpar@1
|
433 |
{ xprintf("No output solution file specified\n");
|
alpar@1
|
434 |
return 1;
|
alpar@1
|
435 |
}
|
alpar@1
|
436 |
if (csa->out_res != NULL)
|
alpar@1
|
437 |
{ xprintf("Only one output solution file allowed\n");
|
alpar@1
|
438 |
return 1;
|
alpar@1
|
439 |
}
|
alpar@1
|
440 |
csa->out_res = argv[k];
|
alpar@1
|
441 |
}
|
alpar@1
|
442 |
else if (p("--ranges") || p("--bounds"))
|
alpar@1
|
443 |
{ k++;
|
alpar@1
|
444 |
if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
|
alpar@1
|
445 |
{ xprintf("No output file specified to write sensitivity a"
|
alpar@1
|
446 |
"nalysis report\n");
|
alpar@1
|
447 |
return 1;
|
alpar@1
|
448 |
}
|
alpar@1
|
449 |
if (csa->out_ranges != NULL)
|
alpar@1
|
450 |
{ xprintf("Only one output file allowed to write sensitivi"
|
alpar@1
|
451 |
"ty analysis report\n");
|
alpar@1
|
452 |
return 1;
|
alpar@1
|
453 |
}
|
alpar@1
|
454 |
csa->out_ranges = argv[k];
|
alpar@1
|
455 |
}
|
alpar@1
|
456 |
else if (p("--tmlim"))
|
alpar@1
|
457 |
{ int tm_lim;
|
alpar@1
|
458 |
k++;
|
alpar@1
|
459 |
if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
|
alpar@1
|
460 |
{ xprintf("No time limit specified\n");
|
alpar@1
|
461 |
return 1;
|
alpar@1
|
462 |
}
|
alpar@1
|
463 |
if (str2int(argv[k], &tm_lim) || tm_lim < 0)
|
alpar@1
|
464 |
{ xprintf("Invalid time limit `%s'\n", argv[k]);
|
alpar@1
|
465 |
return 1;
|
alpar@1
|
466 |
}
|
alpar@1
|
467 |
if (tm_lim <= INT_MAX / 1000)
|
alpar@1
|
468 |
csa->smcp.tm_lim = csa->iocp.tm_lim = 1000 * tm_lim;
|
alpar@1
|
469 |
else
|
alpar@1
|
470 |
csa->smcp.tm_lim = csa->iocp.tm_lim = INT_MAX;
|
alpar@1
|
471 |
}
|
alpar@1
|
472 |
else if (p("--memlim"))
|
alpar@1
|
473 |
{ int mem_lim;
|
alpar@1
|
474 |
k++;
|
alpar@1
|
475 |
if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
|
alpar@1
|
476 |
{ xprintf("No memory limit specified\n");
|
alpar@1
|
477 |
return 1;
|
alpar@1
|
478 |
}
|
alpar@1
|
479 |
if (str2int(argv[k], &mem_lim) || mem_lim < 1)
|
alpar@1
|
480 |
{ xprintf("Invalid memory limit `%s'\n", argv[k]);
|
alpar@1
|
481 |
return 1;
|
alpar@1
|
482 |
}
|
alpar@1
|
483 |
glp_mem_limit(mem_lim);
|
alpar@1
|
484 |
}
|
alpar@1
|
485 |
else if (p("--check"))
|
alpar@1
|
486 |
csa->check = 1;
|
alpar@1
|
487 |
else if (p("--name"))
|
alpar@1
|
488 |
{ k++;
|
alpar@1
|
489 |
if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
|
alpar@1
|
490 |
{ xprintf("No problem name specified\n");
|
alpar@1
|
491 |
return 1;
|
alpar@1
|
492 |
}
|
alpar@1
|
493 |
if (csa->new_name != NULL)
|
alpar@1
|
494 |
{ xprintf("Only one problem name allowed\n");
|
alpar@1
|
495 |
return 1;
|
alpar@1
|
496 |
}
|
alpar@1
|
497 |
csa->new_name = argv[k];
|
alpar@1
|
498 |
}
|
alpar@1
|
499 |
else if (p("--wmps"))
|
alpar@1
|
500 |
{ k++;
|
alpar@1
|
501 |
if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
|
alpar@1
|
502 |
{ xprintf("No fixed MPS output file specified\n");
|
alpar@1
|
503 |
return 1;
|
alpar@1
|
504 |
}
|
alpar@1
|
505 |
if (csa->out_mps != NULL)
|
alpar@1
|
506 |
{ xprintf("Only one fixed MPS output file allowed\n");
|
alpar@1
|
507 |
return 1;
|
alpar@1
|
508 |
}
|
alpar@1
|
509 |
csa->out_mps = argv[k];
|
alpar@1
|
510 |
}
|
alpar@1
|
511 |
else if (p("--wfreemps"))
|
alpar@1
|
512 |
{ k++;
|
alpar@1
|
513 |
if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
|
alpar@1
|
514 |
{ xprintf("No free MPS output file specified\n");
|
alpar@1
|
515 |
return 1;
|
alpar@1
|
516 |
}
|
alpar@1
|
517 |
if (csa->out_freemps != NULL)
|
alpar@1
|
518 |
{ xprintf("Only one free MPS output file allowed\n");
|
alpar@1
|
519 |
return 1;
|
alpar@1
|
520 |
}
|
alpar@1
|
521 |
csa->out_freemps = argv[k];
|
alpar@1
|
522 |
}
|
alpar@1
|
523 |
else if (p("--wlp") || p("--wcpxlp") || p("--wlpt"))
|
alpar@1
|
524 |
{ k++;
|
alpar@1
|
525 |
if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
|
alpar@1
|
526 |
{ xprintf("No CPLEX LP output file specified\n");
|
alpar@1
|
527 |
return 1;
|
alpar@1
|
528 |
}
|
alpar@1
|
529 |
if (csa->out_cpxlp != NULL)
|
alpar@1
|
530 |
{ xprintf("Only one CPLEX LP output file allowed\n");
|
alpar@1
|
531 |
return 1;
|
alpar@1
|
532 |
}
|
alpar@1
|
533 |
csa->out_cpxlp = argv[k];
|
alpar@1
|
534 |
}
|
alpar@1
|
535 |
else if (p("--wglp"))
|
alpar@1
|
536 |
{ k++;
|
alpar@1
|
537 |
if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
|
alpar@1
|
538 |
{ xprintf("No GLPK LP/MIP output file specified\n");
|
alpar@1
|
539 |
return 1;
|
alpar@1
|
540 |
}
|
alpar@1
|
541 |
if (csa->out_glp != NULL)
|
alpar@1
|
542 |
{ xprintf("Only one GLPK LP/MIP output file allowed\n");
|
alpar@1
|
543 |
return 1;
|
alpar@1
|
544 |
}
|
alpar@1
|
545 |
csa->out_glp = argv[k];
|
alpar@1
|
546 |
}
|
alpar@1
|
547 |
else if (p("--wpb"))
|
alpar@1
|
548 |
{ k++;
|
alpar@1
|
549 |
if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
|
alpar@1
|
550 |
{ xprintf("No problem output file specified\n");
|
alpar@1
|
551 |
return 1;
|
alpar@1
|
552 |
}
|
alpar@1
|
553 |
if (csa->out_pb != NULL)
|
alpar@1
|
554 |
{ xprintf("Only one OPB output file allowed\n");
|
alpar@1
|
555 |
return 1;
|
alpar@1
|
556 |
}
|
alpar@1
|
557 |
csa->out_pb = argv[k];
|
alpar@1
|
558 |
}
|
alpar@1
|
559 |
else if (p("--wnpb"))
|
alpar@1
|
560 |
{ k++;
|
alpar@1
|
561 |
if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
|
alpar@1
|
562 |
{ xprintf("No problem output file specified\n");
|
alpar@1
|
563 |
return 1;
|
alpar@1
|
564 |
}
|
alpar@1
|
565 |
if (csa->out_npb != NULL)
|
alpar@1
|
566 |
{ xprintf("Only one normalized OPB output file allowed\n");
|
alpar@1
|
567 |
return 1;
|
alpar@1
|
568 |
}
|
alpar@1
|
569 |
csa->out_npb = argv[k];
|
alpar@1
|
570 |
}
|
alpar@1
|
571 |
else if (p("--log"))
|
alpar@1
|
572 |
{ k++;
|
alpar@1
|
573 |
if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
|
alpar@1
|
574 |
{ xprintf("No log file specified\n");
|
alpar@1
|
575 |
return 1;
|
alpar@1
|
576 |
}
|
alpar@1
|
577 |
if (csa->log_file != NULL)
|
alpar@1
|
578 |
{ xprintf("Only one log file allowed\n");
|
alpar@1
|
579 |
return 1;
|
alpar@1
|
580 |
}
|
alpar@1
|
581 |
csa->log_file = argv[k];
|
alpar@1
|
582 |
}
|
alpar@1
|
583 |
else if (p("-h") || p("--help"))
|
alpar@1
|
584 |
{ print_help(argv[0]);
|
alpar@1
|
585 |
return -1;
|
alpar@1
|
586 |
}
|
alpar@1
|
587 |
else if (p("-v") || p("--version"))
|
alpar@1
|
588 |
{ print_version(0);
|
alpar@1
|
589 |
return -1;
|
alpar@1
|
590 |
}
|
alpar@1
|
591 |
else if (p("--luf"))
|
alpar@1
|
592 |
csa->bfcp.type = GLP_BF_FT;
|
alpar@1
|
593 |
else if (p("--cbg"))
|
alpar@1
|
594 |
csa->bfcp.type = GLP_BF_BG;
|
alpar@1
|
595 |
else if (p("--cgr"))
|
alpar@1
|
596 |
csa->bfcp.type = GLP_BF_GR;
|
alpar@1
|
597 |
else if (p("--primal"))
|
alpar@1
|
598 |
csa->smcp.meth = GLP_PRIMAL;
|
alpar@1
|
599 |
else if (p("--dual"))
|
alpar@1
|
600 |
csa->smcp.meth = GLP_DUAL;
|
alpar@1
|
601 |
else if (p("--std"))
|
alpar@1
|
602 |
csa->crash = USE_STD_BASIS;
|
alpar@1
|
603 |
else if (p("--adv"))
|
alpar@1
|
604 |
csa->crash = USE_ADV_BASIS;
|
alpar@1
|
605 |
else if (p("--bib"))
|
alpar@1
|
606 |
csa->crash = USE_CPX_BASIS;
|
alpar@1
|
607 |
else if (p("--ini"))
|
alpar@1
|
608 |
{ csa->crash = USE_INI_BASIS;
|
alpar@1
|
609 |
csa->smcp.presolve = GLP_OFF;
|
alpar@1
|
610 |
k++;
|
alpar@1
|
611 |
if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
|
alpar@1
|
612 |
{ xprintf("No initial basis file specified\n");
|
alpar@1
|
613 |
return 1;
|
alpar@1
|
614 |
}
|
alpar@1
|
615 |
if (csa->ini_file != NULL)
|
alpar@1
|
616 |
{ xprintf("Only one initial basis file allowed\n");
|
alpar@1
|
617 |
return 1;
|
alpar@1
|
618 |
}
|
alpar@1
|
619 |
csa->ini_file = argv[k];
|
alpar@1
|
620 |
}
|
alpar@1
|
621 |
else if (p("--steep"))
|
alpar@1
|
622 |
csa->smcp.pricing = GLP_PT_PSE;
|
alpar@1
|
623 |
else if (p("--nosteep"))
|
alpar@1
|
624 |
csa->smcp.pricing = GLP_PT_STD;
|
alpar@1
|
625 |
else if (p("--relax"))
|
alpar@1
|
626 |
csa->smcp.r_test = GLP_RT_HAR;
|
alpar@1
|
627 |
else if (p("--norelax"))
|
alpar@1
|
628 |
csa->smcp.r_test = GLP_RT_STD;
|
alpar@1
|
629 |
else if (p("--presol"))
|
alpar@1
|
630 |
csa->smcp.presolve = GLP_ON;
|
alpar@1
|
631 |
else if (p("--nopresol"))
|
alpar@1
|
632 |
csa->smcp.presolve = GLP_OFF;
|
alpar@1
|
633 |
else if (p("--exact"))
|
alpar@1
|
634 |
csa->exact = 1;
|
alpar@1
|
635 |
else if (p("--xcheck"))
|
alpar@1
|
636 |
csa->xcheck = 1;
|
alpar@1
|
637 |
else if (p("--nord"))
|
alpar@1
|
638 |
csa->iptcp.ord_alg = GLP_ORD_NONE;
|
alpar@1
|
639 |
else if (p("--qmd"))
|
alpar@1
|
640 |
csa->iptcp.ord_alg = GLP_ORD_QMD;
|
alpar@1
|
641 |
else if (p("--amd"))
|
alpar@1
|
642 |
csa->iptcp.ord_alg = GLP_ORD_AMD;
|
alpar@1
|
643 |
else if (p("--symamd"))
|
alpar@1
|
644 |
csa->iptcp.ord_alg = GLP_ORD_SYMAMD;
|
alpar@1
|
645 |
else if (p("--nomip"))
|
alpar@1
|
646 |
csa->nomip = 1;
|
alpar@1
|
647 |
else if (p("--first"))
|
alpar@1
|
648 |
csa->iocp.br_tech = GLP_BR_FFV;
|
alpar@1
|
649 |
else if (p("--last"))
|
alpar@1
|
650 |
csa->iocp.br_tech = GLP_BR_LFV;
|
alpar@1
|
651 |
else if (p("--drtom"))
|
alpar@1
|
652 |
csa->iocp.br_tech = GLP_BR_DTH;
|
alpar@1
|
653 |
else if (p("--mostf"))
|
alpar@1
|
654 |
csa->iocp.br_tech = GLP_BR_MFV;
|
alpar@1
|
655 |
else if (p("--pcost"))
|
alpar@1
|
656 |
csa->iocp.br_tech = GLP_BR_PCH;
|
alpar@1
|
657 |
else if (p("--dfs"))
|
alpar@1
|
658 |
csa->iocp.bt_tech = GLP_BT_DFS;
|
alpar@1
|
659 |
else if (p("--bfs"))
|
alpar@1
|
660 |
csa->iocp.bt_tech = GLP_BT_BFS;
|
alpar@1
|
661 |
else if (p("--bestp"))
|
alpar@1
|
662 |
csa->iocp.bt_tech = GLP_BT_BPH;
|
alpar@1
|
663 |
else if (p("--bestb"))
|
alpar@1
|
664 |
csa->iocp.bt_tech = GLP_BT_BLB;
|
alpar@1
|
665 |
else if (p("--intopt"))
|
alpar@1
|
666 |
csa->iocp.presolve = GLP_ON;
|
alpar@1
|
667 |
else if (p("--nointopt"))
|
alpar@1
|
668 |
csa->iocp.presolve = GLP_OFF;
|
alpar@1
|
669 |
else if (p("--binarize"))
|
alpar@1
|
670 |
csa->iocp.presolve = csa->iocp.binarize = GLP_ON;
|
alpar@1
|
671 |
else if (p("--fpump"))
|
alpar@1
|
672 |
csa->iocp.fp_heur = GLP_ON;
|
alpar@1
|
673 |
else if (p("--gomory"))
|
alpar@1
|
674 |
csa->iocp.gmi_cuts = GLP_ON;
|
alpar@1
|
675 |
else if (p("--mir"))
|
alpar@1
|
676 |
csa->iocp.mir_cuts = GLP_ON;
|
alpar@1
|
677 |
else if (p("--cover"))
|
alpar@1
|
678 |
csa->iocp.cov_cuts = GLP_ON;
|
alpar@1
|
679 |
else if (p("--clique"))
|
alpar@1
|
680 |
csa->iocp.clq_cuts = GLP_ON;
|
alpar@1
|
681 |
else if (p("--cuts"))
|
alpar@1
|
682 |
csa->iocp.gmi_cuts = csa->iocp.mir_cuts =
|
alpar@1
|
683 |
csa->iocp.cov_cuts = csa->iocp.clq_cuts = GLP_ON;
|
alpar@1
|
684 |
else if (p("--mipgap"))
|
alpar@1
|
685 |
{ double mip_gap;
|
alpar@1
|
686 |
k++;
|
alpar@1
|
687 |
if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
|
alpar@1
|
688 |
{ xprintf("No relative gap tolerance specified\n");
|
alpar@1
|
689 |
return 1;
|
alpar@1
|
690 |
}
|
alpar@1
|
691 |
if (str2num(argv[k], &mip_gap) || mip_gap < 0.0)
|
alpar@1
|
692 |
{ xprintf("Invalid relative mip gap tolerance `%s'\n",
|
alpar@1
|
693 |
argv[k]);
|
alpar@1
|
694 |
return 1;
|
alpar@1
|
695 |
}
|
alpar@1
|
696 |
csa->iocp.mip_gap = mip_gap;
|
alpar@1
|
697 |
}
|
alpar@1
|
698 |
else if (argv[k][0] == '-' ||
|
alpar@1
|
699 |
(argv[k][0] == '-' && argv[k][1] == '-'))
|
alpar@1
|
700 |
{ xprintf("Invalid option `%s'; try %s --help\n",
|
alpar@1
|
701 |
argv[k], argv[0]);
|
alpar@1
|
702 |
return 1;
|
alpar@1
|
703 |
}
|
alpar@1
|
704 |
else
|
alpar@1
|
705 |
{ if (csa->in_file != NULL)
|
alpar@1
|
706 |
{ xprintf("Only one input problem file allowed\n");
|
alpar@1
|
707 |
return 1;
|
alpar@1
|
708 |
}
|
alpar@1
|
709 |
csa->in_file = argv[k];
|
alpar@1
|
710 |
}
|
alpar@1
|
711 |
}
|
alpar@1
|
712 |
#undef p
|
alpar@1
|
713 |
return 0;
|
alpar@1
|
714 |
}
|
alpar@1
|
715 |
|
alpar@1
|
716 |
typedef struct { double rhs, pi; } v_data;
|
alpar@1
|
717 |
typedef struct { double low, cap, cost, x; } a_data;
|
alpar@1
|
718 |
|
alpar@1
|
719 |
int glp_main(int argc, const char *argv[])
|
alpar@1
|
720 |
{ /* stand-alone LP/MIP solver */
|
alpar@1
|
721 |
struct csa _csa, *csa = &_csa;
|
alpar@1
|
722 |
int ret;
|
alpar@1
|
723 |
glp_long start;
|
alpar@1
|
724 |
/* perform initialization */
|
alpar@1
|
725 |
csa->prob = glp_create_prob();
|
alpar@1
|
726 |
glp_get_bfcp(csa->prob, &csa->bfcp);
|
alpar@1
|
727 |
glp_init_smcp(&csa->smcp);
|
alpar@1
|
728 |
csa->smcp.presolve = GLP_ON;
|
alpar@1
|
729 |
glp_init_iptcp(&csa->iptcp);
|
alpar@1
|
730 |
glp_init_iocp(&csa->iocp);
|
alpar@1
|
731 |
csa->iocp.presolve = GLP_ON;
|
alpar@1
|
732 |
csa->tran = NULL;
|
alpar@1
|
733 |
csa->graph = NULL;
|
alpar@1
|
734 |
csa->format = FMT_MPS_FILE;
|
alpar@1
|
735 |
csa->in_file = NULL;
|
alpar@1
|
736 |
csa->ndf = 0;
|
alpar@1
|
737 |
csa->out_dpy = NULL;
|
alpar@1
|
738 |
csa->seed = 1;
|
alpar@1
|
739 |
csa->solution = SOL_BASIC;
|
alpar@1
|
740 |
csa->in_res = NULL;
|
alpar@1
|
741 |
csa->dir = 0;
|
alpar@1
|
742 |
csa->scale = 1;
|
alpar@1
|
743 |
csa->out_sol = NULL;
|
alpar@1
|
744 |
csa->out_res = NULL;
|
alpar@1
|
745 |
csa->out_ranges = NULL;
|
alpar@1
|
746 |
csa->check = 0;
|
alpar@1
|
747 |
csa->new_name = NULL;
|
alpar@1
|
748 |
csa->out_mps = NULL;
|
alpar@1
|
749 |
csa->out_freemps = NULL;
|
alpar@1
|
750 |
csa->out_cpxlp = NULL;
|
alpar@1
|
751 |
csa->out_glp = NULL;
|
alpar@1
|
752 |
csa->out_pb = NULL;
|
alpar@1
|
753 |
csa->out_npb = NULL;
|
alpar@1
|
754 |
csa->log_file = NULL;
|
alpar@1
|
755 |
csa->crash = USE_ADV_BASIS;
|
alpar@1
|
756 |
csa->ini_file = NULL;
|
alpar@1
|
757 |
csa->exact = 0;
|
alpar@1
|
758 |
csa->xcheck = 0;
|
alpar@1
|
759 |
csa->nomip = 0;
|
alpar@1
|
760 |
/* parse command-line parameters */
|
alpar@1
|
761 |
ret = parse_cmdline(csa, argc, argv);
|
alpar@1
|
762 |
if (ret < 0)
|
alpar@1
|
763 |
{ ret = EXIT_SUCCESS;
|
alpar@1
|
764 |
goto done;
|
alpar@1
|
765 |
}
|
alpar@1
|
766 |
if (ret > 0)
|
alpar@1
|
767 |
{ ret = EXIT_FAILURE;
|
alpar@1
|
768 |
goto done;
|
alpar@1
|
769 |
}
|
alpar@1
|
770 |
/*--------------------------------------------------------------*/
|
alpar@1
|
771 |
/* remove all output files specified in the command line */
|
alpar@1
|
772 |
if (csa->out_dpy != NULL) remove(csa->out_dpy);
|
alpar@1
|
773 |
if (csa->out_sol != NULL) remove(csa->out_sol);
|
alpar@1
|
774 |
if (csa->out_res != NULL) remove(csa->out_res);
|
alpar@1
|
775 |
if (csa->out_ranges != NULL) remove(csa->out_ranges);
|
alpar@1
|
776 |
if (csa->out_mps != NULL) remove(csa->out_mps);
|
alpar@1
|
777 |
if (csa->out_freemps != NULL) remove(csa->out_freemps);
|
alpar@1
|
778 |
if (csa->out_cpxlp != NULL) remove(csa->out_cpxlp);
|
alpar@1
|
779 |
if (csa->out_glp != NULL) remove(csa->out_glp);
|
alpar@1
|
780 |
if (csa->out_pb != NULL) remove(csa->out_pb);
|
alpar@1
|
781 |
if (csa->out_npb != NULL) remove(csa->out_npb);
|
alpar@1
|
782 |
if (csa->log_file != NULL) remove(csa->log_file);
|
alpar@1
|
783 |
/*--------------------------------------------------------------*/
|
alpar@1
|
784 |
/* open log file, if required */
|
alpar@1
|
785 |
if (csa->log_file != NULL)
|
alpar@1
|
786 |
{ if (glp_open_tee(csa->log_file))
|
alpar@1
|
787 |
{ xprintf("Unable to create log file\n");
|
alpar@1
|
788 |
ret = EXIT_FAILURE;
|
alpar@1
|
789 |
goto done;
|
alpar@1
|
790 |
}
|
alpar@1
|
791 |
}
|
alpar@1
|
792 |
/*--------------------------------------------------------------*/
|
alpar@1
|
793 |
/* print version information */
|
alpar@1
|
794 |
print_version(1);
|
alpar@1
|
795 |
/*--------------------------------------------------------------*/
|
alpar@1
|
796 |
/* print parameters specified in the command line */
|
alpar@1
|
797 |
if (argc > 1)
|
alpar@1
|
798 |
{ int k, len = INT_MAX;
|
alpar@1
|
799 |
xprintf("Parameter(s) specified in the command line:");
|
alpar@1
|
800 |
for (k = 1; k < argc; k++)
|
alpar@1
|
801 |
{ if (len > 72)
|
alpar@1
|
802 |
xprintf("\n"), len = 0;
|
alpar@1
|
803 |
xprintf(" %s", argv[k]);
|
alpar@1
|
804 |
len += 1 + strlen(argv[k]);
|
alpar@1
|
805 |
}
|
alpar@1
|
806 |
xprintf("\n");
|
alpar@1
|
807 |
}
|
alpar@1
|
808 |
/*--------------------------------------------------------------*/
|
alpar@1
|
809 |
/* read problem data from the input file */
|
alpar@1
|
810 |
if (csa->in_file == NULL)
|
alpar@1
|
811 |
{ xprintf("No input problem file specified; try %s --help\n",
|
alpar@1
|
812 |
argv[0]);
|
alpar@1
|
813 |
ret = EXIT_FAILURE;
|
alpar@1
|
814 |
goto done;
|
alpar@1
|
815 |
}
|
alpar@1
|
816 |
if (csa->format == FMT_MPS_DECK)
|
alpar@1
|
817 |
{ ret = glp_read_mps(csa->prob, GLP_MPS_DECK, NULL,
|
alpar@1
|
818 |
csa->in_file);
|
alpar@1
|
819 |
if (ret != 0)
|
alpar@1
|
820 |
err1: { xprintf("MPS file processing error\n");
|
alpar@1
|
821 |
ret = EXIT_FAILURE;
|
alpar@1
|
822 |
goto done;
|
alpar@1
|
823 |
}
|
alpar@1
|
824 |
}
|
alpar@1
|
825 |
else if (csa->format == FMT_MPS_FILE)
|
alpar@1
|
826 |
{ ret = glp_read_mps(csa->prob, GLP_MPS_FILE, NULL,
|
alpar@1
|
827 |
csa->in_file);
|
alpar@1
|
828 |
if (ret != 0) goto err1;
|
alpar@1
|
829 |
}
|
alpar@1
|
830 |
else if (csa->format == FMT_LP)
|
alpar@1
|
831 |
{ ret = glp_read_lp(csa->prob, NULL, csa->in_file);
|
alpar@1
|
832 |
if (ret != 0)
|
alpar@1
|
833 |
{ xprintf("CPLEX LP file processing error\n");
|
alpar@1
|
834 |
ret = EXIT_FAILURE;
|
alpar@1
|
835 |
goto done;
|
alpar@1
|
836 |
}
|
alpar@1
|
837 |
}
|
alpar@1
|
838 |
else if (csa->format == FMT_GLP)
|
alpar@1
|
839 |
{ ret = glp_read_prob(csa->prob, 0, csa->in_file);
|
alpar@1
|
840 |
if (ret != 0)
|
alpar@1
|
841 |
{ xprintf("GLPK LP/MIP file processing error\n");
|
alpar@1
|
842 |
ret = EXIT_FAILURE;
|
alpar@1
|
843 |
goto done;
|
alpar@1
|
844 |
}
|
alpar@1
|
845 |
}
|
alpar@1
|
846 |
else if (csa->format == FMT_MATHPROG)
|
alpar@1
|
847 |
{ int k;
|
alpar@1
|
848 |
/* allocate the translator workspace */
|
alpar@1
|
849 |
csa->tran = glp_mpl_alloc_wksp();
|
alpar@1
|
850 |
/* set seed value */
|
alpar@1
|
851 |
if (csa->seed == 0x80000000)
|
alpar@1
|
852 |
{ csa->seed = glp_time().lo;
|
alpar@1
|
853 |
xprintf("Seed value %d will be used\n", csa->seed);
|
alpar@1
|
854 |
}
|
alpar@1
|
855 |
_glp_mpl_init_rand(csa->tran, csa->seed);
|
alpar@1
|
856 |
/* read model section and optional data section */
|
alpar@1
|
857 |
if (glp_mpl_read_model(csa->tran, csa->in_file, csa->ndf > 0))
|
alpar@1
|
858 |
err2: { xprintf("MathProg model processing error\n");
|
alpar@1
|
859 |
ret = EXIT_FAILURE;
|
alpar@1
|
860 |
goto done;
|
alpar@1
|
861 |
}
|
alpar@1
|
862 |
/* read optional data section(s), if necessary */
|
alpar@1
|
863 |
for (k = 1; k <= csa->ndf; k++)
|
alpar@1
|
864 |
{ if (glp_mpl_read_data(csa->tran, csa->in_data[k]))
|
alpar@1
|
865 |
goto err2;
|
alpar@1
|
866 |
}
|
alpar@1
|
867 |
/* generate the model */
|
alpar@1
|
868 |
if (glp_mpl_generate(csa->tran, csa->out_dpy)) goto err2;
|
alpar@1
|
869 |
/* build the problem instance from the model */
|
alpar@1
|
870 |
glp_mpl_build_prob(csa->tran, csa->prob);
|
alpar@1
|
871 |
}
|
alpar@1
|
872 |
else if (csa->format == FMT_MIN_COST)
|
alpar@1
|
873 |
{ csa->graph = glp_create_graph(sizeof(v_data), sizeof(a_data));
|
alpar@1
|
874 |
ret = glp_read_mincost(csa->graph, offsetof(v_data, rhs),
|
alpar@1
|
875 |
offsetof(a_data, low), offsetof(a_data, cap),
|
alpar@1
|
876 |
offsetof(a_data, cost), csa->in_file);
|
alpar@1
|
877 |
if (ret != 0)
|
alpar@1
|
878 |
{ xprintf("DIMACS file processing error\n");
|
alpar@1
|
879 |
ret = EXIT_FAILURE;
|
alpar@1
|
880 |
goto done;
|
alpar@1
|
881 |
}
|
alpar@1
|
882 |
glp_mincost_lp(csa->prob, csa->graph, GLP_ON,
|
alpar@1
|
883 |
offsetof(v_data, rhs), offsetof(a_data, low),
|
alpar@1
|
884 |
offsetof(a_data, cap), offsetof(a_data, cost));
|
alpar@1
|
885 |
glp_set_prob_name(csa->prob, csa->in_file);
|
alpar@1
|
886 |
}
|
alpar@1
|
887 |
else if (csa->format == FMT_MAX_FLOW)
|
alpar@1
|
888 |
{ int s, t;
|
alpar@1
|
889 |
csa->graph = glp_create_graph(sizeof(v_data), sizeof(a_data));
|
alpar@1
|
890 |
ret = glp_read_maxflow(csa->graph, &s, &t,
|
alpar@1
|
891 |
offsetof(a_data, cap), csa->in_file);
|
alpar@1
|
892 |
if (ret != 0)
|
alpar@1
|
893 |
{ xprintf("DIMACS file processing error\n");
|
alpar@1
|
894 |
ret = EXIT_FAILURE;
|
alpar@1
|
895 |
goto done;
|
alpar@1
|
896 |
}
|
alpar@1
|
897 |
glp_maxflow_lp(csa->prob, csa->graph, GLP_ON, s, t,
|
alpar@1
|
898 |
offsetof(a_data, cap));
|
alpar@1
|
899 |
glp_set_prob_name(csa->prob, csa->in_file);
|
alpar@1
|
900 |
}
|
alpar@1
|
901 |
else
|
alpar@1
|
902 |
xassert(csa != csa);
|
alpar@1
|
903 |
/*--------------------------------------------------------------*/
|
alpar@1
|
904 |
/* change problem name, if required */
|
alpar@1
|
905 |
if (csa->new_name != NULL)
|
alpar@1
|
906 |
glp_set_prob_name(csa->prob, csa->new_name);
|
alpar@1
|
907 |
/* change optimization direction, if required */
|
alpar@1
|
908 |
if (csa->dir != 0)
|
alpar@1
|
909 |
glp_set_obj_dir(csa->prob, csa->dir);
|
alpar@1
|
910 |
/* sort elements of the constraint matrix */
|
alpar@1
|
911 |
glp_sort_matrix(csa->prob);
|
alpar@1
|
912 |
/*--------------------------------------------------------------*/
|
alpar@1
|
913 |
/* write problem data in fixed MPS format, if required */
|
alpar@1
|
914 |
if (csa->out_mps != NULL)
|
alpar@1
|
915 |
{ ret = glp_write_mps(csa->prob, GLP_MPS_DECK, NULL,
|
alpar@1
|
916 |
csa->out_mps);
|
alpar@1
|
917 |
if (ret != 0)
|
alpar@1
|
918 |
{ xprintf("Unable to write problem in fixed MPS format\n");
|
alpar@1
|
919 |
ret = EXIT_FAILURE;
|
alpar@1
|
920 |
goto done;
|
alpar@1
|
921 |
}
|
alpar@1
|
922 |
}
|
alpar@1
|
923 |
/* write problem data in free MPS format, if required */
|
alpar@1
|
924 |
if (csa->out_freemps != NULL)
|
alpar@1
|
925 |
{ ret = glp_write_mps(csa->prob, GLP_MPS_FILE, NULL,
|
alpar@1
|
926 |
csa->out_freemps);
|
alpar@1
|
927 |
if (ret != 0)
|
alpar@1
|
928 |
{ xprintf("Unable to write problem in free MPS format\n");
|
alpar@1
|
929 |
ret = EXIT_FAILURE;
|
alpar@1
|
930 |
goto done;
|
alpar@1
|
931 |
}
|
alpar@1
|
932 |
}
|
alpar@1
|
933 |
/* write problem data in CPLEX LP format, if required */
|
alpar@1
|
934 |
if (csa->out_cpxlp != NULL)
|
alpar@1
|
935 |
{ ret = glp_write_lp(csa->prob, NULL, csa->out_cpxlp);
|
alpar@1
|
936 |
if (ret != 0)
|
alpar@1
|
937 |
{ xprintf("Unable to write problem in CPLEX LP format\n");
|
alpar@1
|
938 |
ret = EXIT_FAILURE;
|
alpar@1
|
939 |
goto done;
|
alpar@1
|
940 |
}
|
alpar@1
|
941 |
}
|
alpar@1
|
942 |
/* write problem data in GLPK format, if required */
|
alpar@1
|
943 |
if (csa->out_glp != NULL)
|
alpar@1
|
944 |
{ ret = glp_write_prob(csa->prob, 0, csa->out_glp);
|
alpar@1
|
945 |
if (ret != 0)
|
alpar@1
|
946 |
{ xprintf("Unable to write problem in GLPK format\n");
|
alpar@1
|
947 |
ret = EXIT_FAILURE;
|
alpar@1
|
948 |
goto done;
|
alpar@1
|
949 |
}
|
alpar@1
|
950 |
}
|
alpar@1
|
951 |
/* write problem data in OPB format, if required */
|
alpar@1
|
952 |
if (csa->out_pb != NULL)
|
alpar@1
|
953 |
{ ret = lpx_write_pb(csa->prob, csa->out_pb, 0, 0);
|
alpar@1
|
954 |
if (ret != 0)
|
alpar@1
|
955 |
{ xprintf("Unable to write problem in OPB format\n");
|
alpar@1
|
956 |
ret = EXIT_FAILURE;
|
alpar@1
|
957 |
goto done;
|
alpar@1
|
958 |
}
|
alpar@1
|
959 |
}
|
alpar@1
|
960 |
/* write problem data in normalized OPB format, if required */
|
alpar@1
|
961 |
if (csa->out_npb != NULL)
|
alpar@1
|
962 |
{ ret = lpx_write_pb(csa->prob, csa->out_npb, 1, 1);
|
alpar@1
|
963 |
if (ret != 0)
|
alpar@1
|
964 |
{ xprintf(
|
alpar@1
|
965 |
"Unable to write problem in normalized OPB format\n");
|
alpar@1
|
966 |
ret = EXIT_FAILURE;
|
alpar@1
|
967 |
goto done;
|
alpar@1
|
968 |
}
|
alpar@1
|
969 |
}
|
alpar@1
|
970 |
/*--------------------------------------------------------------*/
|
alpar@1
|
971 |
/* if only problem data check is required, skip computations */
|
alpar@1
|
972 |
if (csa->check)
|
alpar@1
|
973 |
{ ret = EXIT_SUCCESS;
|
alpar@1
|
974 |
goto done;
|
alpar@1
|
975 |
}
|
alpar@1
|
976 |
/*--------------------------------------------------------------*/
|
alpar@1
|
977 |
/* determine the solution type */
|
alpar@1
|
978 |
if (!csa->nomip &&
|
alpar@1
|
979 |
glp_get_num_int(csa->prob) + glp_get_num_bin(csa->prob) > 0)
|
alpar@1
|
980 |
{ if (csa->solution == SOL_INTERIOR)
|
alpar@1
|
981 |
{ xprintf("Interior-point method is not able to solve MIP pro"
|
alpar@1
|
982 |
"blem; use --simplex\n");
|
alpar@1
|
983 |
ret = EXIT_FAILURE;
|
alpar@1
|
984 |
goto done;
|
alpar@1
|
985 |
}
|
alpar@1
|
986 |
csa->solution = SOL_INTEGER;
|
alpar@1
|
987 |
}
|
alpar@1
|
988 |
/*--------------------------------------------------------------*/
|
alpar@1
|
989 |
/* if solution is provided, read it and skip computations */
|
alpar@1
|
990 |
if (csa->in_res != NULL)
|
alpar@1
|
991 |
{ if (csa->solution == SOL_BASIC)
|
alpar@1
|
992 |
ret = glp_read_sol(csa->prob, csa->in_res);
|
alpar@1
|
993 |
else if (csa->solution == SOL_INTERIOR)
|
alpar@1
|
994 |
ret = glp_read_ipt(csa->prob, csa->in_res);
|
alpar@1
|
995 |
else if (csa->solution == SOL_INTEGER)
|
alpar@1
|
996 |
ret = glp_read_mip(csa->prob, csa->in_res);
|
alpar@1
|
997 |
else
|
alpar@1
|
998 |
xassert(csa != csa);
|
alpar@1
|
999 |
if (ret != 0)
|
alpar@1
|
1000 |
{ xprintf("Unable to read problem solution\n");
|
alpar@1
|
1001 |
ret = EXIT_FAILURE;
|
alpar@1
|
1002 |
goto done;
|
alpar@1
|
1003 |
}
|
alpar@1
|
1004 |
goto skip;
|
alpar@1
|
1005 |
}
|
alpar@1
|
1006 |
/*--------------------------------------------------------------*/
|
alpar@1
|
1007 |
/* scale the problem data, if required */
|
alpar@1
|
1008 |
if (csa->scale)
|
alpar@1
|
1009 |
{ if (csa->solution == SOL_BASIC && !csa->smcp.presolve ||
|
alpar@1
|
1010 |
csa->solution == SOL_INTERIOR ||
|
alpar@1
|
1011 |
csa->solution == SOL_INTEGER && !csa->iocp.presolve)
|
alpar@1
|
1012 |
glp_scale_prob(csa->prob, GLP_SF_AUTO);
|
alpar@1
|
1013 |
}
|
alpar@1
|
1014 |
/*--------------------------------------------------------------*/
|
alpar@1
|
1015 |
/* construct starting LP basis */
|
alpar@1
|
1016 |
if (csa->solution == SOL_BASIC && !csa->smcp.presolve ||
|
alpar@1
|
1017 |
csa->solution == SOL_INTEGER && !csa->iocp.presolve)
|
alpar@1
|
1018 |
{ if (csa->crash == USE_STD_BASIS)
|
alpar@1
|
1019 |
glp_std_basis(csa->prob);
|
alpar@1
|
1020 |
else if (csa->crash == USE_ADV_BASIS)
|
alpar@1
|
1021 |
glp_adv_basis(csa->prob, 0);
|
alpar@1
|
1022 |
else if (csa->crash == USE_CPX_BASIS)
|
alpar@1
|
1023 |
glp_cpx_basis(csa->prob);
|
alpar@1
|
1024 |
else if (csa->crash == USE_INI_BASIS)
|
alpar@1
|
1025 |
{ ret = glp_read_sol(csa->prob, csa->ini_file);
|
alpar@1
|
1026 |
if (ret != 0)
|
alpar@1
|
1027 |
{ xprintf("Unable to read initial basis\n");
|
alpar@1
|
1028 |
ret = EXIT_FAILURE;
|
alpar@1
|
1029 |
goto done;
|
alpar@1
|
1030 |
}
|
alpar@1
|
1031 |
}
|
alpar@1
|
1032 |
else
|
alpar@1
|
1033 |
xassert(csa != csa);
|
alpar@1
|
1034 |
}
|
alpar@1
|
1035 |
/*--------------------------------------------------------------*/
|
alpar@1
|
1036 |
/* solve the problem */
|
alpar@1
|
1037 |
start = xtime();
|
alpar@1
|
1038 |
if (csa->solution == SOL_BASIC)
|
alpar@1
|
1039 |
{ if (!csa->exact)
|
alpar@1
|
1040 |
{ glp_set_bfcp(csa->prob, &csa->bfcp);
|
alpar@1
|
1041 |
glp_simplex(csa->prob, &csa->smcp);
|
alpar@1
|
1042 |
if (csa->xcheck)
|
alpar@1
|
1043 |
{ if (csa->smcp.presolve &&
|
alpar@1
|
1044 |
glp_get_status(csa->prob) != GLP_OPT)
|
alpar@1
|
1045 |
xprintf("If you need to check final basis for non-opt"
|
alpar@1
|
1046 |
"imal solution, use --nopresol\n");
|
alpar@1
|
1047 |
else
|
alpar@1
|
1048 |
glp_exact(csa->prob, &csa->smcp);
|
alpar@1
|
1049 |
}
|
alpar@1
|
1050 |
if (csa->out_sol != NULL || csa->out_res != NULL)
|
alpar@1
|
1051 |
{ if (csa->smcp.presolve &&
|
alpar@1
|
1052 |
glp_get_status(csa->prob) != GLP_OPT)
|
alpar@1
|
1053 |
xprintf("If you need actual output for non-optimal solut"
|
alpar@1
|
1054 |
"ion, use --nopresol\n");
|
alpar@1
|
1055 |
}
|
alpar@1
|
1056 |
}
|
alpar@1
|
1057 |
else
|
alpar@1
|
1058 |
glp_exact(csa->prob, &csa->smcp);
|
alpar@1
|
1059 |
}
|
alpar@1
|
1060 |
else if (csa->solution == SOL_INTERIOR)
|
alpar@1
|
1061 |
glp_interior(csa->prob, &csa->iptcp);
|
alpar@1
|
1062 |
else if (csa->solution == SOL_INTEGER)
|
alpar@1
|
1063 |
{ if (!csa->iocp.presolve)
|
alpar@1
|
1064 |
{ glp_set_bfcp(csa->prob, &csa->bfcp);
|
alpar@1
|
1065 |
glp_simplex(csa->prob, &csa->smcp);
|
alpar@1
|
1066 |
}
|
alpar@1
|
1067 |
#if 0
|
alpar@1
|
1068 |
csa->iocp.msg_lev = GLP_MSG_DBG;
|
alpar@1
|
1069 |
csa->iocp.pp_tech = GLP_PP_NONE;
|
alpar@1
|
1070 |
#endif
|
alpar@1
|
1071 |
glp_intopt(csa->prob, &csa->iocp);
|
alpar@1
|
1072 |
}
|
alpar@1
|
1073 |
else
|
alpar@1
|
1074 |
xassert(csa != csa);
|
alpar@1
|
1075 |
/*--------------------------------------------------------------*/
|
alpar@1
|
1076 |
/* display statistics */
|
alpar@1
|
1077 |
xprintf("Time used: %.1f secs\n", xdifftime(xtime(), start));
|
alpar@1
|
1078 |
{ glp_long tpeak;
|
alpar@1
|
1079 |
char buf[50];
|
alpar@1
|
1080 |
glp_mem_usage(NULL, NULL, NULL, &tpeak);
|
alpar@1
|
1081 |
xprintf("Memory used: %.1f Mb (%s bytes)\n",
|
alpar@1
|
1082 |
xltod(tpeak) / 1048576.0, xltoa(tpeak, buf));
|
alpar@1
|
1083 |
}
|
alpar@1
|
1084 |
/*--------------------------------------------------------------*/
|
alpar@1
|
1085 |
skip: /* postsolve the model, if necessary */
|
alpar@1
|
1086 |
if (csa->tran != NULL)
|
alpar@1
|
1087 |
{ if (csa->solution == SOL_BASIC)
|
alpar@1
|
1088 |
ret = glp_mpl_postsolve(csa->tran, csa->prob, GLP_SOL);
|
alpar@1
|
1089 |
else if (csa->solution == SOL_INTERIOR)
|
alpar@1
|
1090 |
ret = glp_mpl_postsolve(csa->tran, csa->prob, GLP_IPT);
|
alpar@1
|
1091 |
else if (csa->solution == SOL_INTEGER)
|
alpar@1
|
1092 |
ret = glp_mpl_postsolve(csa->tran, csa->prob, GLP_MIP);
|
alpar@1
|
1093 |
else
|
alpar@1
|
1094 |
xassert(csa != csa);
|
alpar@1
|
1095 |
if (ret != 0)
|
alpar@1
|
1096 |
{ xprintf("Model postsolving error\n");
|
alpar@1
|
1097 |
ret = EXIT_FAILURE;
|
alpar@1
|
1098 |
goto done;
|
alpar@1
|
1099 |
}
|
alpar@1
|
1100 |
}
|
alpar@1
|
1101 |
/*--------------------------------------------------------------*/
|
alpar@1
|
1102 |
/* write problem solution in printable format, if required */
|
alpar@1
|
1103 |
if (csa->out_sol != NULL)
|
alpar@1
|
1104 |
{ if (csa->solution == SOL_BASIC)
|
alpar@1
|
1105 |
ret = lpx_print_sol(csa->prob, csa->out_sol);
|
alpar@1
|
1106 |
else if (csa->solution == SOL_INTERIOR)
|
alpar@1
|
1107 |
ret = lpx_print_ips(csa->prob, csa->out_sol);
|
alpar@1
|
1108 |
else if (csa->solution == SOL_INTEGER)
|
alpar@1
|
1109 |
ret = lpx_print_mip(csa->prob, csa->out_sol);
|
alpar@1
|
1110 |
else
|
alpar@1
|
1111 |
xassert(csa != csa);
|
alpar@1
|
1112 |
if (ret != 0)
|
alpar@1
|
1113 |
{ xprintf("Unable to write problem solution\n");
|
alpar@1
|
1114 |
ret = EXIT_FAILURE;
|
alpar@1
|
1115 |
goto done;
|
alpar@1
|
1116 |
}
|
alpar@1
|
1117 |
}
|
alpar@1
|
1118 |
/* write problem solution in printable format, if required */
|
alpar@1
|
1119 |
if (csa->out_res != NULL)
|
alpar@1
|
1120 |
{ if (csa->solution == SOL_BASIC)
|
alpar@1
|
1121 |
ret = glp_write_sol(csa->prob, csa->out_res);
|
alpar@1
|
1122 |
else if (csa->solution == SOL_INTERIOR)
|
alpar@1
|
1123 |
ret = glp_write_ipt(csa->prob, csa->out_res);
|
alpar@1
|
1124 |
else if (csa->solution == SOL_INTEGER)
|
alpar@1
|
1125 |
ret = glp_write_mip(csa->prob, csa->out_res);
|
alpar@1
|
1126 |
else
|
alpar@1
|
1127 |
xassert(csa != csa);
|
alpar@1
|
1128 |
if (ret != 0)
|
alpar@1
|
1129 |
{ xprintf("Unable to write problem solution\n");
|
alpar@1
|
1130 |
ret = EXIT_FAILURE;
|
alpar@1
|
1131 |
goto done;
|
alpar@1
|
1132 |
}
|
alpar@1
|
1133 |
}
|
alpar@1
|
1134 |
/* write sensitivity analysis report, if required */
|
alpar@1
|
1135 |
if (csa->out_ranges != NULL)
|
alpar@1
|
1136 |
{ if (csa->solution == SOL_BASIC)
|
alpar@1
|
1137 |
{ if (glp_get_status(csa->prob) == GLP_OPT)
|
alpar@1
|
1138 |
{ if (glp_bf_exists(csa->prob))
|
alpar@1
|
1139 |
ranges: { ret = glp_print_ranges(csa->prob, 0, NULL, 0,
|
alpar@1
|
1140 |
csa->out_ranges);
|
alpar@1
|
1141 |
if (ret != 0)
|
alpar@1
|
1142 |
{ xprintf("Unable to write sensitivity analysis repo"
|
alpar@1
|
1143 |
"rt\n");
|
alpar@1
|
1144 |
ret = EXIT_FAILURE;
|
alpar@1
|
1145 |
goto done;
|
alpar@1
|
1146 |
}
|
alpar@1
|
1147 |
}
|
alpar@1
|
1148 |
else
|
alpar@1
|
1149 |
{ ret = glp_factorize(csa->prob);
|
alpar@1
|
1150 |
if (ret == 0) goto ranges;
|
alpar@1
|
1151 |
xprintf("Cannot produce sensitivity analysis report d"
|
alpar@1
|
1152 |
"ue to error in basis factorization (glp_factorize"
|
alpar@1
|
1153 |
" returned %d); try --nopresol\n", ret);
|
alpar@1
|
1154 |
}
|
alpar@1
|
1155 |
}
|
alpar@1
|
1156 |
else
|
alpar@1
|
1157 |
xprintf("Cannot produce sensitivity analysis report for "
|
alpar@1
|
1158 |
"non-optimal basic solution\n");
|
alpar@1
|
1159 |
}
|
alpar@1
|
1160 |
else
|
alpar@1
|
1161 |
xprintf("Cannot produce sensitivity analysis report for int"
|
alpar@1
|
1162 |
"erior-point or MIP solution\n");
|
alpar@1
|
1163 |
}
|
alpar@1
|
1164 |
/*--------------------------------------------------------------*/
|
alpar@1
|
1165 |
/* all seems to be ok */
|
alpar@1
|
1166 |
ret = EXIT_SUCCESS;
|
alpar@1
|
1167 |
/*--------------------------------------------------------------*/
|
alpar@1
|
1168 |
done: /* delete the LP/MIP problem object */
|
alpar@1
|
1169 |
if (csa->prob != NULL)
|
alpar@1
|
1170 |
glp_delete_prob(csa->prob);
|
alpar@1
|
1171 |
/* free the translator workspace, if necessary */
|
alpar@1
|
1172 |
if (csa->tran != NULL)
|
alpar@1
|
1173 |
glp_mpl_free_wksp(csa->tran);
|
alpar@1
|
1174 |
/* delete the network problem object, if necessary */
|
alpar@1
|
1175 |
if (csa->graph != NULL)
|
alpar@1
|
1176 |
glp_delete_graph(csa->graph);
|
alpar@1
|
1177 |
xassert(gmp_pool_count() == 0);
|
alpar@1
|
1178 |
gmp_free_mem();
|
alpar@1
|
1179 |
/* close log file, if necessary */
|
alpar@1
|
1180 |
if (csa->log_file != NULL) glp_close_tee();
|
alpar@1
|
1181 |
/* check that no memory blocks are still allocated */
|
alpar@1
|
1182 |
{ int count;
|
alpar@1
|
1183 |
glp_long total;
|
alpar@1
|
1184 |
glp_mem_usage(&count, NULL, &total, NULL);
|
alpar@1
|
1185 |
if (count != 0)
|
alpar@1
|
1186 |
xerror("Error: %d memory block(s) were lost\n", count);
|
alpar@1
|
1187 |
xassert(count == 0);
|
alpar@1
|
1188 |
xassert(total.lo == 0 && total.hi == 0);
|
alpar@1
|
1189 |
}
|
alpar@1
|
1190 |
/* free the GLPK environment */
|
alpar@1
|
1191 |
glp_free_env();
|
alpar@1
|
1192 |
/* return to the control program */
|
alpar@1
|
1193 |
return ret;
|
alpar@1
|
1194 |
}
|
alpar@1
|
1195 |
|
alpar@1
|
1196 |
/* eof */
|