1 /* glpapi19.c (stand-alone LP/MIP solver) */
3 /***********************************************************************
4 * This code is part of GLPK (GNU Linear Programming Kit).
6 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
7 * 2009, 2010 Andrew Makhorin, Department for Applied Informatics,
8 * Moscow Aviation Institute, Moscow, Russia. All rights reserved.
9 * E-mail: <mao@gnu.org>.
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.
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.
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 ***********************************************************************/
29 { /* common storage area */
31 /* LP/MIP problem object */
33 /* basis factorization control parameters */
35 /* simplex method control parameters */
37 /* interior-point method control parameters */
39 /* integer optimizer control parameters */
41 /* model translator workspace */
43 /* network problem object */
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 */
54 /* name of input problem file */
56 /* maximal number of input data files */
58 /* number of input data files specified */
59 const char *in_data[1+DATA_MAX];
60 /* name(s) of input data file(s) */
62 /* name of output file to send display output; NULL means the
63 display output is sent to the terminal */
65 /* seed value to be passed to the MathProg translator; initially
66 set to 1; 0x80000000 means the value is omitted */
68 /* solution type flag: */
69 #define SOL_BASIC 1 /* basic */
70 #define SOL_INTERIOR 2 /* interior-point */
71 #define SOL_INTEGER 3 /* mixed integer */
73 /* name of input solution file in raw format */
75 /* optimization direction flag:
77 GLP_MIN - minimization
78 GLP_MAX - maximization */
80 /* automatic problem scaling flag */
82 /* name of output solution file in printable format */
84 /* name of output solution file in raw format */
85 const char *out_ranges;
86 /* name of output file to write sensitivity analysis report */
88 /* input data checking flag; no solution is performed */
90 /* new name to be assigned to the problem */
92 /* name of output problem file in fixed MPS format */
93 const char *out_freemps;
94 /* name of output problem file in free MPS format */
95 const char *out_cpxlp;
96 /* name of output problem file in CPLEX LP format */
98 /* name of output problem file in GLPK format */
100 /* name of output problem file in OPB format */
102 /* name of output problem file in normalized OPB format */
103 const char *log_file;
104 /* name of output file to hardcopy terminal output */
106 /* initial basis option: */
107 #define USE_STD_BASIS 1 /* use standard basis */
108 #define USE_ADV_BASIS 2 /* use advanced basis */
109 #define USE_CPX_BASIS 3 /* use Bixby's basis */
110 #define USE_INI_BASIS 4 /* use initial basis from ini_file */
111 const char *ini_file;
112 /* name of input file containing initial basis */
114 /* flag to use glp_exact rather than glp_simplex */
116 /* flag to check final basis with glp_exact */
118 /* flag to consider MIP as pure LP */
121 static void print_help(const char *my_name)
122 { /* print help information */
123 xprintf("Usage: %s [options...] filename\n", my_name);
125 xprintf("General options:\n");
126 xprintf(" --mps read LP/MIP problem in fixed MPS fo"
128 xprintf(" --freemps read LP/MIP problem in free MPS for"
130 xprintf(" --lp read LP/MIP problem in CPLEX LP for"
132 xprintf(" --glp read LP/MIP problem in GLPK format "
134 xprintf(" --math read LP/MIP model written in GNU Ma"
135 "thProg modeling\n");
136 xprintf(" language\n");
137 xprintf(" -m filename, --model filename\n");
138 xprintf(" read model section and optional dat"
140 xprintf(" filename (same as --math)\n");
141 xprintf(" -d filename, --data filename\n");
142 xprintf(" read data section from filename (fo"
143 "r --math only);\n");
144 xprintf(" if model file also has data section"
145 ", it is ignored\n");
146 xprintf(" -y filename, --display filename\n");
147 xprintf(" send display output to filename (fo"
148 "r --math only);\n");
149 xprintf(" by default the output is sent to te"
151 xprintf(" --seed value initialize pseudo-random number gen"
153 xprintf(" MathProg model with specified seed "
155 xprintf(" if seed value is ?, some random see"
157 xprintf(" --mincost read min-cost flow problem in DIMAC"
159 xprintf(" --maxflow read maximum flow problem in DIMACS"
161 xprintf(" --simplex use simplex method (default)\n");
162 xprintf(" --interior use interior point method (LP only)"
164 xprintf(" -r filename, --read filename\n");
165 xprintf(" read solution from filename rather "
166 "to find it with\n");
167 xprintf(" the solver\n");
168 xprintf(" --min minimization\n");
169 xprintf(" --max maximization\n");
170 xprintf(" --scale scale problem (default)\n");
171 xprintf(" --noscale do not scale problem\n");
172 xprintf(" -o filename, --output filename\n");
173 xprintf(" write solution to filename in print"
175 xprintf(" -w filename, --write filename\n");
176 xprintf(" write solution to filename in plain"
178 xprintf(" --ranges filename\n");
179 xprintf(" write sensitivity analysis report t"
181 xprintf(" printable format (simplex only)\n");
182 xprintf(" --tmlim nnn limit solution time to nnn seconds "
184 xprintf(" --memlim nnn limit available memory to nnn megab"
186 xprintf(" --check do not solve problem, check input d"
188 xprintf(" --name probname change problem name to probname\n");
189 xprintf(" --wmps filename write problem to filename in fixed "
191 xprintf(" --wfreemps filename\n");
192 xprintf(" write problem to filename in free M"
194 xprintf(" --wlp filename write problem to filename in CPLEX "
196 xprintf(" --wglp filename write problem to filename in GLPK f"
199 xprintf(" --wpb filename write problem to filename in OPB fo"
201 xprintf(" --wnpb filename write problem to filename in normal"
202 "ized OPB format\n");
204 xprintf(" --log filename write copy of terminal output to fi"
206 xprintf(" -h, --help display this help information and e"
208 xprintf(" -v, --version display program version and exit\n")
211 xprintf("LP basis factorization options:\n");
212 xprintf(" --luf LU + Forrest-Tomlin update\n");
213 xprintf(" (faster, less stable; default)\n");
214 xprintf(" --cbg LU + Schur complement + Bartels-Gol"
216 xprintf(" (slower, more stable)\n");
217 xprintf(" --cgr LU + Schur complement + Givens rota"
219 xprintf(" (slower, more stable)\n");
221 xprintf("Options specific to simplex solver:\n");
222 xprintf(" --primal use primal simplex (default)\n");
223 xprintf(" --dual use dual simplex\n");
224 xprintf(" --std use standard initial basis of all s"
226 xprintf(" --adv use advanced initial basis (default"
228 xprintf(" --bib use Bixby's initial basis\n");
229 xprintf(" --ini filename use as initial basis previously sav"
231 xprintf(" (disables LP presolver)\n");
232 xprintf(" --steep use steepest edge technique (defaul"
234 xprintf(" --nosteep use standard \"textbook\" pricing\n"
236 xprintf(" --relax use Harris' two-pass ratio test (de"
238 xprintf(" --norelax use standard \"textbook\" ratio tes"
240 xprintf(" --presol use presolver (default; assumes --s"
241 "cale and --adv)\n");
242 xprintf(" --nopresol do not use presolver\n");
243 xprintf(" --exact use simplex method based on exact a"
245 xprintf(" --xcheck check final basis using exact arith"
248 xprintf("Options specific to interior-point solver:\n");
249 xprintf(" --nord use natural (original) ordering\n");
250 xprintf(" --qmd use quotient minimum degree orderin"
252 xprintf(" --amd use approximate minimum degree orde"
254 xprintf(" --symamd use approximate minimum degree orde"
257 xprintf("Options specific to MIP solver:\n");
258 xprintf(" --nomip consider all integer variables as c"
260 xprintf(" (allows solving MIP as pure LP)\n");
261 xprintf(" --first branch on first integer variable\n")
263 xprintf(" --last branch on last integer variable\n");
264 xprintf(" --mostf branch on most fractional variable "
266 xprintf(" --drtom branch using heuristic by Driebeck "
268 xprintf(" (default)\n");
269 xprintf(" --pcost branch using hybrid pseudocost heur"
271 xprintf(" useful for hard instances)\n");
272 xprintf(" --dfs backtrack using depth first search "
274 xprintf(" --bfs backtrack using breadth first searc"
276 xprintf(" --bestp backtrack using the best projection"
278 xprintf(" --bestb backtrack using node with best loca"
280 xprintf(" (default)\n");
281 xprintf(" --intopt use MIP presolver (default)\n");
282 xprintf(" --nointopt do not use MIP presolver\n");
283 xprintf(" --binarize replace general integer variables b"
285 xprintf(" (assumes --intopt)\n");
286 xprintf(" --fpump apply feasibility pump heuristic\n")
288 xprintf(" --gomory generate Gomory's mixed integer cut"
290 xprintf(" --mir generate MIR (mixed integer roundin"
292 xprintf(" --cover generate mixed cover cuts\n");
293 xprintf(" --clique generate clique cuts\n");
294 xprintf(" --cuts generate all cuts above\n");
295 xprintf(" --mipgap tol set relative mip gap tolerance to t"
298 xprintf("For description of the MPS and CPLEX LP formats see Refe"
300 xprintf("For description of the modeling language see \"GLPK: Mod"
302 xprintf("GNU MathProg\". Both documents are included in the GLPK "
305 xprintf("See GLPK web page at <http://www.gnu.org/software/glpk/g"
308 xprintf("Please report bugs to <bug-glpk@gnu.org>.\n");
312 static void print_version(int briefly)
313 { /* print version information */
314 xprintf("GLPSOL: GLPK LP/MIP Solver, v%s\n", glp_version());
315 if (briefly) goto done;
317 xprintf("Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, "
319 xprintf("2009, 2010 Andrew Makhorin, Department for Applied Infor"
321 xprintf("Aviation Institute, Moscow, Russia. All rights reserved."
324 xprintf("This program has ABSOLUTELY NO WARRANTY.\n");
326 xprintf("This program is free software; you may re-distribute it "
327 "under the terms\n");
328 xprintf("of the GNU General Public License version 3 or later.\n")
333 static int parse_cmdline(struct csa *csa, int argc, const char *argv[])
334 { /* parse command-line parameters */
336 #define p(str) (strcmp(argv[k], str) == 0)
337 for (k = 1; k < argc; k++)
339 csa->format = FMT_MPS_DECK;
340 else if (p("--freemps"))
341 csa->format = FMT_MPS_FILE;
342 else if (p("--lp") || p("--cpxlp"))
343 csa->format = FMT_LP;
345 csa->format = FMT_GLP;
346 else if (p("--math") || p("-m") || p("--model"))
347 csa->format = FMT_MATHPROG;
348 else if (p("-d") || p("--data"))
350 if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
351 { xprintf("No input data file specified\n");
354 if (csa->ndf == DATA_MAX)
355 { xprintf("Too many input data files\n");
358 csa->in_data[++(csa->ndf)] = argv[k];
360 else if (p("-y") || p("--display"))
362 if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
363 { xprintf("No display output file specified\n");
366 if (csa->out_dpy != NULL)
367 { xprintf("Only one display output file allowed\n");
370 csa->out_dpy = argv[k];
372 else if (p("--seed"))
374 if (k == argc || argv[k][0] == '\0' ||
375 argv[k][0] == '-' && !isdigit((unsigned char)argv[k][1]))
376 { xprintf("No seed value specified\n");
379 if (strcmp(argv[k], "?") == 0)
380 csa->seed = 0x80000000;
381 else if (str2int(argv[k], &csa->seed))
382 { xprintf("Invalid seed value `%s'\n", argv[k]);
386 else if (p("--mincost"))
387 csa->format = FMT_MIN_COST;
388 else if (p("--maxflow"))
389 csa->format = FMT_MAX_FLOW;
390 else if (p("--simplex"))
391 csa->solution = SOL_BASIC;
392 else if (p("--interior"))
393 csa->solution = SOL_INTERIOR;
394 #if 1 /* 28/V-2010 */
395 else if (p("--alien"))
396 csa->iocp.alien = GLP_ON;
398 else if (p("-r") || p("--read"))
400 if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
401 { xprintf("No input solution file specified\n");
404 if (csa->in_res != NULL)
405 { xprintf("Only one input solution file allowed\n");
408 csa->in_res = argv[k];
414 else if (p("--scale"))
416 else if (p("--noscale"))
418 else if (p("-o") || p("--output"))
420 if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
421 { xprintf("No output solution file specified\n");
424 if (csa->out_sol != NULL)
425 { xprintf("Only one output solution file allowed\n");
428 csa->out_sol = argv[k];
430 else if (p("-w") || p("--write"))
432 if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
433 { xprintf("No output solution file specified\n");
436 if (csa->out_res != NULL)
437 { xprintf("Only one output solution file allowed\n");
440 csa->out_res = argv[k];
442 else if (p("--ranges") || p("--bounds"))
444 if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
445 { xprintf("No output file specified to write sensitivity a"
449 if (csa->out_ranges != NULL)
450 { xprintf("Only one output file allowed to write sensitivi"
451 "ty analysis report\n");
454 csa->out_ranges = argv[k];
456 else if (p("--tmlim"))
459 if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
460 { xprintf("No time limit specified\n");
463 if (str2int(argv[k], &tm_lim) || tm_lim < 0)
464 { xprintf("Invalid time limit `%s'\n", argv[k]);
467 if (tm_lim <= INT_MAX / 1000)
468 csa->smcp.tm_lim = csa->iocp.tm_lim = 1000 * tm_lim;
470 csa->smcp.tm_lim = csa->iocp.tm_lim = INT_MAX;
472 else if (p("--memlim"))
475 if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
476 { xprintf("No memory limit specified\n");
479 if (str2int(argv[k], &mem_lim) || mem_lim < 1)
480 { xprintf("Invalid memory limit `%s'\n", argv[k]);
483 glp_mem_limit(mem_lim);
485 else if (p("--check"))
487 else if (p("--name"))
489 if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
490 { xprintf("No problem name specified\n");
493 if (csa->new_name != NULL)
494 { xprintf("Only one problem name allowed\n");
497 csa->new_name = argv[k];
499 else if (p("--wmps"))
501 if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
502 { xprintf("No fixed MPS output file specified\n");
505 if (csa->out_mps != NULL)
506 { xprintf("Only one fixed MPS output file allowed\n");
509 csa->out_mps = argv[k];
511 else if (p("--wfreemps"))
513 if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
514 { xprintf("No free MPS output file specified\n");
517 if (csa->out_freemps != NULL)
518 { xprintf("Only one free MPS output file allowed\n");
521 csa->out_freemps = argv[k];
523 else if (p("--wlp") || p("--wcpxlp") || p("--wlpt"))
525 if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
526 { xprintf("No CPLEX LP output file specified\n");
529 if (csa->out_cpxlp != NULL)
530 { xprintf("Only one CPLEX LP output file allowed\n");
533 csa->out_cpxlp = argv[k];
535 else if (p("--wglp"))
537 if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
538 { xprintf("No GLPK LP/MIP output file specified\n");
541 if (csa->out_glp != NULL)
542 { xprintf("Only one GLPK LP/MIP output file allowed\n");
545 csa->out_glp = argv[k];
549 if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
550 { xprintf("No problem output file specified\n");
553 if (csa->out_pb != NULL)
554 { xprintf("Only one OPB output file allowed\n");
557 csa->out_pb = argv[k];
559 else if (p("--wnpb"))
561 if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
562 { xprintf("No problem output file specified\n");
565 if (csa->out_npb != NULL)
566 { xprintf("Only one normalized OPB output file allowed\n");
569 csa->out_npb = argv[k];
573 if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
574 { xprintf("No log file specified\n");
577 if (csa->log_file != NULL)
578 { xprintf("Only one log file allowed\n");
581 csa->log_file = argv[k];
583 else if (p("-h") || p("--help"))
584 { print_help(argv[0]);
587 else if (p("-v") || p("--version"))
592 csa->bfcp.type = GLP_BF_FT;
594 csa->bfcp.type = GLP_BF_BG;
596 csa->bfcp.type = GLP_BF_GR;
597 else if (p("--primal"))
598 csa->smcp.meth = GLP_PRIMAL;
599 else if (p("--dual"))
600 csa->smcp.meth = GLP_DUAL;
602 csa->crash = USE_STD_BASIS;
604 csa->crash = USE_ADV_BASIS;
606 csa->crash = USE_CPX_BASIS;
608 { csa->crash = USE_INI_BASIS;
609 csa->smcp.presolve = GLP_OFF;
611 if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
612 { xprintf("No initial basis file specified\n");
615 if (csa->ini_file != NULL)
616 { xprintf("Only one initial basis file allowed\n");
619 csa->ini_file = argv[k];
621 else if (p("--steep"))
622 csa->smcp.pricing = GLP_PT_PSE;
623 else if (p("--nosteep"))
624 csa->smcp.pricing = GLP_PT_STD;
625 else if (p("--relax"))
626 csa->smcp.r_test = GLP_RT_HAR;
627 else if (p("--norelax"))
628 csa->smcp.r_test = GLP_RT_STD;
629 else if (p("--presol"))
630 csa->smcp.presolve = GLP_ON;
631 else if (p("--nopresol"))
632 csa->smcp.presolve = GLP_OFF;
633 else if (p("--exact"))
635 else if (p("--xcheck"))
637 else if (p("--nord"))
638 csa->iptcp.ord_alg = GLP_ORD_NONE;
640 csa->iptcp.ord_alg = GLP_ORD_QMD;
642 csa->iptcp.ord_alg = GLP_ORD_AMD;
643 else if (p("--symamd"))
644 csa->iptcp.ord_alg = GLP_ORD_SYMAMD;
645 else if (p("--nomip"))
647 else if (p("--first"))
648 csa->iocp.br_tech = GLP_BR_FFV;
649 else if (p("--last"))
650 csa->iocp.br_tech = GLP_BR_LFV;
651 else if (p("--drtom"))
652 csa->iocp.br_tech = GLP_BR_DTH;
653 else if (p("--mostf"))
654 csa->iocp.br_tech = GLP_BR_MFV;
655 else if (p("--pcost"))
656 csa->iocp.br_tech = GLP_BR_PCH;
658 csa->iocp.bt_tech = GLP_BT_DFS;
660 csa->iocp.bt_tech = GLP_BT_BFS;
661 else if (p("--bestp"))
662 csa->iocp.bt_tech = GLP_BT_BPH;
663 else if (p("--bestb"))
664 csa->iocp.bt_tech = GLP_BT_BLB;
665 else if (p("--intopt"))
666 csa->iocp.presolve = GLP_ON;
667 else if (p("--nointopt"))
668 csa->iocp.presolve = GLP_OFF;
669 else if (p("--binarize"))
670 csa->iocp.presolve = csa->iocp.binarize = GLP_ON;
671 else if (p("--fpump"))
672 csa->iocp.fp_heur = GLP_ON;
673 else if (p("--gomory"))
674 csa->iocp.gmi_cuts = GLP_ON;
676 csa->iocp.mir_cuts = GLP_ON;
677 else if (p("--cover"))
678 csa->iocp.cov_cuts = GLP_ON;
679 else if (p("--clique"))
680 csa->iocp.clq_cuts = GLP_ON;
681 else if (p("--cuts"))
682 csa->iocp.gmi_cuts = csa->iocp.mir_cuts =
683 csa->iocp.cov_cuts = csa->iocp.clq_cuts = GLP_ON;
684 else if (p("--mipgap"))
687 if (k == argc || argv[k][0] == '\0' || argv[k][0] == '-')
688 { xprintf("No relative gap tolerance specified\n");
691 if (str2num(argv[k], &mip_gap) || mip_gap < 0.0)
692 { xprintf("Invalid relative mip gap tolerance `%s'\n",
696 csa->iocp.mip_gap = mip_gap;
698 else if (argv[k][0] == '-' ||
699 (argv[k][0] == '-' && argv[k][1] == '-'))
700 { xprintf("Invalid option `%s'; try %s --help\n",
705 { if (csa->in_file != NULL)
706 { xprintf("Only one input problem file allowed\n");
709 csa->in_file = argv[k];
716 typedef struct { double rhs, pi; } v_data;
717 typedef struct { double low, cap, cost, x; } a_data;
719 int glp_main(int argc, const char *argv[])
720 { /* stand-alone LP/MIP solver */
721 struct csa _csa, *csa = &_csa;
724 /* perform initialization */
725 csa->prob = glp_create_prob();
726 glp_get_bfcp(csa->prob, &csa->bfcp);
727 glp_init_smcp(&csa->smcp);
728 csa->smcp.presolve = GLP_ON;
729 glp_init_iptcp(&csa->iptcp);
730 glp_init_iocp(&csa->iocp);
731 csa->iocp.presolve = GLP_ON;
734 csa->format = FMT_MPS_FILE;
739 csa->solution = SOL_BASIC;
745 csa->out_ranges = NULL;
747 csa->new_name = NULL;
749 csa->out_freemps = NULL;
750 csa->out_cpxlp = NULL;
754 csa->log_file = NULL;
755 csa->crash = USE_ADV_BASIS;
756 csa->ini_file = NULL;
760 /* parse command-line parameters */
761 ret = parse_cmdline(csa, argc, argv);
763 { ret = EXIT_SUCCESS;
767 { ret = EXIT_FAILURE;
770 /*--------------------------------------------------------------*/
771 /* remove all output files specified in the command line */
772 if (csa->out_dpy != NULL) remove(csa->out_dpy);
773 if (csa->out_sol != NULL) remove(csa->out_sol);
774 if (csa->out_res != NULL) remove(csa->out_res);
775 if (csa->out_ranges != NULL) remove(csa->out_ranges);
776 if (csa->out_mps != NULL) remove(csa->out_mps);
777 if (csa->out_freemps != NULL) remove(csa->out_freemps);
778 if (csa->out_cpxlp != NULL) remove(csa->out_cpxlp);
779 if (csa->out_glp != NULL) remove(csa->out_glp);
780 if (csa->out_pb != NULL) remove(csa->out_pb);
781 if (csa->out_npb != NULL) remove(csa->out_npb);
782 if (csa->log_file != NULL) remove(csa->log_file);
783 /*--------------------------------------------------------------*/
784 /* open log file, if required */
785 if (csa->log_file != NULL)
786 { if (glp_open_tee(csa->log_file))
787 { xprintf("Unable to create log file\n");
792 /*--------------------------------------------------------------*/
793 /* print version information */
795 /*--------------------------------------------------------------*/
796 /* print parameters specified in the command line */
798 { int k, len = INT_MAX;
799 xprintf("Parameter(s) specified in the command line:");
800 for (k = 1; k < argc; k++)
802 xprintf("\n"), len = 0;
803 xprintf(" %s", argv[k]);
804 len += 1 + strlen(argv[k]);
808 /*--------------------------------------------------------------*/
809 /* read problem data from the input file */
810 if (csa->in_file == NULL)
811 { xprintf("No input problem file specified; try %s --help\n",
816 if (csa->format == FMT_MPS_DECK)
817 { ret = glp_read_mps(csa->prob, GLP_MPS_DECK, NULL,
820 err1: { xprintf("MPS file processing error\n");
825 else if (csa->format == FMT_MPS_FILE)
826 { ret = glp_read_mps(csa->prob, GLP_MPS_FILE, NULL,
828 if (ret != 0) goto err1;
830 else if (csa->format == FMT_LP)
831 { ret = glp_read_lp(csa->prob, NULL, csa->in_file);
833 { xprintf("CPLEX LP file processing error\n");
838 else if (csa->format == FMT_GLP)
839 { ret = glp_read_prob(csa->prob, 0, csa->in_file);
841 { xprintf("GLPK LP/MIP file processing error\n");
846 else if (csa->format == FMT_MATHPROG)
848 /* allocate the translator workspace */
849 csa->tran = glp_mpl_alloc_wksp();
851 if (csa->seed == 0x80000000)
852 { csa->seed = glp_time().lo;
853 xprintf("Seed value %d will be used\n", csa->seed);
855 _glp_mpl_init_rand(csa->tran, csa->seed);
856 /* read model section and optional data section */
857 if (glp_mpl_read_model(csa->tran, csa->in_file, csa->ndf > 0))
858 err2: { xprintf("MathProg model processing error\n");
862 /* read optional data section(s), if necessary */
863 for (k = 1; k <= csa->ndf; k++)
864 { if (glp_mpl_read_data(csa->tran, csa->in_data[k]))
867 /* generate the model */
868 if (glp_mpl_generate(csa->tran, csa->out_dpy)) goto err2;
869 /* build the problem instance from the model */
870 glp_mpl_build_prob(csa->tran, csa->prob);
872 else if (csa->format == FMT_MIN_COST)
873 { csa->graph = glp_create_graph(sizeof(v_data), sizeof(a_data));
874 ret = glp_read_mincost(csa->graph, offsetof(v_data, rhs),
875 offsetof(a_data, low), offsetof(a_data, cap),
876 offsetof(a_data, cost), csa->in_file);
878 { xprintf("DIMACS file processing error\n");
882 glp_mincost_lp(csa->prob, csa->graph, GLP_ON,
883 offsetof(v_data, rhs), offsetof(a_data, low),
884 offsetof(a_data, cap), offsetof(a_data, cost));
885 glp_set_prob_name(csa->prob, csa->in_file);
887 else if (csa->format == FMT_MAX_FLOW)
889 csa->graph = glp_create_graph(sizeof(v_data), sizeof(a_data));
890 ret = glp_read_maxflow(csa->graph, &s, &t,
891 offsetof(a_data, cap), csa->in_file);
893 { xprintf("DIMACS file processing error\n");
897 glp_maxflow_lp(csa->prob, csa->graph, GLP_ON, s, t,
898 offsetof(a_data, cap));
899 glp_set_prob_name(csa->prob, csa->in_file);
903 /*--------------------------------------------------------------*/
904 /* change problem name, if required */
905 if (csa->new_name != NULL)
906 glp_set_prob_name(csa->prob, csa->new_name);
907 /* change optimization direction, if required */
909 glp_set_obj_dir(csa->prob, csa->dir);
910 /* sort elements of the constraint matrix */
911 glp_sort_matrix(csa->prob);
912 /*--------------------------------------------------------------*/
913 /* write problem data in fixed MPS format, if required */
914 if (csa->out_mps != NULL)
915 { ret = glp_write_mps(csa->prob, GLP_MPS_DECK, NULL,
918 { xprintf("Unable to write problem in fixed MPS format\n");
923 /* write problem data in free MPS format, if required */
924 if (csa->out_freemps != NULL)
925 { ret = glp_write_mps(csa->prob, GLP_MPS_FILE, NULL,
928 { xprintf("Unable to write problem in free MPS format\n");
933 /* write problem data in CPLEX LP format, if required */
934 if (csa->out_cpxlp != NULL)
935 { ret = glp_write_lp(csa->prob, NULL, csa->out_cpxlp);
937 { xprintf("Unable to write problem in CPLEX LP format\n");
942 /* write problem data in GLPK format, if required */
943 if (csa->out_glp != NULL)
944 { ret = glp_write_prob(csa->prob, 0, csa->out_glp);
946 { xprintf("Unable to write problem in GLPK format\n");
951 /* write problem data in OPB format, if required */
952 if (csa->out_pb != NULL)
953 { ret = lpx_write_pb(csa->prob, csa->out_pb, 0, 0);
955 { xprintf("Unable to write problem in OPB format\n");
960 /* write problem data in normalized OPB format, if required */
961 if (csa->out_npb != NULL)
962 { ret = lpx_write_pb(csa->prob, csa->out_npb, 1, 1);
965 "Unable to write problem in normalized OPB format\n");
970 /*--------------------------------------------------------------*/
971 /* if only problem data check is required, skip computations */
973 { ret = EXIT_SUCCESS;
976 /*--------------------------------------------------------------*/
977 /* determine the solution type */
979 glp_get_num_int(csa->prob) + glp_get_num_bin(csa->prob) > 0)
980 { if (csa->solution == SOL_INTERIOR)
981 { xprintf("Interior-point method is not able to solve MIP pro"
982 "blem; use --simplex\n");
986 csa->solution = SOL_INTEGER;
988 /*--------------------------------------------------------------*/
989 /* if solution is provided, read it and skip computations */
990 if (csa->in_res != NULL)
991 { if (csa->solution == SOL_BASIC)
992 ret = glp_read_sol(csa->prob, csa->in_res);
993 else if (csa->solution == SOL_INTERIOR)
994 ret = glp_read_ipt(csa->prob, csa->in_res);
995 else if (csa->solution == SOL_INTEGER)
996 ret = glp_read_mip(csa->prob, csa->in_res);
1000 { xprintf("Unable to read problem solution\n");
1006 /*--------------------------------------------------------------*/
1007 /* scale the problem data, if required */
1009 { if (csa->solution == SOL_BASIC && !csa->smcp.presolve ||
1010 csa->solution == SOL_INTERIOR ||
1011 csa->solution == SOL_INTEGER && !csa->iocp.presolve)
1012 glp_scale_prob(csa->prob, GLP_SF_AUTO);
1014 /*--------------------------------------------------------------*/
1015 /* construct starting LP basis */
1016 if (csa->solution == SOL_BASIC && !csa->smcp.presolve ||
1017 csa->solution == SOL_INTEGER && !csa->iocp.presolve)
1018 { if (csa->crash == USE_STD_BASIS)
1019 glp_std_basis(csa->prob);
1020 else if (csa->crash == USE_ADV_BASIS)
1021 glp_adv_basis(csa->prob, 0);
1022 else if (csa->crash == USE_CPX_BASIS)
1023 glp_cpx_basis(csa->prob);
1024 else if (csa->crash == USE_INI_BASIS)
1025 { ret = glp_read_sol(csa->prob, csa->ini_file);
1027 { xprintf("Unable to read initial basis\n");
1033 xassert(csa != csa);
1035 /*--------------------------------------------------------------*/
1036 /* solve the problem */
1038 if (csa->solution == SOL_BASIC)
1040 { glp_set_bfcp(csa->prob, &csa->bfcp);
1041 glp_simplex(csa->prob, &csa->smcp);
1043 { if (csa->smcp.presolve &&
1044 glp_get_status(csa->prob) != GLP_OPT)
1045 xprintf("If you need to check final basis for non-opt"
1046 "imal solution, use --nopresol\n");
1048 glp_exact(csa->prob, &csa->smcp);
1050 if (csa->out_sol != NULL || csa->out_res != NULL)
1051 { if (csa->smcp.presolve &&
1052 glp_get_status(csa->prob) != GLP_OPT)
1053 xprintf("If you need actual output for non-optimal solut"
1054 "ion, use --nopresol\n");
1058 glp_exact(csa->prob, &csa->smcp);
1060 else if (csa->solution == SOL_INTERIOR)
1061 glp_interior(csa->prob, &csa->iptcp);
1062 else if (csa->solution == SOL_INTEGER)
1063 { if (!csa->iocp.presolve)
1064 { glp_set_bfcp(csa->prob, &csa->bfcp);
1065 glp_simplex(csa->prob, &csa->smcp);
1068 csa->iocp.msg_lev = GLP_MSG_DBG;
1069 csa->iocp.pp_tech = GLP_PP_NONE;
1071 glp_intopt(csa->prob, &csa->iocp);
1074 xassert(csa != csa);
1075 /*--------------------------------------------------------------*/
1076 /* display statistics */
1077 xprintf("Time used: %.1f secs\n", xdifftime(xtime(), start));
1080 glp_mem_usage(NULL, NULL, NULL, &tpeak);
1081 xprintf("Memory used: %.1f Mb (%s bytes)\n",
1082 xltod(tpeak) / 1048576.0, xltoa(tpeak, buf));
1084 /*--------------------------------------------------------------*/
1085 skip: /* postsolve the model, if necessary */
1086 if (csa->tran != NULL)
1087 { if (csa->solution == SOL_BASIC)
1088 ret = glp_mpl_postsolve(csa->tran, csa->prob, GLP_SOL);
1089 else if (csa->solution == SOL_INTERIOR)
1090 ret = glp_mpl_postsolve(csa->tran, csa->prob, GLP_IPT);
1091 else if (csa->solution == SOL_INTEGER)
1092 ret = glp_mpl_postsolve(csa->tran, csa->prob, GLP_MIP);
1094 xassert(csa != csa);
1096 { xprintf("Model postsolving error\n");
1101 /*--------------------------------------------------------------*/
1102 /* write problem solution in printable format, if required */
1103 if (csa->out_sol != NULL)
1104 { if (csa->solution == SOL_BASIC)
1105 ret = lpx_print_sol(csa->prob, csa->out_sol);
1106 else if (csa->solution == SOL_INTERIOR)
1107 ret = lpx_print_ips(csa->prob, csa->out_sol);
1108 else if (csa->solution == SOL_INTEGER)
1109 ret = lpx_print_mip(csa->prob, csa->out_sol);
1111 xassert(csa != csa);
1113 { xprintf("Unable to write problem solution\n");
1118 /* write problem solution in printable format, if required */
1119 if (csa->out_res != NULL)
1120 { if (csa->solution == SOL_BASIC)
1121 ret = glp_write_sol(csa->prob, csa->out_res);
1122 else if (csa->solution == SOL_INTERIOR)
1123 ret = glp_write_ipt(csa->prob, csa->out_res);
1124 else if (csa->solution == SOL_INTEGER)
1125 ret = glp_write_mip(csa->prob, csa->out_res);
1127 xassert(csa != csa);
1129 { xprintf("Unable to write problem solution\n");
1134 /* write sensitivity analysis report, if required */
1135 if (csa->out_ranges != NULL)
1136 { if (csa->solution == SOL_BASIC)
1137 { if (glp_get_status(csa->prob) == GLP_OPT)
1138 { if (glp_bf_exists(csa->prob))
1139 ranges: { ret = glp_print_ranges(csa->prob, 0, NULL, 0,
1142 { xprintf("Unable to write sensitivity analysis repo"
1149 { ret = glp_factorize(csa->prob);
1150 if (ret == 0) goto ranges;
1151 xprintf("Cannot produce sensitivity analysis report d"
1152 "ue to error in basis factorization (glp_factorize"
1153 " returned %d); try --nopresol\n", ret);
1157 xprintf("Cannot produce sensitivity analysis report for "
1158 "non-optimal basic solution\n");
1161 xprintf("Cannot produce sensitivity analysis report for int"
1162 "erior-point or MIP solution\n");
1164 /*--------------------------------------------------------------*/
1165 /* all seems to be ok */
1167 /*--------------------------------------------------------------*/
1168 done: /* delete the LP/MIP problem object */
1169 if (csa->prob != NULL)
1170 glp_delete_prob(csa->prob);
1171 /* free the translator workspace, if necessary */
1172 if (csa->tran != NULL)
1173 glp_mpl_free_wksp(csa->tran);
1174 /* delete the network problem object, if necessary */
1175 if (csa->graph != NULL)
1176 glp_delete_graph(csa->graph);
1177 xassert(gmp_pool_count() == 0);
1179 /* close log file, if necessary */
1180 if (csa->log_file != NULL) glp_close_tee();
1181 /* check that no memory blocks are still allocated */
1184 glp_mem_usage(&count, NULL, &total, NULL);
1186 xerror("Error: %d memory block(s) were lost\n", count);
1187 xassert(count == 0);
1188 xassert(total.lo == 0 && total.hi == 0);
1190 /* free the GLPK environment */
1192 /* return to the control program */