COIN-OR::LEMON - Graph Library

source: lemon-project-template-glpk/deps/glpk/src/glpapi21.c @ 10:5545663ca997

subpack-glpk
Last change on this file since 10:5545663ca997 was 9:33de93886c88, checked in by Alpar Juttner <alpar@…>, 13 years ago

Import GLPK 4.47

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