1 /****************************************************************************/
2 /* */
3 /* This file is part of CONCORDE */
4 /* */
5 /* (c) Copyright 1995--1999 by David Applegate, Robert Bixby, */
6 /* Vasek Chvatal, and William Cook */
7 /* */
8 /* Permission is granted for academic research use. For other uses, */
9 /* contact the authors for licensing options. */
10 /* */
11 /* Use at your own risk. We make no guarantees about the */
12 /* correctness or usefulness of this code. */
13 /* */
14 /****************************************************************************/
15
16 /****************************************************************************/
17 /* */
18 /* Interface Routines to The CPLEX 6.0-7.0 LP Solvers */
19 /* */
20 /* NOTE: Use this code in place of lp_none.c to access the Cplex 6.0-7.0 */
21 /* libraries. You will also need to link the cplex library via the */
22 /* makefile. */
23 /* */
24 /* */
25 /* Written by: Applegate, Bixby, Chvatal, and Cook */
26 /* Date: April 17, 1997 */
27 /* June 19, 1997 (bico, REB) */
28 /* */
29 /* See the start of the file lp_none.c for a description of the */
30 /* functions exported by this file. */
31 /* */
32 /* */
33 /* NOTES: */
34 /* */
35 /****************************************************************************/
36
37
38 #include "machdefs.h"
39 #include "util.h"
40 #include "macrorus.h"
41 #include "lp.h"
42 #include <cplex.h>
43
44 #undef CC_CPLEX_DISPLAY
45
46 #define CC_ONE_ENV
47
48 #ifdef CC_ONE_ENV
49 static CPXENVptr CClp_cplex_env = (CPXENVptr) NULL;
50 static int CClp_env_count = 0;
51
52 typedef struct CClp_parameters {
53 int scrind;
54 int simdisplay;
55 int fastmip;
56 int advind;
57 int dpriind;
58 int ppriind;
59 double epper;
60 double epopt;
61 double eprhs;
62 int perind;
63 int preind;
64 int aggind;
65 } CClp_parameters;
66 #endif
67
68 struct CClp {
69 CPXENVptr cplex_env;
70 CPXLPptr cplex_lp;
71 #ifdef CC_ONE_ENV
72 CClp_parameters cplex_params;
73 #endif
74 };
75
76 struct CClp_warmstart {
77 int rcount;
78 int ccount;
79 int *rstat;
80 int *cstat;
81 double *dnorm;
82 };
83
84 struct CClp_info {
85 int rcount;
86 int ccount;
87 int *rstat;
88 int *cstat;
89 };
90
91 #define SOLVER_WARMSTART_NAME "CPL5"
92
93
94 static int
95 primalopt (CClp *lp),
96 dualopt (CClp *lp),
97 baropt (CClp *lp),
98 getfarkasmultipliers (CClp *lp, double *y);
99
100 #ifdef CC_ONE_ENV
101 static int
102 set_parameters (CPXENVptr cplex_env, CClp_parameters *params);
103 #endif
104
105
CClp_init(CClp ** lp)106 int CClp_init (CClp **lp)
107 {
108 int rval = 0;
109
110 CClp_free (lp);
111
112 (*lp) = CC_SAFE_MALLOC (1, CClp);
113 if ((*lp) == (CClp *) NULL) {
114 fprintf (stderr, "Out of memory in CClp_init\n");
115 rval = 1; goto CLEANUP;
116 }
117
118 (*lp)->cplex_env = (CPXENVptr) NULL;
119 (*lp)->cplex_lp = (CPXLPptr) NULL;
120
121 #ifdef CC_ONE_ENV
122 if (CClp_cplex_env == (CPXENVptr) NULL) {
123 CClp_cplex_env = CPXopenCPLEX (&rval);
124 if (rval) {
125 fprintf (stderr, "CPXopenCPLEX failed, return code %d\n", rval);
126 goto CLEANUP;
127 }
128 CClp_env_count = 0;
129 }
130 (*lp)->cplex_env = CClp_cplex_env;
131 CClp_env_count++;
132 #else /* CC_ONE_ENV */
133 (*lp)->cplex_env = CPXopenCPLEX (&rval);
134 if (rval) {
135 fprintf (stderr, "CPXopenCPLEX failed, return code %d\n", rval);
136 goto CLEANUP;
137 }
138 #endif /* CC_ONE_ENV */
139
140 #ifdef CC_ONE_ENV
141 #ifdef CC_CPLEX_DISPLAY
142 (*lp)->cplex_params.scrind = 1;
143 (*lp)->cplex_params.simdisplay = 1;
144 #else
145 (*lp)->cplex_params.scrind = 0;
146 (*lp)->cplex_params.simdisplay = 0;
147 #endif
148 (*lp)->cplex_params.fastmip = 1;
149 (*lp)->cplex_params.advind = 1;
150 (*lp)->cplex_params.dpriind = CPX_DPRIIND_STEEP;
151 (*lp)->cplex_params.ppriind = CPX_PPRIIND_STEEP;
152 (*lp)->cplex_params.epper = 1.0E-6;
153 (*lp)->cplex_params.epopt = 1.0E-9;
154 (*lp)->cplex_params.eprhs = 1.0E-9;
155
156 (*lp)->cplex_params.perind = 0;
157 (*lp)->cplex_params.preind = 1;
158 (*lp)->cplex_params.aggind = 1;
159
160 #else /* CC_ONE_ENV */
161
162 #ifdef CC_CPLEX_DISPLAY
163 /* the documentation doesn't say what the return value means */
164 rval = CPXsetintparam ((*lp)->cplex_env, CPX_PARAM_SCRIND, 1);
165 if (rval) {
166 fprintf (stderr, "CPXsetintparam CPX_PARAM_SCRIND failed\n");
167 goto CLEANUP;
168 }
169
170 rval = CPXsetintparam ((*lp)->cplex_env, CPX_PARAM_SIMDISPLAY, 1);
171 if (rval) {
172 fprintf (stderr, "CPXsetintparam CPX_PARAM_SIMDISPLAY failed\n");
173 goto CLEANUP;
174 }
175 #endif
176
177 rval = CPXsetintparam ((*lp)->cplex_env, CPX_PARAM_FASTMIP, 1);
178 if (rval) {
179 fprintf (stderr, "CPXsetintparam CPX_PARAM_FASTMIP failed\n");
180 goto CLEANUP;
181 }
182
183 rval = CPXsetintparam ((*lp)->cplex_env, CPX_PARAM_ADVIND, 1);
184 if (rval) {
185 fprintf (stderr, "CPXsetintparam CPX_PARAM_ADVIND failed\n");
186 goto CLEANUP;
187 }
188 rval = CPXsetintparam ((*lp)->cplex_env, CPX_PARAM_DPRIIND,
189 CPX_DPRIIND_STEEP);
190 if (rval) {
191 fprintf (stderr, "CPXsetintparam CPX_PARAM_DPRIIND failed\n");
192 goto CLEANUP;
193 }
194 rval = CPXsetintparam ((*lp)->cplex_env, CPX_PARAM_PPRIIND,
195 CPX_PPRIIND_STEEP);
196 if (rval) {
197 fprintf (stderr, "CPXsetintparam CPX_PARAM_PPRIIND failed\n");
198 goto CLEANUP;
199 }
200
201 /* REB, 14 October 1997: The following three parameter settings
202 help fl3795 a bunch, and are probably not a bad idea in general */
203
204 rval = CPXsetdblparam ((*lp)->cplex_env, CPX_PARAM_EPPER, 1.0E-6);
205 if (rval) {
206 fprintf (stderr, "CPXsetdblparam CPX_PARAM_EPPER failed\n");
207 goto CLEANUP;
208 }
209 rval = CPXsetdblparam ((*lp)->cplex_env, CPX_PARAM_EPOPT, 1.0E-9);
210 if (rval) {
211 fprintf (stderr, "CPXsetdblparam CPX_PARAM_EPOPT failed\n");
212 goto CLEANUP;
213 }
214 rval = CPXsetdblparam ((*lp)->cplex_env, CPX_PARAM_EPRHS, 1.0E-9);
215 if (rval) {
216 fprintf (stderr, "CPXsetdblparam CPX_PARAM_EPRHS failed\n");
217 goto CLEANUP;
218 }
219
220 #endif /* CC_ONE_ENV */
221
222 CLEANUP:
223
224 if (rval) {
225 CClp_free (lp);
226 }
227
228 return rval;
229 }
230
CClp_force_perturb(CClp * lp)231 int CClp_force_perturb (CClp *lp)
232 {
233 int rval = 0;
234
235 #ifdef CC_ONE_ENV
236 lp->cplex_params.perind = 1;
237 #else /* CC_ONE_ENV */
238 rval = CPXsetintparam (lp->cplex_env, CPX_PARAM_PERIND, 1);
239 if (rval) {
240 fprintf (stderr, "CPXsetintparam CPX_PARAM_PERIND failed\n");
241 }
242 #endif /* CC_ONE_ENV */
243 return rval;
244 }
245
CClp_tune_small(CClp * lp)246 int CClp_tune_small (CClp *lp)
247 {
248 #ifdef CC_ONE_ENV
249 lp->cplex_params.dpriind = CPX_DPRIIND_FULL;
250 lp->cplex_params.ppriind = CPX_PPRIIND_AUTO;
251 #else /* CC_ONE_ENV */
252 int rval;
253
254 rval = CPXsetintparam (lp->cplex_env, CPX_PARAM_DPRIIND,
255 CPX_DPRIIND_FULL);
256 if (rval) {
257 fprintf (stderr, "CPXsetintparam CPX_PARAM_DPRIIND failed\n");
258 return rval;
259 }
260 rval = CPXsetintparam (lp->cplex_env, CPX_PARAM_PPRIIND,
261 CPX_PPRIIND_AUTO);
262 if (rval) {
263 fprintf (stderr, "CPXsetintparam CPX_PARAM_PPRIIND failed\n");
264 return rval;
265 }
266 #endif /* CC_ONE_ENV */
267 return 0;
268 }
269
CClp_disable_presolve(CClp * lp)270 int CClp_disable_presolve (CClp *lp)
271 {
272 #ifdef CC_ONE_ENV
273 lp->cplex_params.preind = CPX_OFF;
274 lp->cplex_params.aggind = 0;
275 #else /* CC_ONE_ENV */
276 if (CPXsetintparam (lp->cplex_env, CPX_PARAM_PREIND, CPX_OFF)) {
277 fprintf (stderr, "CPXsetintparam CPX_PARAM_PREIND failed\n");
278 return 1;
279 }
280 if (CPXsetintparam (lp->cplex_env, CPX_PARAM_AGGIND, 0)) {
281 fprintf (stderr, "CPXsetintparam CPX_PARAM_AGGIND failed\n");
282 return 1;
283 }
284 #endif /* CC_ONE_ENV */
285 return 0;
286 }
287
CClp_free(CClp ** lp)288 void CClp_free (CClp **lp)
289 {
290 if (*lp) {
291 if ((*lp)->cplex_env) {
292 if ((*lp)->cplex_lp) {
293 CPXfreeprob ((*lp)->cplex_env, &((*lp)->cplex_lp));
294 }
295 #ifdef CC_ONE_ENV
296 (*lp)->cplex_env = (CPXENVptr) NULL;
297 CClp_env_count--;
298 if (CClp_env_count == 0) {
299 CPXcloseCPLEX (&CClp_cplex_env);
300 CClp_cplex_env = (CPXENVptr) NULL;
301 }
302 #else
303 CPXcloseCPLEX (&((*lp)->cplex_env));
304 #endif
305 }
306 CC_FREE (*lp, CClp);
307 }
308 }
309
CClp_freelp(CClp ** lp)310 void CClp_freelp (CClp **lp)
311 {
312 if (*lp) {
313 if ((*lp)->cplex_lp) {
314 CPXfreeprob ((*lp)->cplex_env, &((*lp)->cplex_lp));
315 }
316 }
317 }
318
CClp_loadlp(CClp * lp,const char * name,int ncols,int nrows,int objsense,double * obj,double * rhs,char * sense,int * matbeg,int * matcnt,int * matind,double * matval,double * lb,double * ub)319 int CClp_loadlp (CClp *lp, const char *name, int ncols, int nrows,
320 int objsense, double *obj, double *rhs, char *sense, int *matbeg,
321 int *matcnt, int *matind, double *matval, double *lb, double *ub)
322 {
323 int rval = 0;
324 char nambuf[32];
325
326 /* We copy the name since CPXcreateprob doesn't declare name as const */
327 strncpy (nambuf, name, sizeof (nambuf));
328 nambuf[sizeof(nambuf)-1] = '\0';
329
330 lp->cplex_lp = CPXcreateprob (lp->cplex_env, &rval, nambuf);
331 if (!lp->cplex_lp || rval) {
332 fprintf (stderr, "CPXcreateprob failed, return code %d\n", rval);
333 return 1;
334 }
335
336 rval = CPXcopylp (lp->cplex_env, lp->cplex_lp, ncols, nrows,
337 objsense, obj, rhs, sense, matbeg, matcnt,
338 matind, matval, lb, ub, (double *) NULL);
339 if (rval) {
340 fprintf (stderr, "CPXcopylp failed, return code %d\n", rval);
341 return 1;
342 }
343
344 return 0;
345 }
346
CClp_create(CClp * lp,const char * name)347 int CClp_create (CClp *lp, const char *name)
348 {
349 int rval;
350 char nambuf[32];
351
352 /* We copy the name since CPXcreateprob doesn't declare name as const */
353 strncpy (nambuf, name, sizeof (nambuf));
354 nambuf[sizeof(nambuf)-1] = '\0';
355
356 lp->cplex_lp = CPXcreateprob (lp->cplex_env, &rval, nambuf);
357 if (!lp->cplex_lp || rval) {
358 fprintf (stderr, "CPXcreateprob failed, return code %d\n", rval);
359 return 1;
360 }
361 return 0;
362 }
363
CClp_new_row(CClp * lp,char sense,double rhs)364 int CClp_new_row (CClp *lp, char sense, double rhs)
365 {
366 int rval;
367 char asense[1];
368 double arhs[1];
369
370 asense[0] = sense;
371 arhs[0] = rhs;
372
373 rval = CPXnewrows (lp->cplex_env, lp->cplex_lp, 1, arhs, asense,
374 (double *) NULL, (char **) NULL);
375 if (rval) {
376 fprintf (stderr, "CPXnewrows failed\n");
377 return rval;
378 }
379 return 0;
380 }
381
CClp_change_sense(CClp * lp,int row,char sense)382 int CClp_change_sense (CClp *lp, int row, char sense)
383 {
384 int xindex[1];
385 char asense[1];
386 int rval;
387
388 xindex[0] = row;
389 asense[0] = sense;
390 rval = CPXchgsense (lp->cplex_env, lp->cplex_lp, 1, xindex, asense);
391 if (rval) {
392 fprintf (stderr, "CPXchgsense failed\n");
393 return rval;
394 }
395 return 0;
396 }
397
CClp_opt(CClp * lp,int method)398 int CClp_opt (CClp *lp, int method)
399 {
400 int rval = 0;
401
402 #ifdef CC_ONE_ENV
403 if (set_parameters (lp->cplex_env, &lp->cplex_params)) {
404 fprintf (stderr, "Unable to set optimization parameters\n");
405 }
406 #endif
407
408 switch (method) {
409 case CClp_METHOD_PRIMAL:
410 rval = primalopt (lp);
411 break;
412 case CClp_METHOD_DUAL:
413 rval = dualopt (lp);
414 break;
415 case CClp_METHOD_BARRIER:
416 rval = baropt (lp);
417 break;
418 default:
419 rval = 1;
420 fprintf (stderr, "Nonexistent method in CClp_opt\n");
421 break;
422 }
423 return rval;
424 }
425
primalopt(CClp * lp)426 static int primalopt (CClp *lp)
427 {
428 int rval;
429 int solstat;
430 #ifdef CC_CPLEX_WRITE_PRIMAL
431 static int probcnt = 0;
432 char probname[100];
433
434 sprintf (probname, "prim%d.sav", probcnt);
435 probcnt++;
436 printf ("Writing %s\n", probname);
437 CPXsavwrite (lp->cplex_env, lp->cplex_lp, probname);
438 #endif
439
440 rval = CPXprimopt (lp->cplex_env, lp->cplex_lp);
441 if (rval) {
442 if (rval == CPX_STAT_INForUNBD) {
443 int old, oldagg;
444 printf ("Cplex presolve failed, switch to simplex\n");
445 fflush (stdout);
446 if (CPXgetintparam (lp->cplex_env, CPX_PARAM_PREIND, &old)) {
447 fprintf (stderr, "CPXgetintparam CPX_PARAM_PREIND failed\n");
448 return 1;
449 }
450 if (CPXsetintparam (lp->cplex_env, CPX_PARAM_PREIND, CPX_OFF)) {
451 fprintf (stderr, "CPXsetintparam CPX_PARAM_PREIND failed\n");
452 return 1;
453 }
454 if (CPXgetintparam (lp->cplex_env, CPX_PARAM_AGGIND, &oldagg)) {
455 fprintf (stderr, "CPXgetintparam CPX_PARAM_AGGIND failed\n");
456 return 1;
457 }
458 if (CPXsetintparam (lp->cplex_env, CPX_PARAM_AGGIND, 0)) {
459 fprintf (stderr, "CPXsetintparam CPX_PARAM_AGGIND failed\n");
460 return 1;
461 }
462 rval = CPXprimopt (lp->cplex_env, lp->cplex_lp);
463 if (rval) {
464 fprintf (stderr, "CPXprimopt failed, return code %d\n", rval);
465 return 1;
466 }
467 if (CPXsetintparam (lp->cplex_env, CPX_PARAM_PREIND, old)) {
468 fprintf (stderr, "CPXsetintparam CPX_PARAM_PREIND failed\n");
469 return 1;
470 }
471 if (CPXsetintparam (lp->cplex_env, CPX_PARAM_AGGIND, oldagg)) {
472 fprintf (stderr, "CPXsetintparam CPX_PARAM_AGGIND failed\n");
473 return 1;
474 }
475 } else {
476 fprintf (stderr, "CPXprimopt failed, return code %d\n", rval);
477 return 1;
478 }
479 }
480 solstat = CPXgetstat (lp->cplex_env, lp->cplex_lp);
481 if (solstat == CPX_STAT_INFEASIBLE) {
482 return 2;
483 } else if (solstat != CPX_STAT_OPTIMAL &&
484 solstat != CPX_STAT_OPTIMAL_INFEAS ) {
485 fprintf (stderr, "Cplex optimization status %d\n", solstat);
486 return 1;
487 }
488 return 0;
489 }
490
dualopt(CClp * lp)491 static int dualopt (CClp *lp)
492 {
493 int rval;
494 int solstat;
495 #ifdef CC_CPLEX_WRITE_DUAL
496 static int probcnt = 0;
497 char probname[100];
498
499 sprintf (probname, "dual%d.sav", probcnt);
500 probcnt++;
501 printf ("Writing %s\n", probname);
502 CPXsavwrite (lp->cplex_env, lp->cplex_lp, probname);
503 #endif
504
505 rval = CPXdualopt (lp->cplex_env, lp->cplex_lp);
506 if (rval) {
507 if (rval == CPX_STAT_INForUNBD) {
508 int old, oldagg;
509 printf ("Cplex presolve failed, switch to simplex\n");
510 fflush (stdout);
511 if (CPXgetintparam (lp->cplex_env, CPX_PARAM_PREIND, &old)) {
512 fprintf (stderr, "CPXgetintparam CPX_PARAM_PREIND failed\n");
513 return 1;
514 }
515 if (CPXsetintparam (lp->cplex_env, CPX_PARAM_PREIND, CPX_OFF)) {
516 fprintf (stderr, "CPXsetintparam CPX_PARAM_PREIND failed\n");
517 return 1;
518 }
519 if (CPXgetintparam (lp->cplex_env, CPX_PARAM_AGGIND, &oldagg)) {
520 fprintf (stderr, "CPXgetintparam CPX_PARAM_AGGIND failed\n");
521 return 1;
522 }
523 if (CPXsetintparam (lp->cplex_env, CPX_PARAM_AGGIND, 0)) {
524 fprintf (stderr, "CPXsetintparam CPX_PARAM_AGGIND failed\n");
525 return 1;
526 }
527 rval = CPXdualopt (lp->cplex_env, lp->cplex_lp);
528 if (rval) {
529 fprintf (stderr, "CPXdualopt failed, return code %d\n", rval);
530 return 1;
531 }
532 if (CPXsetintparam (lp->cplex_env, CPX_PARAM_PREIND, old)) {
533 fprintf (stderr, "CPXsetintparam CPX_PARAM_PREIND failed\n");
534 return 1;
535 }
536 if (CPXsetintparam (lp->cplex_env, CPX_PARAM_AGGIND, oldagg)) {
537 fprintf (stderr, "CPXsetintparam CPX_PARAM_AGGIND failed\n");
538 return 1;
539 }
540 } else {
541 fprintf (stderr, "CPXdualopt failed, return code %d\n", rval);
542 return 1;
543 }
544 }
545 solstat = CPXgetstat (lp->cplex_env, lp->cplex_lp);
546 if (solstat == CPX_STAT_INFEASIBLE) {
547 return 2;
548 } else if (solstat != CPX_STAT_OPTIMAL &&
549 solstat != CPX_STAT_OPTIMAL_INFEAS ) {
550 fprintf (stderr, "Cplex optimization status %d\n", solstat);
551 if (solstat == CPX_STAT_ABORT_IT_LIM) {
552 int itlim;
553 rval = CPXgetintparam (lp->cplex_env, CPX_PARAM_ITLIM, &itlim);
554 if (!rval) {
555 printf ("cplex iteration limit: %d\n", itlim);
556 fflush (stdout);
557 }
558 }
559 return 1;
560 }
561 return 0;
562 }
563
baropt(CClp * lp)564 static int baropt (CClp *lp)
565 {
566 int rval;
567 int solstat;
568 #ifdef CC_CPLEX_WRITE_BARRIER
569 static int probcnt = 0;
570 char probname[100];
571
572 sprintf (probname, "barrier%d.sav", probcnt);
573 probcnt++;
574 printf ("Writing %s\n", probname);
575 CPXsavwrite (lp->cplex_env, lp->cplex_lp, probname);
576 #endif
577
578 rval = CPXbaropt (lp->cplex_env, lp->cplex_lp);
579 if (rval) {
580 printf ("CPXbaropt failed, return code %d, calling CPXdualopt\n",
581 rval);
582 return dualopt (lp);
583 }
584 solstat = CPXgetstat (lp->cplex_env, lp->cplex_lp);
585 if (solstat != CPX_STAT_OPTIMAL) {
586 printf ("CPXbaropt returned non-optimal solution, calling CPXdualopt\n");
587 return dualopt (lp);
588 }
589 return 0;
590 }
591
592 #define CC_MAX_REFACTORFREQ 150
593
CClp_limited_dualopt(CClp * lp,int iterationlim,int * status,double * objupperlim)594 int CClp_limited_dualopt (CClp *lp, int iterationlim, int *status,
595 double *objupperlim)
596 {
597 int rval = 0;
598 int sval = 0;
599 int solstat;
600 int dfeasind;
601
602 int got_iterationlim = 0;
603 int got_presolveind = 0;
604 int got_aggregateind = 0;
605 int got_objupperlim = 0;
606 int got_refactorfreq = 0;
607 int got_perind = 0;
608
609 int old_iterationlim;
610 int old_presolveind;
611 int old_aggregateind;
612 double old_objupperlim;
613 int old_refactorfreq;
614 int old_perind;
615
616 #ifdef CC_ONE_ENV
617 if (set_parameters (lp->cplex_env, &lp->cplex_params)) {
618 fprintf (stderr, "Unable to set optimization parameters\n");
619 }
620 #endif
621
622 /* REB, 14 October 1997: If perturbation has been turned on elsewhere,
623 we need to turn it off for branch selection */
624
625 rval = CPXgetintparam (lp->cplex_env, CPX_PARAM_PERIND, &old_perind);
626 if (rval) {
627 fprintf (stderr, "CPXgetintparam CPX_PARAM_PERIND failed\n");
628 goto CLEANUP;
629 }
630 got_perind = 1;
631
632 rval = CPXgetintparam (lp->cplex_env, CPX_PARAM_ITLIM, &old_iterationlim);
633 if (rval) {
634 fprintf (stderr, "CPXgetintparam CPX_PARAM_ITLIM failed\n");
635 goto CLEANUP;
636 }
637 got_iterationlim = 1;
638
639 rval = CPXgetdblparam (lp->cplex_env, CPX_PARAM_OBJULIM, &old_objupperlim);
640 if (rval) {
641 fprintf (stderr, "CPXgetdblparam CPX_PARAM_OBJULIM failed\n");
642 goto CLEANUP;
643 }
644 got_objupperlim = 1;
645
646 rval = CPXgetintparam (lp->cplex_env, CPX_PARAM_PREIND, &old_presolveind);
647 if (rval) {
648 fprintf (stderr, "CPXgetintparam CPX_PARAM_PREIND failed\n");
649 goto CLEANUP;
650 }
651 got_presolveind = 1;
652
653 rval = CPXgetintparam (lp->cplex_env, CPX_PARAM_AGGIND, &old_aggregateind);
654 if (rval) {
655 fprintf (stderr, "CPXgetintparam CPX_PARAM_AGGIND failed\n");
656 goto CLEANUP;
657 }
658 got_aggregateind = 1;
659
660 rval = CPXgetintparam (lp->cplex_env, CPX_PARAM_REINV, &old_refactorfreq);
661 if (rval) {
662 fprintf (stderr, "CPXgetintparam CPX_PARAM_REINV failed\n");
663 goto CLEANUP;
664 }
665 got_refactorfreq = 1;
666
667 rval = CPXsetintparam (lp->cplex_env, CPX_PARAM_PERIND, 0);
668 if (rval) {
669 fprintf (stderr, "CPXsetintparam CPX_PARAM_PERIND failed\n");
670 goto CLEANUP;
671 }
672
673 rval = CPXsetintparam (lp->cplex_env, CPX_PARAM_ITLIM, iterationlim);
674 if (rval) {
675 fprintf (stderr, "CPXsetintparam CPX_PARAM_ITLIM failed\n");
676 goto CLEANUP;
677 }
678
679 if ( iterationlim < CC_MAX_REFACTORFREQ ) {
680 rval = CPXsetintparam (lp->cplex_env, CPX_PARAM_REINV, iterationlim+1);
681 if (rval) {
682 fprintf (stderr, "CPXsetintparam CPX_PARAM_REINV failed\n");
683 goto CLEANUP;
684 }
685 }
686
687 if (objupperlim) {
688 rval = CPXsetdblparam (lp->cplex_env, CPX_PARAM_OBJULIM, *objupperlim);
689 if (rval) {
690 fprintf (stderr, "CPXsetdblparam CPX_PARAM_OBJULIM failed\n");
691 goto CLEANUP;
692 }
693 }
694
695 rval = CPXdualopt (lp->cplex_env, lp->cplex_lp);
696 if (rval) {
697 if (rval == CPX_STAT_INForUNBD) {
698 printf ("Cplex presolve failed, force simplex\n");
699 fflush (stdout);
700
701 if (CPXsetintparam (lp->cplex_env, CPX_PARAM_PREIND, CPX_OFF)) {
702 fprintf (stderr, "CPXsetintparam CPX_PARAM_PREIND failed\n");
703 goto CLEANUP;
704 }
705 if (CPXsetintparam (lp->cplex_env, CPX_PARAM_AGGIND, 0)) {
706 fprintf (stderr, "CPXsetintparam CPX_PARAM_AGGIND failed\n");
707 goto CLEANUP;
708 }
709 rval = CPXdualopt (lp->cplex_env, lp->cplex_lp);
710 if (rval) {
711 fprintf (stderr, "CPXdualopt failed, return code %d\n", rval);
712 goto CLEANUP;
713 }
714 } else {
715 fprintf (stderr, "CPXdualopt failed, return code %d\n", rval);
716 goto CLEANUP;
717 }
718 }
719 solstat = CPXgetstat (lp->cplex_env, lp->cplex_lp);
720 rval = CPXsolninfo (lp->cplex_env, lp->cplex_lp, NULL, NULL, NULL,
721 &dfeasind);
722 if ( rval ) {
723 fprintf (stderr, "CPXsolninfo dfeasind failed\n");
724 goto CLEANUP;
725 }
726 if ( solstat==CPX_STAT_ABORT_IT_LIM &&
727 !dfeasind ) {
728 rval = CPXsetdblparam (lp->cplex_env, CPX_PARAM_OBJULIM, -1.0E75);
729 if (rval) {
730 fprintf (stderr, "CPXsetdblparam CPX_PARAM_OBJULIM failed\n");
731 goto CLEANUP;
732 }
733 /* We could be even more aggressive here and make the iteration
734 limit infinite, but that approach seems contrary to the
735 intent of this function. Hence, the repeat test for
736 CPX_IT_LIM_INFEAS below -- REB, 1 July 97 */
737 rval = CPXdualopt (lp->cplex_env, lp->cplex_lp);
738 if (rval) {
739 fprintf (stderr, "CPXdualopt failed, return code %d\n", rval);
740 goto CLEANUP;
741 }
742 solstat = CPXgetstat (lp->cplex_env, lp->cplex_lp);
743 rval = CPXsolninfo (lp->cplex_env, lp->cplex_lp, NULL, NULL, NULL,
744 &dfeasind);
745 if ( rval ) {
746 fprintf (stderr, "CPXsolninfo dfeasind failed\n");
747 goto CLEANUP;
748 }
749 }
750
751 if (solstat == CPX_STAT_INFEASIBLE) {
752 printf ("Infeasible in CPXdualopt\n"); fflush (stdout);
753 if (status) *status = CClp_INFEASIBLE;
754 } else if (solstat == CPX_STAT_ABORT_IT_LIM &&
755 !dfeasind ) {
756 printf ("LP infeasible after the limited number of iterations\n");
757 fflush (stdout);
758 if (status) *status = CClp_UNKNOWN;
759 } else if (solstat != CPX_STAT_OPTIMAL &&
760 solstat != CPX_STAT_OPTIMAL_INFEAS &&
761 solstat != CPX_STAT_ABORT_OBJ_LIM &&
762 (solstat != CPX_STAT_ABORT_IT_LIM ||
763 !dfeasind ) ) {
764 fprintf (stderr, "Cplex optimization status %d\n", solstat);
765 if (status) *status = CClp_FAILURE;
766 } else {
767 if (status) *status = CClp_SUCCESS;
768 }
769
770 CLEANUP:
771
772 if (got_iterationlim == 1) {
773 sval = CPXsetintparam (lp->cplex_env, CPX_PARAM_ITLIM,
774 old_iterationlim);
775 if (sval) {
776 fprintf (stderr, "CPXsetintparam CPX_PARAM_ITLIM failed\n");
777 rval = 1;
778 }
779 }
780
781 if (got_objupperlim == 1) {
782 sval = CPXsetdblparam (lp->cplex_env, CPX_PARAM_OBJULIM,
783 old_objupperlim);
784 if (sval) {
785 fprintf (stderr, "CPXsetdblparam CPX_PARAM_OBJULIM failed\n");
786 rval = 1;
787 }
788 }
789
790 if (got_presolveind == 1) {
791 sval = CPXsetintparam (lp->cplex_env, CPX_PARAM_PREIND,
792 old_presolveind);
793 if (sval) {
794 fprintf (stderr, "CPXsetintparam CPX_PARAM_PREIND failed\n");
795 rval = 1;
796 }
797 }
798
799 if (got_aggregateind == 1) {
800 sval = CPXsetintparam (lp->cplex_env, CPX_PARAM_AGGIND,
801 old_aggregateind);
802 if (sval) {
803 fprintf (stderr, "CPXsetintparam CPX_PARAM_AGGIND failed\n");
804 rval = 1;
805 }
806 }
807
808 if (got_refactorfreq == 1) {
809 sval = CPXsetintparam (lp->cplex_env, CPX_PARAM_REINV,
810 old_refactorfreq);
811 if (sval) {
812 fprintf (stderr, "CPXsetintparam CPX_PARAM_REINV failed\n");
813 rval = 1;
814 }
815 }
816
817 if (got_perind == 1) {
818 sval = CPXsetintparam (lp->cplex_env, CPX_PARAM_PERIND, old_perind);
819 if (sval) {
820 fprintf (stderr, "CPXsetintparam CPX_PARAM_PERIND failed\n");
821 rval = 1;;
822 }
823 }
824
825 if (rval && status) {
826 *status = CClp_FAILURE;
827 }
828
829 return rval;
830 }
831
CClp_addrows(CClp * lp,int newrows,int newnz,double * rhs,char * sense,int * rmatbeg,int * rmatind,double * rmatval)832 int CClp_addrows (CClp *lp, int newrows, int newnz, double *rhs, char *sense,
833 int *rmatbeg, int *rmatind, double *rmatval)
834 {
835 int rval = 0;
836
837 rval = CPXaddrows (lp->cplex_env, lp->cplex_lp, 0, newrows, newnz,
838 rhs, sense, rmatbeg, rmatind, rmatval,
839 (char **) NULL, (char **) NULL);
840 if (rval) fprintf (stderr, "CPXaddrows failed\n");
841 return rval;
842 }
843
CClp_addcols(CClp * lp,int newcols,int newnz,double * obj,int * cmatbeg,int * cmatind,double * cmatval,double * lb,double * ub)844 int CClp_addcols (CClp *lp, int newcols, int newnz, double *obj,
845 int *cmatbeg, int *cmatind, double *cmatval,
846 double *lb, double *ub)
847 {
848 int rval = 0;
849
850 rval = CPXaddcols (lp->cplex_env, lp->cplex_lp, newcols, newnz, obj,
851 cmatbeg, cmatind, cmatval, lb, ub, (char **) NULL);
852 if (rval) fprintf (stderr, "CPXaddcols failed\n");
853 return rval;
854 }
855
CClp_delete_row(CClp * lp,int i)856 int CClp_delete_row (CClp *lp, int i)
857 {
858 int rval = 0;
859 int locali[1];
860
861 #ifdef CC_ONE_ENV
862 if (set_parameters (lp->cplex_env, &lp->cplex_params)) {
863 fprintf (stderr, "Unable to set optimization parameters\n");
864 }
865 #endif
866
867 locali[0] = i;
868 if (CPXpivotin (lp->cplex_env, lp->cplex_lp, locali, 1)) {
869 fprintf (stderr, "CPXpivotin failed, continuing anyway\n");
870 }
871 rval = CPXdelrows (lp->cplex_env, lp->cplex_lp, i, i);
872 if (rval) fprintf (stderr, "CPXdelrows failed\n");
873 return rval;
874 }
875
CClp_delete_set_of_rows(CClp * lp,int * delstat)876 int CClp_delete_set_of_rows (CClp *lp, int *delstat)
877 {
878 int rval = 0;
879 int *dellist = (int *) NULL;
880 int delcnt = 0;
881 int i;
882 int j;
883 int rcnt = CPXgetnumrows (lp->cplex_env, lp->cplex_lp);
884
885 #ifdef CC_ONE_ENV
886 if (set_parameters (lp->cplex_env, &lp->cplex_params)) {
887 fprintf (stderr, "Unable to set optimization parameters\n");
888 }
889 #endif
890
891 for (i=0; i<rcnt; i++) {
892 if (delstat[i]) delcnt++;
893 }
894 if (delcnt == 0) {
895 fprintf (stderr, "delete_set_of_rows with no deleted rows\n");
896 return 0;
897 }
898 dellist = CC_SAFE_MALLOC (delcnt, int);
899 if (dellist == (int *) NULL) {
900 fprintf (stderr, "Out of memory in delete_set_of_rows\n");
901 return 1;
902 }
903 for (i=0, j=0; i<rcnt; i++) {
904 if (delstat[i]) {
905 dellist[j++] = i;
906 }
907 }
908 if (j != delcnt) {
909 fprintf (stderr, "Lost some deleted rows\n");
910 CC_FREE (dellist, int);
911 return 1;
912 }
913
914 if (CPXpivotin (lp->cplex_env, lp->cplex_lp, dellist, delcnt)) {
915 fprintf (stderr, "CPXpivotin failed, continuing anyway\n");
916 }
917 CC_FREE (dellist, int);
918
919 rval = CPXdelsetrows (lp->cplex_env, lp->cplex_lp, delstat);
920 if (rval) fprintf (stderr, "CPXdelsetrows failed\n");
921 return rval;
922 }
923
CClp_delete_column(CClp * lp,int i)924 int CClp_delete_column (CClp *lp, int i)
925 {
926 int rval = 0;
927 int locali[1];
928 char lu[1];
929 double bd[1];
930
931 #ifdef CC_ONE_ENV
932 if (set_parameters (lp->cplex_env, &lp->cplex_params)) {
933 fprintf (stderr, "Unable to set optimization parameters\n");
934 }
935 #endif
936
937 locali[0] = i;
938 lu[0] = 'B';
939 bd[0] = 0.0;
940
941 if (CPXchgbds (lp->cplex_env, lp->cplex_lp, 1, locali, lu, bd)) {
942 fprintf (stderr, "CPXchgbds failed, continuing anyway\n");
943 }
944
945 if (CPXdualopt (lp->cplex_env, lp->cplex_lp)) {
946 fprintf (stderr, "CPXdualopt failed, continuing anyway\n");
947 }
948
949 if (CPXpivotout (lp->cplex_env, lp->cplex_lp, locali, 1)) {
950 fprintf (stderr, "CPXpivotout failed, continuing anyway\n");
951 }
952
953 rval = CPXdelcols (lp->cplex_env, lp->cplex_lp, i, i);
954 if (rval) fprintf (stderr, "CPXdelcols failed\n");
955 return rval;
956 }
957
CClp_delete_set_of_columns(CClp * lp,int * delstat)958 int CClp_delete_set_of_columns (CClp *lp, int *delstat)
959 {
960 int rval = 0;
961 int *dellist = (int *) NULL;
962 char *lu = (char *) NULL;
963 double *bd = (double *) NULL;
964 int delcnt = 0;
965 int i;
966 int j;
967 int ccnt = CPXgetnumcols (lp->cplex_env, lp->cplex_lp);
968
969 #ifdef CC_ONE_ENV
970 if (set_parameters (lp->cplex_env, &lp->cplex_params)) {
971 fprintf (stderr, "Unable to set optimization parameters\n");
972 }
973 #endif
974
975 for (i=0; i<ccnt; i++) {
976 if (delstat[i]) delcnt++;
977 }
978 if (delcnt == 0) {
979 fprintf (stderr, "delete_set_of_columns with no deleted columns\n");
980 return 0;
981 }
982 dellist = CC_SAFE_MALLOC (delcnt, int);
983 lu = CC_SAFE_MALLOC (delcnt, char);
984 bd = CC_SAFE_MALLOC (delcnt, double);
985 if (dellist == (int *) NULL ||
986 lu == (char *) NULL ||
987 bd == (double *) NULL) {
988 fprintf (stderr, "Out of memory in delete_set_of_columns\n");
989 CC_IFFREE (dellist, int);
990 CC_IFFREE (lu, char);
991 CC_IFFREE (bd, double);
992 return 1;
993 }
994 for (i=0, j=0; i<ccnt; i++) {
995 if (delstat[i]) {
996 lu[j] = 'B';
997 bd[j] = 0.0;
998 dellist[j++] = i;
999 }
1000 }
1001 if (j != delcnt) {
1002 fprintf (stderr, "Lost some deleted columns\n");
1003 CC_FREE (dellist, int);
1004 CC_FREE (lu, char);
1005 CC_FREE (bd, double);
1006 return 1;
1007 }
1008
1009 if (CPXchgbds (lp->cplex_env, lp->cplex_lp, delcnt, dellist, lu, bd)) {
1010 fprintf (stderr, "CPXchgbds failed, stumbling on anyway\n");
1011 }
1012
1013 if (CPXdualopt (lp->cplex_env, lp->cplex_lp)) {
1014 fprintf (stderr, "CPXdualopt failed, continuing anyway\n");
1015 }
1016
1017 if (CPXpivotout (lp->cplex_env, lp->cplex_lp, dellist, delcnt)) {
1018 fprintf (stderr, "CPXpivotout failed, continuing anyway\n");
1019 }
1020
1021 CC_FREE (dellist, int);
1022 CC_FREE (lu, char);
1023 CC_FREE (bd, double);
1024
1025 rval = CPXdelsetcols (lp->cplex_env, lp->cplex_lp, delstat);
1026 if (rval) fprintf (stderr, "CPXdelsetcols failed\n");
1027 return rval;
1028 }
1029
CClp_setbnd(CClp * lp,int col,char lower_or_upper,double bnd)1030 int CClp_setbnd (CClp *lp, int col, char lower_or_upper, double bnd)
1031 {
1032 int cindex[1];
1033 double bd[1];
1034 char lu[1];
1035 int rval;
1036
1037 cindex[0] = col;
1038 lu[0] = lower_or_upper;
1039 bd[0] = bnd;
1040
1041 rval = CPXchgbds (lp->cplex_env, lp->cplex_lp, 1, cindex, lu, bd);
1042 if (rval) {
1043 fprintf (stderr, "Couldn't set bnd on variable %d in cplex\n", col);
1044 return rval;
1045 }
1046 return 0;
1047 }
1048
CClp_get_warmstart(CClp * lp,CClp_warmstart ** w)1049 int CClp_get_warmstart (CClp *lp, CClp_warmstart **w)
1050 {
1051 int rval = 0;
1052
1053 CClp_free_warmstart (w);
1054
1055 (*w) = CC_SAFE_MALLOC (1, CClp_warmstart);
1056 if ((*w) == (CClp_warmstart *) NULL) {
1057 fprintf (stderr, "Out of memory in CClp_get_warmstart\n");
1058 rval = 1; goto CLEANUP;
1059 }
1060
1061 (*w)->ccount = 0;
1062 (*w)->rcount = 0;
1063 (*w)->cstat = (int *) NULL;
1064 (*w)->rstat = (int *) NULL;
1065 (*w)->dnorm = (double *) NULL;
1066
1067 (*w)->ccount = CPXgetnumcols (lp->cplex_env, lp->cplex_lp);
1068 if ((*w)->ccount == 0) {
1069 fprintf (stderr, "No columns in LP\n");
1070 rval = 1; goto CLEANUP;
1071 }
1072 (*w)->rcount = CPXgetnumrows (lp->cplex_env, lp->cplex_lp);
1073 if ((*w)->rcount == 0) {
1074 fprintf (stderr ,"No rows in LP\n");
1075 rval = 1; goto CLEANUP;
1076 }
1077
1078 (*w)->cstat = CC_SAFE_MALLOC ((*w)->ccount, int);
1079 (*w)->rstat = CC_SAFE_MALLOC ((*w)->rcount, int);
1080 (*w)->dnorm = CC_SAFE_MALLOC ((*w)->rcount, double);
1081 if (!(*w)->cstat || !(*w)->rstat || !(*w)->dnorm) {
1082 fprintf (stderr, "out of memory in CClp_get_warmstart\n");
1083 rval = 1; goto CLEANUP;
1084 }
1085
1086 rval = CPXgetbasednorms (lp->cplex_env, lp->cplex_lp, (*w)->cstat,
1087 (*w)->rstat, (*w)->dnorm);
1088 if (rval) {
1089 fprintf (stderr, "CPXgetbasednorms failed, trying to get basis\n");
1090 CC_IFFREE ((*w)->dnorm, double);
1091 rval = CPXgetbase (lp->cplex_env, lp->cplex_lp, (*w)->cstat,
1092 (*w)->rstat);
1093 if (rval) {
1094 fprintf (stderr, "CPXgetbase failed\n"); goto CLEANUP;
1095 }
1096 }
1097
1098 return 0;
1099
1100 CLEANUP:
1101
1102 CClp_free_warmstart (w);
1103 return rval;
1104 }
1105
CClp_load_warmstart(CClp * lp,CClp_warmstart * w)1106 int CClp_load_warmstart (CClp *lp, CClp_warmstart *w)
1107 {
1108 int rval = 0;
1109
1110 if (w->cstat && w->rstat && w->dnorm) {
1111 rval = CPXcopybasednorms (lp->cplex_env, lp->cplex_lp, w->cstat,
1112 w->rstat, w->dnorm);
1113 if (rval) {
1114 fprintf (stderr, "CPXcopybasednorms failed\n"); goto CLEANUP;
1115 }
1116 } else if (w->cstat && w->rstat) {
1117 rval = CPXcopybase (lp->cplex_env, lp->cplex_lp, w->cstat, w->rstat);
1118 if (rval) {
1119 fprintf (stderr, "CPXcopybase failed\n"); goto CLEANUP;
1120 }
1121 } else {
1122 printf ("WARNING: No basis in call to load_warmstart\n");
1123 fflush (stdout);
1124 }
1125
1126 CLEANUP:
1127
1128 return rval;
1129 }
1130
CClp_build_warmstart(CClp_warmstart ** w,CClp_info * i)1131 int CClp_build_warmstart (CClp_warmstart **w, CClp_info *i)
1132 {
1133 int rval = 0;
1134 int j;
1135
1136 CClp_free_warmstart (w);
1137
1138 (*w) = CC_SAFE_MALLOC (1, CClp_warmstart);
1139 if ((*w) == (CClp_warmstart *) NULL) {
1140 fprintf (stderr, "Out of memory in CClp_get_warmstart\n");
1141 rval = 1; goto CLEANUP;
1142 }
1143
1144 (*w)->ccount = 0;
1145 (*w)->rcount = 0;
1146 (*w)->cstat = (int *) NULL;
1147 (*w)->rstat = (int *) NULL;
1148 (*w)->dnorm = (double *) NULL;
1149
1150 (*w)->ccount = i->ccount;
1151 if ((*w)->ccount == 0) {
1152 fprintf (stderr, "No columns in CClp_info\n");
1153 rval = 1; goto CLEANUP;
1154 }
1155 (*w)->rcount = i->rcount;
1156 if ((*w)->rcount == 0) {
1157 fprintf (stderr, "No rows in CClp_info\n");
1158 rval = 1; goto CLEANUP;
1159 }
1160
1161 (*w)->cstat = CC_SAFE_MALLOC ((*w)->ccount, int);
1162 (*w)->rstat = CC_SAFE_MALLOC ((*w)->rcount, int);
1163 if (!(*w)->cstat || !(*w)->rstat) {
1164 fprintf (stderr, "out of memory in CClp_get_warmstart\n");
1165 rval = 1; goto CLEANUP;
1166 }
1167
1168 for (j=0; j<(*w)->ccount; j++) {
1169 (*w)->cstat[j] = i->cstat[j];
1170 }
1171 for (j=0; j<(*w)->rcount; j++) {
1172 (*w)->rstat[j] = i->rstat[j];
1173 }
1174
1175 return 0;
1176
1177 CLEANUP:
1178 CClp_free_warmstart (w);
1179 return rval;
1180 }
1181
CClp_free_warmstart(CClp_warmstart ** w)1182 void CClp_free_warmstart (CClp_warmstart **w)
1183 {
1184 if (*w != (CClp_warmstart *) NULL) {
1185 CC_IFFREE ((*w)->cstat, int);
1186 CC_IFFREE ((*w)->rstat, int);
1187 CC_IFFREE ((*w)->dnorm, double);
1188 CC_FREE (*w, CClp_warmstart);
1189 }
1190 }
1191
CClp_sread_warmstart(CC_SFILE * f,CClp_warmstart ** w)1192 int CClp_sread_warmstart (CC_SFILE *f, CClp_warmstart **w)
1193 {
1194 char name[5];
1195 int i;
1196 int ccount;
1197 int rcount;
1198 int has_dnorms;
1199
1200 CClp_free_warmstart (w);
1201
1202 for (i=0; i<4; i++) {
1203 if (CCutil_sread_char (f, &name[i])) goto CLEANUP;
1204 }
1205 name[4] = '\0';
1206
1207 if (strncmp (name, SOLVER_WARMSTART_NAME, 4)) {
1208 fprintf (stderr, "warmstart for another solver (%s) ignored\n", name);
1209 return 0;
1210 }
1211
1212 if (CCutil_sread_int (f, &ccount)) goto CLEANUP;
1213 if (CCutil_sread_int (f, &rcount)) goto CLEANUP;
1214
1215 (*w) = CC_SAFE_MALLOC (1, CClp_warmstart);
1216 if ((*w) == (CClp_warmstart *) NULL) {
1217 fprintf (stderr, "Out of memory in CClp_sread_warmstart\n");
1218 goto CLEANUP;
1219 }
1220
1221 (*w)->ccount = 0;
1222 (*w)->rcount = 0;
1223 (*w)->cstat = (int *) NULL;
1224 (*w)->rstat = (int *) NULL;
1225 (*w)->dnorm = (double *) NULL;
1226
1227 (*w)->cstat = CC_SAFE_MALLOC (ccount, int);
1228 (*w)->rstat = CC_SAFE_MALLOC (rcount, int);
1229 if ((*w)->cstat == (int *) NULL ||
1230 (*w)->rstat == (int *) NULL) {
1231 fprintf (stderr, "out of memory in CClp_sread_warmstart\n");
1232 goto CLEANUP;
1233 }
1234 for (i = 0; i < ccount; i++) {
1235 if (CCutil_sread_bits (f, &(((*w)->cstat)[i]), 2))
1236 goto CLEANUP;
1237 }
1238 for (i = 0; i < rcount; i++) {
1239 if (CCutil_sread_bits (f, &(((*w)->rstat)[i]), 1))
1240 goto CLEANUP;
1241 }
1242
1243 if (CCutil_sread_int (f, &has_dnorms)) goto CLEANUP;
1244
1245 if (has_dnorms) {
1246 (*w)->dnorm = CC_SAFE_MALLOC (rcount, double);
1247 if ((*w)->dnorm == (double *) NULL) {
1248 fprintf (stderr, "out of memory in CClp_sread_warmstart\n");
1249 goto CLEANUP;
1250 }
1251 for (i = 0; i < rcount; i++) {
1252 if (CCutil_sread_double (f, &(((*w)->dnorm)[i]))) goto CLEANUP;
1253 }
1254 }
1255
1256 (*w)->ccount = ccount;
1257 (*w)->rcount = rcount;
1258
1259 return 0;
1260
1261 CLEANUP:
1262
1263 CClp_free_warmstart (w);
1264 return 1;
1265 }
1266
CClp_swrite_warmstart(CC_SFILE * f,CClp_warmstart * w)1267 int CClp_swrite_warmstart (CC_SFILE *f, CClp_warmstart *w)
1268 {
1269 int i;
1270 const char *name = SOLVER_WARMSTART_NAME;
1271
1272 for (i=0; i<4; i++) {
1273 if (CCutil_swrite_char (f, name[i])) return 1;
1274 }
1275
1276 if (CCutil_swrite_int (f, w->ccount)) return 1;
1277 if (CCutil_swrite_int (f, w->rcount)) return 1;
1278
1279 for (i = 0; i < w->ccount; i++) {
1280 if (CCutil_swrite_bits (f, w->cstat[i], 2)) return 1;
1281 }
1282
1283 for (i = 0; i < w->rcount; i++) {
1284 if (CCutil_swrite_bits (f, w->rstat[i], 1)) return 1;
1285 }
1286
1287 if (w->dnorm == (double *) NULL) {
1288 if (CCutil_swrite_int (f, 0)) return 1;
1289 } else {
1290 if (CCutil_swrite_int (f, 1)) return 1;
1291 for (i = 0; i < w->rcount; i++) {
1292 if (CCutil_swrite_double (f, w->dnorm[i])) return 1;
1293 }
1294 }
1295
1296 return 0;
1297 }
1298
CClp_get_info(CClp * lp,CClp_info ** i)1299 int CClp_get_info (CClp *lp, CClp_info **i)
1300 {
1301 int rval = 0;
1302
1303 CClp_free_info (i);
1304
1305 (*i) = CC_SAFE_MALLOC (1, CClp_info);
1306 if ((*i) == (CClp_info *) NULL) {
1307 fprintf (stderr, "Out of memory in CClp_get_info\n");
1308 rval = 1; goto CLEANUP;
1309 }
1310
1311 (*i)->ccount = 0;
1312 (*i)->rcount = 0;
1313 (*i)->cstat = (int *) NULL;
1314 (*i)->rstat = (int *) NULL;
1315
1316 (*i)->ccount = CPXgetnumcols (lp->cplex_env, lp->cplex_lp);
1317 if ((*i)->ccount == 0) {
1318 fprintf (stderr, "No columns in CClp_get_info\n");
1319 rval = 1; goto CLEANUP;
1320 }
1321 (*i)->rcount = CPXgetnumrows (lp->cplex_env, lp->cplex_lp);
1322 if ((*i)->rcount == 0) {
1323 fprintf (stderr ,"No rows in CClp_get_info\n");
1324 rval = 1; goto CLEANUP;
1325 }
1326
1327 (*i)->cstat = CC_SAFE_MALLOC ((*i)->ccount, int);
1328 (*i)->rstat = CC_SAFE_MALLOC ((*i)->rcount, int);
1329 if (!(*i)->cstat || !(*i)->rstat) {
1330 fprintf (stderr, "out of memory in CClp_get_info\n");
1331 rval = 1; goto CLEANUP;
1332 }
1333
1334 rval = CPXgetbase (lp->cplex_env, lp->cplex_lp, (*i)->cstat, (*i)->rstat);
1335 if (rval) {
1336 fprintf (stderr, "CPXgetbase failed\n"); goto CLEANUP;
1337 }
1338
1339 return 0;
1340
1341 CLEANUP:
1342
1343 CClp_free_info (i);
1344 return rval;
1345 }
1346
CClp_create_info(CClp_info ** i,int rcount,int ccount)1347 int CClp_create_info (CClp_info **i, int rcount, int ccount)
1348 {
1349 int rval = 0;
1350 int j;
1351
1352 CClp_free_info (i);
1353
1354 (*i) = CC_SAFE_MALLOC (1, CClp_info);
1355 if ((*i) == (CClp_info *) NULL) {
1356 fprintf (stderr, "Out of memory in CClp_create_info\n");
1357 rval = 1; goto CLEANUP;
1358 }
1359
1360 (*i)->ccount = 0;
1361 (*i)->rcount = 0;
1362 (*i)->cstat = (int *) NULL;
1363 (*i)->rstat = (int *) NULL;
1364
1365 (*i)->ccount = ccount;
1366 if (ccount == 0) {
1367 fprintf (stderr, "No columns in CClp_create_info\n");
1368 rval = 1; goto CLEANUP;
1369 }
1370 (*i)->rcount = rcount;
1371 if (rcount == 0) {
1372 fprintf (stderr, "No rows in CClp_create_info\n");
1373 rval = 1; goto CLEANUP;
1374 }
1375
1376 (*i)->cstat = CC_SAFE_MALLOC ((*i)->ccount, int);
1377 (*i)->rstat = CC_SAFE_MALLOC ((*i)->rcount, int);
1378 if (!(*i)->cstat || !(*i)->rstat) {
1379 fprintf (stderr, "out of memory in CClp_create_info\n");
1380 rval = 1; goto CLEANUP;
1381 }
1382
1383 for (j=0; j<ccount; j++) {
1384 (*i)->cstat[j] = 0;
1385 }
1386 for (j=0; j<rcount; j++) {
1387 (*i)->rstat[j] = 0;
1388 }
1389
1390 return 0;
1391
1392 CLEANUP:
1393 CClp_free_info (i);
1394 return rval;
1395 }
1396
CClp_is_col_active(CClp_info * i,int c)1397 int CClp_is_col_active (CClp_info *i, int c)
1398 {
1399 if (c < 0 || c >= i->ccount) return 0;
1400 return i->cstat[c] == 1 || i->cstat[c] == 2;
1401 }
1402
CClp_is_row_active(CClp_info * i,int r)1403 int CClp_is_row_active (CClp_info *i, int r)
1404 {
1405 if (r < 0 || r >= i->rcount) return 0;
1406 return i->rstat[r] == 0;
1407 }
1408
CClp_set_col_active(CClp_info * i,int c)1409 void CClp_set_col_active (CClp_info *i, int c)
1410 {
1411 if (c >= 0 && c < i->ccount) i->cstat[c] = 1;
1412 }
1413
CClp_set_col_inactive(CClp_info * i,int c)1414 void CClp_set_col_inactive (CClp_info *i, int c)
1415 {
1416 if (c >= 0 && c < i->ccount) i->cstat[c] = 0;
1417 }
1418
CClp_set_col_upper(CClp_info * i,int c)1419 void CClp_set_col_upper (CClp_info *i, int c)
1420 {
1421 if (c >= 0 && c < i->ccount) i->cstat[c] = 2;
1422 }
1423
CClp_set_row_active(CClp_info * i,int r)1424 void CClp_set_row_active (CClp_info *i, int r)
1425 {
1426 if (r >= 0 && r < i->rcount) i->rstat[r] = 0;
1427 }
1428
CClp_set_row_inactive(CClp_info * i,int r)1429 void CClp_set_row_inactive (CClp_info *i, int r)
1430 {
1431 if (r >= 0 && r < i->rcount) i->rstat[r] = 1;
1432 }
1433
CClp_free_info(CClp_info ** i)1434 void CClp_free_info (CClp_info **i)
1435 {
1436 if ((*i) != (CClp_info *) NULL) {
1437 CC_IFFREE ((*i)->cstat, int);
1438 CC_IFFREE ((*i)->rstat, int);
1439 CC_FREE (*i, CClp_info);
1440 }
1441 }
1442
CClp_x(CClp * lp,double * x)1443 int CClp_x (CClp *lp, double *x)
1444 {
1445 int rval = 0;
1446 int ncols;
1447
1448 ncols = CPXgetnumcols (lp->cplex_env, lp->cplex_lp);
1449 if (ncols == 0) {
1450 fprintf (stderr, "No columns in LP\n");
1451 return 1;
1452 }
1453 rval = CPXgetx (lp->cplex_env, lp->cplex_lp, x, 0, ncols - 1);
1454 if (rval) {
1455 fprintf (stderr, "CPXgetx failed\n");
1456 return rval;
1457 }
1458 return 0;
1459 }
1460
CClp_rc(CClp * lp,double * rc)1461 int CClp_rc (CClp *lp, double *rc)
1462 {
1463 int rval = 0;
1464 int ncols;
1465
1466 ncols = CPXgetnumcols (lp->cplex_env, lp->cplex_lp);
1467 if (ncols == 0) {
1468 fprintf (stderr, "No columns in LP\n"); return 1;
1469 }
1470 rval = CPXgetdj (lp->cplex_env, lp->cplex_lp, rc, 0, ncols - 1);
1471 if (rval) {
1472 fprintf (stderr, "CPXgetdj failed\n"); return rval;
1473 }
1474 return 0;
1475 }
1476
CClp_pi(CClp * lp,double * pi)1477 int CClp_pi (CClp *lp, double *pi)
1478 {
1479 int rval = 0;
1480 int nrows;
1481
1482 if ( CPXgetmethod (lp->cplex_env, lp->cplex_lp) == CPX_ALG_DUAL &&
1483 CPXgetstat (lp->cplex_env, lp->cplex_lp ) == CPX_STAT_INFEASIBLE ) {
1484 rval = getfarkasmultipliers (lp, pi);
1485 if (rval) {
1486 fprintf (stderr, "getfarkasmultipliers failed\n"); return rval;
1487 }
1488 return 0;
1489 }
1490
1491 nrows = CPXgetnumrows (lp->cplex_env, lp->cplex_lp);
1492 if (nrows == 0) {
1493 fprintf (stderr, "No rows in LP\n"); return 1;
1494 }
1495 rval = CPXgetpi (lp->cplex_env, lp->cplex_lp, pi, 0, nrows - 1);
1496 if (rval) {
1497 fprintf (stderr, "CPXgetpi failed\n"); return rval;
1498 }
1499 return 0;
1500 }
1501
CClp_objval(CClp * lp,double * obj)1502 int CClp_objval (CClp *lp, double *obj)
1503 {
1504 int rval;
1505
1506 rval = CPXgetobjval (lp->cplex_env, lp->cplex_lp, obj);
1507 if (rval) {
1508 fprintf (stderr, "CPXgetobjval failed\n");
1509 return rval;
1510 }
1511 return 0;
1512 }
1513
CClp_nrows(CClp * lp)1514 int CClp_nrows (CClp *lp)
1515 {
1516 return CPXgetnumrows (lp->cplex_env, lp->cplex_lp);
1517 }
1518
CClp_ncols(CClp * lp)1519 int CClp_ncols (CClp *lp)
1520 {
1521 return CPXgetnumcols (lp->cplex_env, lp->cplex_lp);
1522 }
1523
CClp_nnonzeros(CClp * lp)1524 int CClp_nnonzeros (CClp *lp)
1525 {
1526 return CPXgetnumnz (lp->cplex_env, lp->cplex_lp);
1527 }
1528
CClp_status(CClp * lp,int * status)1529 int CClp_status (CClp *lp, int *status)
1530 {
1531 int solmethod, solstat;
1532
1533 #ifdef CC_ONE_ENV
1534 if (set_parameters (lp->cplex_env, &lp->cplex_params)) {
1535 fprintf (stderr, "Unable to set optimization parameters\n");
1536 }
1537 #endif
1538
1539 solmethod = CPXgetmethod (lp->cplex_env, lp->cplex_lp);
1540 if (solmethod == CPX_ALG_PRIMAL || solmethod == CPX_ALG_DUAL) {
1541 solstat = CPXgetstat (lp->cplex_env, lp->cplex_lp);
1542 if (solstat == CPX_STAT_OPTIMAL || solstat == CPX_STAT_OPTIMAL_INFEAS) {
1543 *status = 0;
1544 return 0;
1545 } else if (solstat == CPX_STAT_INFEASIBLE && solmethod==CPX_ALG_DUAL) {
1546 *status = 1;
1547 return 0;
1548 } else {
1549 fprintf (stderr, "lp in an unknown state: %d %d\n",
1550 solmethod, solstat);
1551 *status = -1;
1552 return 1;
1553 }
1554 } else {
1555 fprintf (stderr, "lp not solved by usual methods: %d\n", solmethod);
1556 *status = -2;
1557 return 1;
1558 }
1559 }
1560
CClp_getweight(CClp * lp,int nrows,int * rmatbeg,int * rmatind,double * rmatval,double * weight)1561 int CClp_getweight (CClp *lp, int nrows, int *rmatbeg, int *rmatind,
1562 double *rmatval, double *weight)
1563 {
1564 int rval = 0;
1565
1566 #ifdef CC_ONE_ENV
1567 if (set_parameters (lp->cplex_env, &lp->cplex_params)) {
1568 fprintf (stderr, "Unable to set optimization parameters\n");
1569 }
1570 #endif
1571
1572 rval = CPXgetweight (lp->cplex_env, lp->cplex_lp, nrows,
1573 rmatbeg, rmatind, rmatval, weight, CPX_DPRIIND_STEEP);
1574 if (rval) {
1575 fprintf (stderr, "CPXgetweight failed\n");
1576 }
1577 return rval;
1578 }
1579
CClp_dump_lp(CClp * lp,const char * fname)1580 int CClp_dump_lp (CClp *lp, const char *fname)
1581 {
1582 int rval = 0;
1583 char nambuf[32];
1584
1585 /* We copy the name since CPXsavwrite doesn't declare fname as const */
1586 strncpy (nambuf, fname, sizeof (nambuf));
1587 nambuf[sizeof(nambuf)-1] = '\0';
1588
1589 rval = CPXsavwrite (lp->cplex_env, lp->cplex_lp, nambuf);
1590 if (rval) {
1591 fprintf (stderr, "CPXsavwrite failed\n");
1592 }
1593 return rval;
1594 }
1595
1596 #define OURCPLEXZERO (1.0E-10)
1597 #define OURCPLEX_INTTOL (0.0001)
1598
CClp_getgoodlist(CClp * lp,int * goodlist,int * goodlen_p,double * downpen,double * uppen)1599 int CClp_getgoodlist (CClp *lp, int *goodlist, int *goodlen_p,
1600 double *downpen, double *uppen)
1601 {
1602 int rval = 0;
1603 int ncols, i, k;
1604 int *cstat = (int *) NULL;
1605 double *x = (double *) NULL;
1606
1607 /* Call CPXdualopt and verify optimality */
1608
1609 #ifdef CC_ONE_ENV
1610 if (set_parameters (lp->cplex_env, &lp->cplex_params)) {
1611 fprintf (stderr, "Unable to set optimization parameters\n");
1612 }
1613 #endif
1614
1615 rval = CPXdualopt (lp->cplex_env, lp->cplex_lp);
1616 if (rval) {
1617 fprintf (stderr, "CPXdualopt failed, return code %d\n", rval);
1618 rval = 1; goto CLEANUP;
1619 }
1620
1621 ncols = CPXgetnumcols (lp->cplex_env, lp->cplex_lp);
1622 if ( ncols == 0 ) {
1623 fprintf (stderr, "No columns in LP\n");
1624 rval = 1; goto CLEANUP;
1625 }
1626
1627 x = CC_SAFE_MALLOC (ncols, double);
1628 if (x == (double *) NULL) {
1629 fprintf (stderr, "out of memory in branch_getgoodlist\n");
1630 rval = 1; goto CLEANUP;
1631 }
1632 if (CPXgetx (lp->cplex_env, lp->cplex_lp, x, 0, ncols-1)) {
1633 fprintf (stderr, "CPXgetx failed\n");
1634 rval = 1; goto CLEANUP;
1635 }
1636
1637 cstat = CC_SAFE_MALLOC (ncols, int);
1638 if ( cstat == (int *) NULL ) {
1639 fprintf (stderr, "Out of memory\n");
1640 rval = 1; goto CLEANUP;
1641 }
1642
1643 /* Get basis */
1644
1645 if ( CPXgetbase (lp->cplex_env, lp->cplex_lp, cstat, (int *) NULL) ) {
1646 fprintf (stderr, "CPXgetbase failed\n");
1647 rval = 1; goto CLEANUP;
1648 }
1649
1650 /* Make initial goodlist and goodlen */
1651
1652 *goodlen_p = 0;
1653 for (i = 0; i < ncols; i++) {
1654 if ( cstat[i] == 1 ) {
1655 goodlist[(*goodlen_p)++] = i;
1656 }
1657 }
1658
1659 /* Call CPXmdleave */
1660
1661 if ( CPXmdleave (lp->cplex_env, lp->cplex_lp, goodlist, *goodlen_p,
1662 downpen, uppen)) {
1663 fprintf (stderr, "CPXmdleave failed\n");
1664 rval = 1; goto CLEANUP;
1665 }
1666
1667 /* Keep only the nondegenerate ones */
1668
1669 k = *goodlen_p;
1670 *goodlen_p = 0;
1671 for (i = 0; i < k; i++) {
1672 if ( CC_OURABS (downpen[i]) > OURCPLEXZERO &&
1673 CC_OURABS (uppen[i]) > OURCPLEXZERO &&
1674 x[goodlist[i]] >= OURCPLEX_INTTOL &&
1675 x[goodlist[i]] <= 1.0 - OURCPLEX_INTTOL ) {
1676 goodlist[*goodlen_p] = goodlist[i];
1677 downpen[*goodlen_p] = x[goodlist[i]] * downpen[i];
1678 uppen[*goodlen_p] = (1.0 - x[goodlist[i]]) * uppen[i];
1679 (*goodlen_p)++;
1680 }
1681 }
1682
1683 if (*goodlen_p == 0) {
1684 /* All edges have degenerate pivots */
1685 for (i = 0; i < k; i++) {
1686 if (x[goodlist[i]] >= OURCPLEX_INTTOL &&
1687 x[goodlist[i]] <= 1.0 - OURCPLEX_INTTOL) {
1688 goodlist[*goodlen_p] = goodlist[i];
1689 downpen[*goodlen_p] = x[goodlist[i]];
1690 uppen[*goodlen_p] = 1.0 - x[goodlist[i]];
1691 (*goodlen_p)++;
1692 }
1693 }
1694 }
1695
1696 rval = 0;
1697
1698 CLEANUP:
1699
1700 CC_IFFREE (cstat, int);
1701 CC_IFFREE (x, double);
1702 return rval;
1703 }
1704
CClp_strongbranch(CClp * lp,int * candidatelist,int ncand,double * downpen,double * uppen,int iterations,double upperbound)1705 int CClp_strongbranch (CClp *lp, int *candidatelist, int ncand,
1706 double *downpen, double *uppen, int iterations,
1707 double upperbound)
1708 {
1709 double oldupperbound;
1710 int rval = 0;
1711 int sval = 0;
1712 int old_perind;
1713 int i;
1714
1715 #ifdef CC_ONE_ENV
1716 if (set_parameters (lp->cplex_env, &lp->cplex_params)) {
1717 fprintf (stderr, "Unable to set optimization parameters\n");
1718 }
1719 #endif
1720
1721 rval = CPXgetdblparam (lp->cplex_env, CPX_PARAM_OBJULIM,
1722 &oldupperbound);
1723 if (rval) {
1724 fprintf (stderr, "CPXgetdblparam failed\n"); return rval;
1725 }
1726 rval = CPXsetdblparam (lp->cplex_env, CPX_PARAM_OBJULIM,
1727 upperbound);
1728 if (rval) {
1729 fprintf (stderr, "CPXsetdblparam failed\n"); return rval;
1730 }
1731
1732 /* REB, 14 October 1997: If perturbation has been turned on elsewhere,
1733 we need to turn it off for branch selection */
1734
1735 rval = CPXgetintparam (lp->cplex_env, CPX_PARAM_PERIND, &old_perind);
1736 if (rval) {
1737 fprintf (stderr, "CPXgetintparam failed\n"); return rval;
1738 }
1739
1740 rval = CPXsetintparam (lp->cplex_env, CPX_PARAM_PERIND, 0);
1741 if (rval) {
1742 fprintf (stderr, "CPXsetintparam failed\n"); return rval;
1743 }
1744
1745 rval = CPXstrongbranch (lp->cplex_env, lp->cplex_lp, candidatelist,
1746 ncand, downpen, uppen, iterations);
1747
1748 if (rval) {
1749 fprintf (stderr, "CPXstrongbranch failed, return code %d\n", rval);
1750 sval = CPXsetdblparam (lp->cplex_env, CPX_PARAM_OBJULIM,
1751 oldupperbound);
1752 if (sval) {
1753 fprintf (stderr,
1754 "CPXsetdblparam failed with return code %d\n",
1755 sval);
1756 }
1757 return rval;
1758 }
1759
1760 rval = CPXsetintparam (lp->cplex_env, CPX_PARAM_PERIND, old_perind);
1761 if (rval) {
1762 fprintf (stderr, "CPXsetintparam failed\n"); return rval;
1763 }
1764
1765 rval = CPXsetdblparam (lp->cplex_env, CPX_PARAM_OBJULIM,
1766 oldupperbound);
1767 if (rval) {
1768 fprintf (stderr, "CPXsetdblparam failed\n"); return rval;
1769 }
1770
1771 for (i=0; i<ncand; i++) {
1772 if (downpen[i] > upperbound) downpen[i] = upperbound;
1773 if (uppen[i] > upperbound) uppen[i] = upperbound;
1774 }
1775
1776 return 0;
1777 }
1778
getfarkasmultipliers(CClp * lp,double * y)1779 static int getfarkasmultipliers (CClp *lp, double *y)
1780 {
1781 int rval = 0;
1782
1783 int i = 0, nrows, idiv, jdiv;
1784 double val, lb, ub;
1785 int *bhead = (int *) NULL;
1786 char *sense = (char *) NULL;
1787
1788 #ifdef CC_ONE_ENV
1789 if (set_parameters (lp->cplex_env, &lp->cplex_params)) {
1790 fprintf (stderr, "Unable to set optimization parameters\n");
1791 }
1792 #endif
1793
1794 if ( lp->cplex_env == (struct cpxenv *) NULL ||
1795 lp->cplex_lp == (struct cpxlp *) NULL) {
1796 rval = 1; fprintf (stderr, "env object or lp object is NULL\n");
1797 goto CLEANUP;
1798 }
1799
1800 if ( CPXgetmethod (lp->cplex_env, lp->cplex_lp) != CPX_ALG_DUAL ||
1801 CPXgetstat (lp->cplex_env, lp->cplex_lp ) != CPX_STAT_INFEASIBLE ) {
1802 rval = 1; fprintf (stderr, "Incorrect solution type\n");
1803 goto CLEANUP;
1804 }
1805
1806 if ( CPXgetijdiv (lp->cplex_env, lp->cplex_lp, &idiv, &jdiv) ) {
1807 rval = 1; fprintf (stderr, "CPXgetijdiv failed\n");
1808 goto CLEANUP;
1809 }
1810
1811 if ( (jdiv == -1 && idiv == -1) ||
1812 (jdiv != -1 && idiv != -1) ) {
1813 rval = 1; fprintf (stderr, "CPLEX returned illegal indices\n");
1814 goto CLEANUP;
1815 }
1816
1817 nrows = CPXgetnumrows (lp->cplex_env, lp->cplex_lp);
1818 if ( nrows == 0 ) {
1819 rval = 1; fprintf (stderr, "lp->cplex_lp has no rows\n");
1820 goto CLEANUP;
1821 }
1822
1823 bhead = CC_SAFE_MALLOC (nrows, int);
1824 sense = CC_SAFE_MALLOC (nrows, char);
1825 if ( bhead == (int *) NULL ||
1826 sense == (char *) NULL ) {
1827 rval = -1; fprintf (stderr, "Out of memory\n");
1828 goto CLEANUP;
1829 }
1830
1831 if ( CPXgetbhead (lp->cplex_env, lp->cplex_lp, bhead, NULL) ) {
1832 rval = 1; fprintf (stderr, "CPXgetbhead failed\n");
1833 goto CLEANUP;
1834 }
1835
1836 if ( CPXgetsense (lp->cplex_env, lp->cplex_lp, sense, 0, nrows-1) ) {
1837 rval = 1; fprintf (stderr, "CPXgetsense failed\n");
1838 goto CLEANUP;
1839 }
1840
1841 if ( jdiv >= 0 ) {
1842 for (i = 0; i < nrows; i++) {
1843 if ( bhead[i] == jdiv ) break;
1844 }
1845 if ( i == nrows ) {
1846 rval = 1; fprintf (stderr, "Basis index not found\n");
1847 goto CLEANUP;
1848 }
1849 if ( CPXgetx (lp->cplex_env, lp->cplex_lp, &val, jdiv, jdiv) ) {
1850 rval = 1; fprintf (stderr, "CPXgetx failed\n");
1851 goto CLEANUP;
1852 }
1853 if ( CPXgetlb (lp->cplex_env, lp->cplex_lp, &lb, jdiv, jdiv) ) {
1854 rval = 1; fprintf (stderr, "CPXgetlb failed\n");
1855 goto CLEANUP;
1856 }
1857 if ( CPXgetub (lp->cplex_env, lp->cplex_lp, &ub, jdiv, jdiv) ) {
1858 rval = 1; fprintf (stderr, "CPXgetub failed\n");
1859 goto CLEANUP;
1860 }
1861 } else {
1862 for (i = 0; i < nrows; i++) {
1863 if ( bhead[i] == -idiv-1 ) break;
1864 }
1865 if ( i == nrows ) {
1866 rval = 1; fprintf (stderr, "Basis index not found\n");
1867 goto CLEANUP;
1868 }
1869 if ( CPXgetslack (lp->cplex_env, lp->cplex_lp, &val, idiv, idiv) ) {
1870 rval = 1; fprintf (stderr, "CPXgetslack failed\n");
1871 goto CLEANUP;
1872 }
1873 lb = 0.0;
1874 if ( sense[idiv] == 'E' ) ub = 0.0;
1875 else ub = CPX_INFBOUND;
1876 if ( sense[idiv] == 'G' ) val *= -1.0;
1877 }
1878
1879 if ( CPXbinvrow (lp->cplex_env, lp->cplex_lp, i, y) ) {
1880 rval = 1; fprintf (stderr, "CPXbinvrow failed\n");
1881 goto CLEANUP;
1882 }
1883
1884 if ( val < lb ) {
1885 for (i = 0; i < nrows; i++) y[i] *= -1.0;
1886 }
1887
1888 for (i = 0; i < nrows; i++) {
1889 if ( sense[i] == 'L' && y[i] > 0.0 ) y[i] = 0.0;
1890 if ( sense[i] == 'G' && y[i] < 0.0 ) y[i] = 0.0;
1891 }
1892
1893 CLEANUP:
1894
1895 CC_IFFREE (bhead, int);
1896 CC_IFFREE (sense, char);
1897
1898 return rval;
1899 }
1900
1901 #ifdef CC_ONE_ENV
1902
set_parameters(CPXENVptr cplex_env,CClp_parameters * params)1903 static int set_parameters (CPXENVptr cplex_env, CClp_parameters *params)
1904 {
1905 int rval;
1906
1907 /* the documentation doesn't say what the return value means */
1908 rval = CPXsetintparam (cplex_env, CPX_PARAM_SCRIND, params->scrind);
1909 if (rval) {
1910 fprintf (stderr, "CPXsetintparam CPX_PARAM_SCRIND failed\n");
1911 goto CLEANUP;
1912 }
1913
1914 rval = CPXsetintparam (cplex_env, CPX_PARAM_SIMDISPLAY,
1915 params->simdisplay);
1916 if (rval) {
1917 fprintf (stderr, "CPXsetintparam CPX_PARAM_SIMDISPLAY failed\n");
1918 goto CLEANUP;
1919 }
1920
1921 rval = CPXsetintparam (cplex_env, CPX_PARAM_FASTMIP, params->fastmip);
1922 if (rval) {
1923 fprintf (stderr, "CPXsetintparam CPX_PARAM_FASTMIP failed\n");
1924 goto CLEANUP;
1925 }
1926 rval = CPXsetintparam (cplex_env, CPX_PARAM_ADVIND, params->advind);
1927 if (rval) {
1928 fprintf (stderr, "CPXsetintparam CPX_PARAM_ADVIND failed\n");
1929 goto CLEANUP;
1930 }
1931 rval = CPXsetintparam (cplex_env, CPX_PARAM_DPRIIND, params->dpriind);
1932 if (rval) {
1933 fprintf (stderr, "CPXsetintparam CPX_PARAM_DPRIIND failed\n");
1934 goto CLEANUP;
1935 }
1936 rval = CPXsetintparam (cplex_env, CPX_PARAM_PPRIIND, params->ppriind);
1937 if (rval) {
1938 fprintf (stderr, "CPXsetintparam CPX_PARAM_PPRIIND failed\n");
1939 goto CLEANUP;
1940 }
1941
1942 rval = CPXsetdblparam (cplex_env, CPX_PARAM_EPPER, params->epper);
1943 if (rval) {
1944 fprintf (stderr, "CPXsetdblparam CPX_PARAM_EPPER failed\n");
1945 goto CLEANUP;
1946 }
1947 rval = CPXsetdblparam (cplex_env, CPX_PARAM_EPOPT, params->epopt);
1948 if (rval) {
1949 fprintf (stderr, "CPXsetdblparam CPX_PARAM_EPOPT failed\n");
1950 goto CLEANUP;
1951 }
1952 rval = CPXsetdblparam (cplex_env, CPX_PARAM_EPRHS, params->eprhs);
1953 if (rval) {
1954 fprintf (stderr, "CPXsetdblparam CPX_PARAM_EPRHS failed\n");
1955 goto CLEANUP;
1956 }
1957
1958 rval = CPXsetintparam (cplex_env, CPX_PARAM_PERIND, params->perind);
1959 if (rval) {
1960 fprintf (stderr, "CPXsetintparam CPX_PARAM_PERIND failed\n");
1961 goto CLEANUP;
1962 }
1963
1964 rval = CPXsetintparam (cplex_env, CPX_PARAM_PREIND, params->preind);
1965 if (rval) {
1966 fprintf (stderr, "CPXsetintparam CPX_PARAM_PREIND failed\n");
1967 goto CLEANUP;
1968 }
1969
1970 rval = CPXsetintparam (cplex_env, CPX_PARAM_AGGIND, params->aggind);
1971 if (rval) {
1972 fprintf (stderr, "CPXsetintparam CPX_PARAM_AGGIND failed\n");
1973 goto CLEANUP;
1974 }
1975
1976 rval = 0;
1977 CLEANUP:
1978 return rval;
1979 }
1980 #endif /* CC_ONE_ENV */
1981