1 #include <string.h>
2 #include <time.h>
3 #include <signal.h>
4 #include <math.h>
5 #include <ctype.h>
6 #include "lp_lib.h"
7 
8 #ifdef FORTIFY
9 # include "lp_fortify.h"
10 #endif
11 
12 #define filetypeLP      1
13 #define filetypeMPS     2
14 #define filetypeFREEMPS 3
15 #define filetypeCPLEX   4
16 #define filetypeXLI     5
17 
18 #define FORCED_EXIT 255
19 
EndOfPgr(int i)20 int EndOfPgr(int i)
21 {
22 #   if defined FORTIFY
23       Fortify_LeaveScope();
24 #   endif
25     exit(i);
26     return(0);
27 }
28 
SIGABRT_func(int sig)29 void SIGABRT_func(int sig)
30  {
31    EndOfPgr(FORCED_EXIT);
32  }
33 
print_help(char * argv[])34 void print_help(char *argv[])
35 {
36   printf("Usage of %s version %d.%d.%d.%d:\n", argv[0], MAJORVERSION, MINORVERSION, RELEASE, BUILD);
37   printf("%s [options] [[<]input_file]\n", argv[0]);
38   printf("List of options:\n");
39   printf("-h\t\tprints this message\n");
40 #if defined PARSER_LP
41   printf("-lp\t\tread from LP file (default)\n");
42 #endif
43   printf("-mps\t\tread from MPS file, default in fixed format\n");
44   printf("-mps_free\t\tuse free format\n");
45   printf("-mps_ibm\t\tinterprete integers accoring to ibm format\n");
46   printf("-mps_negobjconst\tnegate objective constant\n");
47   printf("-fmps\t\tread from MPS file in free format\n");
48   printf("-rpar filename\tread parameters from filename.\n");
49   printf("-rparopt options\n\t\toptions for parameter file:\n");
50   printf("\t\t -H headername: header name for parameters. By default 'Default'\n");
51   printf("-rxli xliname filename\n\t\tread file with xli library\n");
52   printf("-rxlidata datafilename\n\t\tdata file name for xli library.\n");
53   printf("-rxliopt options\n\t\toptions for xli library.\n");
54   printf("-rbas filename\tread basis from filename.\n");
55   printf("-gbas filename\tguess basis with variables from filename.\n");
56   printf("-plp\t\tprint model.\n");
57   printf("-wlp filename\twrite to LP file\n");
58   printf("-wmps filename\twrite to MPS file in fixed format\n");
59   printf("-wfmps filename\twrite to MPS file in free format\n");
60   printf("-wxli xliname filename\n\t\twrite file with xli library\n");
61   printf("-wxliopt options\n\t\toptions for xli library.\n");
62   printf("-wxlisol xliname filename\n\t\twrite solution file with xli library\n");
63   printf("-wxlisolopt options\n\t\toptions for xli library.\n");
64   printf("-wbas filename\twrite basis to filename.\n");
65   printf("-wpar filename\twrite parameters to filename.\n");
66   printf("-wparopt options\n\t\toptions for parameter file:\n");
67   printf("\t\t -H headername: header name for parameters. By default 'Default'\n");
68   printf("-wafter\t\tWrite model after solve (useful if presolve used).\n");
69   printf("-parse_only\tparse input file but do not solve\n");
70   printf("-nonames\tIgnore variables and constraint names\n");
71   printf("-norownames\tIgnore constraint names\n");
72   printf("-nocolnames\tIgnore variable names\n");
73   printf("\n");
74   printf("-min\t\tMinimize the lp problem (overrules setting in file)\n");
75   printf("-max\t\tMaximize the lp problem (overrules setting in file)\n");
76   printf("-r <value>\tspecify max nbr of pivots between a re-inversion of the matrix\n");
77   printf("-piv <rule>\tspecify simplex pivot rule\n");
78   printf("\t -piv0: Select first\n");
79   printf("\t -piv1: Select according to Dantzig\n");
80   printf("\t -piv2: Select Devex pricing from Paula Harris (default)\n");
81   printf("\t -piv3: Select steepest edge\n");
82   printf("These pivot rules can be combined with any of the following:\n");
83   printf("-pivf\t\tIn case of Steepest Edge, fall back to DEVEX in primal.\n");
84   printf("-pivm\t\tMultiple pricing.\n");
85   printf("-piva\t\tTemporarily use First Index if cycling is detected.\n");
86   printf("-pivr\t\tAdds a small randomization effect to the selected pricer.\n");
87 #if defined EnablePartialOptimization
88   printf("-pivp\t\tEnable partial pricing.\n");
89   printf("-pivpc\t\tEnable partial pricing on columns.\n");
90   printf("-pivpr\t\tEnable partial pricing on rows.\n");
91 #endif
92   printf("-pivll\t\tScan entering/leaving columns left rather than right.\n");
93   printf("-pivla\t\tScan entering/leaving columns alternatingly left/right.\n");
94   printf("-pivh\t\tUse Harris' primal pivot logic rather than the default.\n");
95   printf("-pivt\t\tUse true norms for Devex and Steepest Edge initializations.\n");
96   printf("-o0\t\tDon't put objective in basis%s.\n", DEF_OBJINBASIS ? "" : " (default)");
97   printf("-o1\t\tPut objective in basis%s.\n", DEF_OBJINBASIS ? " (default)" : "");
98   printf("-s <mode> <scaleloop>\tuse automatic problem scaling.\n");
99   printf("\t -s0: No scaling\n");
100   printf("\t -s1: Geometric scaling (default)\n");
101   printf("\t -s2: Curtis-reid scaling\n");
102   printf("\t -s3: Scale to convergence using largest absolute value\n");
103   printf("\t  -s:\n");
104   printf("\t -s4: Numerical range-based scaling\n");
105   printf("\t -s5: Same as -s4 -sl\n");
106   printf("\t -s6: Scale based on the simple numerical range\n");
107   printf("\t -s7: Same as -s4 -sq\n");
108   printf("These scaling rules can be combined with any of the following:\n");
109   printf("\t -sp: also do power scaling.\n");
110   printf("\t -si: also do integer scaling (default).\n");
111   printf("\t -se: also do equilibration to scale to the -1..1 range (default).\n");
112   printf("\t -sq: also do quadratic scaling.\n");
113   printf("\t -sl: Scale to convergence using logarithmic mean of all values.\n");
114   printf("\t -sd: Dynamic update.\n");
115   printf("\t -sr: Scale only rows.\n");
116   printf("\t -sc: Scale only columns.\n");
117   printf("-presolve\tpresolve problem before start optimizing (rows+columns)\n");
118   printf("-presolverow\tpresolve problem before start optimizing (rows only)\n");
119   printf("-presolvecol\tpresolve problem before start optimizing (columns only)\n");
120   printf("-presolvel\talso eliminate linearly dependent rows\n");
121   printf("-presolves\talso convert constraints to SOSes (only SOS1 handled)\n");
122   printf("-presolver\tIf the phase 1 solution process finds that a constraint is\n\t\tredundant then this constraint is deleted\n");
123   printf("-presolvek\tSimplification of knapsack-type constraints through\n\t\taddition of an extra variable, which also helps bound the OF\n");
124   printf("-presolveq\tDirect substitution of one variable in 2-element equality\n\t\tconstraints; this requires changes to the constraint matrix\n");
125   printf("-presolvem\tMerge rows\n");
126   printf("-presolvefd\tCOLFIXDUAL\n");
127   printf("-presolvebnd\tPresolve bounds\n");
128   printf("-presolved\tPresolve duals\n");
129   printf("-presolvef\tIdentify implied free variables (releasing their expl. bounds)\n");
130   printf("-presolveslk\tIMPLIEDSLK\n");
131   printf("-presolveg\tReduce (tighten) coef. in integer models based on GCD argument\n");
132   printf("-presolveb\tAttempt to fix binary variables at one of their bounds\n");
133   printf("-presolvec\tAttempt to reduce coefficients in binary models\n");
134   printf("-presolverowd\tIdenfify and delete qualifying constraints that\n\t\tare dominated by others, also fixes variables at a bound\n");
135   printf("-presolvecold\tDeletes variables (mainly binary), that are dominated\n\t\tby others (only one can be non-zero)\n");
136   printf("-C <mode>\tbasis crash mode\n");
137   printf("\t -C0: No crash basis\n");
138   printf("\t -C2: Most feasible basis\n");
139   printf("\t -C3: Least degenerate basis\n");
140   printf("-prim\t\tPrefer the primal simplex for both phases.\n");
141   printf("-dual\t\tPrefer the dual simplex for both phases.\n");
142   printf("-simplexpp\tSet Phase1 Primal, Phase2 Primal.\n");
143   printf("-simplexdp\tSet Phase1 Dual, Phase2 Primal.\n");
144   printf("-simplexpd\tSet Phase1 Primal, Phase2 Dual.\n");
145   printf("-simplexdd\tSet Phase1 Dual, Phase2 Dual.\n");
146   printf("-degen\t\tuse perturbations to reduce degeneracy,\n\t\tcan increase numerical instability\n");
147   printf("-degenc\t\tuse column check to reduce degeneracy\n");
148   printf("-degend\t\tdynamic check to reduce degeneracy\n");
149   printf("-degenf\t\tanti-degen fixedvars\n");
150   printf("-degens\t\tanti-degen stalling\n");
151   printf("-degenn\t\tanti-degen numfailure\n");
152   printf("-degenl\t\tanti-degen lostfeas\n");
153   printf("-degeni\t\tanti-degen infeasible\n");
154   printf("-degenb\t\tanti-degen B&B\n");
155   printf("-degenr\t\tanti-degen Perturbation of the working RHS at refactorization\n");
156   printf("-degenp\t\tanti-degen Limit bound flips\n");
157   printf("-trej <Trej>\tset minimum pivot value\n");
158   printf("-epsd <epsd>\tset minimum tolerance for reduced costs\n");
159   printf("-epsb <epsb>\tset minimum tolerance for the RHS\n");
160   printf("-epsel <epsel>\tset tolerance for rounding values to zero\n");
161   printf("-epsp <epsp>\tset the value that is used as perturbation scalar for\n\t\tdegenerative problems\n");
162   printf("-improve <level>\titerative improvement level\n");
163   printf("\t -improve0: none\n");
164   printf("\t -improve1: Running accuracy measurement of solved equations on Bx=r\n");
165   printf("\t -improve2: Improve initial dual feasibility by bound flips (default)\n");
166   printf("\t -improve4: Low-cost accuracy monitoring in the dual\n");
167   printf("\t -improve8: check for primal/dual feasibility at the node level\n");
168   printf("-timeout <sec>\tTimeout after sec seconds when not solution found.\n");
169   printf("-ac <accuracy>\tFail when accuracy is less then specified value.\n");
170 /*
171   printf("-timeoutok\tIf timeout, take the best yet found solution.\n");
172 */
173   printf("-bfp <filename>\tSet basis factorization package.\n");
174   printf("\n");
175   printf("-noint\t\tIgnore integer restrictions\n");
176   printf("-e <number>\tspecifies the tolerance which is used to determine whether a\n\t\tfloating point number is in fact an integer.\n\t\tShould be < 0.5\n");
177   printf("-g <number>\n");
178   printf("-ga <number>\tspecifies the absolute MIP gap for branch-and-bound.\n\t\tThis specifies the absolute allowed tolerance\n\t\ton the object function. Can result in faster solving times.\n");
179   printf("-gr <number>\tspecifies the relative MIP gap for branch-and-bound.\n\t\tThis specifies the relative allowed tolerance\n\t\ton the object function. Can result in faster solving times.\n");
180   printf("-f\t\tspecifies that branch-and-bound algorithm stops at first found\n");
181   printf("\t\tsolution\n");
182   printf("-b <bound>\tspecify a lower bound for the objective function\n\t\tto the program. If close enough, may speed up the\n\t\tcalculations.\n");
183   printf("-o <value>\tspecifies that branch-and-bound algorithm stops when objective\n");
184   printf("\t\tvalue is better than value\n");
185   printf("-c\n");
186   printf("-cc\t\tduring branch-and-bound, take the ceiling branch first\n");
187   printf("-cf\t\tduring branch-and-bound, take the floor branch first\n");
188   printf("-ca\t\tduring branch-and-bound, the algorithm chooses branch\n");
189   printf("-depth <limit>\tset branch-and-bound depth limit\n");
190   printf("-n <solnr>\tspecify which solution number to return\n");
191   printf("-B <rule>\tspecify branch-and-bound rule\n");
192   printf("\t -B0: Select Lowest indexed non-integer column (default)\n");
193   printf("\t -B1: Selection based on distance from the current bounds\n");
194   printf("\t -B2: Selection based on the largest current bound\n");
195   printf("\t -B3: Selection based on largest fractional value\n");
196   printf("\t -B4: Simple, unweighted pseudo-cost of a variable\n");
197   printf("\t -B5: This is an extended pseudo-costing strategy based on minimizing\n\t      the number of integer infeasibilities\n");
198   printf("\t -B6: This is an extended pseudo-costing strategy based on maximizing\n\t      the normal pseudo-cost divided by the number of infeasibilities.\n\t      Similar to (the reciprocal of) a cost/benefit ratio\n");
199   printf("These branch-and-bound rules can be combined with any of the following:\n");
200   printf("-Bw\t\tWeightReverse branch-and-bound\n");
201   printf("-Bb\t\tBranchReverse branch-and-bound\n");
202   printf("-Bg\t\tGreedy branch-and-bound\n");
203   printf("-Bp\t\tPseudoCost branch-and-bound\n");
204   printf("-BR\t\tExtended PseudoCost branch-and-bound\n");
205   printf("-Bf\t\tDepthFirst branch-and-bound\n");
206   printf("-Br\t\tRandomize branch-and-bound\n");
207   printf("-BG\t\tGubMode branch-and-bound\n");
208   printf("-Bd\t\tDynamic branch-and-bound\n");
209   printf("-Bs\t\tRestartMode branch-and-bound\n");
210   printf("-BB\t\tBreadthFirst branch-and-bound\n");
211   printf("-Bo\t\tOrder variables to improve branch-and-bound performance\n");
212   printf("-Bc\t\tDo bound tightening during B&B based of reduced cost info\n");
213   printf("-Bi\t\tInitialize pseudo-costs by strong branching\n");
214   printf("\n");
215   printf("-time\t\tPrint CPU time to parse input and to calculate result.\n");
216   printf("-v <level>\tverbose mode, gives flow through the program.\n");
217   printf("\t\t if level not provided (-v) then -v4 (NORMAL) is taken.\n");
218   printf("\t -v0: NEUTRAL\n");
219   printf("\t -v1: CRITICAL\n");
220   printf("\t -v2: SEVERE\n");
221   printf("\t -v3: IMPORTANT (default)\n");
222   printf("\t -v4: NORMAL\n");
223   printf("\t -v5: DETAILED\n");
224   printf("\t -v6: FULL\n");
225   printf("-t\t\ttrace pivot selection\n");
226   printf("-d\t\tdebug mode, all intermediate results are printed,\n\t\tand the branch-and-bound decisions\n");
227   printf("-R\t\treport information while solving the model\n");
228   printf("-Db <filename>\tDo a generic readable data dump of key lp_solve model variables\n\t\tbefore solve.\n\t\tPrincipally for run difference and debugging purposes\n");
229   printf("-Da <filename>\tDo a generic readable data dump of key lp_solve model variables\n\t\tafter solve.\n\t\tPrincipally for run difference and debugging purposes\n");
230   printf("-i\t\tprint all intermediate valid solutions.\n\t\tCan give you useful solutions even if the total run time\n\t\tis too long\n");
231   printf("-ia\t\tprint all intermediate (only non-zero values) valid solutions.\n\t\tCan give you useful solutions even if the total run time\n\t\tis too long\n");
232   printf("-stat\t\tPrint model statistics\n");
233   printf("-S <detail>\tPrint solution. If detail omitted, then -S2 is used.\n");
234   printf("\t -S0: Print nothing\n");
235   printf("\t -S1: Only objective value\n");
236   printf("\t -S2: Obj value+variables (default)\n");
237   printf("\t -S3: Obj value+variables+constraints\n");
238   printf("\t -S4: Obj value+variables+constraints+duals\n");
239   printf("\t -S5: Obj value+variables+constraints+duals+lp model\n");
240   printf("\t -S6: Obj value+variables+constraints+duals+lp model+scales\n");
241   printf("\t -S7: Obj value+variables+constraints+duals+lp model+scales+lp tableau\n");
242 }
243 
print_cpu_times(const char * info)244 void print_cpu_times(const char *info)
245 {
246   static clock_t last_time = 0;
247   clock_t new_time;
248 
249   new_time = clock();
250   fprintf(stderr, "CPU Time for %s: %gs (%gs total since program start)\n",
251           info, (new_time - last_time) / (double) CLOCKS_PER_SEC,
252           new_time / (double) CLOCKS_PER_SEC);
253   last_time = new_time;
254 }
255 
256 #if 0
257 int myabortfunc(lprec *lp, void *aborthandle)
258 {
259   /* printf("%f\n",lp->rhs[0]*(lp->maximise ? 1 : -1)); */
260   return(0);
261 }
262 #endif
263 
isNum(char * val)264 static MYBOOL isNum(char *val)
265 {
266   int ord;
267   char *pointer;
268 
269   ord = strtol(val, &pointer, 10);
270   return(*pointer == 0);
271 }
272 
DoReport(lprec * lp,char * str)273 static void DoReport(lprec *lp, char *str)
274 {
275   fprintf(stderr, "%s %6.1fsec %8g\n", str, time_elapsed(lp), get_working_objective(lp));
276 }
277 
LPMessageCB(lprec * lp,void * USERHANDLE,int msg)278 static void __WINAPI LPMessageCB(lprec *lp, void *USERHANDLE, int msg)
279 {
280   if(msg==MSG_LPFEASIBLE)
281     DoReport(lp, "Feasible solution ");
282   else if(msg==MSG_LPOPTIMAL)
283     DoReport(lp, "Real solution ");
284   else if(msg==MSG_MILPFEASIBLE)
285     DoReport(lp, "First MILP    ");
286   else if(msg==MSG_MILPBETTER)
287     DoReport(lp, "Improved MILP ");
288 }
289 
write_model(lprec * lp,char plp,char * wlp,char * wmps,char * wfmps,char * wxli,char * wxlisol,char * wxliname,char * wxlioptions)290 void write_model(lprec *lp, char plp, char *wlp, char *wmps, char *wfmps, char *wxli, char *wxlisol, char *wxliname, char *wxlioptions)
291 {
292   if(plp)
293     print_lp(lp);
294 
295   if(wlp != NULL)
296     write_lp(lp, wlp);
297 
298   if(wmps != NULL)
299     write_mps(lp, wmps);
300 
301   if(wfmps != NULL)
302     write_freemps(lp, wfmps);
303 
304   if((wxliname != NULL) && (wxli != NULL)) {
305     if(!set_XLI(lp, wxliname)) {
306       fprintf(stderr, "Unable to set XLI library (%s).\n", wxliname);
307       EndOfPgr(FORCED_EXIT);
308     }
309     write_XLI(lp, wxli, wxlioptions, FALSE);
310     set_XLI(lp, NULL);
311   }
312 
313   if((wxliname != NULL) && (wxlisol != NULL)) {
314     if(!set_XLI(lp, wxliname)) {
315       fprintf(stderr, "Unable to set XLI library (%s).\n", wxliname);
316       EndOfPgr(FORCED_EXIT);
317     }
318     write_XLI(lp, wxlisol, wxlioptions, TRUE);
319     set_XLI(lp, NULL);
320   }
321 }
322 
or_value(int * value,int orvalue)323 static void or_value(int *value, int orvalue)
324 {
325   if(*value == -1)
326     *value = 0;
327   *value |= orvalue;
328 }
329 
set_value(int * value,int orvalue)330 static void set_value(int *value, int orvalue)
331 {
332   *value = orvalue;
333 }
334 
335 #define nstats 5
336 
minmax1(REAL value0,REAL factor,REAL * minmax,int * nminmax,int row,int * rowminmax,int col,int * colminmax)337 static void minmax1(REAL value0, REAL factor, REAL *minmax, int *nminmax, int row, int *rowminmax, int col, int *colminmax)
338 {
339   int i, n;
340   REAL value;
341 
342   if (value0 == 0)
343     return;
344   value = fabs(value0) * factor;
345   for (i = 0; (i < *nminmax) && (value <= fabs(minmax[i]) * factor); i++)
346     if (value == fabs(minmax[i]) * factor)
347       return;
348   if (i >= nstats)
349     return;
350   n = *nminmax;
351   if (n == nstats)
352     n--;
353   memmove(minmax + i + 1, minmax + i, (n - i) * sizeof(*minmax));
354   minmax[i] = value0;
355   if (rowminmax != NULL) {
356     memmove(rowminmax + i + 1, rowminmax + i, (n - i) * sizeof(*rowminmax));
357     rowminmax[i] = row;
358   }
359   if (colminmax != NULL) {
360     memmove(colminmax + i + 1, colminmax + i, (n - i) * sizeof(*colminmax));
361     colminmax[i] = col;
362   }
363   if (*nminmax < nstats)
364     (*nminmax)++;
365 }
366 
minmax(REAL value,REAL * minima,REAL * maxima,int * nminima,int * nmaxima,int row,int * rowmin,int * rowmax,int col,int * colmin,int * colmax)367 static void minmax(REAL value, REAL *minima, REAL *maxima, int *nminima, int *nmaxima, int row, int *rowmin, int *rowmax, int col, int *colmin, int *colmax)
368 {
369   minmax1(value, -1.0, minima, nminima, row, rowmin, col, colmin);
370   minmax1(value, +1.0, maxima, nmaxima, row, rowmax, col, colmax);
371 }
372 
373 /*
374 static void printminmax1(lprec *lp, char *s, REAL *minmax, int nminmax, int *rowminmax, int *colminmax)
375 {
376   int i;
377 
378   for (i = 0; i < nminmax; i++) {
379     printf(" %s(", s);
380     if (rowminmax != NULL)
381       printf("%s", get_row_name(lp, rowminmax[i]));
382     if ((rowminmax != NULL) && (colminmax != NULL))
383       printf(", ");
384     if (colminmax != NULL)
385       printf("%s", get_col_name(lp, colminmax[i]));
386     printf(") = %.8f\n", minmax[i]);
387   }
388 }
389 
390 static void printminmax(lprec *lp, char *s, REAL *minima, REAL *maxima, int nminima, int nmaxima, int *rowmin, int *rowmax, int *colmin, int *colmax)
391 {
392   printf("Minima:\n");
393   printminmax1(lp, s, minima, nminima, rowmin, colmin);
394   printf("Maxima:\n");
395   printminmax1(lp, s, maxima, nmaxima, rowmax, colmax);
396 }
397 */
398 
printminmax(lprec * lp,char * s,REAL * minima,REAL * maxima,int nminima,int nmaxima,int * rowmin,int * rowmax,int * colmin,int * colmax)399 static void printminmax(lprec *lp, char *s, REAL *minima, REAL *maxima, int nminima, int nmaxima, int *rowmin, int *rowmax, int *colmin, int *colmax)
400 {
401   int i, nminmax, n;
402 
403   nminmax = nminima;
404   if (nmaxima > nminmax)
405     nminmax = nmaxima;
406   for (i = 0; i < nminmax; i++) {
407     n = 0;
408     if (i < nminima) {
409       n += printf("%s(", s);
410       if (rowmin != NULL)
411         n+= printf("%s", get_row_name(lp, rowmin[i]));
412       if ((rowmin != NULL) && (colmin != NULL))
413         n += printf(", ");
414       if (colmin != NULL)
415         n += printf("%s", get_col_name(lp, colmin[i]));
416       n += printf(") = %.8f", minima[i]);
417     }
418     if (n < 40)
419       n = 40 - n;
420     else
421       n = 1;
422     printf("%*.*s", n, n, "");
423 
424     if (i < nmaxima) {
425       n += printf("%s(", s);
426       if (rowmax != NULL)
427         n+= printf("%s", get_row_name(lp, rowmax[i]));
428       if ((rowmax != NULL) && (colmax != NULL))
429         n += printf(", ");
430       if (colmax != NULL)
431         n += printf("%s", get_col_name(lp, colmax[i]));
432       n += printf(") = %.8f", maxima[i]);
433     }
434 
435     printf("\n");
436   }
437 }
438 
print_statistics(lprec * lp)439 static void print_statistics(lprec *lp)
440 {
441   REAL *col, *RHSmin, *RHSmax, *OBJmin, *OBJmax, *MATmin, *MATmax;
442   int *nz, ret, m, n, i, j, k, l, nRHSmin = 0, nRHSmax = 0, nOBJmin = 0, nOBJmax = 0, nMATmin = 0, nMATmax = 0, *rowRHSmin, *rowRHSmax, *colOBJmin, *colOBJmax, *rowMATmin, *rowMATmax, *colMATmin, *colMATmax;
443 
444   m = get_Nrows(lp);
445   n = get_Ncolumns(lp);
446 
447   col = (REAL *) malloc((1 + m) * sizeof(*col));
448   nz = (int *) malloc((1 + m) * sizeof(*RHSmin));
449   RHSmin = (REAL *) malloc(nstats * sizeof(*RHSmin));
450   RHSmax = (REAL *) malloc(nstats * sizeof(*RHSmax));
451   rowRHSmin = (int *) malloc(nstats * sizeof(*RHSmin));
452   rowRHSmax = (int *) malloc(nstats * sizeof(*RHSmax));
453   OBJmin = (REAL *) malloc(nstats * sizeof(*OBJmin));
454   OBJmax = (REAL *) malloc(nstats * sizeof(*OBJmax));
455   colOBJmin = (int *) malloc(nstats * sizeof(*colOBJmin));
456   colOBJmax = (int *) malloc(nstats * sizeof(*colOBJmax));
457   MATmin = (REAL *) malloc(nstats * sizeof(*MATmin));
458   MATmax = (REAL *) malloc(nstats * sizeof(*MATmax));
459   rowMATmin = (int *) malloc(nstats * sizeof(*rowMATmin));
460   rowMATmax = (int *) malloc(nstats * sizeof(*rowMATmax));
461   colMATmin = (int *) malloc(nstats * sizeof(*colMATmin));
462   colMATmax = (int *) malloc(nstats * sizeof(*colMATmax));
463 
464 /*
465   minmax(2.0, MATmin, MATmax, &nMATmin, &nMATmax, 1, rowMATmin, rowMATmax, 8, colMATmin, colMATmax);
466   minmax(1.0, MATmin, MATmax, &nMATmin, &nMATmax, 2, rowMATmin, rowMATmax, 7, colMATmin, colMATmax);
467   minmax(1.5, MATmin, MATmax, &nMATmin, &nMATmax, 3, rowMATmin, rowMATmax, 6, colMATmin, colMATmax);
468   minmax(3.0, MATmin, MATmax, &nMATmin, &nMATmax, 4, rowMATmin, rowMATmax, 5, colMATmin, colMATmax);
469   minmax(4.0, MATmin, MATmax, &nMATmin, &nMATmax, 5, rowMATmin, rowMATmax, 4, colMATmin, colMATmax);
470   minmax(0.1, MATmin, MATmax, &nMATmin, &nMATmax, 6, rowMATmin, rowMATmax, 3, colMATmin, colMATmax);
471   minmax(5.0, MATmin, MATmax, &nMATmin, &nMATmax, 7, rowMATmin, rowMATmax, 2, colMATmin, colMATmax);
472   minmax(1.4, MATmin, MATmax, &nMATmin, &nMATmax, 8, rowMATmin, rowMATmax, 1, colMATmin, colMATmax);
473 
474   printminmax(MATmin, MATmax, nMATmin, nMATmax, rowMATmin, rowMATmax, colMATmin, colMATmax);
475 */
476 
477   for (i = 1; i <= m; i++)
478     minmax(get_rh(lp, i), RHSmin, RHSmax, &nRHSmin, &nRHSmax, i, rowRHSmin, rowRHSmax, 0, NULL, NULL);
479 
480   for (j = 1; j <= n; j++) {
481     ret = get_columnex(lp, j, col, nz);
482     for (i = 0; i < ret; i++)
483       if (nz[i] == 0)
484         minmax(col[i], OBJmin, OBJmax, &nOBJmin, &nOBJmax, 0, NULL, NULL, j, colOBJmin, colOBJmax);
485       else
486         minmax(col[i], MATmin, MATmax, &nMATmin, &nMATmax, nz[i], rowMATmin, rowMATmax, j, colMATmin, colMATmax);
487   }
488 
489   printf("Constraints: %d\n", get_Nrows(lp));
490   printf("Variables  : %d\n", get_Ncolumns(lp));
491   for (j = k = l = 0, i = n; i >= 1; i--) {
492     if (is_int(lp, i))
493       j++;
494     if (is_semicont(lp, i))
495       k++;
496     if (is_SOS_var(lp, i))
497       l++;
498   }
499   printf("Integers   : %d\n", j);
500   printf("Semi-cont  : %d\n", k);
501   printf("SOS        : %d\n", l);
502   k = get_nonzeros(lp);
503   printf("Non-zeros  : %d\tdensity=%f%%\n", k, ((double) k) / (((double) m) * ((double) n)) * 100.0);
504 
505   printf("\nAbsolute Ranges:\n\n       Minima                                  Maxima\n");
506   printf("\nMatrix Coeficients:\n");
507   printminmax(lp, "A", MATmin, MATmax, nMATmin, nMATmax, rowMATmin, rowMATmax, colMATmin, colMATmax);
508 
509   printf("\nObj. Vector:\n");
510   printminmax(lp, "c", OBJmin, OBJmax, nOBJmin, nOBJmax, NULL, NULL, colOBJmin, colOBJmax);
511 
512   printf("\nRHS Vector:\n");
513   printminmax(lp, "b", RHSmin, RHSmax, nRHSmin, nRHSmax, rowRHSmin, rowRHSmax, NULL, NULL);
514 
515   free(col);
516   free(nz);
517   free(RHSmin);
518   free(RHSmax);
519   free(rowRHSmin);
520   free(rowRHSmax);
521   free(OBJmin);
522   free(OBJmax);
523   free(colOBJmin);
524   free(colOBJmax);
525   free(MATmin);
526   free(MATmax);
527   free(rowMATmin);
528   free(rowMATmax);
529   free(colMATmin);
530   free(colMATmax);
531 }
532 
main(int argc,char * argv[])533 int main(int argc, char *argv[])
534 {
535   lprec *lp = NULL;
536   char *filen, *wlp = NULL, *wmps = NULL, *wfmps = NULL, plp = FALSE;
537   int i;
538   int verbose = IMPORTANT /* CRITICAL */;
539   int debug = -1;
540   MYBOOL report = FALSE;
541   MYBOOL nonames = FALSE, norownames = FALSE, nocolnames = FALSE;
542   MYBOOL write_model_after = FALSE;
543   MYBOOL noint = FALSE;
544   int print_sol = -1;
545   MYBOOL print_stats = FALSE;
546   int floor_first = -1;
547   MYBOOL do_set_bb_depthlimit = FALSE;
548   int bb_depthlimit = 0;
549   MYBOOL do_set_solutionlimit = FALSE;
550   int solutionlimit = 0;
551   MYBOOL break_at_first = FALSE;
552   int scaling = 0;
553   double scaleloop = 0;
554   MYBOOL tracing = FALSE;
555   short filetype = filetypeLP;
556   int anti_degen1 = -1;
557   int anti_degen2 = -1;
558   short print_timing = FALSE;
559   short parse_only = FALSE;
560   int do_presolve = -1;
561   short objective = 0;
562   short PRINT_SOLUTION = 2;
563   int improve = -1;
564   int pivoting1 = -1;
565   int pivoting2 = -1;
566   int bb_rule1 = -1;
567   int bb_rule2 = -1;
568   int max_num_inv = -1;
569   int scalemode1 = -1;
570   int scalemode2 = -1;
571   int crashmode = -1;
572   char *guessbasis = NULL;
573   /* short timeoutok = FALSE; */
574   long sectimeout = -1;
575   int result;
576   MYBOOL preferdual = AUTOMATIC;
577   int simplextype = -1;
578   MYBOOL do_set_obj_bound = FALSE;
579   REAL obj_bound = 0;
580   REAL mip_absgap = -1;
581   REAL mip_relgap = -1;
582   REAL epsperturb = -1;
583   REAL epsint = -1;
584   REAL epspivot = -1;
585   REAL epsd = -1;
586   REAL epsb = -1;
587   REAL epsel = -1;
588   MYBOOL do_set_break_at_value = FALSE;
589   REAL break_at_value = 0;
590   REAL accuracy_error0, accuracy_error = -1;
591   FILE *fpin = stdin;
592   char *bfp = NULL;
593   char *rxliname = NULL, *rxli = NULL, *rxlidata = NULL, *rxlioptions = NULL, *wxliname = NULL, *wxlisol = NULL, *wxli = NULL, *wxlioptions = NULL, *wxlisoloptions = NULL;
594   char *rbasname = NULL, *wbasname = NULL;
595   char *debugdump_before = NULL;
596   char *debugdump_after = NULL;
597   char *rparname = NULL;
598   char *rparoptions = NULL;
599   char *wparname = NULL;
600   char *wparoptions = NULL;
601   char obj_in_basis = -1;
602   char mps_ibm = FALSE;
603   char mps_negobjconst = FALSE;
604   char mps_free = FALSE;
605   MYBOOL ok;
606 # define SCALINGTHRESHOLD 0.03
607 
608   /* read command line arguments */
609 
610 # if defined FORTIFY
611    Fortify_EnterScope();
612 # endif
613 
614   for(i = 1; i < argc; i++) {
615     ok = FALSE;
616     if(strncmp(argv[i], "-v", 2) == 0) {
617       if (argv[i][2])
618         verbose = atoi(argv[i] + 2);
619       else
620         verbose = NORMAL;
621     }
622     else if(strcmp(argv[i], "-d") == 0)
623       debug = TRUE;
624     else if(strcmp(argv[i], "-R") == 0)
625       report = TRUE;
626     else if(strcmp(argv[i], "-i") == 0)
627       print_sol = TRUE;
628     else if(strcmp(argv[i], "-ia") == 0)
629       print_sol = AUTOMATIC;
630     else if(strcmp(argv[i], "-stat") == 0)
631       print_stats = TRUE;
632     else if(strcmp(argv[i], "-nonames") == 0)
633       nonames = TRUE;
634     else if(strcmp(argv[i], "-norownames") == 0)
635       norownames = TRUE;
636     else if(strcmp(argv[i], "-nocolnames") == 0)
637       nocolnames = TRUE;
638     else if((strcmp(argv[i], "-c") == 0) || (strcmp(argv[i], "-cc") == 0))
639       floor_first = BRANCH_CEILING;
640     else if(strcmp(argv[i], "-cf") == 0)
641       floor_first = BRANCH_FLOOR;
642     else if(strcmp(argv[i], "-ca") == 0)
643       floor_first = BRANCH_AUTOMATIC;
644     else if((strcmp(argv[i], "-depth") == 0) && (i + 1 < argc)) {
645       do_set_bb_depthlimit = TRUE;
646       bb_depthlimit = atoi(argv[++i]);
647     }
648     else if(strcmp(argv[i], "-Bw") == 0)
649       or_value(&bb_rule2, NODE_WEIGHTREVERSEMODE);
650     else if(strcmp(argv[i], "-Bb") == 0)
651       or_value(&bb_rule2, NODE_BRANCHREVERSEMODE);
652     else if(strcmp(argv[i], "-Bg") == 0)
653       or_value(&bb_rule2, NODE_GREEDYMODE);
654     else if(strcmp(argv[i], "-Bp") == 0)
655       or_value(&bb_rule2, NODE_PSEUDOCOSTMODE);
656     else if(strcmp(argv[i], "-BR") == 0)
657       or_value(&bb_rule2, NODE_PSEUDORATIOSELECT);
658     else if(strcmp(argv[i], "-Bf") == 0)
659       or_value(&bb_rule2, NODE_DEPTHFIRSTMODE);
660     else if(strcmp(argv[i], "-Br") == 0)
661       or_value(&bb_rule2, NODE_RANDOMIZEMODE);
662     else if(strcmp(argv[i], "-BG") == 0)
663       or_value(&bb_rule2, 0 /* NODE_GUBMODE */); /* doesn't work yet */
664     else if(strcmp(argv[i], "-Bd") == 0)
665       or_value(&bb_rule2, NODE_DYNAMICMODE);
666     else if(strcmp(argv[i], "-Bs") == 0)
667       or_value(&bb_rule2, NODE_RESTARTMODE);
668     else if(strcmp(argv[i], "-BB") == 0)
669       or_value(&bb_rule2, NODE_BREADTHFIRSTMODE);
670     else if(strcmp(argv[i], "-Bo") == 0)
671       or_value(&bb_rule2, NODE_AUTOORDER);
672     else if(strcmp(argv[i], "-Bc") == 0)
673       or_value(&bb_rule2, NODE_RCOSTFIXING);
674     else if(strcmp(argv[i], "-Bi") == 0)
675       or_value(&bb_rule2, NODE_STRONGINIT);
676     else if(strncmp(argv[i], "-B", 2) == 0) {
677       if (argv[i][2])
678         set_value(&bb_rule1, atoi(argv[i] + 2));
679       else
680         set_value(&bb_rule1, NODE_FIRSTSELECT);
681     }
682     else if((strcmp(argv[i], "-n") == 0) && (i + 1 < argc)) {
683       do_set_solutionlimit = TRUE;
684       solutionlimit = atoi(argv[++i]);
685     }
686     else if((strcmp(argv[i], "-b") == 0) && (i + 1 < argc)) {
687       obj_bound = atof(argv[++i]);
688       do_set_obj_bound = TRUE;
689     }
690     else if(((strcmp(argv[i], "-g") == 0) || (strcmp(argv[i], "-ga") == 0)) && (i + 1 < argc))
691       mip_absgap = atof(argv[++i]);
692     else if((strcmp(argv[i], "-gr") == 0) && (i + 1 < argc))
693       mip_relgap = atof(argv[++i]);
694     else if((strcmp(argv[i], "-e") == 0) && (i + 1 < argc)) {
695       epsint = atof(argv[++i]);
696       if((epsint <= 0.0) || (epsint >= 0.5)) {
697         fprintf(stderr, "Invalid tolerance %g; 0 < epsilon < 0.5\n",
698                 (double)epsint);
699         EndOfPgr(FORCED_EXIT);
700       }
701     }
702     else if((strcmp(argv[i], "-r") == 0) && (i + 1 < argc))
703       max_num_inv = atoi(argv[++i]);
704     else if((strcmp(argv[i], "-o") == 0) && (i + 1 < argc)) {
705       break_at_value = atof(argv[++i]);
706       do_set_break_at_value = TRUE;
707     }
708     else if(strcmp(argv[i], "-f") == 0)
709       break_at_first = TRUE;
710     else if(strcmp(argv[i], "-timeoutok") == 0)
711       /* timeoutok = TRUE */; /* option no longer needed, but still accepted */
712     else if(strcmp(argv[i], "-h") == 0) {
713       print_help(argv);
714       EndOfPgr(EXIT_SUCCESS);
715     }
716     else if(strcmp(argv[i], "-prim") == 0)
717       preferdual = FALSE;
718     else if(strcmp(argv[i], "-dual") == 0)
719       preferdual = TRUE;
720     else if(strcmp(argv[i], "-simplexpp") == 0)
721       simplextype = SIMPLEX_PRIMAL_PRIMAL;
722     else if(strcmp(argv[i], "-simplexdp") == 0)
723       simplextype = SIMPLEX_DUAL_PRIMAL;
724     else if(strcmp(argv[i], "-simplexpd") == 0)
725       simplextype = SIMPLEX_PRIMAL_DUAL;
726     else if(strcmp(argv[i], "-simplexdd") == 0)
727       simplextype = SIMPLEX_DUAL_DUAL;
728     else if(strcmp(argv[i], "-sp") == 0)
729       or_value(&scalemode2, SCALE_POWER2);
730     else if(strcmp(argv[i], "-si") == 0)
731       or_value(&scalemode2, SCALE_INTEGERS);
732     else if(strcmp(argv[i], "-se") == 0)
733       or_value(&scalemode2, SCALE_EQUILIBRATE);
734     else if(strcmp(argv[i], "-sq") == 0)
735       or_value(&scalemode2, SCALE_QUADRATIC);
736     else if(strcmp(argv[i], "-sl") == 0)
737       or_value(&scalemode2, SCALE_LOGARITHMIC);
738     else if(strcmp(argv[i], "-sd") == 0)
739       or_value(&scalemode2, SCALE_DYNUPDATE);
740     else if(strcmp(argv[i], "-sr") == 0)
741       or_value(&scalemode2, SCALE_ROWSONLY);
742     else if(strcmp(argv[i], "-sc") == 0)
743       or_value(&scalemode2, SCALE_COLSONLY);
744     else if(strncmp(argv[i], "-s", 2) == 0) {
745       set_value(&scalemode1, SCALE_NONE);
746       scaling = SCALE_MEAN;
747       if (argv[i][2]) {
748         switch (atoi(argv[i] + 2)) {
749         case 0:
750           scaling = SCALE_NONE;
751           break;
752         case 1:
753           set_value(&scalemode1, SCALE_GEOMETRIC);
754           break;
755         case 2:
756           set_value(&scalemode1, SCALE_CURTISREID);
757           break;
758         case 3:
759           set_value(&scalemode1, SCALE_EXTREME);
760           break;
761         case 4:
762           set_value(&scalemode1, SCALE_MEAN);
763           break;
764         case 5:
765           set_value(&scalemode1, SCALE_MEAN | SCALE_LOGARITHMIC);
766           break;
767         case 6:
768           set_value(&scalemode1, SCALE_RANGE);
769           break;
770         case 7:
771           set_value(&scalemode1, SCALE_MEAN | SCALE_QUADRATIC);
772           break;
773         }
774       }
775       else
776         set_value(&scalemode1, SCALE_MEAN);
777       if((i + 1 < argc) && (isNum(argv[i + 1])))
778         scaleloop = atoi(argv[++i]);
779     }
780     else if(strncmp(argv[i], "-C", 2) == 0)
781       crashmode = atoi(argv[i] + 2);
782     else if((strcmp(argv[i],"-gbas") == 0) && (i + 1 < argc))
783       guessbasis = argv[++i];
784     else if(strcmp(argv[i], "-t") == 0)
785       tracing = TRUE;
786     else if(strncmp(argv[i], "-S", 2) == 0) {
787       if (argv[i][2])
788         PRINT_SOLUTION = (short) atoi(argv[i] + 2);
789       else
790         PRINT_SOLUTION = 2;
791     }
792     else if(strncmp(argv[i], "-improve", 8) == 0) {
793       if (argv[i][8])
794         or_value(&improve, atoi(argv[i] + 8));
795     }
796     else if(strcmp(argv[i], "-pivll") == 0)
797       or_value(&pivoting2, PRICE_LOOPLEFT);
798     else if(strcmp(argv[i], "-pivla") == 0)
799       or_value(&pivoting2, PRICE_LOOPALTERNATE);
800 #if defined EnablePartialOptimization
801     else if(strcmp(argv[i], "-pivpc") == 0)
802       or_value(&pivoting2, PRICE_AUTOPARTIALCOLS);
803     else if(strcmp(argv[i], "-pivpr") == 0)
804       or_value(&pivoting2, PRICE_AUTOPARTIALROWS);
805     else if(strcmp(argv[i], "-pivp") == 0)
806       or_value(&pivoting2, PRICE_AUTOPARTIAL);
807 #endif
808     else if(strcmp(argv[i], "-pivf") == 0)
809       or_value(&pivoting2, PRICE_PRIMALFALLBACK);
810     else if(strcmp(argv[i], "-pivm") == 0)
811       or_value(&pivoting2, PRICE_MULTIPLE);
812     else if(strcmp(argv[i], "-piva") == 0)
813       or_value(&pivoting2, PRICE_ADAPTIVE);
814     else if(strcmp(argv[i], "-pivr") == 0)
815       or_value(&pivoting2, PRICE_RANDOMIZE);
816     else if(strcmp(argv[i], "-pivh") == 0)
817       or_value(&pivoting2, PRICE_HARRISTWOPASS);
818     else if(strcmp(argv[i], "-pivt") == 0)
819       or_value(&pivoting2, PRICE_TRUENORMINIT);
820     else if(strncmp(argv[i], "-piv", 4) == 0) {
821       if (argv[i][4])
822         set_value(&pivoting1, atoi(argv[i] + 4));
823       else
824     set_value(&pivoting1, PRICER_DEVEX | PRICE_ADAPTIVE);
825     }
826 #if defined PARSER_LP
827     else if(strcmp(argv[i],"-lp") == 0)
828       filetype = filetypeLP;
829 #endif
830     else if((strcmp(argv[i],"-wlp") == 0) && (i + 1 < argc))
831       wlp = argv[++i];
832     else if(strcmp(argv[i],"-plp") == 0)
833       plp = TRUE;
834     else if(strcmp(argv[i],"-mps") == 0)
835       filetype = filetypeMPS;
836     else if(strcmp(argv[i],"-mps_ibm") == 0)
837       mps_ibm = TRUE;
838     else if(strcmp(argv[i],"-mps_negobjconst") == 0)
839       mps_negobjconst = TRUE;
840     else if(strcmp(argv[i],"-mps_free") == 0)
841       mps_free = TRUE;
842     else if(strcmp(argv[i],"-fmps") == 0)
843       filetype = filetypeFREEMPS;
844     else if((strcmp(argv[i],"-wmps") == 0) && (i + 1 < argc))
845       wmps = argv[++i];
846     else if((strcmp(argv[i],"-wfmps") == 0) && (i + 1 < argc))
847       wfmps = argv[++i];
848     else if(strcmp(argv[i],"-wafter") == 0)
849       write_model_after = TRUE;
850     else if(strcmp(argv[i],"-degen") == 0)
851       set_value(&anti_degen1, ANTIDEGEN_DEFAULT);
852     else if(strcmp(argv[i],"-degenf") == 0)
853       or_value(&anti_degen2, ANTIDEGEN_FIXEDVARS);
854     else if(strcmp(argv[i],"-degenc") == 0)
855       or_value(&anti_degen2, ANTIDEGEN_COLUMNCHECK);
856     else if(strcmp(argv[i],"-degens") == 0)
857       or_value(&anti_degen2, ANTIDEGEN_STALLING);
858     else if(strcmp(argv[i],"-degenn") == 0)
859       or_value(&anti_degen2, ANTIDEGEN_NUMFAILURE);
860     else if(strcmp(argv[i],"-degenl") == 0)
861       or_value(&anti_degen2, ANTIDEGEN_LOSTFEAS);
862     else if(strcmp(argv[i],"-degeni") == 0)
863       or_value(&anti_degen2, ANTIDEGEN_INFEASIBLE);
864     else if(strcmp(argv[i],"-degend") == 0)
865       or_value(&anti_degen2, ANTIDEGEN_DYNAMIC);
866     else if(strcmp(argv[i],"-degenb") == 0)
867       or_value(&anti_degen2, ANTIDEGEN_DURINGBB);
868     else if(strcmp(argv[i],"-degenr") == 0)
869       or_value(&anti_degen2, ANTIDEGEN_RHSPERTURB);
870     else if(strcmp(argv[i],"-degenp") == 0)
871       or_value(&anti_degen2, ANTIDEGEN_BOUNDFLIP);
872     else if(strcmp(argv[i],"-time") == 0) {
873       if(clock() == -1)
874         fprintf(stderr, "CPU times not available on this machine\n");
875       else
876         print_timing = TRUE;
877     }
878     else if((strcmp(argv[i],"-bfp") == 0) && (i + 1 < argc))
879       bfp = argv[++i];
880     else if((strcmp(argv[i],"-rxli") == 0) && (i + 2 < argc)) {
881       rxliname = argv[++i];
882       rxli = argv[++i];
883       fpin = NULL;
884       filetype = filetypeXLI;
885     }
886     else if((strcmp(argv[i],"-rxlidata") == 0) && (i + 1 < argc))
887       rxlidata = argv[++i];
888     else if((strcmp(argv[i],"-rxliopt") == 0) && (i + 1 < argc))
889       rxlioptions = argv[++i];
890     else if((strcmp(argv[i],"-wxli") == 0) && (i + 2 < argc)) {
891       wxliname = argv[++i];
892       wxli = argv[++i];
893     }
894     else if((strcmp(argv[i],"-wxliopt") == 0) && (i + 1 < argc))
895       wxlioptions = argv[++i];
896     else if((strcmp(argv[i],"-wxlisol") == 0) && (i + 2 < argc)) {
897       wxliname = argv[++i];
898       wxlisol = argv[++i];
899     }
900     else if((strcmp(argv[i],"-wxlisolopt") == 0) && (i + 1 < argc))
901       wxlisoloptions = argv[++i];
902     else if((strcmp(argv[i],"-rbas") == 0) && (i + 1 < argc))
903       rbasname = argv[++i];
904     else if((strcmp(argv[i],"-wbas") == 0) && (i + 1 < argc))
905       wbasname = argv[++i];
906     else if((strcmp(argv[i],"-Db") == 0) && (i + 1 < argc))
907       debugdump_before = argv[++i];
908     else if((strcmp(argv[i],"-Da") == 0) && (i + 1 < argc))
909       debugdump_after = argv[++i];
910     else if((strcmp(argv[i],"-timeout") == 0) && (i + 1 < argc))
911       sectimeout = atol(argv[++i]);
912     else if((strcmp(argv[i],"-trej") == 0) && (i + 1 < argc))
913       epspivot = atof(argv[++i]);
914     else if((strcmp(argv[i],"-epsp") == 0) && (i + 1 < argc))
915       epsperturb = atof(argv[++i]);
916     else if((strcmp(argv[i],"-epsd") == 0) && (i + 1 < argc))
917       epsd = atof(argv[++i]);
918     else if((strcmp(argv[i],"-epsb") == 0) && (i + 1 < argc))
919       epsb = atof(argv[++i]);
920     else if((strcmp(argv[i],"-epsel") == 0) && (i + 1 < argc))
921       epsel = atof(argv[++i]);
922     else if(strcmp(argv[i],"-parse_only") == 0)
923       parse_only = TRUE;
924     else
925       ok = TRUE;
926 
927     if(!ok)
928       ;
929     else if(strcmp(argv[i],"-presolverow") == 0)
930       or_value(&do_presolve, PRESOLVE_ROWS);
931     else if(strcmp(argv[i],"-presolvecol") == 0)
932       or_value(&do_presolve, PRESOLVE_COLS);
933     else if(strcmp(argv[i],"-presolve") == 0)
934       or_value(&do_presolve, PRESOLVE_ROWS | PRESOLVE_COLS);
935     else if(strcmp(argv[i],"-presolvel") == 0)
936       or_value(&do_presolve, PRESOLVE_LINDEP);
937     else if(strcmp(argv[i],"-presolves") == 0)
938       or_value(&do_presolve, PRESOLVE_SOS);
939     else if(strcmp(argv[i],"-presolver") == 0)
940       or_value(&do_presolve, PRESOLVE_REDUCEMIP);
941     else if(strcmp(argv[i],"-presolvek") == 0)
942       or_value(&do_presolve, PRESOLVE_KNAPSACK);
943     else if(strcmp(argv[i],"-presolveq") == 0)
944       or_value(&do_presolve, PRESOLVE_ELIMEQ2);
945     else if(strcmp(argv[i],"-presolvem") == 0)
946       or_value(&do_presolve, PRESOLVE_MERGEROWS);
947     else if(strcmp(argv[i],"-presolvefd") == 0)
948       or_value(&do_presolve, PRESOLVE_COLFIXDUAL);
949     else if(strcmp(argv[i],"-presolvebnd") == 0)
950       or_value(&do_presolve, PRESOLVE_BOUNDS);
951     else if(strcmp(argv[i],"-presolved") == 0)
952       or_value(&do_presolve, PRESOLVE_DUALS);
953     else if(strcmp(argv[i],"-presolvef") == 0)
954       or_value(&do_presolve, PRESOLVE_IMPLIEDFREE);
955     else if(strcmp(argv[i],"-presolveslk") == 0)
956       or_value(&do_presolve, PRESOLVE_IMPLIEDSLK);
957     else if(strcmp(argv[i],"-presolveg") == 0)
958       or_value(&do_presolve, PRESOLVE_REDUCEGCD);
959     else if(strcmp(argv[i],"-presolveb") == 0)
960       or_value(&do_presolve, PRESOLVE_PROBEFIX);
961     else if(strcmp(argv[i],"-presolvec") == 0)
962       or_value(&do_presolve, PRESOLVE_PROBEREDUCE);
963     else if(strcmp(argv[i],"-presolverowd") == 0)
964       or_value(&do_presolve, PRESOLVE_ROWDOMINATE);
965     else if(strcmp(argv[i],"-presolvecold") == 0)
966       or_value(&do_presolve, PRESOLVE_COLDOMINATE);
967     else if(strcmp(argv[i],"-min") == 0)
968       objective = -1;
969     else if(strcmp(argv[i],"-max") == 0)
970       objective =  1;
971     else if(strcmp(argv[i],"-noint") == 0)
972       noint =  TRUE;
973     else if((strcmp(argv[i],"-rpar") == 0) && (i + 1 < argc))
974       i++;
975     else if((strcmp(argv[i],"-rparopt") == 0) && (i + 1 < argc))
976       i++;
977     else if((strcmp(argv[i],"-wpar") == 0) && (i + 1 < argc))
978       i++;
979     else if((strcmp(argv[i],"-wparopt") == 0) && (i + 1 < argc))
980       i++;
981     else if(strcmp(argv[i],"-o0") == 0)
982       obj_in_basis = FALSE;
983     else if(strcmp(argv[i],"-o1") == 0)
984       obj_in_basis = TRUE;
985     else if((strcmp(argv[i], "-ac") == 0) && (i + 1 < argc))
986       accuracy_error = atof(argv[++i]);
987     else if(fpin == stdin) {
988       filen = argv[i];
989       if(*filen == '<')
990         filen++;
991       if((fpin = fopen(filen, "r")) == NULL) {
992         print_help(argv);
993         fprintf(stderr,"\nError, Unable to open input file '%s'\n",
994                 argv[i]);
995         EndOfPgr(FORCED_EXIT);
996       }
997     }
998     else {
999       filen = argv[i];
1000       if(*filen != '>') {
1001         print_help(argv);
1002         fprintf(stderr, "\nError, Unrecognized command line argument '%s'\n",
1003                 argv[i]);
1004         EndOfPgr(FORCED_EXIT);
1005       }
1006     }
1007   }
1008 
1009   signal(SIGABRT,/* (void (*) OF((int))) */ SIGABRT_func);
1010 
1011   if ((filetype != filetypeXLI) && (fpin == NULL)) {
1012     lp = NULL;
1013     fprintf(stderr, "Cannot combine -rxli option with -lp, -mps, -fmps.\n");
1014   }
1015   else {
1016     switch(filetype) {
1017   #if defined PARSER_LP
1018     case filetypeLP:
1019       lp = read_lp(fpin, verbose, NULL);
1020       break;
1021   #endif
1022     case filetypeMPS:
1023       lp = read_mps(fpin, verbose | (mps_free ? MPS_FREE : 0) | (mps_ibm ? MPS_IBM : 0) | (mps_negobjconst ? MPS_NEGOBJCONST : 0));
1024       break;
1025     case filetypeFREEMPS:
1026       lp = read_freemps(fpin, verbose | (mps_ibm ? MPS_IBM : 0) | (mps_negobjconst ? MPS_NEGOBJCONST : 0));
1027       break;
1028     case filetypeXLI:
1029       lp = read_XLI(rxliname, rxli, rxlidata, rxlioptions, verbose);
1030       break;
1031     }
1032   }
1033 
1034   if((fpin != NULL) && (fpin != stdin))
1035     fclose(fpin);
1036 
1037   if(print_timing)
1038     print_cpu_times("Parsing input");
1039 
1040   if(lp == NULL) {
1041     fprintf(stderr, "Unable to read model.\n");
1042     EndOfPgr(FORCED_EXIT);
1043   }
1044 
1045   for(i = 1; i < argc; i++) {
1046     if((strcmp(argv[i],"-rpar") == 0) && (i + 1 < argc)) {
1047       if(rparname != NULL) {
1048         if(!read_params(lp, rparname, rparoptions)) {
1049           fprintf(stderr, "Unable to read parameter file (%s)\n", rparname);
1050           delete_lp(lp);
1051           EndOfPgr(FORCED_EXIT);
1052         }
1053       }
1054       rparname = argv[++i];
1055     }
1056     else if((strcmp(argv[i],"-rparopt") == 0) && (i + 1 < argc))
1057       rparoptions = argv[++i];
1058     else if((strcmp(argv[i],"-wpar") == 0) && (i + 1 < argc))
1059       wparname = argv[++i];
1060     else if((strcmp(argv[i],"-wparopt") == 0) && (i + 1 < argc))
1061       wparoptions = argv[++i];
1062   }
1063 
1064   if(rparname != NULL)
1065     if(!read_params(lp, rparname, rparoptions)) {
1066       fprintf(stderr, "Unable to read parameter file (%s)\n", rparname);
1067       delete_lp(lp);
1068       EndOfPgr(FORCED_EXIT);
1069     }
1070 
1071   if((nonames) || (nocolnames))
1072     set_use_names(lp, FALSE, FALSE);
1073   if((nonames) || (norownames))
1074     set_use_names(lp, TRUE, FALSE);
1075 
1076   if(objective != 0) {
1077     if(objective == 1)
1078       set_maxim(lp);
1079     else
1080       set_minim(lp);
1081   }
1082 
1083   if (obj_in_basis != -1)
1084     set_obj_in_basis(lp, obj_in_basis);
1085 
1086   if(noint) { /* remove integer conditions */
1087     for(i = get_Ncolumns(lp); i >= 1; i--) {
1088       if(is_SOS_var(lp, i)) {
1089         fprintf(stderr, "Unable to remove integer conditions because there is at least one SOS constraint\n");
1090         delete_lp(lp);
1091         EndOfPgr(FORCED_EXIT);
1092       }
1093       set_semicont(lp, i, FALSE);
1094       set_int(lp, i, FALSE);
1095     }
1096   }
1097 
1098   if(!write_model_after)
1099     write_model(lp, plp, wlp, wmps, wfmps, wxli, NULL, wxliname, wxlioptions);
1100 
1101   if(print_stats)
1102     print_statistics(lp);
1103 
1104   if(parse_only) {
1105     if(!write_model_after) {
1106       delete_lp(lp);
1107       EndOfPgr(0);
1108     }
1109     /* else if(!sectimeout) */
1110       sectimeout = 1;
1111   }
1112 
1113   if(PRINT_SOLUTION >= 5)
1114     print_lp(lp);
1115 
1116 #if 0
1117   put_abortfunc(lp,(abortfunc *) myabortfunc, NULL);
1118 #endif
1119 
1120   if(sectimeout > 0)
1121     set_timeout(lp, sectimeout);
1122   if(print_sol >= 0)
1123     set_print_sol(lp, print_sol);
1124   if(epsint >= 0)
1125     set_epsint(lp, epsint);
1126   if(epspivot >= 0)
1127     set_epspivot(lp, epspivot);
1128   if(epsperturb >= 0)
1129     set_epsperturb(lp, epsperturb);
1130   if(epsd >= 0)
1131     set_epsd(lp, epsd);
1132   if(epsb >= 0)
1133     set_epsb(lp, epsb);
1134   if(epsel >= 0)
1135     set_epsel(lp, epsel);
1136   if(debug >= 0)
1137     set_debug(lp, (MYBOOL) debug);
1138   if(floor_first != -1)
1139     set_bb_floorfirst(lp, floor_first);
1140   if(do_set_bb_depthlimit)
1141     set_bb_depthlimit(lp, bb_depthlimit);
1142   if(do_set_solutionlimit)
1143     set_solutionlimit(lp, solutionlimit);
1144   if(tracing)
1145     set_trace(lp, tracing);
1146   if(do_set_obj_bound)
1147     set_obj_bound(lp, obj_bound);
1148   if(do_set_break_at_value)
1149     set_break_at_value(lp, break_at_value);
1150   if(break_at_first)
1151     set_break_at_first(lp, break_at_first);
1152   if(mip_absgap >= 0)
1153     set_mip_gap(lp, TRUE, mip_absgap);
1154   if(mip_relgap >= 0)
1155     set_mip_gap(lp, FALSE, mip_relgap);
1156   if((anti_degen1 != -1) || (anti_degen2 != -1)) {
1157     if((anti_degen1 == -1) || (anti_degen2 != -1))
1158       anti_degen1 = 0;
1159     if(anti_degen2 == -1)
1160       anti_degen2 = 0;
1161     set_anti_degen(lp, anti_degen1 | anti_degen2);
1162   }
1163   set_presolve(lp, ((do_presolve == -1) ? get_presolve(lp): do_presolve) | ((PRINT_SOLUTION >= 4) ? PRESOLVE_SENSDUALS : 0), get_presolveloops(lp));
1164   if(improve != -1)
1165     set_improve(lp, improve);
1166   if(max_num_inv >= 0)
1167     set_maxpivot(lp, max_num_inv);
1168   if(preferdual != AUTOMATIC)
1169     set_preferdual(lp, preferdual);
1170   if((pivoting1 != -1) || (pivoting2 != -1)) {
1171     if(pivoting1 == -1)
1172       pivoting1 = get_pivoting(lp) & PRICER_LASTOPTION;
1173     if(pivoting2 == -1)
1174       pivoting2 = 0;
1175     set_pivoting(lp, pivoting1 | pivoting2);
1176   }
1177   if((scalemode1 != -1) || (scalemode2 != -1)) {
1178     if(scalemode1 == -1)
1179       scalemode1 = get_scaling(lp) & SCALE_CURTISREID;
1180     if(scalemode2 == -1)
1181       scalemode2 = 0;
1182     set_scaling(lp, scalemode1 | scalemode2);
1183   }
1184   if(crashmode != -1)
1185     set_basiscrash(lp, crashmode);
1186   if((bb_rule1 != -1) || (bb_rule2 != -1)) {
1187     if(bb_rule1 == -1)
1188       bb_rule1 = get_bb_rule(lp) & NODE_USERSELECT;
1189     if(bb_rule2 == -1)
1190       bb_rule2 = 0;
1191     set_bb_rule(lp, bb_rule1 | bb_rule2);
1192   }
1193   if(simplextype != -1)
1194     set_simplextype(lp, simplextype);
1195   if(bfp != NULL)
1196     if(!set_BFP(lp, bfp)) {
1197       fprintf(stderr, "Unable to set BFP package.\n");
1198       delete_lp(lp);
1199       EndOfPgr(FORCED_EXIT);
1200     }
1201   if(debugdump_before != NULL)
1202     print_debugdump(lp, debugdump_before);
1203   if(report)
1204     put_msgfunc(lp, LPMessageCB, NULL, MSG_LPFEASIBLE | MSG_LPOPTIMAL | MSG_MILPFEASIBLE | MSG_MILPBETTER | MSG_PERFORMANCE);
1205 
1206   if(scaling) {
1207     if(scaleloop <= 0)
1208       scaleloop = 5;
1209     if(scaleloop - (int) scaleloop < SCALINGTHRESHOLD)
1210       scaleloop = (int) scaleloop + SCALINGTHRESHOLD;
1211     set_scalelimit(lp, scaleloop);
1212   }
1213 
1214   if (accuracy_error != -1)
1215     set_break_numeric_accuracy(lp, accuracy_error);
1216 
1217   if(guessbasis != NULL) {
1218     REAL *guessvector, a;
1219     int *basisvector;
1220     int Nrows = get_Nrows(lp);
1221     int Ncolumns = get_Ncolumns(lp);
1222     int col;
1223     char buf[50], *ptr;
1224     FILE *fp;
1225 
1226     if ((fp = fopen(guessbasis, "r")) != NULL) {
1227       guessvector = (REAL *) calloc(1+Ncolumns, sizeof(*guessvector));
1228       basisvector = (int *) malloc((1+Nrows+Ncolumns)*sizeof(*basisvector));
1229       if ((guessvector != NULL) && (basisvector != NULL)) {
1230         while ((!feof(fp)) && (fgets(buf, sizeof(buf), fp) != NULL)) {
1231           ptr = strrchr(buf, ':');
1232           if (ptr == NULL) {
1233             printf("Mallformed line: %s\n", buf);
1234           }
1235           else {
1236             a = atof(ptr + 1);
1237             while ((ptr > buf) && (isspace(ptr[-1])))
1238               ptr--;
1239             *ptr = 0;
1240             col = get_nameindex(lp, buf, FALSE);
1241             if (col < 1)
1242               printf("guess_basis: Unknown variable name %s\n", buf);
1243             else
1244               guessvector[col] = a;
1245           }
1246         }
1247         if (guess_basis(lp, guessvector, basisvector)) {
1248           if (!set_basis(lp, basisvector, TRUE))
1249             printf("Unable to set guessed basis.\n");
1250         }
1251         else
1252           printf("Unable to guess basis from provided variables.\n");
1253       }
1254       else
1255         printf("guess_basis: Out of memory.\n");
1256       if (basisvector != NULL)
1257         free(basisvector);
1258       if (guessvector != NULL)
1259         free(guessvector);
1260       fclose(fp);
1261     }
1262     else
1263       printf("Unable to open file %s\n", guessbasis);
1264   }
1265 
1266   if(rbasname != NULL)
1267     if(!read_basis(lp, rbasname, NULL)) {
1268       fprintf(stderr, "Unable to read basis file.\n");
1269       delete_lp(lp);
1270       EndOfPgr(FORCED_EXIT);
1271     }
1272 
1273   result = solve(lp);
1274 
1275   if(wbasname != NULL)
1276     if(!write_basis(lp, wbasname))
1277       fprintf(stderr, "Unable to write basis file.\n");
1278 
1279   if(write_model_after)
1280     write_model(lp, plp, wlp, wmps, wfmps, wxli, NULL, wxliname, wxlioptions);
1281 
1282   write_model(lp, FALSE, NULL, NULL, NULL, NULL, wxlisol, wxliname, wxlisoloptions);
1283 
1284   if(PRINT_SOLUTION >= 6)
1285     print_scales(lp);
1286 
1287   if((print_timing) && (!parse_only))
1288     print_cpu_times("solving");
1289 
1290   if(debugdump_after != NULL)
1291     print_debugdump(lp, debugdump_after);
1292 
1293   if(wparname != NULL)
1294     if(!write_params(lp, wparname, wparoptions)) {
1295       fprintf(stderr, "Unable to write parameter file (%s)\n", wparname);
1296       delete_lp(lp);
1297       EndOfPgr(FORCED_EXIT);
1298     }
1299 
1300   if(parse_only) {
1301     delete_lp(lp);
1302     EndOfPgr(0);
1303   }
1304 
1305 /*
1306   if((timeoutok) && (result == TIMEOUT) && (get_solutioncount(lp) > 0))
1307     result = OPTIMAL;
1308 */
1309 
1310   switch(result) {
1311   case SUBOPTIMAL:
1312   case PRESOLVED:
1313   case OPTIMAL:
1314   case PROCBREAK:
1315   case FEASFOUND:
1316     if ((result == SUBOPTIMAL) && (PRINT_SOLUTION >= 1))
1317       printf("Suboptimal solution\n");
1318 
1319     if (result == PRESOLVED)
1320       printf("Presolved solution\n");
1321 
1322     if (PRINT_SOLUTION >= 1)
1323       print_objective(lp);
1324 
1325     if (PRINT_SOLUTION >= 2)
1326       print_solution(lp, 1);
1327 
1328     if (PRINT_SOLUTION >= 3)
1329       print_constraints(lp, 1);
1330 
1331     if (PRINT_SOLUTION >= 4)
1332       print_duals(lp);
1333 
1334     if(tracing)
1335       fprintf(stderr,
1336               "Branch & Bound depth: %d\nNodes processed: %.0f\nSimplex pivots: %.0f\nNumber of equal solutions: %d\n",
1337               get_max_level(lp), (REAL) get_total_nodes(lp), (REAL) get_total_iter(lp), get_solutioncount(lp));
1338     break;
1339   case NOMEMORY:
1340     if (PRINT_SOLUTION >= 1)
1341       printf("Out of memory\n");
1342     break;
1343   case INFEASIBLE:
1344     if (PRINT_SOLUTION >= 1)
1345       printf("This problem is infeasible\n");
1346     break;
1347   case UNBOUNDED:
1348     if (PRINT_SOLUTION >= 1)
1349       printf("This problem is unbounded\n");
1350     break;
1351   case PROCFAIL:
1352    if (PRINT_SOLUTION >= 1)
1353       printf("The B&B routine failed\n");
1354     break;
1355   case TIMEOUT:
1356     if (PRINT_SOLUTION >= 1)
1357       printf("Timeout\n");
1358     break;
1359   case USERABORT:
1360     if (PRINT_SOLUTION >= 1)
1361       printf("User aborted\n");
1362     break;
1363   case ACCURACYERROR:
1364     if (PRINT_SOLUTION >= 1)
1365       printf("Accuracy error\n");
1366     break;
1367   default:
1368     if (PRINT_SOLUTION >= 1)
1369       printf("lp_solve failed\n");
1370     break;
1371   }
1372 
1373   if (PRINT_SOLUTION >= 7)
1374     print_tableau(lp);
1375 
1376   delete_lp(lp);
1377 
1378   EndOfPgr(result);
1379   return(result);
1380 }
1381