lemon-project-template-glpk

annotate deps/glpk/src/glpapi21.c @ 11:4fc6ad2fb8a6

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