Scippy

SCIP

Solving Constraint Integer Programs

lpi_cpx.c
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the program and library */
4 /* SCIP --- Solving Constraint Integer Programs */
5 /* */
6 /* Copyright (C) 2002-2015 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SCIP is distributed under the terms of the ZIB Academic License. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SCIP; see the file COPYING. If not email to scip@zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file lpi_cpx.c
17  * @ingroup LPIS
18  * @brief LP interface for CPLEX >= 8.0
19  * @author Tobias Achterberg
20  * @author Timo Berthold
21  * @author Stefan Heinz
22  * @author Gerald Gamrath
23  * @author Ambros Gleixner
24  * @author Marc Pfetsch
25  * @author Stefan Vigerske
26  * @author Michael Winkler
27  * @author Kati Wolter
28  * @author Felipe Serrano
29  */
30 
31 /* CPLEX supports FASTMIP which fastens the lp solving process but therefor it might happen that there will be a loss in
32  * precision (because e.g. the optimal basis will not be factorized again)
33  */
34 
35 /*--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
36 
37 #include <assert.h>
38 
39 #include "cplex.h"
40 #ifndef CPX_SUBVERSION
41 #define CPX_SUBVERSION 0
42 #endif
43 #include "scip/bitencode.h"
44 #include "lpi/lpi.h"
45 #include "scip/pub_message.h"
46 
47 
48 
49 #define CHECK_ZERO(messagehdlr, x) { int _restat_; \
50  if( (_restat_ = (x)) != 0 ) \
51  { \
52  SCIPmessagePrintWarning((messagehdlr), "LP Error: CPLEX returned %d\n", _restat_); \
53  return SCIP_LPERROR; \
54  } \
55  }
56 
57 /* this macro is only called in functions returning SCIP_Bool; thus, we return FALSE if there is an error in optimized mode */
58 #define ABORT_ZERO(x) { int _restat_; \
59  if( (_restat_ = (x)) != 0 ) \
60  { \
61  SCIPerrorMessage("LP Error: CPLEX returned %d\n", _restat_); \
62  SCIPABORT(); \
63  return FALSE; \
64  } \
65  }
66 
67 #define CPX_INT_MAX 2100000000 /* CPLEX doesn't accept larger values in integer parameters */
68 
69 /* At several places we need to guarantee to have a factorization of an optimal basis and call the simplex to produce
70  * it. In a numerical perfect world, this should need no iterations. However, due to numerical inaccuracies after
71  * refactorization, it might be necessary to do a few extra pivot steps, in particular if FASTMIP is used. */
72 #define CPX_REFACTORMAXITERS 50 /* maximal number of iterations allowed for producing a refactorization of the basis */
73 
74 /* CPLEX seems to ignore bounds with absolute value less than 1e-10. There is no interface define for this constant yet,
75  * so we define it here. */
76 #define CPX_MAGICZEROCONSTANT 1e-10
77 
78 typedef SCIP_DUALPACKET COLPACKET; /* each column needs two bits of information (basic/on_lower/on_upper) */
79 #define COLS_PER_PACKET SCIP_DUALPACKETSIZE
80 typedef SCIP_DUALPACKET ROWPACKET; /* each row needs two bit of information (basic/on_lower/on_upper) */
81 #define ROWS_PER_PACKET SCIP_DUALPACKETSIZE
82 
83 /* CPLEX parameter lists which can be changed */
84 #if (CPX_VERSION < 12060100)
85 #define NUMINTPARAM 10
86 #else
87 #define NUMINTPARAM 9
88 #endif
89 static const int intparam[NUMINTPARAM] =
90 {
91  CPX_PARAM_ADVIND,
92  CPX_PARAM_ITLIM,
93 #if (CPX_VERSION < 12060100)
94  CPX_PARAM_FASTMIP,
95 #endif
96  CPX_PARAM_SCAIND,
97  CPX_PARAM_PREIND,
98  CPX_PARAM_PPRIIND,
99  CPX_PARAM_DPRIIND,
100  CPX_PARAM_SIMDISPLAY,
101  CPX_PARAM_SCRIND,
102  CPX_PARAM_THREADS
103 };
104 
105 #define NUMDBLPARAM 7
106 static const int dblparam[NUMDBLPARAM] =
107 {
108  CPX_PARAM_EPRHS,
109  CPX_PARAM_EPOPT,
110  CPX_PARAM_BAREPCOMP,
111  CPX_PARAM_OBJLLIM,
112  CPX_PARAM_OBJULIM,
113  CPX_PARAM_TILIM,
114  CPX_PARAM_EPMRK
115 };
116 
117 static const double dblparammin[NUMDBLPARAM] =
118 {
119  +1e-09, /*CPX_PARAM_EPRHS*/
120  +1e-09, /*CPX_PARAM_EPOPT*/
121  +1e-12, /*CPX_PARAM_BAREPCOMP*/
122  -1e+99, /*CPX_PARAM_OBJLLIM*/
123  -1e+99, /*CPX_PARAM_OBJULIM*/
124  -1e+99, /*CPX_PARAM_TILIM*/
125  0.0001 /*CPX_PARAM_EPMRK*/
126 };
127 
128 /** CPLEX parameter settings */
130 {
131  int intparval[NUMINTPARAM]; /**< integer parameter values */
132  double dblparval[NUMDBLPARAM]; /**< double parameter values */
133 };
135 
136 /** LP interface */
137 struct SCIP_LPi
138 {
139  CPXENVptr cpxenv; /**< CPLEX environment */
140  SCIP_CPXPARAM defparam; /**< default CPLEX parameters */
141  SCIP_CPXPARAM curparam; /**< current CPLEX parameters in the environment */
142  CPXLPptr cpxlp; /**< CPLEX LP pointer */
143  int solstat; /**< solution status of last optimization call */
144  SCIP_CPXPARAM cpxparam; /**< current parameter values for this LP */
145  char* larray; /**< array with 'L' entries for changing lower bounds */
146  char* uarray; /**< array with 'U' entries for changing upper bounds */
147  char* senarray; /**< array for storing row senses */
148  SCIP_Real* rhsarray; /**< array for storing rhs values */
149  SCIP_Real* rngarray; /**< array for storing range values */
150  SCIP_Real* valarray; /**< array for storing coefficient values */
151  int* rngindarray; /**< array for storing row indices with range values */
152  int* cstat; /**< array for storing column basis status */
153  int* rstat; /**< array for storing row basis status */
154  int* indarray; /**< array for storing coefficient indices */
155  int boundchgsize; /**< size of larray and uarray */
156  int sidechgsize; /**< size of senarray, rngarray, and rngindarray */
157  int valsize; /**< size of valarray and indarray */
158  int cstatsize; /**< size of cstat array */
159  int rstatsize; /**< size of rstat array */
160  int iterations; /**< number of iterations used in the last solving call */
161  SCIP_PRICING pricing; /**< SCIP pricing setting */
162  SCIP_Bool solisbasic; /**< is current LP solution a basic solution? */
163  SCIP_Bool instabilityignored; /**< was the instability of the last LP ignored? */
164  SCIP_Bool fromscratch; /**< shall solves be performed with CPX_PARAM_ADVIND turned off? */
165  SCIP_Bool clearstate; /**< shall next solve be performed with CPX_PARAM_ADVIND turned off? */
166  SCIP_Real feastol; /**< feasibility tolerance for integrality */
167  SCIP_Real conditionlimit; /**< maximum condition number of LP basis counted as stable (-1.0: no limit) */
168  SCIP_Bool checkcondition; /**< should condition number of LP basis be checked for stability? */
169 #if (CPX_VERSION <= 1100)
170  SCIP_Bool rngfound; /**< was ranged row found; scaling is disabled, because there is a bug
171  * in the scaling algorithm for ranged rows in CPLEX up to version 11.0 */
172 #endif
173 #if (CPX_VERSION == 1100 || (CPX_VERSION == 1220 && (CPX_SUBVERSION == 0 || CPX_SUBVERSION == 2)))
174  int pseudonthreads; /**< number of threads that SCIP set for the LP solver, but due to CPLEX bug,
175  * we set the thread count to 1. In order to fulfill assert in lp.c,
176  * we have to return the value set by SCIP and not the real thread count */
177 #endif
178  SCIP_MESSAGEHDLR* messagehdlr; /**< messagehdlr handler to printing messages, or NULL */
179 };
180 
181 /** LPi state stores basis information */
182 struct SCIP_LPiState
183 {
184  int ncols; /**< number of LP columns */
185  int nrows; /**< number of LP rows */
186  COLPACKET* packcstat; /**< column basis status in compressed form */
187  ROWPACKET* packrstat; /**< row basis status in compressed form */
188 };
189 
190 /** LPi norms stores pricing norms */
192 {
193  int normlen; /**< number of rows for which dual norm is stored */
194  double* norm; /**< dual norms */
195  int* head; /**< row/column indices corresponding to norms */
196 };
197 
198 
199 /*
200  * dynamic memory arrays
201  */
202 
203 /** resizes larray and uarray to have at least num entries */
204 static
205 SCIP_RETCODE ensureBoundchgMem(
206  SCIP_LPI* lpi, /**< LP interface structure */
207  int num /**< minimal number of entries in array */
208  )
209 {
210  assert(lpi != NULL);
211 
212  if( num > lpi->boundchgsize )
213  {
214  int newsize;
215  int i;
216 
217  newsize = MAX(2*lpi->boundchgsize, num);
218  SCIP_ALLOC( BMSreallocMemoryArray(&lpi->larray, newsize) );
219  SCIP_ALLOC( BMSreallocMemoryArray(&lpi->uarray, newsize) );
220  for( i = lpi->boundchgsize; i < newsize; ++i )
221  {
222  lpi->larray[i] = 'L';
223  lpi->uarray[i] = 'U';
224  }
225  lpi->boundchgsize = newsize;
226  }
227  assert(num <= lpi->boundchgsize);
228 
229  return SCIP_OKAY;
230 }
231 
232 /** resizes senarray, rngarray, and rngindarray to have at least num entries */
233 static
234 SCIP_RETCODE ensureSidechgMem(
235  SCIP_LPI* lpi, /**< LP interface structure */
236  int num /**< minimal number of entries in array */
237  )
238 {
239  assert(lpi != NULL);
240 
241  if( num > lpi->sidechgsize )
242  {
243  int newsize;
244 
245  newsize = MAX(2*lpi->sidechgsize, num);
246  SCIP_ALLOC( BMSreallocMemoryArray(&lpi->senarray, newsize) );
247  SCIP_ALLOC( BMSreallocMemoryArray(&lpi->rhsarray, newsize) );
248  SCIP_ALLOC( BMSreallocMemoryArray(&lpi->rngarray, newsize) );
249  SCIP_ALLOC( BMSreallocMemoryArray(&lpi->rngindarray, newsize) );
250  lpi->sidechgsize = newsize;
251  }
252  assert(num <= lpi->sidechgsize);
253 
254  return SCIP_OKAY;
255 }
256 
257 /** resizes valarray and indarray to have at least num entries */
258 static
259 SCIP_RETCODE ensureValMem(
260  SCIP_LPI* lpi, /**< LP interface structure */
261  int num /**< minimal number of entries in array */
262  )
263 {
264  assert(lpi != NULL);
265 
266  if( num > lpi->valsize )
267  {
268  int newsize;
269 
270  newsize = MAX(2*lpi->valsize, num);
271  SCIP_ALLOC( BMSreallocMemoryArray(&lpi->valarray, newsize) );
272  SCIP_ALLOC( BMSreallocMemoryArray(&lpi->indarray, newsize) );
273  lpi->valsize = newsize;
274  }
275  assert(num <= lpi->valsize);
276 
277  return SCIP_OKAY;
278 }
279 
280 /** resizes cstat array to have at least num entries */
281 static
282 SCIP_RETCODE ensureCstatMem(
283  SCIP_LPI* lpi, /**< LP interface structure */
284  int num /**< minimal number of entries in array */
285  )
286 {
287  assert(lpi != NULL);
288 
289  if( num > lpi->cstatsize )
290  {
291  int newsize;
292 
293  newsize = MAX(2*lpi->cstatsize, num);
294  SCIP_ALLOC( BMSreallocMemoryArray(&lpi->cstat, newsize) );
295  lpi->cstatsize = newsize;
296  }
297  assert(num <= lpi->cstatsize);
298 
299  return SCIP_OKAY;
300 }
301 
302 /** resizes rstat array to have at least num entries */
303 static
304 SCIP_RETCODE ensureRstatMem(
305  SCIP_LPI* lpi, /**< LP interface structure */
306  int num /**< minimal number of entries in array */
307  )
308 {
309  assert(lpi != NULL);
310 
311  if( num > lpi->rstatsize )
312  {
313  int newsize;
314 
315  newsize = MAX(2*lpi->rstatsize, num);
316  SCIP_ALLOC( BMSreallocMemoryArray(&lpi->rstat, newsize) );
317  lpi->rstatsize = newsize;
318  }
319  assert(num <= lpi->rstatsize);
320 
321  return SCIP_OKAY;
322 }
323 
324 /** stores current basis in internal arrays of LPI data structure */
325 static
326 SCIP_RETCODE getBase(
327  SCIP_LPI* lpi /**< LP interface structure */
328  )
329 {
330  int ncols;
331  int nrows;
332 
333  assert(lpi != NULL);
334  assert(lpi->cpxenv != NULL);
335 
336  SCIPdebugMessage("getBase()\n");
337 
338  ncols = CPXgetnumcols(lpi->cpxenv, lpi->cpxlp);
339  nrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
340 
341  /* allocate enough memory for storing uncompressed basis information */
342  SCIP_CALL( ensureCstatMem(lpi, ncols) );
343  SCIP_CALL( ensureRstatMem(lpi, nrows) );
344 
345  /* get unpacked basis information from CPLEX */
346  CHECK_ZERO( lpi->messagehdlr, CPXgetbase(lpi->cpxenv, lpi->cpxlp, lpi->cstat, lpi->rstat) );
347 
348  return SCIP_OKAY;
349 }
350 
351 /** loads basis stored in internal arrays of LPI data structure into CPLEX */
352 static
353 SCIP_RETCODE setBase(
354  SCIP_LPI* lpi /**< LP interface structure */
355  )
356 {
357  assert(lpi != NULL);
358  assert(lpi->cpxenv != NULL);
359 
360  SCIPdebugMessage("setBase()\n");
361 
362  /* load basis information into CPLEX */
363  CHECK_ZERO( lpi->messagehdlr, CPXcopybase(lpi->cpxenv, lpi->cpxlp, lpi->cstat, lpi->rstat) );
364 
365  /* because the basis status values are equally defined in SCIP and CPLEX, they don't need to be transformed */
366  assert((int)SCIP_BASESTAT_LOWER == CPX_AT_LOWER);
367  assert((int)SCIP_BASESTAT_BASIC == CPX_BASIC);
368  assert((int)SCIP_BASESTAT_UPPER == CPX_AT_UPPER);
369  assert((int)SCIP_BASESTAT_ZERO == CPX_FREE_SUPER);
370 
371  return SCIP_OKAY;
372 }
373 
374 
375 
376 
377 /*
378  * LPi state methods
379  */
380 
381 /** returns the number of packets needed to store column packet information */
382 static
383 int colpacketNum(
384  int ncols /**< number of columns to store */
385  )
386 {
387  return (ncols+(int)COLS_PER_PACKET-1)/(int)COLS_PER_PACKET;
388 }
389 
390 /** returns the number of packets needed to store row packet information */
391 static
392 int rowpacketNum(
393  int nrows /**< number of rows to store */
394  )
395 {
396  return (nrows+(int)ROWS_PER_PACKET-1)/(int)ROWS_PER_PACKET;
397 }
398 
399 /** store row and column basis status in a packed LPi state object */
400 static
401 void lpistatePack(
402  SCIP_LPISTATE* lpistate, /**< pointer to LPi state data */
403  const int* cstat, /**< basis status of columns in unpacked format */
404  const int* rstat /**< basis status of rows in unpacked format */
405  )
406 {
407  assert(lpistate != NULL);
408  assert(lpistate->packcstat != NULL);
409  assert(lpistate->packrstat != NULL);
410 
411  SCIPencodeDualBit(cstat, lpistate->packcstat, lpistate->ncols);
412  SCIPencodeDualBit(rstat, lpistate->packrstat, lpistate->nrows);
413 }
414 
415 /** unpacks row and column basis status from a packed LPi state object */
416 static
417 void lpistateUnpack(
418  const SCIP_LPISTATE* lpistate, /**< pointer to LPi state data */
419  int* cstat, /**< buffer for storing basis status of columns in unpacked format */
420  int* rstat /**< buffer for storing basis status of rows in unpacked format */
421  )
422 {
423  assert(lpistate != NULL);
424  assert(lpistate->packcstat != NULL);
425  assert(lpistate->packrstat != NULL);
426 
427  SCIPdecodeDualBit(lpistate->packcstat, cstat, lpistate->ncols);
428  SCIPdecodeDualBit(lpistate->packrstat, rstat, lpistate->nrows);
429 }
430 
431 /** creates LPi state information object */
432 static
433 SCIP_RETCODE lpistateCreate(
434  SCIP_LPISTATE** lpistate, /**< pointer to LPi state */
435  BMS_BLKMEM* blkmem, /**< block memory */
436  int ncols, /**< number of columns to store */
437  int nrows /**< number of rows to store */
438  )
439 {
440  assert(lpistate != NULL);
441  assert(blkmem != NULL);
442  assert(ncols >= 0);
443  assert(nrows >= 0);
444 
445  SCIP_ALLOC( BMSallocBlockMemory(blkmem, lpistate) );
446  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpistate)->packcstat, colpacketNum(ncols)) );
447  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpistate)->packrstat, rowpacketNum(nrows)) );
448 
449  return SCIP_OKAY;
450 }
451 
452 /** frees LPi state information */
453 static
454 void lpistateFree(
455  SCIP_LPISTATE** lpistate, /**< pointer to LPi state information (like basis information) */
456  BMS_BLKMEM* blkmem /**< block memory */
457  )
458 {
459  assert(blkmem != NULL);
460  assert(lpistate != NULL);
461  assert(*lpistate != NULL);
462 
463  BMSfreeBlockMemoryArray(blkmem, &(*lpistate)->packcstat, colpacketNum((*lpistate)->ncols));
464  BMSfreeBlockMemoryArray(blkmem, &(*lpistate)->packrstat, rowpacketNum((*lpistate)->nrows));
465  BMSfreeBlockMemory(blkmem, lpistate);
466 }
467 
468 
469 
470 /*
471  * local methods
472  */
473 
474 /** gets all CPLEX parameters used in LPI */
475 static
476 SCIP_RETCODE getParameterValues(
477  SCIP_LPI* lpi, /**< LP interface structure */
478  SCIP_CPXPARAM* cpxparam /**< current parameter values for this LP */
479  )
480 {
481  int i;
482 
483  assert(lpi != NULL);
484  assert(cpxparam != NULL);
485 
486  SCIPdebugMessage("getParameterValues()\n");
487 
488  for( i = 0; i < NUMINTPARAM; ++i )
489  {
490  CHECK_ZERO( lpi->messagehdlr, CPXgetintparam(lpi->cpxenv, intparam[i], &(cpxparam->intparval[i])) );
491  }
492  for( i = 0; i < NUMDBLPARAM; ++i )
493  {
494  CHECK_ZERO( lpi->messagehdlr, CPXgetdblparam(lpi->cpxenv, dblparam[i], &(cpxparam->dblparval[i])) );
495  }
496 
497  return SCIP_OKAY;
498 }
499 
500 /** in debug mode, checks validity of CPLEX parameters */
501 static
502 SCIP_RETCODE checkParameterValues(
503  SCIP_LPI*const lpi /**< LP interface structure */
504  )
505 {
506 #ifndef NDEBUG
507  SCIP_CPXPARAM par;
508  int i;
509 
510  assert(lpi != NULL);
511  assert(lpi->cpxenv != NULL);
512 
513  SCIP_CALL( getParameterValues(lpi, &par) );
514  for( i = 0; i < NUMINTPARAM; ++i )
515  assert(lpi->curparam.intparval[i] == par.intparval[i]
516  || (lpi->curparam.intparval[i] == CPX_INT_MAX && par.intparval[i] >= CPX_INT_MAX));
517  for( i = 0; i < NUMDBLPARAM; ++i )
518  assert(MAX(lpi->curparam.dblparval[i], dblparammin[i]) == par.dblparval[i]); /*lint !e777*/
519 #endif
520 
521  return SCIP_OKAY;
522 }
523 
524 /** sets all CPLEX parameters used in LPI */
525 static
526 SCIP_RETCODE setParameterValues(
527  SCIP_LPI*const lpi, /**< LP interface structure */
528  SCIP_CPXPARAM*const cpxparam /**< current parameter values for this LP */
529  )
530 {
531  int i;
532 
533  assert(lpi != NULL);
534  assert(lpi->cpxenv != NULL);
535  assert(cpxparam != NULL);
536 
537  SCIPdebugMessage("setParameterValues()\n");
538 
539  for( i = 0; i < NUMINTPARAM; ++i )
540  {
541  if( lpi->curparam.intparval[i] != cpxparam->intparval[i] )
542  {
543  SCIPdebugMessage("setting CPLEX int parameter %d from %d to %d\n",
544  intparam[i], lpi->curparam.intparval[i], cpxparam->intparval[i]);
545  lpi->curparam.intparval[i] = cpxparam->intparval[i];
546  CHECK_ZERO( lpi->messagehdlr, CPXsetintparam(lpi->cpxenv, intparam[i], lpi->curparam.intparval[i]) );
547  }
548  }
549  for( i = 0; i < NUMDBLPARAM; ++i )
550  {
551  if( lpi->curparam.dblparval[i] != cpxparam->dblparval[i] ) /*lint !e777*/
552  {
553  SCIPdebugMessage("setting CPLEX dbl parameter %d from %g to %g\n",
554  dblparam[i], lpi->curparam.dblparval[i], MAX(cpxparam->dblparval[i], dblparammin[i]));
555  lpi->curparam.dblparval[i] = MAX(cpxparam->dblparval[i], dblparammin[i]);
556  CHECK_ZERO( lpi->messagehdlr, CPXsetdblparam(lpi->cpxenv, dblparam[i], lpi->curparam.dblparval[i]) );
557  }
558  }
559 
560  SCIP_CALL( checkParameterValues(lpi) );
561 
562  return SCIP_OKAY;
563 }
564 
565 /** copies CPLEX parameters from source to dest */
566 static
567 void copyParameterValues(
568  SCIP_CPXPARAM* dest, /**< CPLEX parameters to copy to */
569  SCIP_CPXPARAM*const source /**< CPLEX parameters which will be copied */
570  )
571 {
572  int i;
573 
574  for( i = 0; i < NUMINTPARAM; ++i )
575  dest->intparval[i] = source->intparval[i];
576  for( i = 0; i < NUMDBLPARAM; ++i )
577  dest->dblparval[i] = source->dblparval[i];
578 }
579 
580 /** gets a single integer parameter value */
581 static
582 int getIntParam(
583  SCIP_LPI* lpi, /**< LP interface structure */
584  int const param /**< parameter to get value for */
585  )
586 {
587  int i;
588 
589  assert(lpi != NULL);
590 
591  for( i = 0; i < NUMINTPARAM; ++i )
592  {
593  if( intparam[i] == param )
594  return lpi->cpxparam.intparval[i];
595  }
596 
597  SCIPerrorMessage("unknown CPLEX integer parameter\n");
598  SCIPABORT();
599  return 0; /*lint !e527*/
600 }
601 
602 /** gets a single double parameter value */
603 static
604 double getDblParam(
605  SCIP_LPI* lpi, /**< LP interface structure */
606  int const param /**< parameter to get value for */
607  )
608 {
609  SCIP_Real val;
610  int i;
611 
612  assert(lpi != NULL);
613 
614  for( i = 0; i < NUMDBLPARAM; ++i )
615  {
616  if( dblparam[i] == param )
617  {
618  val = lpi->cpxparam.dblparval[i];
619  if( val >= CPX_INFBOUND )
620  return CPX_INFBOUND;
621  else if( val <= -CPX_INFBOUND )
622  return -CPX_INFBOUND;
623  else
624  return val;
625  }
626  }
627 
628  SCIPerrorMessage("unknown CPLEX double parameter\n");
629  SCIPABORT();
630  return 0.0; /*lint !e527*/
631 }
632 
633 /** sets a single integer parameter value */
634 static
635 void setIntParam(
636  SCIP_LPI* lpi, /**< LP interface structure */
637  int const param, /**< parameter to set value */
638  int const parval /**< new value for parameter */
639  )
640 {
641  int i;
642 
643  assert(lpi != NULL);
644 
645  for( i = 0; i < NUMINTPARAM; ++i )
646  {
647  if( intparam[i] == param )
648  {
649  lpi->cpxparam.intparval[i] = parval;
650  return;
651  }
652  }
653 
654  SCIPerrorMessage("unknown CPLEX integer parameter\n");
655  SCIPABORT();
656 }
657 
658 /** sets a single double parameter value */
659 static
660 void setDblParam(
661  SCIP_LPI* lpi, /**< LP interface structure */
662  int const param, /**< parameter to set value */
663  double parval /**< new value for parameter */
664  )
665 {
666  int i;
667 
668  assert(lpi != NULL);
669 
670  if( parval >= CPX_INFBOUND )
671  parval = 1e+75;
672  else if( parval <= -CPX_INFBOUND )
673  parval = -1e+75;
674 
675  for( i = 0; i < NUMDBLPARAM; ++i )
676  {
677  if( dblparam[i] == param )
678  {
679  lpi->cpxparam.dblparval[i] = parval;
680  return;
681  }
682  }
683 
684  SCIPerrorMessage("unknown CPLEX double parameter\n");
685  SCIPABORT();
686 }
687 
688 /** marks the current LP to be unsolved */
689 static
690 void invalidateSolution(
691  SCIP_LPI* const lpi /**< LP interface structure */
692  )
693 {
694  assert(lpi != NULL);
695  lpi->solstat = -1;
696  lpi->instabilityignored = FALSE;
697 }
698 
699 /** converts SCIP's objective sense into CPLEX's objective sense */
700 static
701 int cpxObjsen(
702  SCIP_OBJSEN const objsen /**< objective sense */
703  )
704 {
705  switch( objsen )
706  {
708  return CPX_MAX;
710  return CPX_MIN;
711  default:
712  SCIPerrorMessage("invalid objective sense\n");
713  SCIPABORT();
714  return 0; /*lint !e527*/
715  }
716 }
717 
718 /** converts SCIP's lhs/rhs pairs into CPLEX's sen/rhs/rng */
719 static
720 void convertSides(
721  SCIP_LPI* lpi, /**< LP interface structure */
722  int nrows, /**< number of rows */
723  const SCIP_Real* lhs, /**< left hand side vector */
724  const SCIP_Real* rhs, /**< right hand side vector */
725  int indoffset, /**< index of first row in LP */
726  int* rngcount /**< pointer to store the number of range rows */
727  )
728 {
729  int i;
730 
731  assert(lpi != NULL);
732  assert(nrows >= 0);
733  assert(lhs != NULL);
734  assert(rhs != NULL);
735  assert(rngcount != NULL);
736 
737  /* convert lhs/rhs into sen/rhs/rng */
738  *rngcount = 0;
739  for( i = 0; i < nrows; ++i )
740  {
741  assert(lhs[i] <= rhs[i]);
742  if( lhs[i] == rhs[i] ) /*lint !e777*/
743  {
744  assert(-CPX_INFBOUND < rhs[i] && rhs[i] < CPX_INFBOUND);
745  lpi->senarray[i] = 'E';
746  lpi->rhsarray[i] = rhs[i];
747  }
748  else if( lhs[i] <= -CPX_INFBOUND )
749  {
750  assert(-CPX_INFBOUND < rhs[i] && rhs[i] < CPX_INFBOUND);
751  lpi->senarray[i] = 'L';
752  lpi->rhsarray[i] = rhs[i];
753  }
754  else if( rhs[i] >= CPX_INFBOUND )
755  {
756  assert(-CPX_INFBOUND < lhs[i] && lhs[i] < CPX_INFBOUND);
757  lpi->senarray[i] = 'G';
758  lpi->rhsarray[i] = lhs[i];
759  }
760  else
761  {
762  /* CPLEX defines a ranged row to be within rhs and rhs+rng.
763  * -> To keep SCIP's meaning of the rhs value, we would like to use negative range values: rng := lhs - rhs,
764  * but there seems to be a bug in CPLEX's presolve with negative range values:
765  * the ranged row
766  * 0 <= -x <= 100000 with x >= 0 (rhs=0, rng=-100000)
767  * would lead to the CPLEX row
768  * -x -Rg = 100000
769  * Rg = 0
770  * instead of the correct presolving implication Rg = -100000.
771  * -> Because of this bug, we have to use an additional rhsarray[] for the converted right hand sides and
772  * use rhsarray[i] = lhs[i] and rngarray[i] = rhs[i] - lhs[i] for ranged rows to keep the range values
773  * non-negative.
774  */
775  lpi->senarray[i] = 'R';
776  lpi->rhsarray[i] = lhs[i];
777  lpi->rngarray[*rngcount] = rhs[i] - lhs[i];
778  lpi->rngindarray[*rngcount] = i + indoffset;
779  (*rngcount)++;
780  }
781  }
782 }
783 
784 /** converts CPLEX's sen/rhs/rng triplets into SCIP's lhs/rhs pairs */
785 static
786 void reconvertBothSides(
787  SCIP_LPI* lpi, /**< LP interface structure */
788  int nrows, /**< number of rows */
789  SCIP_Real* lhs, /**< buffer to store the left hand side vector */
790  SCIP_Real* rhs /**< buffer to store the right hand side vector */
791  )
792 {
793  int i;
794 
795  assert(lpi != NULL);
796  assert(nrows >= 0);
797  assert(lhs != NULL);
798  assert(rhs != NULL);
799 
800  for( i = 0; i < nrows; ++i )
801  {
802  switch( lpi->senarray[i] )
803  {
804  case 'E':
805  lhs[i] = lpi->rhsarray[i];
806  rhs[i] = lpi->rhsarray[i];
807  break;
808 
809  case 'L':
810  lhs[i] = -CPX_INFBOUND;
811  rhs[i] = lpi->rhsarray[i];
812  break;
813 
814  case 'G':
815  lhs[i] = lpi->rhsarray[i];
816  rhs[i] = CPX_INFBOUND;
817  break;
818 
819  case 'R':
820  assert(lpi->rngarray[i] != 0.0);
821  if( lpi->rngarray[i] > 0.0 )
822  {
823  lhs[i] = lpi->rhsarray[i];
824  rhs[i] = lpi->rhsarray[i] + lpi->rngarray[i];
825  }
826  else
827  {
828  lhs[i] = lpi->rhsarray[i] + lpi->rngarray[i];
829  rhs[i] = lpi->rhsarray[i];
830  }
831  break;
832 
833  default:
834  SCIPerrorMessage("invalid row sense\n");
835  SCIPABORT();
836  }
837  assert(lhs[i] <= rhs[i]);
838  }
839 }
840 
841 /** converts CPLEX's sen/rhs/rng triplets into SCIP's lhs/rhs pairs, only storing the left hand side */
842 static
843 void reconvertLhs(
844  SCIP_LPI* lpi, /**< LP interface structure */
845  int nrows, /**< number of rows */
846  SCIP_Real* lhs /**< buffer to store the left hand side vector */
847  )
848 {
849  int i;
850 
851  assert(lpi != NULL);
852  assert(nrows >= 0);
853  assert(lhs != NULL);
854 
855  for( i = 0; i < nrows; ++i )
856  {
857  switch( lpi->senarray[i] )
858  {
859  case 'E':
860  assert(lpi->rngarray[i] == 0.0);
861  lhs[i] = lpi->rhsarray[i];
862  break;
863 
864  case 'L':
865  assert(lpi->rngarray[i] == 0.0);
866  lhs[i] = -CPX_INFBOUND;
867  break;
868 
869  case 'G':
870  assert(lpi->rngarray[i] == 0.0);
871  lhs[i] = lpi->rhsarray[i];
872  break;
873 
874  case 'R':
875  assert(lpi->rngarray[i] != 0.0);
876  if( lpi->rngarray[i] > 0.0 )
877  lhs[i] = lpi->rhsarray[i];
878  else
879  lhs[i] = lpi->rhsarray[i] + lpi->rngarray[i];
880  break;
881 
882  default:
883  SCIPerrorMessage("invalid row sense\n");
884  SCIPABORT();
885  }
886  }
887 }
888 
889 /** converts CPLEX's sen/rhs/rng triplets into SCIP's lhs/rhs pairs, only storing the right hand side */
890 static
891 void reconvertRhs(
892  SCIP_LPI* lpi, /**< LP interface structure */
893  int nrows, /**< number of rows */
894  SCIP_Real* rhs /**< buffer to store the right hand side vector */
895  )
896 {
897  int i;
898 
899  assert(lpi != NULL);
900  assert(nrows >= 0);
901  assert(rhs != NULL);
902 
903  for( i = 0; i < nrows; ++i )
904  {
905  switch( lpi->senarray[i] )
906  {
907  case 'E':
908  assert(lpi->rngarray[i] == 0.0);
909  rhs[i] = lpi->rhsarray[i];
910  break;
911 
912  case 'L':
913  assert(lpi->rngarray[i] == 0.0);
914  rhs[i] = lpi->rhsarray[i];
915  break;
916 
917  case 'G':
918  assert(lpi->rngarray[i] == 0.0);
919  rhs[i] = CPX_INFBOUND;
920  break;
921 
922  case 'R':
923  assert(lpi->rngarray[i] != 0.0);
924  if( lpi->rngarray[i] > 0.0 )
925  rhs[i] = lpi->rhsarray[i] + lpi->rngarray[i];
926  else
927  rhs[i] = lpi->rhsarray[i];
928  break;
929 
930  default:
931  SCIPerrorMessage("invalid row sense\n");
932  SCIPABORT();
933  }
934  }
935 }
936 
937 /** converts CPLEX's sen/rhs/rng triplets into SCIP's lhs/rhs pairs */
938 static
939 void reconvertSides(
940  SCIP_LPI* lpi, /**< LP interface structure */
941  int nrows, /**< number of rows */
942  SCIP_Real* lhs, /**< buffer to store the left hand side vector, or NULL */
943  SCIP_Real* rhs /**< buffer to store the right hand side vector, or NULL */
944  )
945 {
946  if( lhs != NULL && rhs != NULL )
947  reconvertBothSides(lpi, nrows, lhs, rhs);
948  else if( lhs != NULL )
949  reconvertLhs(lpi, nrows, lhs);
950  else if( rhs != NULL )
951  reconvertRhs(lpi, nrows, rhs);
952 }
953 
954 
955 /** after restoring the old lp data in CPLEX we need to resolve the lp to be able to retrieve correct information */
956 static
957 SCIP_RETCODE restoreLPData(
958  SCIP_LPI* lpi /**< LP interface structure */
959  )
960 {
961  assert(lpi != NULL);
962 
963  /* modifying the LP, restoring the old LP, and loading the old basis is not enough for CPLEX to be able to return the
964  * basis -> we have to resolve the LP;
965  *
966  * this may happen after manual strong branching on an integral variable, or after conflict analysis on a strong
967  * branching conflict created a constraint that is not able to modify the LP but trigger the additional call of the
968  * separators, in particular, the Gomory separator
969  *
970  * In a numerical perfect world, CPX_REFACTORMAXITERS below should be zero. However, due to numerical inaccuracies
971  * after refactorization, it might be necessary to do a few extra pivot steps.
972  */
973  CHECK_ZERO( lpi->messagehdlr, CPXdualopt(lpi->cpxenv, lpi->cpxlp) );
974 #ifndef NDEBUG
975  if ( CPXgetphase1cnt(lpi->cpxenv, lpi->cpxlp) > CPX_REFACTORMAXITERS )
976  SCIPmessagePrintWarning(lpi->messagehdlr, "CPLEX needed %d phase 1 iterations to restore optimal basis.\n", CPXgetphase1cnt(lpi->cpxenv, lpi->cpxlp));
977  if ( CPXgetitcnt(lpi->cpxenv, lpi->cpxlp) > CPX_REFACTORMAXITERS )
978  SCIPmessagePrintWarning(lpi->messagehdlr, "CPLEX needed %d iterations to restore optimal basis.\n", CPXgetitcnt(lpi->cpxenv, lpi->cpxlp));
979 #endif
980 
981  return SCIP_OKAY;
982 }
983 
984 
985 /*
986  * LP Interface Methods
987  */
988 
989 
990 /*
991  * Miscellaneous Methods
992  */
993 
994 static char cpxname[100];
995 
996 /**@name Miscellaneous Methods */
997 /**@{ */
998 
999 /** gets name and version of LP solver */
1001  void
1002  )
1003 {
1004 #ifdef CPX_VERSION_VERSION
1005  sprintf(cpxname, "CPLEX %d.%d.%d.%d", CPX_VERSION_VERSION, CPX_VERSION_RELEASE, CPX_VERSION_MODIFICATION, CPX_VERSION_FIX);
1006 #else
1007  sprintf(cpxname, "CPLEX %d.%d.%d.%d", CPX_VERSION/100, (CPX_VERSION%100)/10, CPX_VERSION%10, CPX_SUBVERSION);
1008 #endif
1009  return cpxname;
1010 }
1011 
1012 /** gets description of LP solver (developer, webpage, ...) */
1014  void
1015  )
1016 {
1017  return "Linear Programming Solver developed by IBM (www.cplex.com)";
1018 }
1019 
1020 /** gets pointer for LP solver - use only with great care
1021  *
1022  * Here we return the pointer to the LP environment.
1023  */
1025  SCIP_LPI* lpi /**< pointer to an LP interface structure */
1026  )
1027 {
1028  return (void*) lpi->cpxlp;
1029 }
1030 /**@} */
1031 
1032 
1033 
1034 
1035 /*
1036  * LPI Creation and Destruction Methods
1037  */
1038 
1039 /**@name LPI Creation and Destruction Methods */
1040 /**@{ */
1041 
1042 /** creates an LP problem object */
1044  SCIP_LPI** lpi, /**< pointer to an LP interface structure */
1045  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler to use for printing messages, or NULL */
1046  const char* name, /**< problem name */
1047  SCIP_OBJSEN objsen /**< objective sense */
1048  )
1049 {
1050  int restat;
1051 
1052  assert(sizeof(SCIP_Real) == sizeof(double)); /* CPLEX only works with doubles as floating points */
1053  assert(sizeof(SCIP_Bool) == sizeof(int)); /* CPLEX only works with ints as bools */
1054  assert(lpi != NULL);
1055 
1056  SCIPdebugMessage("SCIPlpiCreate()\n");
1057 
1058  SCIP_ALLOC( BMSallocMemory(lpi) );
1059 
1060  /* create environment */
1061  (*lpi)->cpxenv = CPXopenCPLEX(&restat);
1062  CHECK_ZERO( messagehdlr, restat );
1063 
1064 #if (CPX_VERSION == 1100 || (CPX_VERSION == 1220 && (CPX_SUBVERSION == 0 || CPX_SUBVERSION == 2)))
1065  /* manually set number of threads to 1 to avoid huge system load due to CPLEX bug (version 1100) or segmentation fault (version 1220) */
1066  CHECK_ZERO( messagehdlr, CPXsetintparam((*lpi)->cpxenv, CPX_PARAM_THREADS, 1) );
1067 #endif
1068 
1069 #if 0 /* turning presolve off seems to be faster than turning it off on demand (if presolve detects infeasibility) */
1070  /* turn presolve off, s.t. for an infeasible problem, a ray is always available */
1071  CHECK_ZERO( messagehdlr, CPXsetintparam((*lpi)->cpxenv, CPX_PARAM_PREIND, CPX_OFF) );
1072 #endif
1073 
1074  /* get default parameter values */
1075  SCIP_CALL( getParameterValues((*lpi), &((*lpi)->defparam)) );
1076  copyParameterValues(&((*lpi)->curparam), &((*lpi)->defparam));
1077 
1078  /* create LP */
1079  (*lpi)->larray = NULL;
1080  (*lpi)->uarray = NULL;
1081  (*lpi)->senarray = NULL;
1082  (*lpi)->rhsarray = NULL;
1083  (*lpi)->rngarray = NULL;
1084  (*lpi)->valarray = NULL;
1085  (*lpi)->rngindarray = NULL;
1086  (*lpi)->cstat = NULL;
1087  (*lpi)->rstat = NULL;
1088  (*lpi)->indarray = NULL;
1089  (*lpi)->boundchgsize = 0;
1090  (*lpi)->sidechgsize = 0;
1091  (*lpi)->valsize = 0;
1092  (*lpi)->cstatsize = 0;
1093  (*lpi)->rstatsize = 0;
1094  (*lpi)->iterations = 0;
1095  (*lpi)->pricing = SCIP_PRICING_LPIDEFAULT;
1096  (*lpi)->solisbasic = FALSE;
1097  (*lpi)->cpxlp = CPXcreateprob((*lpi)->cpxenv, &restat, name);
1098  (*lpi)->instabilityignored = FALSE;
1099  (*lpi)->fromscratch = FALSE;
1100  (*lpi)->clearstate = FALSE;
1101  (*lpi)->feastol = 1e-06;
1102  (*lpi)->conditionlimit = -1.0;
1103  (*lpi)->checkcondition = FALSE;
1104 #if (CPX_VERSION <= 1100)
1105  (*lpi)->rngfound = FALSE;
1106 #endif
1107  (*lpi)->messagehdlr = messagehdlr;
1108 
1109  CHECK_ZERO( messagehdlr, restat );
1110  invalidateSolution(*lpi);
1111  copyParameterValues(&((*lpi)->cpxparam), &((*lpi)->defparam));
1112 
1113  /* set objective sense */
1114  SCIP_CALL( SCIPlpiChgObjsen(*lpi, objsen) );
1115 
1116  /* set default pricing */
1117  SCIP_CALL( SCIPlpiSetIntpar(*lpi, SCIP_LPPAR_PRICING, (int)(*lpi)->pricing) );
1118 
1119  return SCIP_OKAY;
1120 }
1121 
1122 /** deletes an LP problem object */
1124  SCIP_LPI** lpi /**< pointer to an LP interface structure */
1125  )
1126 {
1127  assert(lpi != NULL);
1128  assert(*lpi != NULL);
1129  assert((*lpi)->cpxenv != NULL);
1130 
1131  SCIPdebugMessage("SCIPlpiFree()\n");
1132 
1133  /* free LP */
1134  CHECK_ZERO( (*lpi)->messagehdlr, CPXfreeprob((*lpi)->cpxenv, &((*lpi)->cpxlp)) );
1135 
1136  /* free memory */
1137  BMSfreeMemoryArrayNull(&(*lpi)->larray);
1138  BMSfreeMemoryArrayNull(&(*lpi)->uarray);
1139  BMSfreeMemoryArrayNull(&(*lpi)->senarray);
1140  BMSfreeMemoryArrayNull(&(*lpi)->rhsarray);
1141  BMSfreeMemoryArrayNull(&(*lpi)->rngarray);
1142  BMSfreeMemoryArrayNull(&(*lpi)->valarray);
1143  BMSfreeMemoryArrayNull(&(*lpi)->rngindarray);
1144  BMSfreeMemoryArrayNull(&(*lpi)->cstat);
1145  BMSfreeMemoryArrayNull(&(*lpi)->rstat);
1146  BMSfreeMemoryArrayNull(&(*lpi)->indarray);
1147 
1148  /* free environment */
1149  CHECK_ZERO( (*lpi)->messagehdlr, CPXcloseCPLEX(&((*lpi)->cpxenv)) );
1150 
1151  BMSfreeMemory(lpi);
1152 
1153  return SCIP_OKAY;
1154 }
1155 
1156 /**@} */
1157 
1158 
1159 
1160 
1161 /*
1162  * Modification Methods
1163  */
1164 
1165 /**@name Modification Methods */
1166 /**@{ */
1167 
1168 /** copies LP data with column matrix into LP solver */
1170  SCIP_LPI* lpi, /**< LP interface structure */
1171  SCIP_OBJSEN objsen, /**< objective sense */
1172  int ncols, /**< number of columns */
1173  const SCIP_Real* obj, /**< objective function values of columns */
1174  const SCIP_Real* lb, /**< lower bounds of columns */
1175  const SCIP_Real* ub, /**< upper bounds of columns */
1176  char** colnames, /**< column names, or NULL */
1177  int nrows, /**< number of rows */
1178  const SCIP_Real* lhs, /**< left hand sides of rows */
1179  const SCIP_Real* rhs, /**< right hand sides of rows */
1180  char** rownames, /**< row names, or NULL */
1181  int nnonz, /**< number of nonzero elements in the constraint matrix */
1182  const int* beg, /**< start index of each column in ind- and val-array */
1183  const int* ind, /**< row indices of constraint matrix entries */
1184  const SCIP_Real* val /**< values of constraint matrix entries */
1185  )
1186 {
1187  int* cnt;
1188  int rngcount;
1189  int c;
1190 
1191  assert(lpi != NULL);
1192  assert(lpi->cpxlp != NULL);
1193  assert(lpi->cpxenv != NULL);
1194 
1195  SCIPdebugMessage("loading LP in column format into CPLEX: %d cols, %d rows\n", ncols, nrows);
1196 
1197  invalidateSolution(lpi);
1198 
1199  SCIP_CALL( ensureSidechgMem(lpi, nrows) );
1200 
1201  /* convert lhs/rhs into sen/rhs/range tuples */
1202  convertSides(lpi, nrows, lhs, rhs, 0, &rngcount);
1203 
1204  /* calculate column lengths */
1205  SCIP_ALLOC( BMSallocMemoryArray(&cnt, ncols) );
1206  for( c = 0; c < ncols-1; ++c )
1207  {
1208  cnt[c] = beg[c+1] - beg[c];
1209  assert(cnt[c] >= 0);
1210  }
1211  cnt[ncols-1] = nnonz - beg[ncols-1];
1212  assert(cnt[ncols-1] >= 0);
1213 
1214  /* copy data into CPLEX */
1215  CHECK_ZERO( lpi->messagehdlr, CPXcopylpwnames(lpi->cpxenv, lpi->cpxlp, ncols, nrows, cpxObjsen(objsen), obj,
1216  lpi->rhsarray, lpi->senarray, beg, cnt, ind, val, lb, ub, lpi->rngarray, colnames, rownames) );
1217 
1218  /* free temporary memory */
1219  BMSfreeMemoryArray(&cnt);
1220 
1221  assert(CPXgetnumcols(lpi->cpxenv, lpi->cpxlp) == ncols);
1222  assert(CPXgetnumrows(lpi->cpxenv, lpi->cpxlp) == nrows);
1223  assert(CPXgetnumnz(lpi->cpxenv, lpi->cpxlp) == nnonz);
1224 
1225  return SCIP_OKAY;
1226 }
1227 
1228 /** adds columns to the LP */
1230  SCIP_LPI* lpi, /**< LP interface structure */
1231  int ncols, /**< number of columns to be added */
1232  const SCIP_Real* obj, /**< objective function values of new columns */
1233  const SCIP_Real* lb, /**< lower bounds of new columns */
1234  const SCIP_Real* ub, /**< upper bounds of new columns */
1235  char** colnames, /**< column names, or NULL */
1236  int nnonz, /**< number of nonzero elements to be added to the constraint matrix */
1237  const int* beg, /**< start index of each column in ind- and val-array, or NULL if nnonz == 0 */
1238  const int* ind, /**< row indices of constraint matrix entries, or NULL if nnonz == 0 */
1239  const SCIP_Real* val /**< values of constraint matrix entries, or NULL if nnonz == 0 */
1240  )
1241 {
1242  assert(lpi != NULL);
1243  assert(lpi->cpxlp != NULL);
1244  assert(lpi->cpxenv != NULL);
1245 
1246  SCIPdebugMessage("adding %d columns with %d nonzeros to CPLEX\n", ncols, nnonz);
1247 
1248  invalidateSolution(lpi);
1249 
1250  if( nnonz > 0 )
1251  {
1252  CHECK_ZERO( lpi->messagehdlr, CPXaddcols(lpi->cpxenv, lpi->cpxlp, ncols, nnonz, obj, beg, ind, val, lb, ub, colnames) );
1253  }
1254  else
1255  {
1256  CHECK_ZERO( lpi->messagehdlr, CPXnewcols(lpi->cpxenv, lpi->cpxlp, ncols, obj, lb, ub, NULL, colnames) );
1257  }
1258 
1259  return SCIP_OKAY;
1260 }
1261 
1262 /** deletes all columns in the given range from LP */
1264  SCIP_LPI* lpi, /**< LP interface structure */
1265  int firstcol, /**< first column to be deleted */
1266  int lastcol /**< last column to be deleted */
1267  )
1268 {
1269  assert(lpi != NULL);
1270  assert(lpi->cpxlp != NULL);
1271  assert(lpi->cpxenv != NULL);
1272  assert(0 <= firstcol && firstcol <= lastcol && lastcol < CPXgetnumcols(lpi->cpxenv, lpi->cpxlp));
1273 
1274  SCIPdebugMessage("deleting %d columns from CPLEX\n", lastcol - firstcol + 1);
1275 
1276  invalidateSolution(lpi);
1277 
1278  CHECK_ZERO( lpi->messagehdlr, CPXdelcols(lpi->cpxenv, lpi->cpxlp, firstcol, lastcol) );
1279 
1280  return SCIP_OKAY;
1281 }
1282 
1283 /** deletes columns from SCIP_LP; the new position of a column must not be greater that its old position */
1285  SCIP_LPI* lpi, /**< LP interface structure */
1286  int* dstat /**< deletion status of columns
1287  * input: 1 if column should be deleted, 0 if not
1288  * output: new position of column, -1 if column was deleted */
1289  )
1290 {
1291  assert(lpi != NULL);
1292  assert(lpi->cpxlp != NULL);
1293  assert(lpi->cpxenv != NULL);
1294 
1295  SCIPdebugMessage("deleting a column set from CPLEX\n");
1296 
1297  invalidateSolution(lpi);
1298 
1299  CHECK_ZERO( lpi->messagehdlr, CPXdelsetcols(lpi->cpxenv, lpi->cpxlp, dstat) );
1300 
1301  return SCIP_OKAY;
1302 }
1303 
1304 /** adds rows to the LP */
1306  SCIP_LPI* lpi, /**< LP interface structure */
1307  int nrows, /**< number of rows to be added */
1308  const SCIP_Real* lhs, /**< left hand sides of new rows */
1309  const SCIP_Real* rhs, /**< right hand sides of new rows */
1310  char** rownames, /**< row names, or NULL */
1311  int nnonz, /**< number of nonzero elements to be added to the constraint matrix */
1312  const int* beg, /**< start index of each row in ind- and val-array, or NULL if nnonz == 0 */
1313  const int* ind, /**< column indices of constraint matrix entries, or NULL if nnonz == 0 */
1314  const SCIP_Real* val /**< values of constraint matrix entries, or NULL if nnonz == 0 */
1315  )
1316 {
1317  int rngcount;
1318 
1319  assert(lpi != NULL);
1320  assert(lpi->cpxlp != NULL);
1321  assert(lpi->cpxenv != NULL);
1322 
1323  SCIPdebugMessage("adding %d rows with %d nonzeros to CPLEX\n", nrows, nnonz);
1324 
1325  invalidateSolution(lpi);
1326 
1327  SCIP_CALL( ensureSidechgMem(lpi, nrows) );
1328 
1329  /* convert lhs/rhs into sen/rhs/range tuples */
1330  convertSides(lpi, nrows, lhs, rhs, CPXgetnumrows(lpi->cpxenv, lpi->cpxlp), &rngcount);
1331 
1332  /* add rows to LP */
1333  if( nnonz > 0 )
1334  {
1335  CHECK_ZERO( lpi->messagehdlr, CPXaddrows(lpi->cpxenv, lpi->cpxlp, 0, nrows, nnonz, lpi->rhsarray, lpi->senarray, beg, ind, val, NULL,
1336  rownames) );
1337  }
1338  else
1339  {
1340  CHECK_ZERO( lpi->messagehdlr, CPXnewrows(lpi->cpxenv, lpi->cpxlp, nrows, lpi->rhsarray, lpi->senarray, NULL, rownames) );
1341  }
1342  if( rngcount > 0 )
1343  {
1344 #if (CPX_VERSION <= 1100)
1345  if( lpi->rngfound == FALSE )
1346  {
1348  lpi->rngfound = TRUE;
1349  }
1350 #endif
1351  CHECK_ZERO( lpi->messagehdlr, CPXchgrngval(lpi->cpxenv, lpi->cpxlp, rngcount, lpi->rngindarray, lpi->rngarray) );
1352  }
1353 
1354  return SCIP_OKAY;
1355 }
1356 
1357 /** deletes all rows in the given range from LP */
1359  SCIP_LPI* lpi, /**< LP interface structure */
1360  int firstrow, /**< first row to be deleted */
1361  int lastrow /**< last row to be deleted */
1362  )
1363 {
1364  assert(lpi != NULL);
1365  assert(lpi->cpxlp != NULL);
1366  assert(lpi->cpxenv != NULL);
1367  assert(0 <= firstrow && firstrow <= lastrow && lastrow < CPXgetnumrows(lpi->cpxenv, lpi->cpxlp));
1368 
1369  SCIPdebugMessage("deleting %d rows from CPLEX\n", lastrow - firstrow + 1);
1370 
1371  invalidateSolution(lpi);
1372 
1373  CHECK_ZERO( lpi->messagehdlr, CPXdelrows(lpi->cpxenv, lpi->cpxlp, firstrow, lastrow) );
1374 
1375  return SCIP_OKAY;
1376 }
1377 
1378 /** deletes rows from SCIP_LP; the new position of a row must not be greater that its old position */
1380  SCIP_LPI* lpi, /**< LP interface structure */
1381  int* dstat /**< deletion status of rows
1382  * input: 1 if row should be deleted, 0 if not
1383  * output: new position of row, -1 if row was deleted */
1384  )
1385 {
1386  assert(lpi != NULL);
1387  assert(lpi->cpxlp != NULL);
1388  assert(lpi->cpxenv != NULL);
1389 
1390  SCIPdebugMessage("deleting a row set from CPLEX\n");
1391 
1392  invalidateSolution(lpi);
1393 
1394  CHECK_ZERO( lpi->messagehdlr, CPXdelsetrows(lpi->cpxenv, lpi->cpxlp, dstat) );
1395 
1396  return SCIP_OKAY;
1397 }
1398 
1399 /** clears the whole LP */
1401  SCIP_LPI* lpi /**< LP interface structure */
1402  )
1403 {
1404  int ncols;
1405  int nrows;
1406 
1407  assert(lpi != NULL);
1408  assert(lpi->cpxlp != NULL);
1409  assert(lpi->cpxenv != NULL);
1410 
1411  SCIPdebugMessage("clearing CPLEX LP\n");
1412 
1413  invalidateSolution(lpi);
1414 
1415  ncols = CPXgetnumcols(lpi->cpxenv, lpi->cpxlp);
1416  nrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
1417  if( ncols >= 1 )
1418  {
1419  CHECK_ZERO( lpi->messagehdlr, CPXdelcols(lpi->cpxenv, lpi->cpxlp, 0, ncols-1) );
1420  }
1421  if( nrows >= 1 )
1422  {
1423  CHECK_ZERO( lpi->messagehdlr, CPXdelrows(lpi->cpxenv, lpi->cpxlp, 0, nrows-1) );
1424  }
1425 
1426  return SCIP_OKAY;
1427 }
1428 
1429 /** changes lower and upper bounds of columns */
1431  SCIP_LPI* lpi, /**< LP interface structure */
1432  int ncols, /**< number of columns to change bounds for */
1433  const int* ind, /**< column indices */
1434  const SCIP_Real* lb, /**< values for the new lower bounds */
1435  const SCIP_Real* ub /**< values for the new upper bounds */
1436  )
1437 {
1438  assert(lpi != NULL);
1439  assert(lpi->cpxlp != NULL);
1440  assert(lpi->cpxenv != NULL);
1441 
1442  SCIPdebugMessage("changing %d bounds in CPLEX\n", ncols);
1443 #ifdef SCIP_DEBUG
1444  {
1445  int i;
1446  for( i = 0; i < ncols; ++i )
1447  SCIPdebugPrintf(" col %d: [%g,%g]\n", ind[i], lb[i], ub[i]);
1448  }
1449 #endif
1450 
1451  invalidateSolution(lpi);
1452 
1453  SCIP_CALL( ensureBoundchgMem(lpi, ncols) );
1454 
1455  CHECK_ZERO( lpi->messagehdlr, CPXchgbds(lpi->cpxenv, lpi->cpxlp, ncols, ind, lpi->larray, (SCIP_Real*)lb) );
1456  CHECK_ZERO( lpi->messagehdlr, CPXchgbds(lpi->cpxenv, lpi->cpxlp, ncols, ind, lpi->uarray, (SCIP_Real*)ub) );
1457 
1458 #ifndef NDEBUG
1459  {
1460  int i;
1461  for( i = 0; i < ncols; ++i )
1462  {
1463  SCIP_Real cpxlb;
1464  SCIP_Real cpxub;
1465 
1466  CHECK_ZERO( lpi->messagehdlr, CPXgetlb(lpi->cpxenv, lpi->cpxlp, &cpxlb, ind[i], ind[i]) );
1467  CHECK_ZERO( lpi->messagehdlr, CPXgetub(lpi->cpxenv, lpi->cpxlp, &cpxub, ind[i], ind[i]) );
1468 
1469  /* Note that CPLEX seems to set bounds below 1e-10 in absolute value to 0.*/
1470  assert( EPSZ(cpxlb, CPX_MAGICZEROCONSTANT) || cpxlb == lb[i] ); /*lint !e777*/
1471  assert( EPSZ(cpxub, CPX_MAGICZEROCONSTANT) || cpxub == ub[i] ); /*lint !e777*/
1472  }
1473  }
1474 #endif
1475 
1476  return SCIP_OKAY;
1477 }
1478 
1479 /** changes left and right hand sides of rows */
1481  SCIP_LPI* lpi, /**< LP interface structure */
1482  int nrows, /**< number of rows to change sides for */
1483  const int* ind, /**< row indices */
1484  const SCIP_Real* lhs, /**< new values for left hand sides */
1485  const SCIP_Real* rhs /**< new values for right hand sides */
1486  )
1487 {
1488  int rngcount;
1489  int i;
1490 
1491  assert(lpi != NULL);
1492  assert(lpi->cpxlp != NULL);
1493  assert(lpi->cpxenv != NULL);
1494 
1495  SCIPdebugMessage("changing %d sides in CPLEX\n", nrows);
1496 
1497  invalidateSolution(lpi);
1498 
1499  SCIP_CALL( ensureSidechgMem(lpi, nrows) );
1500 
1501  /* convert lhs/rhs into sen/rhs/range tuples */
1502  convertSides(lpi, nrows, lhs, rhs, 0, &rngcount);
1503 
1504  /* change row sides */
1505  CHECK_ZERO( lpi->messagehdlr, CPXchgsense(lpi->cpxenv, lpi->cpxlp, nrows, ind, lpi->senarray) );
1506  CHECK_ZERO( lpi->messagehdlr, CPXchgrhs(lpi->cpxenv, lpi->cpxlp, nrows, ind, lpi->rhsarray) );
1507  if( rngcount > 0 )
1508  {
1509  /* adjust the range count indices to the correct row indices */
1510  for( i = 0; i < rngcount; ++i )
1511  {
1512  assert(0 <= lpi->rngindarray[i] && lpi->rngindarray[i] < nrows);
1513  assert(lpi->senarray[lpi->rngindarray[i]] == 'R');
1514  lpi->rngindarray[i] = ind[lpi->rngindarray[i]];
1515  }
1516 
1517  /* change the range values in CPLEX */
1518  CHECK_ZERO( lpi->messagehdlr, CPXchgrngval(lpi->cpxenv, lpi->cpxlp, rngcount, lpi->rngindarray, lpi->rngarray) );
1519  }
1520 
1521  return SCIP_OKAY;
1522 }
1523 
1524 /** changes a single coefficient */
1526  SCIP_LPI* lpi, /**< LP interface structure */
1527  int row, /**< row number of coefficient to change */
1528  int col, /**< column number of coefficient to change */
1529  SCIP_Real newval /**< new value of coefficient */
1530  )
1531 {
1532  assert(lpi != NULL);
1533  assert(lpi->cpxlp != NULL);
1534  assert(lpi->cpxenv != NULL);
1535 
1536  SCIPdebugMessage("changing coefficient row %d, column %d in CPLEX to %g\n", row, col, newval);
1537 
1538  invalidateSolution(lpi);
1539 
1540  CHECK_ZERO( lpi->messagehdlr, CPXchgcoef(lpi->cpxenv, lpi->cpxlp, row, col, newval) );
1541 
1542  return SCIP_OKAY;
1543 }
1544 
1545 /** changes the objective sense */
1547  SCIP_LPI* lpi, /**< LP interface structure */
1548  SCIP_OBJSEN objsen /**< new objective sense */
1549  )
1550 {
1551  assert(lpi != NULL);
1552  assert(lpi->cpxlp != NULL);
1553  assert(lpi->cpxenv != NULL);
1554 
1555  SCIPdebugMessage("changing objective sense in CPLEX to %d\n", objsen);
1556 
1557  invalidateSolution(lpi);
1558 
1559  CHECK_ZERO( lpi->messagehdlr, CPXchgobjsen(lpi->cpxenv, lpi->cpxlp, cpxObjsen(objsen)) );
1560 
1561  return SCIP_OKAY;
1562 }
1563 
1564 /** changes objective values of columns in the LP */
1566  SCIP_LPI* lpi, /**< LP interface structure */
1567  int ncols, /**< number of columns to change objective value for */
1568  int* ind, /**< column indices to change objective value for */
1569  SCIP_Real* obj /**< new objective values for columns */
1570  )
1571 {
1572  assert(lpi != NULL);
1573  assert(lpi->cpxlp != NULL);
1574  assert(lpi->cpxenv != NULL);
1575 
1576  SCIPdebugMessage("changing %d objective values in CPLEX\n", ncols);
1577 
1578  CHECK_ZERO( lpi->messagehdlr, CPXchgobj(lpi->cpxenv, lpi->cpxlp, ncols, ind, obj) );
1579 
1580  return SCIP_OKAY;
1581 }
1582 
1583 /** multiplies a row with a non-zero scalar; for negative scalars, the row's sense is switched accordingly */
1585  SCIP_LPI* lpi, /**< LP interface structure */
1586  int row, /**< row number to scale */
1587  SCIP_Real scaleval /**< scaling multiplier */
1588  )
1589 {
1590  SCIP_Real lhs;
1591  SCIP_Real rhs;
1592  int nnonz;
1593  int beg;
1594  int i;
1595 
1596  assert(lpi != NULL);
1597  assert(lpi->cpxlp != NULL);
1598  assert(lpi->cpxenv != NULL);
1599  assert(scaleval != 0.0);
1600 
1601  SCIPdebugMessage("scaling row %d with factor %g in CPLEX\n", row, scaleval);
1602 
1603  invalidateSolution(lpi);
1604 
1605  SCIP_CALL( ensureValMem(lpi, CPXgetnumcols(lpi->cpxenv, lpi->cpxlp)) );
1606 
1607  /* get the row */
1608  SCIP_CALL( SCIPlpiGetRows(lpi, row, row, &lhs, &rhs, &nnonz, &beg, lpi->indarray, lpi->valarray) );
1609 
1610  /* scale row coefficients */
1611  for( i = 0; i < nnonz; ++i )
1612  {
1613  SCIP_CALL( SCIPlpiChgCoef(lpi, row, lpi->indarray[i], lpi->valarray[i] * scaleval) );
1614  }
1615 
1616  /* scale row sides */
1617  if( lhs > -CPX_INFBOUND )
1618  lhs *= scaleval;
1619  else if( scaleval < 0.0 )
1620  lhs = CPX_INFBOUND;
1621  if( rhs < CPX_INFBOUND )
1622  rhs *= scaleval;
1623  else if( scaleval < 0.0 )
1624  rhs = -CPX_INFBOUND;
1625  if( scaleval > 0.0 )
1626  {
1627  SCIP_CALL( SCIPlpiChgSides(lpi, 1, &row, &lhs, &rhs) );
1628  }
1629  else
1630  {
1631  SCIP_CALL( SCIPlpiChgSides(lpi, 1, &row, &rhs, &lhs) );
1632  }
1633 
1634  return SCIP_OKAY;
1635 }
1636 
1637 /** multiplies a column with a non-zero scalar; the objective value is multiplied with the scalar, and the bounds
1638  * are divided by the scalar; for negative scalars, the column's bounds are switched
1639  */
1641  SCIP_LPI* lpi, /**< LP interface structure */
1642  int col, /**< column number to scale */
1643  SCIP_Real scaleval /**< scaling multiplier */
1644  )
1645 {
1646  SCIP_Real lb;
1647  SCIP_Real ub;
1648  SCIP_Real obj;
1649  int nnonz;
1650  int beg;
1651  int i;
1652 
1653  assert(lpi != NULL);
1654  assert(lpi->cpxlp != NULL);
1655  assert(lpi->cpxenv != NULL);
1656  assert(scaleval != 0.0);
1657 
1658  SCIPdebugMessage("scaling column %d with factor %g in CPLEX\n", col, scaleval);
1659 
1660  invalidateSolution(lpi);
1661 
1662  SCIP_CALL( ensureValMem(lpi, CPXgetnumrows(lpi->cpxenv, lpi->cpxlp)) );
1663 
1664  /* get the column */
1665  SCIP_CALL( SCIPlpiGetCols(lpi, col, col, &lb, &ub, &nnonz, &beg, lpi->indarray, lpi->valarray) );
1666 
1667  /* get objective coefficient */
1668  SCIP_CALL( SCIPlpiGetObj(lpi, col, col, &obj) );
1669 
1670  /* scale column coefficients */
1671  for( i = 0; i < nnonz; ++i )
1672  {
1673  SCIP_CALL( SCIPlpiChgCoef(lpi, lpi->indarray[i], col, lpi->valarray[i] * scaleval) );
1674  }
1675 
1676  /* scale objective value */
1677  obj *= scaleval;
1678  SCIP_CALL( SCIPlpiChgObj(lpi, 1, &col, &obj) );
1679 
1680  /* scale column bounds */
1681  if( lb > -CPX_INFBOUND )
1682  lb /= scaleval;
1683  else if( scaleval < 0.0 )
1684  lb = CPX_INFBOUND;
1685  if( ub < CPX_INFBOUND )
1686  ub /= scaleval;
1687  else if( scaleval < 0.0 )
1688  ub = -CPX_INFBOUND;
1689  if( scaleval > 0.0 )
1690  {
1691  SCIP_CALL( SCIPlpiChgBounds(lpi, 1, &col, &lb, &ub) );
1692  }
1693  else
1694  {
1695  SCIP_CALL( SCIPlpiChgBounds(lpi, 1, &col, &ub, &lb) );
1696  }
1697 
1698  return SCIP_OKAY;
1699 }
1700 
1701 /**@} */
1702 
1703 
1704 
1705 
1706 /*
1707  * Data Accessing Methods
1708  */
1709 
1710 /**@name Data Accessing Methods */
1711 /**@{ */
1712 
1713 /** gets the number of rows in the LP */
1715  SCIP_LPI* lpi, /**< LP interface structure */
1716  int* nrows /**< pointer to store the number of rows */
1717  )
1718 {
1719  assert(lpi != NULL);
1720  assert(lpi->cpxenv != NULL);
1721  assert(nrows != NULL);
1722 
1723  SCIPdebugMessage("getting number of rows\n");
1724 
1725  *nrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
1726 
1727  return SCIP_OKAY;
1728 }
1729 
1730 /** gets the number of columns in the LP */
1732  SCIP_LPI* lpi, /**< LP interface structure */
1733  int* ncols /**< pointer to store the number of cols */
1734  )
1735 {
1736  assert(lpi != NULL);
1737  assert(lpi->cpxenv != NULL);
1738  assert(ncols != NULL);
1739 
1740  SCIPdebugMessage("getting number of columns\n");
1741 
1742  *ncols = CPXgetnumcols(lpi->cpxenv, lpi->cpxlp);
1743 
1744  return SCIP_OKAY;
1745 }
1746 
1747 /** gets the number of nonzero elements in the LP constraint matrix */
1749  SCIP_LPI* lpi, /**< LP interface structure */
1750  int* nnonz /**< pointer to store the number of nonzeros */
1751  )
1752 {
1753  assert(lpi != NULL);
1754  assert(lpi->cpxenv != NULL);
1755  assert(nnonz != NULL);
1756 
1757  SCIPdebugMessage("getting number of non-zeros\n");
1758 
1759  *nnonz = CPXgetnumnz(lpi->cpxenv, lpi->cpxlp);
1760 
1761  return SCIP_OKAY;
1762 }
1763 
1764 /** gets columns from LP problem object; the arrays have to be large enough to store all values
1765  * Either both, lb and ub, have to be NULL, or both have to be non-NULL,
1766  * either nnonz, beg, ind, and val have to be NULL, or all of them have to be non-NULL.
1767  */
1769  SCIP_LPI* lpi, /**< LP interface structure */
1770  int firstcol, /**< first column to get from LP */
1771  int lastcol, /**< last column to get from LP */
1772  SCIP_Real* lb, /**< buffer to store the lower bound vector, or NULL */
1773  SCIP_Real* ub, /**< buffer to store the upper bound vector, or NULL */
1774  int* nnonz, /**< pointer to store the number of nonzero elements returned, or NULL */
1775  int* beg, /**< buffer to store start index of each column in ind- and val-array, or NULL */
1776  int* ind, /**< buffer to store column indices of constraint matrix entries, or NULL */
1777  SCIP_Real* val /**< buffer to store values of constraint matrix entries, or NULL */
1778  )
1779 {
1780  assert(lpi != NULL);
1781  assert(lpi->cpxlp != NULL);
1782  assert(lpi->cpxenv != NULL);
1783  assert(0 <= firstcol && firstcol <= lastcol && lastcol < CPXgetnumcols(lpi->cpxenv, lpi->cpxlp));
1784 
1785  SCIPdebugMessage("getting columns %d to %d\n", firstcol, lastcol);
1786 
1787  if( lb != NULL )
1788  {
1789  assert(ub != NULL);
1790 
1791  CHECK_ZERO( lpi->messagehdlr, CPXgetlb(lpi->cpxenv, lpi->cpxlp, lb, firstcol, lastcol) );
1792  CHECK_ZERO( lpi->messagehdlr, CPXgetub(lpi->cpxenv, lpi->cpxlp, ub, firstcol, lastcol) );
1793  }
1794  else
1795  assert(ub == NULL);
1796 
1797  if( nnonz != NULL )
1798  {
1799  int surplus;
1800 
1801  assert(beg != NULL);
1802  assert(ind != NULL);
1803  assert(val != NULL);
1804 
1805  /* get matrix entries */
1806  CHECK_ZERO( lpi->messagehdlr, CPXgetcols(lpi->cpxenv, lpi->cpxlp, nnonz, beg, ind, val,
1807  CPXgetnumnz(lpi->cpxenv, lpi->cpxlp), &surplus, firstcol, lastcol) );
1808  assert(surplus >= 0);
1809  }
1810  else
1811  {
1812  assert(beg == NULL);
1813  assert(ind == NULL);
1814  assert(val == NULL);
1815  }
1816 
1817  return SCIP_OKAY;
1818 }
1819 
1820 /** gets rows from LP problem object; the arrays have to be large enough to store all values.
1821  * Either both, lhs and rhs, have to be NULL, or both have to be non-NULL,
1822  * either nnonz, beg, ind, and val have to be NULL, or all of them have to be non-NULL.
1823  */
1825  SCIP_LPI* lpi, /**< LP interface structure */
1826  int firstrow, /**< first row to get from LP */
1827  int lastrow, /**< last row to get from LP */
1828  SCIP_Real* lhs, /**< buffer to store left hand side vector, or NULL */
1829  SCIP_Real* rhs, /**< buffer to store right hand side vector, or NULL */
1830  int* nnonz, /**< pointer to store the number of nonzero elements returned, or NULL */
1831  int* beg, /**< buffer to store start index of each row in ind- and val-array, or NULL */
1832  int* ind, /**< buffer to store row indices of constraint matrix entries, or NULL */
1833  SCIP_Real* val /**< buffer to store values of constraint matrix entries, or NULL */
1834  )
1835 {
1836  int retcode;
1837 
1838  assert(lpi != NULL);
1839  assert(lpi->cpxlp != NULL);
1840  assert(lpi->cpxenv != NULL);
1841  assert(0 <= firstrow && firstrow <= lastrow && lastrow < CPXgetnumrows(lpi->cpxenv, lpi->cpxlp));
1842 
1843  SCIPdebugMessage("getting rows %d to %d\n", firstrow, lastrow);
1844 
1845  if( lhs != NULL || rhs != NULL )
1846  {
1847  /* get row sense, rhs, and ranges */
1848  SCIP_CALL( ensureSidechgMem(lpi, lastrow - firstrow + 1) );
1849  CHECK_ZERO( lpi->messagehdlr, CPXgetsense(lpi->cpxenv, lpi->cpxlp, lpi->senarray, firstrow, lastrow) );
1850  CHECK_ZERO( lpi->messagehdlr, CPXgetrhs(lpi->cpxenv, lpi->cpxlp, lpi->rhsarray, firstrow, lastrow) );
1851  retcode = CPXgetrngval(lpi->cpxenv, lpi->cpxlp, lpi->rngarray, firstrow, lastrow);
1852  if( retcode != CPXERR_NO_RNGVAL ) /* ignore "No range values" error */
1853  {
1854  CHECK_ZERO( lpi->messagehdlr, retcode );
1855  }
1856  else
1857  BMSclearMemoryArray(lpi->rngarray, lastrow-firstrow+1);
1858 
1859  /* convert sen/rhs/range into lhs/rhs tuples */
1860  reconvertSides(lpi, lastrow - firstrow + 1, lhs, rhs);
1861  }
1862 
1863  if( nnonz != NULL )
1864  {
1865  int surplus;
1866 
1867  assert(beg != NULL);
1868  assert(ind != NULL);
1869  assert(val != NULL);
1870 
1871  /* get matrix entries */
1872  CHECK_ZERO( lpi->messagehdlr, CPXgetrows(lpi->cpxenv, lpi->cpxlp, nnonz, beg, ind, val,
1873  CPXgetnumnz(lpi->cpxenv, lpi->cpxlp), &surplus, firstrow, lastrow) );
1874  assert(surplus >= 0);
1875  }
1876  else
1877  {
1878  assert(beg == NULL);
1879  assert(ind == NULL);
1880  assert(val == NULL);
1881  }
1882 
1883  return SCIP_OKAY;
1884 }
1885 
1886 /** gets column names */
1888  SCIP_LPI* lpi, /**< LP interface structure */
1889  int firstcol, /**< first column to get name from LP */
1890  int lastcol, /**< last column to get name from LP */
1891  char** colnames, /**< pointers to column names (of size at least lastcol-firstcol+1) */
1892  char* namestorage, /**< storage for col names */
1893  int namestoragesize, /**< size of namestorage (if 0, storageleft returns the storage needed) */
1894  int* storageleft /**< amount of storage left (if < 0 the namestorage was not big enough) */
1895  )
1896 {
1897  int retcode;
1898 
1899  assert(lpi != NULL);
1900  assert(lpi->cpxlp != NULL);
1901  assert(lpi->cpxenv != NULL);
1902  assert(colnames != NULL || namestoragesize == 0);
1903  assert(namestorage != NULL || namestoragesize == 0);
1904  assert(namestoragesize >= 0);
1905  assert(storageleft != NULL);
1906  assert(0 <= firstcol && firstcol <= lastcol && lastcol < CPXgetnumcols(lpi->cpxenv, lpi->cpxlp));
1907 
1908  SCIPdebugMessage("getting column names %d to %d\n", firstcol, lastcol);
1909 
1910  retcode = CPXgetcolname(lpi->cpxenv, lpi->cpxlp, colnames, namestorage, namestoragesize, storageleft, firstcol, lastcol);
1911  assert( namestoragesize != 0 || retcode == CPXERR_NEGATIVE_SURPLUS );
1912  if( namestoragesize != 0 )
1913  {
1914  CHECK_ZERO( lpi->messagehdlr, retcode );
1915  }
1916 
1917  return SCIP_OKAY;
1918 }
1919 
1920 /** gets row names */
1922  SCIP_LPI* lpi, /**< LP interface structure */
1923  int firstrow, /**< first row to get name from LP */
1924  int lastrow, /**< last row to get name from LP */
1925  char** rownames, /**< pointers to row names (of size at least lastrow-firstrow+1) */
1926  char* namestorage, /**< storage for row names */
1927  int namestoragesize, /**< size of namestorage (if 0, -storageleft returns the storage needed) */
1928  int* storageleft /**< amount of storage left (if < 0 the namestorage was not big enough) */
1929  )
1930 {
1931  int retcode;
1932 
1933  assert(lpi != NULL);
1934  assert(lpi->cpxlp != NULL);
1935  assert(lpi->cpxenv != NULL);
1936  assert(rownames != NULL || namestoragesize == 0);
1937  assert(namestorage != NULL || namestoragesize == 0);
1938  assert(namestoragesize >= 0);
1939  assert(storageleft != NULL);
1940  assert(0 <= firstrow && firstrow <= lastrow && lastrow < CPXgetnumrows(lpi->cpxenv, lpi->cpxlp));
1941 
1942  SCIPdebugMessage("getting row names %d to %d\n", firstrow, lastrow);
1943 
1944  retcode = CPXgetrowname(lpi->cpxenv, lpi->cpxlp, rownames, namestorage, namestoragesize, storageleft, firstrow, lastrow);
1945  assert( namestoragesize != 0 || retcode == CPXERR_NEGATIVE_SURPLUS );
1946  if( namestoragesize != 0 )
1947  {
1948  CHECK_ZERO( lpi->messagehdlr, retcode );
1949  }
1950 
1951  return SCIP_OKAY;
1952 }
1953 
1954 /** gets objective sense of the LP */
1956  SCIP_LPI* lpi, /**< LP interface structure */
1957  SCIP_OBJSEN* objsen /**< pointer to store objective sense */
1958  )
1959 {
1960  assert(lpi != NULL);
1961  assert(objsen != NULL);
1962  assert(CPXgetobjsen(lpi->cpxenv, lpi->cpxlp) == CPX_MIN || CPXgetobjsen(lpi->cpxenv, lpi->cpxlp) == CPX_MAX);
1963 
1964  SCIPdebugMessage("getting objective sense\n");
1965 
1966  *objsen = (CPXgetobjsen(lpi->cpxenv, lpi->cpxlp) == CPX_MIN) ? SCIP_OBJSEN_MINIMIZE : SCIP_OBJSEN_MAXIMIZE;
1967 
1968  return SCIP_OKAY;
1969 }
1970 
1971 /** gets objective coefficients from LP problem object */
1973  SCIP_LPI* lpi, /**< LP interface structure */
1974  int firstcol, /**< first column to get objective coefficient for */
1975  int lastcol, /**< last column to get objective coefficient for */
1976  SCIP_Real* vals /**< array to store objective coefficients */
1977  )
1978 {
1979  assert(lpi != NULL);
1980  assert(lpi->cpxlp != NULL);
1981  assert(lpi->cpxenv != NULL);
1982  assert(firstcol <= lastcol);
1983  assert(vals != NULL);
1984 
1985  SCIPdebugMessage("getting objective values %d to %d\n", firstcol, lastcol);
1986 
1987  CHECK_ZERO( lpi->messagehdlr, CPXgetobj(lpi->cpxenv, lpi->cpxlp, vals, firstcol, lastcol) );
1988 
1989  return SCIP_OKAY;
1990 }
1991 
1992 /** gets current bounds from LP problem object */
1994  SCIP_LPI* lpi, /**< LP interface structure */
1995  int firstcol, /**< first column to get bounds for */
1996  int lastcol, /**< last column to get bounds for */
1997  SCIP_Real* lbs, /**< array to store lower bound values, or NULL */
1998  SCIP_Real* ubs /**< array to store upper bound values, or NULL */
1999  )
2000 {
2001  assert(lpi != NULL);
2002  assert(lpi->cpxlp != NULL);
2003  assert(lpi->cpxenv != NULL);
2004  assert(firstcol <= lastcol);
2005 
2006  SCIPdebugMessage("getting bounds %d to %d\n", firstcol, lastcol);
2007 
2008  if( lbs != NULL )
2009  {
2010  CHECK_ZERO( lpi->messagehdlr, CPXgetlb(lpi->cpxenv, lpi->cpxlp, lbs, firstcol, lastcol) );
2011  }
2012 
2013  if( ubs != NULL )
2014  {
2015  CHECK_ZERO( lpi->messagehdlr, CPXgetub(lpi->cpxenv, lpi->cpxlp, ubs, firstcol, lastcol) );
2016  }
2017 
2018  return SCIP_OKAY;
2019 }
2020 
2021 /** gets current row sides from LP problem object */
2023  SCIP_LPI* lpi, /**< LP interface structure */
2024  int firstrow, /**< first row to get sides for */
2025  int lastrow, /**< last row to get sides for */
2026  SCIP_Real* lhss, /**< array to store left hand side values, or NULL */
2027  SCIP_Real* rhss /**< array to store right hand side values, or NULL */
2028  )
2029 {
2030  int retval;
2031 
2032  assert(lpi != NULL);
2033  assert(lpi->cpxlp != NULL);
2034  assert(lpi->cpxenv != NULL);
2035  assert(firstrow <= lastrow);
2036 
2037  SCIPdebugMessage("getting row sides %d to %d\n", firstrow, lastrow);
2038 
2039  /* get row sense, rhs, and ranges */
2040  SCIP_CALL( ensureSidechgMem(lpi, lastrow - firstrow + 1) );
2041  CHECK_ZERO( lpi->messagehdlr, CPXgetsense(lpi->cpxenv, lpi->cpxlp, lpi->senarray, firstrow, lastrow) );
2042  CHECK_ZERO( lpi->messagehdlr, CPXgetrhs(lpi->cpxenv, lpi->cpxlp, lpi->rhsarray, firstrow, lastrow) );
2043  retval = CPXgetrngval(lpi->cpxenv, lpi->cpxlp, lpi->rngarray, firstrow, lastrow);
2044  if( retval != CPXERR_NO_RNGVAL ) /* ignore "No range values" error */
2045  {
2046  CHECK_ZERO( lpi->messagehdlr, retval );
2047  }
2048  else
2049  BMSclearMemoryArray(lpi->rngarray, lastrow-firstrow+1);
2050 
2051  /* convert sen/rhs/range into lhs/rhs tuples */
2052  reconvertSides(lpi, lastrow - firstrow + 1, lhss, rhss);
2053 
2054  return SCIP_OKAY;
2055 }
2056 
2057 /** gets a single coefficient */
2059  SCIP_LPI* lpi, /**< LP interface structure */
2060  int row, /**< row number of coefficient */
2061  int col, /**< column number of coefficient */
2062  SCIP_Real* val /**< pointer to store the value of the coefficient */
2063  )
2064 {
2065  assert(lpi != NULL);
2066  assert(lpi->cpxlp != NULL);
2067  assert(lpi->cpxenv != NULL);
2068 
2069  SCIPdebugMessage("getting coefficient of row %d col %d\n", row, col);
2070 
2071  CHECK_ZERO( lpi->messagehdlr, CPXgetcoef(lpi->cpxenv, lpi->cpxlp, row, col, val) );
2072 
2073  return SCIP_OKAY;
2074 }
2075 
2076 /**@} */
2077 
2078 
2079 
2080 
2081 /*
2082  * Solving Methods
2083  */
2084 
2085 /**@name Solving Methods */
2086 /**@{ */
2087 
2088 /** calls primal simplex to solve the LP */
2090  SCIP_LPI* lpi /**< LP interface structure */
2091  )
2092 {
2093  int retval;
2094  int primalfeasible;
2095  int dualfeasible;
2096  int solntype;
2097 
2098  assert(lpi != NULL);
2099  assert(lpi->cpxlp != NULL);
2100  assert(lpi->cpxenv != NULL);
2101 
2102  SCIPdebugMessage("calling CPLEX primal simplex: %d cols, %d rows\n",
2103  CPXgetnumcols(lpi->cpxenv, lpi->cpxlp), CPXgetnumrows(lpi->cpxenv, lpi->cpxlp));
2104 
2105  invalidateSolution(lpi);
2106 
2107  setIntParam(lpi, CPX_PARAM_ADVIND, lpi->fromscratch || lpi->clearstate ? CPX_OFF : CPX_ON);
2108  lpi->clearstate = FALSE;
2109 
2110  SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
2111 
2112  SCIPdebugMessage("calling CPXprimopt()\n");
2113  retval = CPXprimopt(lpi->cpxenv, lpi->cpxlp);
2114  lpi->iterations = CPXgetphase1cnt(lpi->cpxenv, lpi->cpxlp) + CPXgetitcnt(lpi->cpxenv, lpi->cpxlp);
2115  switch( retval )
2116  {
2117  case 0:
2118  break;
2119  case CPXERR_NO_MEMORY:
2120  return SCIP_NOMEMORY;
2121  default:
2122  return SCIP_LPERROR;
2123  }
2124 
2125  lpi->solstat = CPXgetstat(lpi->cpxenv, lpi->cpxlp);
2126  lpi->instabilityignored = FALSE;
2127  CHECK_ZERO( lpi->messagehdlr, CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, NULL, &primalfeasible, &dualfeasible) );
2128  SCIPdebugMessage(" -> CPLEX returned solstat=%d, pfeas=%d, dfeas=%d (%d iterations)\n",
2129  lpi->solstat, primalfeasible, dualfeasible, lpi->iterations);
2130 
2131  if( lpi->solstat == CPX_STAT_INForUNBD
2132  || (lpi->solstat == CPX_STAT_INFEASIBLE && !dualfeasible)
2133  || (lpi->solstat == CPX_STAT_UNBOUNDED && !primalfeasible) )
2134  {
2135  if( getIntParam(lpi, CPX_PARAM_PREIND) == CPX_ON )
2136  {
2137  /* maybe the preprocessor solved the problem; but we need a solution, so solve again without preprocessing */
2138  SCIPdebugMessage("presolver may have solved the problem -> calling CPLEX primal simplex again without presolve\n");
2139 
2140  /* switch off preprocessing */
2141  setIntParam(lpi, CPX_PARAM_PREIND, CPX_OFF);
2142  SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
2143 
2144  retval = CPXprimopt(lpi->cpxenv, lpi->cpxlp);
2145  switch( retval )
2146  {
2147  case 0:
2148  break;
2149  case CPXERR_NO_MEMORY:
2150  return SCIP_NOMEMORY;
2151  default:
2152  return SCIP_LPERROR;
2153  }
2154 
2155  lpi->iterations += CPXgetphase1cnt(lpi->cpxenv, lpi->cpxlp) + CPXgetitcnt(lpi->cpxenv, lpi->cpxlp);
2156  lpi->solstat = CPXgetstat(lpi->cpxenv, lpi->cpxlp);
2157  lpi->instabilityignored = FALSE;
2158  SCIPdebugMessage(" -> CPLEX returned solstat=%d (%d iterations)\n", lpi->solstat, lpi->iterations);
2159 
2160  /* switch on preprocessing again */
2161  setIntParam(lpi, CPX_PARAM_PREIND, CPX_ON);
2162  }
2163 
2164  if( lpi->solstat == CPX_STAT_INForUNBD )
2165  {
2166  /* preprocessing was not the problem; issue a warning message and treat LP as infeasible */
2167  SCIPerrorMessage("CPLEX primal simplex returned CPX_STAT_INForUNBD after presolving was turned off\n");
2168  }
2169  }
2170 
2171  /* check whether the solution is basic: if Cplex, e.g., hits a time limit in data setup, this might not be the case,
2172  * also for some pathological cases of infeasibility, e.g., contradictory bounds
2173  */
2174  if( lpi->solstat == CPX_STAT_OPTIMAL )
2175  {
2176 #ifdef NDEBUG
2177  lpi->solisbasic = TRUE;
2178 #else
2179  CHECK_ZERO( lpi->messagehdlr, CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, &solntype, NULL, NULL) );
2180  lpi->solisbasic = (solntype == CPX_BASIC_SOLN);
2181  assert(lpi->solisbasic);
2182 #endif
2183  }
2184  else
2185  {
2186  CHECK_ZERO( lpi->messagehdlr, CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, &solntype, NULL, NULL) );
2187  lpi->solisbasic = (solntype == CPX_BASIC_SOLN);
2188  }
2189 
2190  return SCIP_OKAY;
2191 }
2192 
2193 /** calls dual simplex to solve the LP */
2195  SCIP_LPI* lpi /**< LP interface structure */
2196  )
2197 {
2198  int retval;
2199  int primalfeasible;
2200  int dualfeasible;
2201  int solntype;
2202 
2203  assert(lpi != NULL);
2204  assert(lpi->cpxlp != NULL);
2205  assert(lpi->cpxenv != NULL);
2206 
2207  SCIPdebugMessage("calling CPLEX dual simplex: %d cols, %d rows\n",
2208  CPXgetnumcols(lpi->cpxenv, lpi->cpxlp), CPXgetnumrows(lpi->cpxenv, lpi->cpxlp));
2209 
2210  invalidateSolution(lpi);
2211 
2212  setIntParam(lpi, CPX_PARAM_ADVIND, lpi->fromscratch || lpi->clearstate ? CPX_OFF : CPX_ON);
2213  lpi->clearstate = FALSE;
2214 
2215  SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
2216 
2217  SCIPdebugMessage("calling CPXdualopt()\n");
2218  retval = CPXdualopt(lpi->cpxenv, lpi->cpxlp);
2219  lpi->iterations = CPXgetphase1cnt(lpi->cpxenv, lpi->cpxlp) + CPXgetitcnt(lpi->cpxenv, lpi->cpxlp);
2220  switch( retval )
2221  {
2222  case 0:
2223  break;
2224  case CPXERR_NO_MEMORY:
2225  return SCIP_NOMEMORY;
2226  default:
2227  return SCIP_LPERROR;
2228  }
2229 
2230  CHECK_ZERO( lpi->messagehdlr, CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, &solntype, NULL, NULL) );
2231 
2232  lpi->solstat = CPXgetstat(lpi->cpxenv, lpi->cpxlp);
2233  lpi->instabilityignored = FALSE;
2234  CHECK_ZERO( lpi->messagehdlr, CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, NULL, &primalfeasible, &dualfeasible) );
2235  SCIPdebugMessage(" -> CPLEX returned solstat=%d, pfeas=%d, dfeas=%d (%d iterations)\n",
2236  lpi->solstat, primalfeasible, dualfeasible, lpi->iterations);
2237 
2238  if( lpi->solstat == CPX_STAT_INForUNBD
2239  || (lpi->solstat == CPX_STAT_INFEASIBLE && !dualfeasible)
2240  || (lpi->solstat == CPX_STAT_UNBOUNDED && !primalfeasible) )
2241  {
2242  if( getIntParam(lpi, CPX_PARAM_PREIND) == CPX_ON )
2243  {
2244  /* maybe the preprocessor solved the problem; but we need a solution, so solve again without preprocessing */
2245  SCIPdebugMessage("presolver may have solved the problem -> calling CPLEX dual simplex again without presolve\n");
2246 
2247  /* switch off preprocessing */
2248  setIntParam(lpi, CPX_PARAM_PREIND, CPX_OFF);
2249  SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
2250 
2251  retval = CPXdualopt(lpi->cpxenv, lpi->cpxlp);
2252  switch( retval )
2253  {
2254  case 0:
2255  break;
2256  case CPXERR_NO_MEMORY:
2257  return SCIP_NOMEMORY;
2258  default:
2259  return SCIP_LPERROR;
2260  }
2261 
2262  lpi->iterations += CPXgetphase1cnt(lpi->cpxenv, lpi->cpxlp) + CPXgetitcnt(lpi->cpxenv, lpi->cpxlp);
2263  lpi->solstat = CPXgetstat(lpi->cpxenv, lpi->cpxlp);
2264  lpi->instabilityignored = FALSE;
2265  CHECK_ZERO( lpi->messagehdlr, CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, NULL, &primalfeasible, &dualfeasible) );
2266  SCIPdebugMessage(" -> CPLEX returned solstat=%d (%d iterations)\n", lpi->solstat, lpi->iterations);
2267 
2268  /* switch on preprocessing again */
2269  setIntParam(lpi, CPX_PARAM_PREIND, CPX_ON);
2270  }
2271 
2272  if( lpi->solstat == CPX_STAT_INForUNBD )
2273  {
2274  /* preprocessing was not the problem; issue a warning message and treat LP as infeasible */
2275  SCIPerrorMessage("CPLEX dual simplex returned CPX_STAT_INForUNBD after presolving was turned off\n");
2276  }
2277  }
2278 
2279  /* check whether the solution is basic: if Cplex, e.g., hits a time limit in data setup, this might not be the case,
2280  * also for some pathological cases of infeasibility, e.g., contradictory bounds
2281  */
2282  if( lpi->solstat == CPX_STAT_OPTIMAL )
2283  {
2284 #ifdef NDEBUG
2285  lpi->solisbasic = TRUE;
2286 #else
2287  CHECK_ZERO( lpi->messagehdlr, CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, &solntype, NULL, NULL) );
2288  lpi->solisbasic = (solntype == CPX_BASIC_SOLN);
2289  assert(lpi->solisbasic);
2290 #endif
2291  }
2292  else
2293  {
2294  CHECK_ZERO( lpi->messagehdlr, CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, &solntype, NULL, NULL) );
2295  lpi->solisbasic = (solntype == CPX_BASIC_SOLN);
2296  }
2297 
2298 #if 0
2299  /* this fixes the strange behavior of CPLEX, that in case of the objective limit exceedance, it returns the
2300  * solution for the basis preceeding the one with exceeding objective limit
2301  * (using this "wrong" dual solution can cause column generation algorithms to fail to find an improving column)
2302  */
2303  if( SCIPlpiIsObjlimExc(lpi) )
2304  {
2305  SCIP_Real objval;
2306  SCIP_Real llim;
2307  SCIP_Real ulim;
2308  SCIP_Real eps;
2309 
2310  /* check, if the dual solution returned by CPLEX really exceeds the objective limit;
2311  * CPLEX usually returns the basis one iteration before the one that exceeds the limit
2312  */
2313  SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
2314  llim = getDblParam(lpi, CPX_PARAM_OBJLLIM);
2315  ulim = getDblParam(lpi, CPX_PARAM_OBJULIM);
2316  eps = getDblParam(lpi, CPX_PARAM_EPOPT);
2317  if( objval >= llim - eps && objval <= ulim + eps )
2318  {
2319  int itlim;
2320  int advind;
2321 
2322  /* perform one additional simplex iteration without objective limit */
2323  SCIPdebugMessage("dual solution %g does not exceed objective limit [%g,%g] (%d iterations) -> calling CPLEX dual simplex again for one iteration\n",
2324  objval, llim, ulim, lpi->iterations);
2325  itlim = getIntParam(lpi, CPX_PARAM_ITLIM);
2326  setIntParam(lpi, CPX_PARAM_ITLIM, 1);
2327  advind = getIntParam(lpi, CPX_PARAM_ADVIND);
2328  setIntParam(lpi, CPX_PARAM_ADVIND, CPX_ON);
2329  setDblParam(lpi, CPX_PARAM_OBJLLIM, -CPX_INFBOUND);
2330  setDblParam(lpi, CPX_PARAM_OBJULIM, CPX_INFBOUND);
2331  SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
2332  CHECK_ZERO( lpi->messagehdlr, CPXsetintparam(lpi->cpxenv, CPX_PARAM_FINALFACTOR, FALSE) );
2333 
2334  retval = CPXdualopt(lpi->cpxenv, lpi->cpxlp);
2335  switch( retval )
2336  {
2337  case 0:
2338  break;
2339  case CPXERR_NO_MEMORY:
2340  return SCIP_NOMEMORY;
2341  default:
2342  return SCIP_LPERROR;
2343  }
2344 
2345  lpi->iterations += CPXgetphase1cnt(lpi->cpxenv, lpi->cpxlp) + CPXgetitcnt(lpi->cpxenv, lpi->cpxlp);
2346 
2347  /* reset the iteration limit and objective bounds */
2348  setIntParam(lpi, CPX_PARAM_ITLIM, itlim);
2349  setIntParam(lpi, CPX_PARAM_ADVIND, advind);
2350  setDblParam(lpi, CPX_PARAM_OBJLLIM, llim);
2351  setDblParam(lpi, CPX_PARAM_OBJULIM, ulim);
2352  SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
2353  CHECK_ZERO( lpi->messagehdlr, CPXsetintparam(lpi->cpxenv, CPX_PARAM_FINALFACTOR, TRUE) );
2354 
2355  /* resolve LP again in order to restore the status of exceeded objective limit */
2356  retval = CPXdualopt(lpi->cpxenv, lpi->cpxlp);
2357  switch( retval )
2358  {
2359  case 0:
2360  break;
2361  case CPXERR_NO_MEMORY:
2362  return SCIP_NOMEMORY;
2363  default:
2364  return SCIP_LPERROR;
2365  }
2366 
2367  lpi->iterations += CPXgetphase1cnt(lpi->cpxenv, lpi->cpxlp) + CPXgetitcnt(lpi->cpxenv, lpi->cpxlp);
2368  lpi->solstat = CPXgetstat(lpi->cpxenv, lpi->cpxlp);
2369  lpi->instabilityignored = FALSE;
2370  SCIPdebugMessage(" -> CPLEX returned solstat=%d (%d iterations)\n", lpi->solstat, lpi->iterations);
2371  }
2372  }
2373 #endif
2374 
2375  return SCIP_OKAY;
2376 }
2377 
2378 /** calls barrier or interior point algorithm to solve the LP with crossover to simplex basis */
2380  SCIP_LPI* lpi, /**< LP interface structure */
2381  SCIP_Bool crossover /**< perform crossover */
2382  )
2383 {
2384  int solntype;
2385  int retval;
2386 
2387  assert(lpi != NULL);
2388  assert(lpi->cpxlp != NULL);
2389  assert(lpi->cpxenv != NULL);
2390 
2391  SCIPdebugMessage("calling CPLEX barrier: %d cols, %d rows\n",
2392  CPXgetnumcols(lpi->cpxenv, lpi->cpxlp), CPXgetnumrows(lpi->cpxenv, lpi->cpxlp));
2393 
2394  invalidateSolution(lpi);
2395 
2396  setIntParam(lpi, CPX_PARAM_ADVIND, lpi->fromscratch || lpi->clearstate ? CPX_OFF : CPX_ON);
2397  lpi->clearstate = FALSE;
2398 
2399  SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
2400 
2401  SCIPdebugMessage("calling CPXhybaropt()\n");
2402  retval = CPXhybbaropt(lpi->cpxenv, lpi->cpxlp, crossover ? 0 : CPX_ALG_NONE);
2403  lpi->iterations = CPXgetbaritcnt(lpi->cpxenv, lpi->cpxlp);
2404  switch( retval )
2405  {
2406  case 0:
2407  break;
2408  case CPXERR_NO_MEMORY:
2409  return SCIP_NOMEMORY;
2410  default:
2411  return SCIP_LPERROR;
2412  }
2413 
2414  CHECK_ZERO( lpi->messagehdlr, CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, &solntype, NULL, NULL) );
2415 
2416  lpi->solisbasic = (solntype == CPX_BASIC_SOLN);
2417  lpi->solstat = CPXgetstat(lpi->cpxenv, lpi->cpxlp);
2418  lpi->instabilityignored = FALSE;
2419  SCIPdebugMessage(" -> CPLEX returned solstat=%d (%d iterations)\n", lpi->solstat, lpi->iterations);
2420 
2421  if( lpi->solstat == CPX_STAT_INForUNBD )
2422  {
2423  /* maybe the preprocessor solved the problem; but we need a solution, so solve again without preprocessing */
2424  SCIPdebugMessage("CPLEX returned INForUNBD -> calling CPLEX barrier again without presolve\n");
2425 
2426  /* switch off preprocessing */
2427  setIntParam(lpi, CPX_PARAM_PREIND, CPX_OFF);
2428  SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
2429 
2430  retval = CPXhybbaropt(lpi->cpxenv, lpi->cpxlp, crossover ? 0 : CPX_ALG_NONE);
2431  switch( retval )
2432  {
2433  case 0:
2434  break;
2435  case CPXERR_NO_MEMORY:
2436  return SCIP_NOMEMORY;
2437  default:
2438  return SCIP_LPERROR;
2439  }
2440 
2441  CHECK_ZERO( lpi->messagehdlr, CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, &solntype, NULL, NULL) );
2442 
2443  lpi->solisbasic = (solntype == CPX_BASIC_SOLN);
2444  lpi->iterations += CPXgetbaritcnt(lpi->cpxenv, lpi->cpxlp);
2445  lpi->solstat = CPXgetstat(lpi->cpxenv, lpi->cpxlp);
2446  lpi->instabilityignored = FALSE;
2447  SCIPdebugMessage(" -> CPLEX returned solstat=%d\n", lpi->solstat);
2448 
2449  if( lpi->solstat == CPX_STAT_INForUNBD )
2450  {
2451  /* preprocessing was not the problem; issue a warning message and treat LP as infeasible */
2452  SCIPerrorMessage("CPLEX barrier returned CPX_STAT_INForUNBD after presolving was turned off\n");
2453  }
2454 
2455  setIntParam(lpi, CPX_PARAM_PREIND, CPX_ON);
2456  }
2457 
2458  return SCIP_OKAY;
2459 }
2460 
2461 /** manually performs strong branching on one integral variable */
2462 static
2463 SCIP_RETCODE lpiStrongbranchIntegral(
2464  SCIP_LPI* lpi, /**< LP interface structure */
2465  int col, /**< column to apply strong branching on */
2466  SCIP_Real psol, /**< current integral primal solution value of column */
2467  int itlim, /**< iteration limit for strong branchings */
2468  SCIP_Real* down, /**< stores dual bound after branching column down */
2469  SCIP_Real* up, /**< stores dual bound after branching column up */
2470  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
2471  * otherwise, it can only be used as an estimate value */
2472  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
2473  * otherwise, it can only be used as an estimate value */
2474  int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
2475  )
2476 {
2477  const char lbound = 'L';
2478  const char ubound = 'U';
2479  SCIP_Real oldlb;
2480  SCIP_Real oldub;
2481  SCIP_Real newlb;
2482  SCIP_Real newub;
2483  int objsen;
2484  int olditlim;
2485  int it;
2486 
2487  SCIPdebugMessage(" -> strong branching on integral variable %d\n", col);
2488 
2489  assert( EPSISINT(psol, lpi->feastol) );
2490 
2491  objsen = CPXgetobjsen(lpi->cpxenv, lpi->cpxlp);
2492 
2493  /* results of CPLEX are valid in any case */
2494  *downvalid = TRUE;
2495  *upvalid = TRUE;
2496 
2497  /* save current LP basis and bounds*/
2498  SCIP_CALL( getBase(lpi) );
2499  CHECK_ZERO( lpi->messagehdlr, CPXgetlb(lpi->cpxenv, lpi->cpxlp, &oldlb, col, col) );
2500  CHECK_ZERO( lpi->messagehdlr, CPXgetub(lpi->cpxenv, lpi->cpxlp, &oldub, col, col) );
2501 
2502  /* save old iteration limit and set iteration limit to strong branching limit */
2503  if( itlim > CPX_INT_MAX )
2504  itlim = CPX_INT_MAX;
2505  olditlim = getIntParam(lpi, CPX_PARAM_ITLIM);
2506  setIntParam(lpi, CPX_PARAM_ITLIM, itlim);
2507 
2508  /* down branch */
2509  newub = EPSCEIL(psol-1.0, lpi->feastol);
2510  if( newub >= oldlb - 0.5 )
2511  {
2512  CHECK_ZERO( lpi->messagehdlr, CPXchgbds(lpi->cpxenv, lpi->cpxlp, 1, &col, &ubound, &newub) );
2513  SCIP_CALL( SCIPlpiSolveDual(lpi) );
2515  *down = objsen == CPX_MIN ? getDblParam(lpi, CPX_PARAM_OBJULIM) : getDblParam(lpi, CPX_PARAM_OBJLLIM);
2516  else if( SCIPlpiIsOptimal(lpi) || SCIPlpiIsIterlimExc(lpi) )
2517  {
2518  SCIP_CALL( SCIPlpiGetObjval(lpi, down) );
2519  }
2520  else
2521  *down = objsen == CPX_MIN ? getDblParam(lpi, CPX_PARAM_OBJLLIM) : getDblParam(lpi, CPX_PARAM_OBJULIM);
2522  if( iter != NULL )
2523  {
2524  SCIP_CALL( SCIPlpiGetIterations(lpi, &it) );
2525  *iter += it;
2526  }
2527  SCIPdebugMessage(" -> down (x%d <= %g): %g\n", col, newub, *down);
2528 
2529  CHECK_ZERO( lpi->messagehdlr, CPXchgbds(lpi->cpxenv, lpi->cpxlp, 1, &col, &ubound, &oldub) );
2530  SCIP_CALL( setBase(lpi) );
2531  }
2532  else
2533  *down = objsen == CPX_MIN ? getDblParam(lpi, CPX_PARAM_OBJULIM) : getDblParam(lpi, CPX_PARAM_OBJLLIM);
2534 
2535  /* up branch */
2536  newlb = EPSFLOOR(psol+1.0, lpi->feastol);
2537  if( newlb <= oldub + 0.5 )
2538  {
2539  CHECK_ZERO( lpi->messagehdlr, CPXchgbds(lpi->cpxenv, lpi->cpxlp, 1, &col, &lbound, &newlb) );
2540  SCIP_CALL( SCIPlpiSolveDual(lpi) );
2542  *up = objsen == CPX_MIN ? getDblParam(lpi, CPX_PARAM_OBJULIM) : getDblParam(lpi, CPX_PARAM_OBJLLIM);
2543  else if( SCIPlpiIsOptimal(lpi) || SCIPlpiIsIterlimExc(lpi) )
2544  {
2545  SCIP_CALL( SCIPlpiGetObjval(lpi, up) );
2546  }
2547  else
2548  *up = objsen == CPX_MIN ? getDblParam(lpi, CPX_PARAM_OBJLLIM) : getDblParam(lpi, CPX_PARAM_OBJULIM);
2549  if( iter != NULL )
2550  {
2551  SCIP_CALL( SCIPlpiGetIterations(lpi, &it) );
2552  *iter += it;
2553  }
2554  SCIPdebugMessage(" -> up (x%d >= %g): %g\n", col, newlb, *up);
2555 
2556  CHECK_ZERO( lpi->messagehdlr, CPXchgbds(lpi->cpxenv, lpi->cpxlp, 1, &col, &lbound, &oldlb) );
2557  SCIP_CALL( setBase(lpi) );
2558  }
2559  else
2560  *up = objsen == CPX_MIN ? getDblParam(lpi, CPX_PARAM_OBJLLIM) : getDblParam(lpi, CPX_PARAM_OBJULIM);
2561 
2562  /* reset iteration limit */
2563  setIntParam(lpi, CPX_PARAM_ITLIM, olditlim);
2564 
2565  return SCIP_OKAY;
2566 }
2567 
2568 /** start strong branching */
2570  SCIP_LPI* lpi /**< LP interface structure */
2571  )
2572 { /*lint --e{715}*/
2573  /* no work necessary */
2574  return SCIP_OKAY;
2575 }
2576 
2577 /** end strong branching */
2579  SCIP_LPI* lpi /**< LP interface structure */
2580  )
2581 { /*lint --e{715}*/
2582  /* no work necessary */
2583  return SCIP_OKAY;
2584 }
2585 
2586 /** performs strong branching iterations on one @b fractional candidate */
2588  SCIP_LPI* lpi, /**< LP interface structure */
2589  int col, /**< column to apply strong branching on */
2590  SCIP_Real psol, /**< fractional current primal solution value of column */
2591  int itlim, /**< iteration limit for strong branchings */
2592  SCIP_Real* down, /**< stores dual bound after branching column down */
2593  SCIP_Real* up, /**< stores dual bound after branching column up */
2594  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
2595  * otherwise, it can only be used as an estimate value */
2596  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
2597  * otherwise, it can only be used as an estimate value */
2598  int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
2599  )
2600 {
2601  int retval;
2602 
2603  assert(lpi != NULL);
2604  assert(lpi->cpxlp != NULL);
2605  assert(lpi->cpxenv != NULL);
2606  assert(down != NULL);
2607  assert(up != NULL);
2608  assert(downvalid != NULL);
2609  assert(upvalid != NULL);
2610 
2611  SCIPdebugMessage("calling CPLEX strongbranching on fractional variable %d (%d iterations)\n", col, itlim);
2612 
2613  assert( !EPSISINT(psol, lpi->feastol) );
2614 
2615  /* results of CPLEX are valid in any case */
2616  *downvalid = TRUE;
2617  *upvalid = TRUE;
2618 
2619  setIntParam(lpi, CPX_PARAM_ADVIND, lpi->fromscratch || lpi->clearstate ? CPX_OFF : CPX_ON);
2620  lpi->clearstate = FALSE;
2621 
2622  SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
2623 
2624  retval = CPXstrongbranch(lpi->cpxenv, lpi->cpxlp, &col, 1, down, up, itlim);
2625  if( retval == CPXERR_NEED_OPT_SOLN )
2626  {
2627  SCIPdebugMessage(" -> no optimal solution available\n");
2628  return SCIP_LPERROR;
2629  }
2630  else if( retval == CPXERR_TILIM_STRONGBRANCH )
2631  {
2632  SCIPdebugMessage(" -> time limit exceeded during strong branching\n");
2633  return SCIP_LPERROR;
2634  }
2635  else if( retval == CPXERR_SINGULAR )
2636  {
2637  SCIPdebugMessage(" -> numerical troubles (basis singular)\n");
2638  return SCIP_LPERROR;
2639  }
2640  CHECK_ZERO( lpi->messagehdlr, retval );
2641  SCIPdebugMessage(" -> down: %g, up:%g\n", *down, *up);
2642 
2643  /* CPLEX is not able to return the iteration counts in strong branching */
2644  if( iter != NULL )
2645  *iter = -1;
2646 
2647  return SCIP_OKAY;
2648 }
2649 
2650 /** performs strong branching iterations on given @b fractional candidates */
2652  SCIP_LPI* lpi, /**< LP interface structure */
2653  int* cols, /**< columns to apply strong branching on */
2654  int ncols, /**< number of columns */
2655  SCIP_Real* psols, /**< fractional current primal solution values of columns */
2656  int itlim, /**< iteration limit for strong branchings */
2657  SCIP_Real* down, /**< stores dual bounds after branching columns down */
2658  SCIP_Real* up, /**< stores dual bounds after branching columns up */
2659  SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds;
2660  * otherwise, they can only be used as an estimate values */
2661  SCIP_Bool* upvalid, /**< stores whether the returned up values are a valid dual bounds;
2662  * otherwise, they can only be used as an estimate values */
2663  int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
2664  )
2665 {
2666  int retval;
2667  int j;
2668 
2669  assert(lpi != NULL);
2670  assert(lpi->cpxlp != NULL);
2671  assert(lpi->cpxenv != NULL);
2672  assert(cols != NULL);
2673  assert(psols != NULL);
2674  assert(down != NULL);
2675  assert(up != NULL);
2676  assert(downvalid != NULL);
2677  assert(upvalid != NULL);
2678 
2679  SCIPdebugMessage("calling CPLEX strongbranching on %d fractional variables (%d iterations)\n", ncols, itlim);
2680 
2681  setIntParam(lpi, CPX_PARAM_ADVIND, lpi->fromscratch || lpi->clearstate ? CPX_OFF : CPX_ON);
2682  lpi->clearstate = FALSE;
2683 
2684  SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
2685 
2686  /* initialize */
2687  for( j = 0; j < ncols; ++j )
2688  {
2689  /* results of CPLEX are valid in any case */
2690  *downvalid = TRUE;
2691  *upvalid = TRUE;
2692 
2693  assert( !EPSISINT(psols[j], lpi->feastol) );
2694  }
2695 
2696  retval = CPXstrongbranch(lpi->cpxenv, lpi->cpxlp, cols, ncols, down, up, itlim);
2697  if( retval == CPXERR_NEED_OPT_SOLN )
2698  {
2699  SCIPdebugMessage(" -> no optimal solution available\n");
2700  return SCIP_LPERROR;
2701  }
2702  else if( retval == CPXERR_TILIM_STRONGBRANCH )
2703  {
2704  SCIPdebugMessage(" -> time limit exceeded during strong branching\n");
2705  return SCIP_LPERROR;
2706  }
2707  CHECK_ZERO( lpi->messagehdlr, retval );
2708 
2709  /* CPLEX is not able to return the iteration counts in strong branching */
2710  if( iter != NULL )
2711  *iter = -1;
2712 
2713  return SCIP_OKAY;
2714 }
2715 
2716 /** performs strong branching iterations on one candidate with @b integral value */
2718  SCIP_LPI* lpi, /**< LP interface structure */
2719  int col, /**< column to apply strong branching on */
2720  SCIP_Real psol, /**< current integral primal solution value of column */
2721  int itlim, /**< iteration limit for strong branchings */
2722  SCIP_Real* down, /**< stores dual bound after branching column down */
2723  SCIP_Real* up, /**< stores dual bound after branching column up */
2724  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
2725  * otherwise, it can only be used as an estimate value */
2726  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
2727  * otherwise, it can only be used as an estimate value */
2728  int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
2729  )
2730 {
2731  assert(lpi != NULL);
2732  assert(lpi->cpxlp != NULL);
2733  assert(down != NULL);
2734  assert(up != NULL);
2735  assert(downvalid != NULL);
2736  assert(upvalid != NULL);
2737 
2738  SCIPdebugMessage("calling CPLEX strongbranching on variable %d with integral value (%d iterations)\n", col, itlim);
2739 
2740  assert( EPSISINT(psol, lpi->feastol) );
2741 
2742  if( iter != NULL )
2743  *iter = 0;
2744 
2745  SCIP_CALL( lpiStrongbranchIntegral(lpi, col, psol, itlim, down, up, downvalid, upvalid, iter) );
2746 
2747  return SCIP_OKAY;
2748 }
2749 
2750 /** performs strong branching iterations on given candidates with @b integral values */
2752  SCIP_LPI* lpi, /**< LP interface structure */
2753  int* cols, /**< columns to apply strong branching on */
2754  int ncols, /**< number of columns */
2755  SCIP_Real* psols, /**< current integral primal solution values of columns */
2756  int itlim, /**< iteration limit for strong branchings */
2757  SCIP_Real* down, /**< stores dual bounds after branching columns down */
2758  SCIP_Real* up, /**< stores dual bounds after branching columns up */
2759  SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds;
2760  * otherwise, they can only be used as an estimate values */
2761  SCIP_Bool* upvalid, /**< stores whether the returned up values are a valid dual bounds;
2762  * otherwise, they can only be used as an estimate values */
2763  int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
2764  )
2765 {
2766  int j;
2767 
2768  assert(lpi != NULL);
2769  assert(lpi->cpxlp != NULL);
2770  assert(cols != NULL);
2771  assert(psols != NULL);
2772  assert(down != NULL);
2773  assert(up != NULL);
2774  assert(downvalid != NULL);
2775  assert(upvalid != NULL);
2776 
2777  SCIPdebugMessage("calling CPLEX strongbranching on %d variables with integer values (%d iterations)\n", ncols, itlim);
2778 
2779  if( iter != NULL )
2780  *iter = 0;
2781 
2782  /* initialize */
2783  for( j = 0; j < ncols; ++j )
2784  {
2785  assert( EPSISINT(psols[j], lpi->feastol) );
2786  SCIP_CALL( lpiStrongbranchIntegral(lpi, cols[j], psols[j], itlim, &(down[j]), &(up[j]), &(downvalid[j]), &(upvalid[j]), iter) );
2787  }
2788 
2789  return SCIP_OKAY;
2790 }
2791 /**@} */
2792 
2793 
2794 
2795 
2796 /*
2797  * Solution Information Methods
2798  */
2799 
2800 /**@name Solution Information Methods */
2801 /**@{ */
2802 
2803 /** returns whether a solve method was called after the last modification of the LP */
2805  SCIP_LPI* lpi /**< LP interface structure */
2806  )
2807 {
2808  assert(lpi != NULL);
2809 
2810  return (lpi->solstat != -1);
2811 }
2812 
2813 /** gets information about primal and dual feasibility of the current LP solution */
2815  SCIP_LPI* lpi, /**< LP interface structure */
2816  SCIP_Bool* primalfeasible, /**< stores primal feasibility status */
2817  SCIP_Bool* dualfeasible /**< stores dual feasibility status */
2818  )
2819 {
2820  int pfeas;
2821  int dfeas;
2822 
2823  assert(lpi != NULL);
2824  assert(lpi->cpxlp != NULL);
2825  assert(lpi->cpxenv != NULL);
2826  assert(primalfeasible != NULL);
2827  assert(dualfeasible != NULL);
2828 
2829  SCIPdebugMessage("getting solution feasibility\n");
2830 
2831  CHECK_ZERO( lpi->messagehdlr, CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, NULL, &pfeas, &dfeas) );
2832  *primalfeasible = (SCIP_Bool)pfeas;
2833  *dualfeasible = (SCIP_Bool)dfeas;
2834 
2835  return SCIP_OKAY;
2836 }
2837 
2838 /** returns TRUE iff LP is proven to have a primal unbounded ray (but not necessary a primal feasible point);
2839  * this does not necessarily mean, that the solver knows and can return the primal ray
2840  */
2842  SCIP_LPI* lpi /**< LP interface structure */
2843  )
2844 {
2845  assert(lpi != NULL);
2846  assert(lpi->cpxlp != NULL);
2847  assert(lpi->solstat >= 0);
2848 
2849  return (lpi->solstat == CPX_STAT_UNBOUNDED || lpi->solstat == CPX_STAT_OPTIMAL_FACE_UNBOUNDED);
2850 }
2851 
2852 /** returns TRUE iff LP is proven to have a primal unbounded ray (but not necessary a primal feasible point),
2853  * and the solver knows and can return the primal ray
2854  */
2856  SCIP_LPI* lpi /**< LP interface structure */
2857  )
2858 {
2859  assert(lpi != NULL);
2860  assert(lpi->cpxlp != NULL);
2861  assert(lpi->cpxenv != NULL);
2862  assert(lpi->solstat >= 0);
2863 
2864  return (lpi->solstat == CPX_STAT_UNBOUNDED && CPXgetmethod(lpi->cpxenv, lpi->cpxlp) == CPX_ALG_PRIMAL);
2865 }
2866 
2867 /** returns TRUE iff LP is proven to be primal unbounded */
2869  SCIP_LPI* lpi /**< LP interface structure */
2870  )
2871 {
2872  int primalfeasible;
2873 
2874  assert(lpi != NULL);
2875  assert(lpi->cpxlp != NULL);
2876  assert(lpi->cpxenv != NULL);
2877  assert(lpi->solstat >= 0);
2878 
2879  SCIPdebugMessage("checking for primal unboundedness\n");
2880 
2881  ABORT_ZERO( CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, NULL, &primalfeasible, NULL) );
2882 
2883  /* If the solution status of CPLEX is CPX_STAT_UNBOUNDED, it only means, there is an unbounded ray,
2884  * but not necessarily a feasible primal solution. If primalfeasible == FALSE, we cannot conclude,
2885  * that the problem is unbounded
2886  */
2887  return ((primalfeasible && (lpi->solstat == CPX_STAT_UNBOUNDED || lpi->solstat == CPX_STAT_INForUNBD))
2888  || lpi->solstat == CPX_STAT_OPTIMAL_FACE_UNBOUNDED);
2889 }
2890 
2891 /** returns TRUE iff LP is proven to be primal infeasible */
2893  SCIP_LPI* lpi /**< LP interface structure */
2894  )
2895 {
2896  int dualfeasible;
2897 
2898  assert(lpi != NULL);
2899  assert(lpi->cpxlp != NULL);
2900  assert(lpi->cpxenv != NULL);
2901  assert(lpi->solstat >= 0);
2902 
2903  SCIPdebugMessage("checking for primal infeasibility\n");
2904 
2905  ABORT_ZERO( CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, NULL, NULL, &dualfeasible) );
2906 
2907  return (lpi->solstat == CPX_STAT_INFEASIBLE || (lpi->solstat == CPX_STAT_INForUNBD && dualfeasible));
2908 }
2909 
2910 /** returns TRUE iff LP is proven to be primal feasible */
2912  SCIP_LPI* lpi /**< LP interface structure */
2913  )
2914 {
2915  int primalfeasible;
2916 
2917  assert(lpi != NULL);
2918  assert(lpi->cpxlp != NULL);
2919  assert(lpi->cpxenv != NULL);
2920  assert(lpi->solstat >= 0);
2921 
2922  SCIPdebugMessage("checking for primal feasibility\n");
2923 
2924  ABORT_ZERO( CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, NULL, &primalfeasible, NULL) );
2925 
2926  return (SCIP_Bool)primalfeasible;
2927 }
2928 
2929 /** returns TRUE iff LP is proven to have a dual unbounded ray (but not necessary a dual feasible point);
2930  * this does not necessarily mean, that the solver knows and can return the dual ray
2931  */
2933  SCIP_LPI* lpi /**< LP interface structure */
2934  )
2935 {
2936  assert(lpi != NULL);
2937  assert(lpi->solstat >= 0);
2938 
2939  return (lpi->solstat == CPX_STAT_INFEASIBLE);
2940 }
2941 
2942 /** returns TRUE iff LP is proven to have a dual unbounded ray (but not necessary a dual feasible point),
2943  * and the solver knows and can return the dual ray
2944  */
2946  SCIP_LPI* lpi /**< LP interface structure */
2947  )
2948 {
2949  assert(lpi != NULL);
2950  assert(lpi->cpxlp != NULL);
2951  assert(lpi->cpxenv != NULL);
2952  assert(lpi->solstat >= 0);
2953 
2954  return (lpi->solstat == CPX_STAT_INFEASIBLE && CPXgetmethod(lpi->cpxenv, lpi->cpxlp) == CPX_ALG_DUAL);
2955 }
2956 
2957 /** returns TRUE iff LP is proven to be dual unbounded */
2959  SCIP_LPI* lpi /**< LP interface structure */
2960  )
2961 {
2962  int dualfeasible;
2963 
2964  assert(lpi != NULL);
2965  assert(lpi->cpxlp != NULL);
2966  assert(lpi->cpxenv != NULL);
2967  assert(lpi->solstat >= 0);
2968 
2969  SCIPdebugMessage("checking for dual unboundedness\n");
2970 
2971  ABORT_ZERO( CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, NULL, NULL, &dualfeasible) );
2972 
2973  return (dualfeasible && (lpi->solstat == CPX_STAT_INFEASIBLE || lpi->solstat == CPX_STAT_INForUNBD));
2974 }
2975 
2976 /** returns TRUE iff LP is proven to be dual infeasible */
2978  SCIP_LPI* lpi /**< LP interface structure */
2979  )
2980 {
2981  int primalfeasible;
2982 
2983  assert(lpi != NULL);
2984  assert(lpi->cpxlp != NULL);
2985  assert(lpi->cpxenv != NULL);
2986  assert(lpi->solstat >= 0);
2987 
2988  SCIPdebugMessage("checking for dual infeasibility\n");
2989 
2990  ABORT_ZERO( CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, NULL, &primalfeasible, NULL) );
2991 
2992  return (lpi->solstat == CPX_STAT_UNBOUNDED
2993  || lpi->solstat == CPX_STAT_OPTIMAL_FACE_UNBOUNDED
2994  || (lpi->solstat == CPX_STAT_INForUNBD && primalfeasible));
2995 }
2996 
2997 /** returns TRUE iff LP is proven to be dual feasible */
2999  SCIP_LPI* lpi /**< LP interface structure */
3000  )
3001 {
3002  int dualfeasible;
3003 
3004  assert(lpi != NULL);
3005  assert(lpi->cpxlp != NULL);
3006  assert(lpi->cpxenv != NULL);
3007  assert(lpi->solstat >= 0);
3008 
3009  SCIPdebugMessage("checking for dual feasibility\n");
3010 
3011  ABORT_ZERO( CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, NULL, NULL, &dualfeasible) );
3012 
3013  return (SCIP_Bool)dualfeasible;
3014 }
3015 
3016 /** returns TRUE iff LP was solved to optimality */
3018  SCIP_LPI* lpi /**< LP interface structure */
3019  )
3020 {
3021  assert(lpi != NULL);
3022  assert(lpi->solstat >= 0);
3023 
3024  return (lpi->solstat == CPX_STAT_OPTIMAL);
3025 }
3026 
3027 /** returns TRUE iff current LP basis is stable */
3029  SCIP_LPI* lpi /**< LP interface structure */
3030  )
3031 {
3032  assert(lpi != NULL);
3033  assert(lpi->cpxlp != NULL);
3034  assert(lpi->cpxenv != NULL);
3035  assert(lpi->solstat >= 0);
3036 
3037  SCIPdebugMessage("checking for stability: CPLEX solstat = %d\n", lpi->solstat);
3038 
3039  /* If the solution status of CPLEX is CPX_STAT_UNBOUNDED, it only means, there is an unbounded ray,
3040  * but not necessarily a feasible primal solution. If primalfeasible == FALSE, we interpret this
3041  * result as instability, s.t. the problem is resolved from scratch
3042  */
3043  if( lpi->solstat == CPX_STAT_UNBOUNDED )
3044  {
3045  int primalfeasible;
3046 
3047  ABORT_ZERO( CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, NULL, &primalfeasible, NULL) );
3048 
3049  if( !primalfeasible )
3050  return FALSE;
3051  }
3052 
3053  /* If the condition number of the basis should be checked, everything above the specified threshold is counted
3054  * as instable.
3055  */
3056  if( lpi->checkcondition && (SCIPlpiIsOptimal(lpi) || SCIPlpiIsObjlimExc(lpi)) )
3057  {
3058  SCIP_Real kappa;
3059  SCIP_RETCODE retcode;
3060 
3062  if ( retcode != SCIP_OKAY )
3063  {
3064  SCIPABORT();
3065  return FALSE; /*lint !e527*/
3066  }
3067 
3068  /* if the kappa could not be computed (e.g., because we do not have a basis), we cannot check the condition */
3069  if( kappa != SCIP_INVALID || kappa > lpi->conditionlimit ) /*lint !e777*/
3070  return FALSE;
3071  }
3072 
3073  return (lpi->solstat != CPX_STAT_NUM_BEST && lpi->solstat != CPX_STAT_OPTIMAL_INFEAS);
3074 }
3075 
3076 /** returns TRUE iff the objective limit was reached */
3078  SCIP_LPI* lpi /**< LP interface structure */
3079  )
3080 {
3081  assert(lpi != NULL);
3082  assert(lpi->solstat >= 0);
3083 
3084  return (lpi->solstat == CPX_STAT_ABORT_OBJ_LIM
3085  || lpi->solstat == CPX_STAT_ABORT_DUAL_OBJ_LIM
3086  || lpi->solstat == CPX_STAT_ABORT_PRIM_OBJ_LIM);
3087 }
3088 
3089 /** returns TRUE iff the iteration limit was reached */
3091  SCIP_LPI* lpi /**< LP interface structure */
3092  )
3093 {
3094  assert(lpi != NULL);
3095  assert(lpi->solstat >= 0);
3096 
3097  return (lpi->solstat == CPX_STAT_ABORT_IT_LIM);
3098 }
3099 
3100 /** returns TRUE iff the time limit was reached */
3102  SCIP_LPI* lpi /**< LP interface structure */
3103  )
3104 {
3105  assert(lpi != NULL);
3106  assert(lpi->solstat >= 0);
3107 
3108  return (lpi->solstat == CPX_STAT_ABORT_TIME_LIM);
3109 }
3110 
3111 /** returns the internal solution status of the solver */
3113  SCIP_LPI* lpi /**< LP interface structure */
3114  )
3115 {
3116  assert(lpi != NULL);
3117  assert(lpi->cpxlp != NULL);
3118 
3119  return lpi->solstat;
3120 }
3121 
3122 /** tries to reset the internal status of the LP solver in order to ignore an instability of the last solving call */
3124  SCIP_LPI* lpi, /**< LP interface structure */
3125  SCIP_Bool* success /**< pointer to store, whether the instability could be ignored */
3126  )
3127 {
3128  assert(lpi != NULL);
3129  assert(lpi->cpxlp != NULL);
3130  assert(success != NULL);
3131  assert(lpi->solstat == CPX_STAT_UNBOUNDED
3132  || lpi->solstat == CPX_STAT_NUM_BEST
3133  || lpi->solstat == CPX_STAT_OPTIMAL_INFEAS);
3134 
3135  /* replace instable status with optimal status */
3136  if( lpi->solstat == CPX_STAT_NUM_BEST || lpi->solstat == CPX_STAT_OPTIMAL_INFEAS )
3137  lpi->solstat = CPX_STAT_OPTIMAL;
3138 
3139  *success = TRUE;
3140  lpi->instabilityignored = TRUE;
3141 
3142  return SCIP_OKAY;
3143 }
3144 
3145 /** gets objective value of solution */
3147  SCIP_LPI* lpi, /**< LP interface structure */
3148  SCIP_Real* objval /**< stores the objective value */
3149  )
3150 {
3151  int retcode;
3152 
3153  assert(lpi != NULL);
3154  assert(lpi->cpxlp != NULL);
3155  assert(lpi->cpxenv != NULL);
3156 
3157  SCIPdebugMessage("getting solution's objective value\n");
3158 
3159  retcode = CPXgetobjval(lpi->cpxenv, lpi->cpxlp, objval);
3160 
3161  /* if CPLEX has no solution, e.g., because of a reached time limit, we return -infinity */
3162  if( retcode == CPXERR_NO_SOLN )
3163  {
3164  *objval = -SCIPlpiInfinity(lpi);
3165  }
3166  else
3167  {
3168  CHECK_ZERO( lpi->messagehdlr, retcode );
3169  }
3170 
3171  return SCIP_OKAY;
3172 }
3173 
3174 /** gets primal and dual solution vectors */
3176  SCIP_LPI* lpi, /**< LP interface structure */
3177  SCIP_Real* objval, /**< stores the objective value, may be NULL if not needed */
3178  SCIP_Real* primsol, /**< primal solution vector, may be NULL if not needed */
3179  SCIP_Real* dualsol, /**< dual solution vector, may be NULL if not needed */
3180  SCIP_Real* activity, /**< row activity vector, may be NULL if not needed */
3181  SCIP_Real* redcost /**< reduced cost vector, may be NULL if not needed */
3182  )
3183 {
3184  int dummy;
3185 
3186  assert(lpi != NULL);
3187  assert(lpi->cpxlp != NULL);
3188  assert(lpi->cpxenv != NULL);
3189  assert(lpi->solstat >= 0);
3190 
3191  SCIPdebugMessage("getting solution\n");
3192 
3193  CHECK_ZERO( lpi->messagehdlr, CPXsolution(lpi->cpxenv, lpi->cpxlp, &dummy, objval, primsol, dualsol, NULL, redcost) );
3194  assert(dummy == lpi->solstat || lpi->instabilityignored);
3195 
3196  if( activity != NULL )
3197  {
3198  CHECK_ZERO( lpi->messagehdlr, CPXgetax(lpi->cpxenv, lpi->cpxlp, activity, 0, CPXgetnumrows(lpi->cpxenv, lpi->cpxlp)-1) );
3199  }
3200 
3201  return SCIP_OKAY;
3202 }
3203 
3204 /** gets primal ray for unbounded LPs */
3206  SCIP_LPI* lpi, /**< LP interface structure */
3207  SCIP_Real* ray /**< primal ray */
3208  )
3209 {
3210  assert(lpi != NULL);
3211  assert(lpi->cpxlp != NULL);
3212  assert(lpi->cpxenv != NULL);
3213  assert(lpi->solstat >= 0);
3214 
3215  SCIPdebugMessage("calling CPLEX get primal ray: %d cols, %d rows\n",
3216  CPXgetnumcols(lpi->cpxenv, lpi->cpxlp), CPXgetnumrows(lpi->cpxenv, lpi->cpxlp));
3217 
3218  CHECK_ZERO( lpi->messagehdlr, CPXgetray(lpi->cpxenv, lpi->cpxlp, ray) );
3219 
3220  return SCIP_OKAY;
3221 }
3222 
3223 /** gets dual Farkas proof for infeasibility */
3225  SCIP_LPI* lpi, /**< LP interface structure */
3226  SCIP_Real* dualfarkas /**< dual Farkas row multipliers */
3227  )
3228 {
3229  assert(lpi != NULL);
3230  assert(lpi->cpxlp != NULL);
3231  assert(lpi->cpxenv != NULL);
3232  assert(lpi->solstat >= 0);
3233  assert(dualfarkas != NULL);
3234 
3235  SCIPdebugMessage("calling CPLEX dual Farkas: %d cols, %d rows\n",
3236  CPXgetnumcols(lpi->cpxenv, lpi->cpxlp), CPXgetnumrows(lpi->cpxenv, lpi->cpxlp));
3237 
3238  CHECK_ZERO( lpi->messagehdlr, CPXdualfarkas(lpi->cpxenv, lpi->cpxlp, dualfarkas, NULL) );
3239 
3240  return SCIP_OKAY;
3241 }
3242 
3243 /** gets the number of LP iterations of the last solve call */
3245  SCIP_LPI* lpi, /**< LP interface structure */
3246  int* iterations /**< pointer to store the number of iterations of the last solve call */
3247  )
3248 {
3249  assert(lpi != NULL);
3250  assert(iterations != NULL);
3251 
3252  *iterations = lpi->iterations;
3253 
3254  return SCIP_OKAY;
3255 }
3256 
3257 /** gets information about the quality of an LP solution
3258  *
3259  * Such information is usually only available, if also a (maybe not optimal) solution is available.
3260  * The LPI should return SCIP_INVALID for @p quality, if the requested quantity is not available.
3261  */
3263  SCIP_LPI* lpi, /**< LP interface structure */
3264  SCIP_LPSOLQUALITY qualityindicator, /**< indicates which quality should be returned */
3265  SCIP_Real* quality /**< pointer to store quality number */
3266  )
3267 {
3268  int solntype;
3269  int what;
3270 
3271  assert(lpi != NULL);
3272  assert(quality != NULL);
3273 
3274  *quality = SCIP_INVALID;
3275 
3276  SCIPdebugMessage("requesting solution quality from CPLEX: quality %d\n", qualityindicator);
3277 
3278  switch( qualityindicator )
3279  {
3281  what = CPX_KAPPA;
3282  break;
3283 
3285  what = CPX_EXACT_KAPPA;
3286  break;
3287 
3288  default:
3289  SCIPerrorMessage("Solution quality %d unknown.\n", qualityindicator);
3290  return SCIP_INVALIDDATA;
3291  }
3292 
3293  CHECK_ZERO( lpi->messagehdlr, CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, &solntype, NULL, NULL) );
3294 
3295  if( solntype == CPX_BASIC_SOLN )
3296  {
3297  CHECK_ZERO( lpi->messagehdlr, CPXgetdblquality(lpi->cpxenv, lpi->cpxlp, quality, what) );
3298  }
3299 
3300  return SCIP_OKAY;
3301 }
3302 
3303 /**@} */
3304 
3305 
3306 
3307 
3308 /*
3309  * LP Basis Methods
3310  */
3311 
3312 /**@name LP Basis Methods */
3313 /**@{ */
3314 
3315 /** gets current basis status for columns and rows; arrays must be large enough to store the basis status */
3317  SCIP_LPI* lpi, /**< LP interface structure */
3318  int* cstat, /**< array to store column basis status, or NULL */
3319  int* rstat /**< array to store row basis status, or NULL */
3320  )
3321 {
3322  int i;
3323  int nrows;
3324  char sense;
3325 
3326  assert(lpi != NULL);
3327  assert(lpi->cpxlp != NULL);
3328  assert(lpi->cpxenv != NULL);
3329 
3330  SCIPdebugMessage("saving CPLEX basis into %p/%p\n", (void *) cstat, (void *) rstat);
3331 
3332  CHECK_ZERO( lpi->messagehdlr, CPXgetbase(lpi->cpxenv, lpi->cpxlp, cstat, rstat) );
3333 
3334  /* correct rstat values for "<=" constraints: Here CPX_AT_LOWER bound means that the slack is 0, i.e., the upper bound is tight */
3335  nrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
3336  for (i = 0; i < nrows; ++i)
3337  {
3338  if ( rstat[i] == CPX_AT_LOWER )
3339  {
3340  CHECK_ZERO( lpi->messagehdlr, CPXgetsense(lpi->cpxenv, lpi->cpxlp, &sense, i, i) );
3341  if ( sense == 'L' )
3342  rstat[i] = (int) SCIP_BASESTAT_UPPER;
3343  }
3344  }
3345 
3346  /* because the basis status values are equally defined in SCIP and CPLEX, they don't need to be transformed */
3347  assert((int)SCIP_BASESTAT_LOWER == CPX_AT_LOWER);
3348  assert((int)SCIP_BASESTAT_BASIC == CPX_BASIC);
3349  assert((int)SCIP_BASESTAT_UPPER == CPX_AT_UPPER);
3350  assert((int)SCIP_BASESTAT_ZERO == CPX_FREE_SUPER);
3351 
3352  return SCIP_OKAY;
3353 }
3354 
3355 /** sets current basis status for columns and rows */
3357  SCIP_LPI* lpi, /**< LP interface structure */
3358  int* cstat, /**< array with column basis status */
3359  int* rstat /**< array with row basis status */
3360  )
3361 {
3362  int i;
3363  int nrows;
3364  char sense;
3365 
3366  assert(lpi != NULL);
3367  assert(lpi->cpxlp != NULL);
3368  assert(lpi->cpxenv != NULL);
3369  assert(cstat != NULL);
3370  assert(rstat != NULL);
3371 
3372  SCIPdebugMessage("loading basis %p/%p into CPLEX\n", (void *) cstat, (void *) rstat);
3373 
3374  invalidateSolution(lpi);
3375 
3376  /* because the basis status values are equally defined in SCIP and CPLEX, they don't need to be transformed */
3377  assert((int)SCIP_BASESTAT_LOWER == CPX_AT_LOWER);
3378  assert((int)SCIP_BASESTAT_BASIC == CPX_BASIC);
3379  assert((int)SCIP_BASESTAT_UPPER == CPX_AT_UPPER);
3380  assert((int)SCIP_BASESTAT_ZERO == CPX_FREE_SUPER);
3381 
3382  /* correct rstat values for ">=" constraints: Here CPX_AT_LOWER bound means that the slack is 0, i.e., the upper bound is tight */
3383  nrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
3384  for (i = 0; i < nrows; ++i)
3385  {
3386  if ( rstat[i] == (int) SCIP_BASESTAT_UPPER )
3387  {
3388  CHECK_ZERO( lpi->messagehdlr, CPXgetsense(lpi->cpxenv, lpi->cpxlp, &sense, i, i) );
3389  if ( sense == 'L' )
3390  rstat[i] = CPX_AT_LOWER;
3391  }
3392  }
3393 
3394  CHECK_ZERO( lpi->messagehdlr, CPXcopybase(lpi->cpxenv, lpi->cpxlp, cstat, rstat) );
3395 
3396  return SCIP_OKAY;
3397 }
3398 
3399 /** returns the indices of the basic columns and rows; basic column n gives value n, basic row m gives value -1-m */
3401  SCIP_LPI* lpi, /**< LP interface structure */
3402  int* bind /**< pointer to store basis indices ready to keep number of rows entries */
3403  )
3404 {
3405  int retval;
3406 
3407  assert(lpi != NULL);
3408  assert(lpi->cpxlp != NULL);
3409  assert(lpi->cpxenv != NULL);
3410 
3411  SCIPdebugMessage("getting basis information\n");
3412 
3413  /* this might be turned off if the user as called SCIPlpiClearState() or set SCIP_LPPAR_FROMSCRATCH to TRUE */
3414  setIntParam(lpi, CPX_PARAM_ADVIND, CPX_ON);
3415  SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
3416 
3417  retval = CPXgetbhead(lpi->cpxenv, lpi->cpxlp, bind, NULL);
3418  if( retval == CPXERR_NO_SOLN || retval == CPXERR_NO_LU_FACTOR || retval == CPXERR_NO_BASIC_SOLN || retval == CPXERR_NO_BASIS )
3419  {
3420  SCIP_CALL_QUIET( restoreLPData(lpi) );
3421  retval = CPXgetbhead(lpi->cpxenv, lpi->cpxlp, bind, NULL);
3422  }
3423  CHECK_ZERO( lpi->messagehdlr, retval );
3424 
3425  return SCIP_OKAY;
3426 }
3427 
3428 /** get dense row of inverse basis matrix B^-1
3429  *
3430  * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
3431  * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
3432  * see also the explanation in lpi.h.
3433  */
3435  SCIP_LPI* lpi, /**< LP interface structure */
3436  int r, /**< row number */
3437  SCIP_Real* coef, /**< pointer to store the coefficients of the row */
3438  int* inds, /**< array to store the non-zero indices */
3439  int* ninds /**< pointer to store the number of non-zero indices
3440  * (-1: if we do not store sparsity informations) */
3441  )
3442 { /*lint --e{715}*/
3443  int retval;
3444  int nrows;
3445 
3446  assert(lpi != NULL);
3447  assert(lpi->cpxlp != NULL);
3448  assert(lpi->cpxenv != NULL);
3449 
3450  SCIPdebugMessage("getting binv-row %d\n", r);
3451 
3452  /* can only return dense result */
3453  if ( ninds != NULL )
3454  *ninds = -1;
3455 
3456  /* this might be turned off if the user as called SCIPlpiClearState() or set SCIP_LPPAR_FROMSCRATCH to TRUE */
3457  setIntParam(lpi, CPX_PARAM_ADVIND, CPX_ON);
3458  SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
3459 
3460  retval = CPXbinvrow(lpi->cpxenv, lpi->cpxlp, r, coef);
3461  if( retval == CPXERR_NO_SOLN || retval == CPXERR_NO_LU_FACTOR || retval == CPXERR_NO_BASIC_SOLN || retval == CPXERR_NO_BASIS )
3462  {
3463  SCIP_CALL_QUIET( restoreLPData(lpi) );
3464  retval = CPXbinvrow(lpi->cpxenv, lpi->cpxlp, r, coef);
3465  }
3466  CHECK_ZERO( lpi->messagehdlr, retval );
3467 
3468  /* the LPi expects slack variables with coefficient +1; CPLEX adds slack variables with a coefficient -1 for 'G'
3469  * constraints, so we have to change the sign of the corresponding rows
3470  */
3471  nrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
3472  SCIP_CALL( ensureValMem(lpi, nrows) );
3473  CHECK_ZERO( lpi->messagehdlr, CPXgetbhead(lpi->cpxenv, lpi->cpxlp, lpi->indarray, NULL) );
3474 
3475  if( lpi->indarray[r] < 0 )
3476  {
3477  int basicrow;
3478  char rowsense;
3479 
3480  basicrow = -lpi->indarray[r] - 1;
3481  assert(basicrow >= 0);
3482  assert(basicrow < nrows);
3483 
3484  CHECK_ZERO( lpi->messagehdlr, CPXgetsense(lpi->cpxenv, lpi->cpxlp, &rowsense, basicrow, basicrow) );
3485 
3486  if( rowsense == 'G' )
3487  {
3488  int i;
3489 
3490  for( i = 0; i < nrows; i++ )
3491  coef[i] *= -1.0;
3492  }
3493  }
3494 
3495  return SCIP_OKAY;
3496 }
3497 
3498 /** get dense column of inverse basis matrix B^-1
3499  *
3500  * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
3501  * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
3502  * see also the explanation in lpi.h.
3503  */
3505  SCIP_LPI* lpi, /**< LP interface structure */
3506  int c, /**< column number of B^-1; this is NOT the number of the column in the LP;
3507  * you have to call SCIPlpiGetBasisInd() to get the array which links the
3508  * B^-1 column numbers to the row and column numbers of the LP!
3509  * c must be between 0 and nrows-1, since the basis has the size
3510  * nrows * nrows */
3511  SCIP_Real* coef, /**< pointer to store the coefficients of the column */
3512  int* inds, /**< array to store the non-zero indices */
3513  int* ninds /**< pointer to store the number of non-zero indices
3514  * (-1: if we do not store sparsity informations) */
3515  )
3516 {
3517  int retval;
3518  int nrows;
3519  int r;
3520 
3521  assert(lpi != NULL);
3522  assert(lpi->cpxlp != NULL);
3523  assert(lpi->cpxenv != NULL);
3524 
3525  SCIPdebugMessage("getting binv-col %d\n", c);
3526 
3527  /* can only return dense result */
3528  if ( ninds != NULL )
3529  *ninds = -1;
3530 
3531  /* this might be turned off if the user as called SCIPlpiClearState() or set SCIP_LPPAR_FROMSCRATCH to TRUE */
3532  setIntParam(lpi, CPX_PARAM_ADVIND, CPX_ON);
3533  SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
3534 
3535  retval = CPXbinvcol(lpi->cpxenv, lpi->cpxlp, c, coef);
3536  if( retval == CPXERR_NO_SOLN || retval == CPXERR_NO_LU_FACTOR || retval == CPXERR_NO_BASIC_SOLN || retval == CPXERR_NO_BASIS )
3537  {
3538  SCIP_CALL_QUIET( restoreLPData(lpi) );
3539  retval = CPXbinvcol(lpi->cpxenv, lpi->cpxlp, c, coef);
3540  }
3541  CHECK_ZERO( lpi->messagehdlr, retval );
3542 
3543  /* the LPi expects slack variables with coefficient +1; CPLEX adds slack variables with a coefficient -1 for 'G'
3544  * constraints, so we have to change the sign of the corresponding rows
3545  */
3546  nrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
3547  SCIP_CALL( ensureValMem(lpi, nrows) );
3548  CHECK_ZERO( lpi->messagehdlr, CPXgetbhead(lpi->cpxenv, lpi->cpxlp, lpi->indarray, NULL) );
3549  SCIP_CALL( ensureSidechgMem(lpi, nrows) );
3550  CHECK_ZERO( lpi->messagehdlr, CPXgetsense(lpi->cpxenv, lpi->cpxlp, lpi->senarray, 0, nrows - 1) );
3551 
3552  for( r = 0; r < nrows; r++ )
3553  {
3554  if( lpi->indarray[r] < 0 )
3555  {
3556  int basicrow;
3557 
3558  basicrow = -lpi->indarray[r] - 1;
3559  assert(basicrow >= 0);
3560  assert(basicrow < nrows);
3561 
3562  if( basicrow >= 0 && basicrow < nrows && lpi->senarray[basicrow] == 'G' )
3563  coef[r] *= -1.0;
3564  }
3565  }
3566 
3567  return SCIP_OKAY;
3568 }
3569 
3570 /** get dense row of inverse basis matrix times constraint matrix B^-1 * A
3571  *
3572  * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
3573  * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
3574  * see also the explanation in lpi.h.
3575  */
3577  SCIP_LPI* lpi, /**< LP interface structure */
3578  int r, /**< row number */
3579  const SCIP_Real* binvrow, /**< row in (A_B)^-1 from prior call to SCIPlpiGetBInvRow(), or NULL */
3580  SCIP_Real* coef, /**< vector to return coefficients */
3581  int* inds, /**< array to store the non-zero indices */
3582  int* ninds /**< pointer to store the number of non-zero indices
3583  * (-1: if we do not store sparsity informations) */
3584  )
3585 { /*lint --e{715}*/
3586  int retval;
3587  int nrows;
3588 
3589  assert(lpi != NULL);
3590  assert(lpi->cpxlp != NULL);
3591  assert(lpi->cpxenv != NULL);
3592 
3593  SCIPdebugMessage("getting binva-row %d\n", r);
3594 
3595  /* can only return dense result */
3596  if ( ninds != NULL )
3597  *ninds = -1;
3598 
3599  /* this might be turned off if the user as called SCIPlpiClearState() or set SCIP_LPPAR_FROMSCRATCH to TRUE */
3600  setIntParam(lpi, CPX_PARAM_ADVIND, CPX_ON);
3601  SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
3602 
3603  retval = CPXbinvarow(lpi->cpxenv, lpi->cpxlp, r, coef);
3604  if( retval == CPXERR_NO_SOLN || retval == CPXERR_NO_LU_FACTOR || retval == CPXERR_NO_BASIC_SOLN || retval == CPXERR_NO_BASIS )
3605  {
3606  SCIP_CALL_QUIET( restoreLPData(lpi) );
3607  retval = CPXbinvarow(lpi->cpxenv, lpi->cpxlp, r, coef);
3608  }
3609  CHECK_ZERO( lpi->messagehdlr, retval );
3610 
3611  /* the LPi expects slack variables with coefficient +1; CPLEX adds slack variables with a coefficient -1 for 'G'
3612  * constraints, so we have to change the sign of the corresponding rows
3613  */
3614  nrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
3615  SCIP_CALL( ensureValMem(lpi, nrows) );
3616  CHECK_ZERO( lpi->messagehdlr, CPXgetbhead(lpi->cpxenv, lpi->cpxlp, lpi->indarray, NULL) );
3617 
3618  if( lpi->indarray[r] < 0 )
3619  {
3620  int basicrow;
3621  char rowsense;
3622 
3623  basicrow = -lpi->indarray[r] - 1;
3624  assert(basicrow >= 0);
3625  assert(basicrow < nrows);
3626 
3627  CHECK_ZERO( lpi->messagehdlr, CPXgetsense(lpi->cpxenv, lpi->cpxlp, &rowsense, basicrow, basicrow) );
3628 
3629  if( rowsense == 'G' )
3630  {
3631  int i;
3632 
3633  for( i = 0; i < nrows; i++ )
3634  coef[i] *= -1.0;
3635  }
3636  }
3637 
3638  return SCIP_OKAY;
3639 }
3640 
3641 /** get dense column of inverse basis matrix times constraint matrix B^-1 * A
3642  *
3643  * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
3644  * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
3645  * see also the explanation in lpi.h.
3646  */
3648  SCIP_LPI* lpi, /**< LP interface structure */
3649  int c, /**< column number */
3650  SCIP_Real* coef, /**< vector to return coefficients */
3651  int* inds, /**< array to store the non-zero indices */
3652  int* ninds /**< pointer to store the number of non-zero indices
3653  * (-1: if we do not store sparsity informations) */
3654  )
3655 { /*lint --e{715}*/
3656  int retval;
3657  int nrows;
3658  int r;
3659 
3660  assert(lpi->cpxenv != NULL);
3661  assert(lpi != NULL);
3662  assert(lpi->cpxlp != NULL);
3663 
3664  SCIPdebugMessage("getting binva-col %d\n", c);
3665 
3666  /* can only return dense result */
3667  if ( ninds != NULL )
3668  *ninds = -1;
3669 
3670  /* this might be turned off if the user as called SCIPlpiClearState() or set SCIP_LPPAR_FROMSCRATCH to TRUE */
3671  setIntParam(lpi, CPX_PARAM_ADVIND, CPX_ON);
3672  SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
3673 
3674  retval = CPXbinvacol(lpi->cpxenv, lpi->cpxlp, c, coef);
3675  if( retval == CPXERR_NO_SOLN || retval == CPXERR_NO_LU_FACTOR || retval == CPXERR_NO_BASIC_SOLN || retval == CPXERR_NO_BASIS )
3676  {
3677  SCIP_CALL_QUIET( restoreLPData(lpi) );
3678  retval = CPXbinvacol(lpi->cpxenv, lpi->cpxlp, c, coef);
3679  }
3680  CHECK_ZERO( lpi->messagehdlr, retval );
3681 
3682  /* the LPi expects slack variables with coefficient +1; CPLEX adds slack variables with a coefficient -1 for 'G'
3683  * constraints, so we have to change the sign of the corresponding rows
3684  */
3685  nrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
3686  SCIP_CALL( ensureValMem(lpi, nrows) );
3687  CHECK_ZERO( lpi->messagehdlr, CPXgetbhead(lpi->cpxenv, lpi->cpxlp, lpi->indarray, NULL) );
3688  SCIP_CALL( ensureSidechgMem(lpi, nrows) );
3689  CHECK_ZERO( lpi->messagehdlr, CPXgetsense(lpi->cpxenv, lpi->cpxlp, lpi->senarray, 0, nrows - 1) );
3690 
3691  for( r = 0; r < nrows; r++ )
3692  {
3693  if( lpi->indarray[r] < 0 )
3694  {
3695  int basicrow;
3696 
3697  basicrow = -lpi->indarray[r] - 1;
3698  assert(basicrow >= 0);
3699  assert(basicrow < nrows);
3700 
3701  if( basicrow >= 0 && basicrow < nrows && lpi->senarray[basicrow] == 'G' )
3702  coef[r] *= -1.0;
3703  }
3704  }
3705 
3706  return SCIP_OKAY;
3707 }
3708 
3709 /**@} */
3710 
3711 
3712 
3713 
3714 /*
3715  * LP State Methods
3716  */
3717 
3718 /**@name LP State Methods */
3719 /**@{ */
3720 
3721 /** stores LPi state (like basis information) into lpistate object */
3723  SCIP_LPI* lpi, /**< LP interface structure */
3724  BMS_BLKMEM* blkmem, /**< block memory */
3725  SCIP_LPISTATE** lpistate /**< pointer to LPi state information (like basis information) */
3726  )
3727 {
3728  int ncols;
3729  int nrows;
3730 
3731  assert(blkmem != NULL);
3732  assert(lpi != NULL);
3733  assert(lpi->cpxlp != NULL);
3734  assert(lpi->cpxenv != NULL);
3735  assert(lpistate != NULL);
3736 
3737  /* if there is no basis information available (e.g. after barrier without crossover), or no state can be saved; if
3738  * SCIPlpiClearState() has been called, do not return the state
3739  */
3740  if( !lpi->solisbasic || lpi->clearstate )
3741  {
3742  *lpistate = NULL;
3743  return SCIP_OKAY;
3744  }
3745 
3746  ncols = CPXgetnumcols(lpi->cpxenv, lpi->cpxlp);
3747  nrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
3748  assert(ncols >= 0);
3749  assert(nrows >= 0);
3750 
3751  /* allocate lpistate data */
3752  SCIP_CALL( lpistateCreate(lpistate, blkmem, ncols, nrows) );
3753 
3754  SCIPdebugMessage("storing CPLEX LPI state in %p (%d cols, %d rows)\n", (void *) *lpistate, ncols, nrows);
3755 
3756  /* get unpacked basis information from CPLEX */
3757  SCIP_CALL( getBase(lpi) );
3758 
3759  /* pack LPi state data */
3760  (*lpistate)->ncols = ncols;
3761  (*lpistate)->nrows = nrows;
3762  lpistatePack(*lpistate, lpi->cstat, lpi->rstat);
3763 
3764  return SCIP_OKAY;
3765 }
3766 
3767 /** loads LPi state (like basis information) into solver; note that the LP might have been extended with additional
3768  * columns and rows since the state was stored with SCIPlpiGetState()
3769  */
3771  SCIP_LPI* lpi, /**< LP interface structure */
3772  BMS_BLKMEM* blkmem, /**< block memory */
3773  SCIP_LPISTATE* lpistate /**< LPi state information (like basis information) */
3774  )
3775 {
3776  int lpncols;
3777  int lpnrows;
3778  int i;
3779 
3780  assert(blkmem != NULL);
3781  assert(lpi != NULL);
3782  assert(lpi->cpxlp != NULL);
3783  assert(lpi->cpxenv != NULL);
3784 
3785  /* if there was no basis information available, the LPI state was not stored */
3786  if( lpistate == NULL )
3787  return SCIP_OKAY;
3788 
3789  lpncols = CPXgetnumcols(lpi->cpxenv, lpi->cpxlp);
3790  lpnrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
3791  assert(lpistate->ncols <= lpncols);
3792  assert(lpistate->nrows <= lpnrows);
3793 
3794  SCIPdebugMessage("loading LPI state %p (%d cols, %d rows) into CPLEX LP with %d cols and %d rows\n",
3795  (void *) lpistate, lpistate->ncols, lpistate->nrows, lpncols, lpnrows);
3796 
3797  if( lpistate->ncols == 0 || lpistate->nrows == 0 )
3798  return SCIP_OKAY;
3799 
3800  /* allocate enough memory for storing uncompressed basis information */
3801  SCIP_CALL( ensureCstatMem(lpi, lpncols) );
3802  SCIP_CALL( ensureRstatMem(lpi, lpnrows) );
3803 
3804  /* unpack LPi state data */
3805  lpistateUnpack(lpistate, lpi->cstat, lpi->rstat);
3806 
3807  /* extend the basis to the current LP beyond the previously existing columns */
3808  for( i = lpistate->ncols; i < lpncols; ++i )
3809  {
3810  SCIP_Real bnd;
3811  CHECK_ZERO( lpi->messagehdlr, CPXgetlb(lpi->cpxenv, lpi->cpxlp, &bnd, i, i) );
3812  if ( SCIPlpiIsInfinity(lpi, REALABS(bnd)) )
3813  {
3814  /* if lower bound is +/- infinity -> try upper bound */
3815  CHECK_ZERO( lpi->messagehdlr, CPXgetub(lpi->cpxenv, lpi->cpxlp, &bnd, i, i) );
3816  if ( SCIPlpiIsInfinity(lpi, REALABS(bnd)) )
3817  lpi->cstat[i] = (int) SCIP_BASESTAT_ZERO; /* variable is free -> super basic */
3818  else
3819  lpi->cstat[i] = (int) SCIP_BASESTAT_UPPER; /* use finite upper bound */
3820  }
3821  else
3822  lpi->cstat[i] = (int) SCIP_BASESTAT_LOWER; /* use finite lower bound */
3823  }
3824  for( i = lpistate->nrows; i < lpnrows; ++i )
3825  lpi->rstat[i] = (int) SCIP_BASESTAT_BASIC;
3826 
3827  /* load basis information into CPLEX */
3828  SCIP_CALL( setBase(lpi) );
3829 
3830  return SCIP_OKAY;
3831 }
3832 
3833 /** clears current LPi state (like basis information) of the solver */
3835  SCIP_LPI* lpi /**< LP interface structure */
3836  )
3837 {
3838  assert(lpi != NULL);
3839 
3840  /* set CPX_PARAM_ADVIND to CPX_OFF for the next solve */
3841  lpi->clearstate = TRUE;
3842 
3843  return SCIP_OKAY;
3844 }
3845 
3846 /** frees LPi state information */
3848  SCIP_LPI* lpi, /**< LP interface structure */
3849  BMS_BLKMEM* blkmem, /**< block memory */
3850  SCIP_LPISTATE** lpistate /**< pointer to LPi state information (like basis information) */
3851  )
3852 {
3853  assert(lpi != NULL);
3854  assert(lpistate != NULL);
3855 
3856  if( *lpistate != NULL )
3857  {
3858  lpistateFree(lpistate, blkmem);
3859  }
3860 
3861  return SCIP_OKAY;
3862 }
3863 
3864 /** checks, whether the given LP state contains simplex basis information */
3866  SCIP_LPI* lpi, /**< LP interface structure */
3867  SCIP_LPISTATE* lpistate /**< LP state information (like basis information) */
3868  )
3869 { /*lint --e{715}*/
3870  return (lpistate != NULL);
3871 }
3872 
3873 /** reads LP state (like basis information from a file */
3875  SCIP_LPI* lpi, /**< LP interface structure */
3876  const char* fname /**< file name */
3877  )
3878 {
3879  assert(lpi != NULL);
3880  assert(lpi->cpxlp != NULL);
3881  assert(lpi->cpxenv != NULL);
3882 
3883  SCIPdebugMessage("reading LP state from file <%s>\n", fname);
3884 
3885  CHECK_ZERO( lpi->messagehdlr, CPXreadcopybase(lpi->cpxenv, lpi->cpxlp, fname) );
3886 
3887  return SCIP_OKAY;
3888 }
3889 
3890 /** writes LP state (like basis information) to a file */
3892  SCIP_LPI* lpi, /**< LP interface structure */
3893  const char* fname /**< file name */
3894  )
3895 {
3896  assert(lpi != NULL);
3897  assert(lpi->cpxlp != NULL);
3898  assert(lpi->cpxenv != NULL);
3899 
3900  SCIPdebugMessage("writing LP state to file <%s>\n", fname);
3901 
3902  CHECK_ZERO( lpi->messagehdlr, CPXmbasewrite(lpi->cpxenv, lpi->cpxlp, fname) );
3903 
3904  return SCIP_OKAY;
3905 }
3906 
3907 /**@} */
3908 
3909 
3910 
3911 
3912 /*
3913  * LP Pricing Norms Methods
3914  */
3915 
3916 /**@name LP Pricing Norms Methods */
3917 /**@{ */
3918 
3919 /** stores LPi pricing norms information
3920  *
3921  * @todo store primal norms as well?
3922  */
3924  SCIP_LPI* lpi, /**< LP interface structure */
3925  BMS_BLKMEM* blkmem, /**< block memory */
3926  SCIP_LPINORMS** lpinorms /**< pointer to LPi pricing norms information */
3927  )
3928 {
3929  int nrows;
3930  int retval;
3931 
3932  assert(blkmem != NULL);
3933  assert(lpi != NULL);
3934  assert(lpi->cpxlp != NULL);
3935  assert(lpi->cpxenv != NULL);
3936  assert(lpi->messagehdlr != NULL);
3937  assert(lpinorms != NULL);
3938 
3939  /* if there is no basis information available (e.g. after barrier without crossover), norms cannot be saved; if
3940  * SCIPlpiClearState() has been called, do not return the state
3941  */
3942  if( !lpi->solisbasic || lpi->clearstate )
3943  {
3944  *lpinorms = NULL;
3945  return SCIP_OKAY;
3946  }
3947 
3948  nrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
3949  assert(nrows >= 0);
3950 
3951  /* allocate lpinorms data */
3952  SCIP_ALLOC( BMSallocBlockMemory(blkmem, lpinorms) );
3953  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpinorms)->norm, nrows) );
3954  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpinorms)->head, nrows) );
3955  (*lpinorms)->normlen = 0;
3956 
3957  SCIPdebugMessage("storing CPLEX LPI pricing norms in %p (%d rows)\n", (void *) *lpinorms, nrows);
3958 
3959  /* get dual norms */
3960  retval = CPXgetdnorms(lpi->cpxenv, lpi->cpxlp, (*lpinorms)->norm, (*lpinorms)->head, &((*lpinorms)->normlen));
3961 
3962  /* if CPLEX used the primal simplex in the last optimization call, we do not have dual norms (error 1264) */
3963  if( retval == 1264 )
3964  {
3965  /* no norms available, free lpinorms data */
3966  BMSfreeBlockMemoryArray(blkmem, &(*lpinorms)->head, nrows);
3967  BMSfreeBlockMemoryArray(blkmem, &(*lpinorms)->norm, nrows);
3968  BMSfreeBlockMemory(blkmem, lpinorms);
3969  assert(*lpinorms == NULL);
3970  }
3971  else
3972  {
3973  assert((*lpinorms)->normlen == nrows);
3974  CHECK_ZERO( lpi->messagehdlr, retval );
3975  }
3976 
3977  return SCIP_OKAY;
3978 }
3979 
3980 /** loads LPi pricing norms into solver; note that the LP might have been extended with additional
3981  * columns and rows since the state was stored with SCIPlpiGetNorms()
3982  */
3984  SCIP_LPI* lpi, /**< LP interface structure */
3985  BMS_BLKMEM* blkmem, /**< block memory */
3986  SCIP_LPINORMS* lpinorms /**< LPi pricing norms information */
3987  )
3988 {
3989  int lpnrows;
3990 
3991  assert(blkmem != NULL);
3992  assert(lpi != NULL);
3993  assert(lpi->cpxlp != NULL);
3994  assert(lpi->cpxenv != NULL);
3995 
3996  /* if there was no pricing norms information available, the LPI norms were not stored */
3997  if( lpinorms == NULL )
3998  return SCIP_OKAY;
3999 
4000  lpnrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
4001  assert(lpinorms->normlen <= lpnrows);
4002 
4003  SCIPdebugMessage("loading LPI simplex norms %p (%d rows) into CPLEX LP with %d rows\n",
4004  (void *) lpinorms, lpinorms->normlen, lpnrows);
4005 
4006  if( lpinorms->normlen == 0 )
4007  return SCIP_OKAY;
4008 
4009  /* load pricing norms information into CPLEX */
4010  CHECK_ZERO( lpi->messagehdlr, CPXcopydnorms(lpi->cpxenv, lpi->cpxlp, lpinorms->norm, lpinorms->head, lpinorms->normlen) );
4011 
4012  return SCIP_OKAY;
4013 }
4014 
4015 /** frees pricing norms information */
4017  SCIP_LPI* lpi, /**< LP interface structure */
4018  BMS_BLKMEM* blkmem, /**< block memory */
4019  SCIP_LPINORMS** lpinorms /**< pointer to LPi pricing norms information */
4020  )
4021 {
4022  assert(lpi != NULL);
4023  assert(lpinorms != NULL);
4024 
4025  BMSfreeBlockMemoryArray(blkmem, &(*lpinorms)->head, (*lpinorms)->normlen);
4026  BMSfreeBlockMemoryArray(blkmem, &(*lpinorms)->norm, (*lpinorms)->normlen);
4027  BMSfreeBlockMemory(blkmem, lpinorms);
4028 
4029  return SCIP_OKAY;
4030 }
4031 
4032 /**@} */
4033 
4034 
4035 
4036 
4037 /*
4038  * Parameter Methods
4039  */
4040 
4041 /**@name Parameter Methods */
4042 /**@{ */
4043 
4044 /** gets integer parameter of LP */
4046  SCIP_LPI* lpi, /**< LP interface structure */
4047  SCIP_LPPARAM type, /**< parameter number */
4048  int* ival /**< buffer to store the parameter value */
4049  )
4050 {
4051  assert(lpi != NULL);
4052  assert(lpi->cpxlp != NULL);
4053  assert(ival != NULL);
4054 
4055  SCIPdebugMessage("getting int parameter %d\n", type);
4056 
4057  switch( type )
4058  {
4060  *ival = (int) lpi->fromscratch;
4061  break;
4062 #if (CPX_VERSION < 12060100)
4063  case SCIP_LPPAR_FASTMIP:
4064  *ival = getIntParam(lpi, CPX_PARAM_FASTMIP);
4065  break;
4066 #endif
4067  case SCIP_LPPAR_SCALING:
4068 #if (CPX_VERSION <= 1100)
4069  if( lpi->rngfound )
4070  return SCIP_PARAMETERUNKNOWN;
4071 #endif
4072  *ival = (getIntParam(lpi, CPX_PARAM_SCAIND) == 0);
4073  break;
4074  case SCIP_LPPAR_PRESOLVING:
4075  *ival = (getIntParam(lpi, CPX_PARAM_PREIND) == CPX_ON);
4076  break;
4077  case SCIP_LPPAR_PRICING:
4078  *ival = (int)lpi->pricing; /* store pricing method in LPI struct */
4079  break;
4080 #if 0
4081  case SCIP_LPPAR_PRICING:
4082  switch( getIntParam(lpi, CPX_PARAM_PPRIIND) )
4083  {
4084  case CPX_PPRIIND_FULL:
4085  *ival = (int)SCIP_PRICING_FULL;
4086  break;
4087  case CPX_PPRIIND_PARTIAL:
4088  *ival = (int)SCIP_PRICING_PARTIAL;
4089  break;
4090  case CPX_PPRIIND_STEEP:
4091  *ival = (int)SCIP_PRICING_STEEP;
4092  break;
4093  case CPX_PPRIIND_STEEPQSTART:
4094  *ival = (int)SCIP_PRICING_STEEPQSTART;
4095  break;
4096 #if (CPX_VERSION >= 900)
4097  case CPX_PPRIIND_DEVEX:
4098  *ival = (int)SCIP_PRICING_DEVEX;
4099  break;
4100 #endif
4101  default:
4102  *ival = (int)SCIP_PRICING_AUTO;
4103  break;
4104  }
4105  break;
4106 #endif
4107  case SCIP_LPPAR_LPINFO:
4108  *ival = (getIntParam(lpi, CPX_PARAM_SCRIND) == CPX_ON);
4109  break;
4110  case SCIP_LPPAR_LPITLIM:
4111  *ival = getIntParam(lpi, CPX_PARAM_ITLIM);
4112 #if (CPX_VERSION <= 1230)
4113  if( *ival >= CPX_INT_MAX )
4114  *ival = INT_MAX;
4115 #endif
4116  break;
4117  case SCIP_LPPAR_THREADS:
4118 #if (CPX_VERSION == 1100 || (CPX_VERSION == 1220 && (CPX_SUBVERSION == 0 || CPX_SUBVERSION == 2)))
4119  /* Due to CPLEX bug, we always set the thread count to 1. In order to fulfill an assert in lp.c, we have to
4120  * return the value set by SCIP and not the real thread count */
4121  *ival = lpi->pseudonthreads;
4122  assert(getIntParam(lpi, CPX_PARAM_THREADS) == 1);
4123 #else
4124  *ival = getIntParam(lpi, CPX_PARAM_THREADS);
4125 #endif
4126  break;
4127  default:
4128  return SCIP_PARAMETERUNKNOWN;
4129  } /*lint !e788*/
4130 
4131  return SCIP_OKAY;
4132 }
4133 
4134 /** sets integer parameter of LP */
4136  SCIP_LPI* lpi, /**< LP interface structure */
4137  SCIP_LPPARAM type, /**< parameter number */
4138  int ival /**< parameter value */
4139  )
4140 {
4141  assert(lpi != NULL);
4142  assert(lpi->cpxlp != NULL);
4143 
4144  SCIPdebugMessage("setting int parameter %d to %d\n", type, ival);
4145 
4146  switch( type )
4147  {
4149  assert(ival == TRUE || ival == FALSE);
4150  lpi->fromscratch = ival;
4151  break;
4152 #if (CPX_VERSION < 12060100)
4153  case SCIP_LPPAR_FASTMIP:
4154  assert(0 <= ival && ival <= 1);
4155  setIntParam(lpi, CPX_PARAM_FASTMIP, ival);
4156  break;
4157 #endif
4158  case SCIP_LPPAR_SCALING:
4159  assert(ival == TRUE || ival == FALSE);
4160 #if (CPX_VERSION <= 1100)
4161  if( lpi->rngfound )
4162  return SCIP_PARAMETERUNKNOWN;
4163 #endif
4164  setIntParam(lpi, CPX_PARAM_SCAIND, ival == TRUE ? 0 : -1);
4165  break;
4166  case SCIP_LPPAR_PRESOLVING:
4167  assert(ival == TRUE || ival == FALSE);
4168  setIntParam(lpi, CPX_PARAM_PREIND, ival == TRUE ? CPX_ON : CPX_OFF);
4169  break;
4170  case SCIP_LPPAR_PRICING:
4171  lpi->pricing = (SCIP_PRICING)ival;
4172  switch( (SCIP_PRICING)ival )
4173  {
4174  case SCIP_PRICING_AUTO:
4175  setIntParam(lpi, CPX_PARAM_PPRIIND, CPX_PPRIIND_AUTO);
4176  setIntParam(lpi, CPX_PARAM_DPRIIND, CPX_DPRIIND_AUTO);
4177  break;
4178  case SCIP_PRICING_FULL:
4179  setIntParam(lpi, CPX_PARAM_PPRIIND, CPX_PPRIIND_FULL);
4180  setIntParam(lpi, CPX_PARAM_DPRIIND, CPX_DPRIIND_FULL);
4181  break;
4182  case SCIP_PRICING_PARTIAL:
4183  setIntParam(lpi, CPX_PARAM_PPRIIND, CPX_PPRIIND_PARTIAL);
4184  setIntParam(lpi, CPX_PARAM_DPRIIND, CPX_DPRIIND_AUTO);
4185  break;
4187  case SCIP_PRICING_STEEP:
4188  setIntParam(lpi, CPX_PARAM_PPRIIND, CPX_PPRIIND_STEEP);
4189  setIntParam(lpi, CPX_PARAM_DPRIIND, CPX_DPRIIND_STEEP);
4190  break;
4192  setIntParam(lpi, CPX_PARAM_PPRIIND, CPX_PPRIIND_STEEPQSTART);
4193  setIntParam(lpi, CPX_PARAM_DPRIIND, CPX_DPRIIND_STEEPQSTART);
4194  break;
4195 #if (CPX_VERSION >= 900)
4196  case SCIP_PRICING_DEVEX:
4197  setIntParam(lpi, CPX_PARAM_PPRIIND, CPX_PPRIIND_DEVEX);
4198  setIntParam(lpi, CPX_PARAM_DPRIIND, CPX_DPRIIND_DEVEX);
4199  break;
4200 #endif
4201  default:
4202  return SCIP_LPERROR;
4203  }
4204  break;
4205  case SCIP_LPPAR_LPINFO:
4206  assert(ival == TRUE || ival == FALSE);
4207  if( ival )
4208  setIntParam(lpi, CPX_PARAM_SCRIND, CPX_ON);
4209  else
4210  setIntParam(lpi, CPX_PARAM_SCRIND, CPX_OFF);
4211  break;
4212  case SCIP_LPPAR_LPITLIM:
4213 #if (CPX_VERSION <= 1230)
4214  ival = MIN(ival, CPX_INT_MAX);
4215 #endif
4216  setIntParam(lpi, CPX_PARAM_ITLIM, ival);
4217  break;
4218  case SCIP_LPPAR_THREADS:
4219 #if (CPX_VERSION == 1100 || (CPX_VERSION == 1220 && (CPX_SUBVERSION == 0 || CPX_SUBVERSION == 2)))
4220  /* Due to CPLEX bug, we always set the thread count to 1. In order to fulfill an assert in lp.c, we have to
4221  * store the value set by SCIP and return it later instead of the real thread count */
4222  lpi->pseudonthreads = ival;
4223  ival = 1;
4224 #else
4225  ival = MIN(ival, CPX_INT_MAX);
4226 #endif
4227  setIntParam(lpi, CPX_PARAM_THREADS, ival);
4228  break;
4229  default:
4230  return SCIP_PARAMETERUNKNOWN;
4231  } /*lint !e788*/
4232 
4233  return SCIP_OKAY;
4234 }
4235 
4236 /** gets floating point parameter of LP */
4238  SCIP_LPI* lpi, /**< LP interface structure */
4239  SCIP_LPPARAM type, /**< parameter number */
4240  SCIP_Real* dval /**< buffer to store the parameter value */
4241  )
4242 {
4243  assert(lpi != NULL);
4244  assert(lpi->cpxlp != NULL);
4245  assert(dval != NULL);
4246 
4247  SCIPdebugMessage("getting real parameter %d\n", type);
4248 
4249  switch( type )
4250  {
4251  case SCIP_LPPAR_FEASTOL:
4252  *dval = getDblParam(lpi, CPX_PARAM_EPRHS);
4253  break;
4255  *dval = getDblParam(lpi, CPX_PARAM_EPOPT);
4256  break;
4258  *dval = getDblParam(lpi, CPX_PARAM_BAREPCOMP);
4259  break;
4260  case SCIP_LPPAR_LOBJLIM:
4261  *dval = getDblParam(lpi, CPX_PARAM_OBJLLIM);
4262  break;
4263  case SCIP_LPPAR_UOBJLIM:
4264  *dval = getDblParam(lpi, CPX_PARAM_OBJULIM);
4265  break;
4266  case SCIP_LPPAR_LPTILIM:
4267  *dval = getDblParam(lpi, CPX_PARAM_TILIM);
4268  break;
4269  case SCIP_LPPAR_MARKOWITZ:
4270  *dval = getDblParam(lpi, CPX_PARAM_EPMRK);
4271  break;
4273  *dval = lpi->conditionlimit;
4274  break;
4275  default:
4276  return SCIP_PARAMETERUNKNOWN;
4277  } /*lint !e788*/
4278 
4279  return SCIP_OKAY;
4280 }
4281 
4282 /** sets floating point parameter of LP */
4284  SCIP_LPI* lpi, /**< LP interface structure */
4285  SCIP_LPPARAM type, /**< parameter number */
4286  SCIP_Real dval /**< parameter value */
4287  )
4288 {
4289  assert(lpi != NULL);
4290  assert(lpi->cpxlp != NULL);
4291 
4292  SCIPdebugMessage("setting real parameter %d to %.15g\n", type, dval);
4293 
4294  switch( type )
4295  {
4296  case SCIP_LPPAR_FEASTOL:
4297  setDblParam(lpi, CPX_PARAM_EPRHS, dval);
4298  lpi->feastol = dval;
4299  break;
4301  setDblParam(lpi, CPX_PARAM_EPOPT, dval);
4302  break;
4304  setDblParam(lpi, CPX_PARAM_BAREPCOMP, dval);
4305  break;
4306  case SCIP_LPPAR_LOBJLIM:
4307  setDblParam(lpi, CPX_PARAM_OBJLLIM, dval);
4308  break;
4309  case SCIP_LPPAR_UOBJLIM:
4310  setDblParam(lpi, CPX_PARAM_OBJULIM, dval);
4311  break;
4312  case SCIP_LPPAR_LPTILIM:
4313  setDblParam(lpi, CPX_PARAM_TILIM, dval);
4314  break;
4315  case SCIP_LPPAR_MARKOWITZ:
4316  setDblParam(lpi, CPX_PARAM_EPMRK, dval);
4317  break;
4319  lpi->conditionlimit = dval;
4320  lpi->checkcondition = (dval >= 0);
4321  break;
4322  default:
4323  return SCIP_PARAMETERUNKNOWN;
4324  } /*lint !e788*/
4325 
4326  return SCIP_OKAY;
4327 }
4328 
4329 /**@} */
4330 
4331 
4332 
4333 
4334 /*
4335  * Numerical Methods
4336  */
4337 
4338 /**@name Numerical Methods */
4339 /**@{ */
4340 
4341 /** returns value treated as infinity in the LP solver */
4343  SCIP_LPI* lpi /**< LP interface structure */
4344  )
4345 { /*lint --e{715}*/
4346  return CPX_INFBOUND;
4347 }
4348 
4349 /** checks if given value is treated as infinity in the LP solver */
4351  SCIP_LPI* lpi, /**< LP interface structure */
4352  SCIP_Real val /**< value to be checked for infinity */
4353  )
4354 { /*lint --e{715}*/
4355  return (val >= CPX_INFBOUND);
4356 }
4357 
4358 /**@} */
4359 
4360 
4361 
4362 
4363 /*
4364  * File Interface Methods
4365  */
4366 
4367 /**@name File Interface Methods */
4368 /**@{ */
4369 
4370 /** reads LP from a file */
4372  SCIP_LPI* lpi, /**< LP interface structure */
4373  const char* fname /**< file name */
4374  )
4375 {
4376  int restat;
4377 
4378  assert(lpi != NULL);
4379  assert(lpi->cpxlp != NULL);
4380  assert(lpi->cpxenv != NULL);
4381 
4382  SCIPdebugMessage("reading LP from file <%s>\n", fname);
4383 
4384  restat = CPXreadcopyprob(lpi->cpxenv, lpi->cpxlp, fname, NULL);
4385  if( restat != 0 )
4386  {
4387  SCIPerrorMessage("LP Error: CPLEX returned %d\n", restat);
4388  return SCIP_READERROR;
4389  }
4390 
4391  return SCIP_OKAY;
4392 }
4393 
4394 /** writes LP to a file */
4396  SCIP_LPI* lpi, /**< LP interface structure */
4397  const char* fname /**< file name */
4398  )
4399 {
4400  int restat;
4401 
4402  assert(lpi != NULL);
4403  assert(lpi->cpxlp != NULL);
4404  assert(lpi->cpxenv != NULL);
4405 
4406  SCIPdebugMessage("writing LP to file <%s>\n", fname);
4407 
4408  restat = CPXwriteprob(lpi->cpxenv, lpi->cpxlp, fname, NULL);
4409  if( restat != 0 )
4410  {
4411  SCIPerrorMessage("LP Error: CPLEX returned %d\n", restat);
4412  return SCIP_READERROR;
4413  }
4414 
4415  return SCIP_OKAY;
4416 }
4417 
4418 /**@} */
SCIP_Bool SCIPlpiIsPrimalUnbounded(SCIP_LPI *lpi)
Definition: lpi_cpx.c:2868
SCIP_RETCODE SCIPlpiGetDualfarkas(SCIP_LPI *lpi, SCIP_Real *dualfarkas)
Definition: lpi_cpx.c:3224
enum SCIP_LPSolQuality SCIP_LPSOLQUALITY
Definition: type_lpi.h:92
SCIP_Bool SCIPlpiIsPrimalFeasible(SCIP_LPI *lpi)
Definition: lpi_cpx.c:2911
SCIP_RETCODE SCIPlpiClear(SCIP_LPI *lpi)
Definition: lpi_cpx.c:1400
SCIP_RETCODE SCIPlpiDelColset(SCIP_LPI *lpi, int *dstat)
Definition: lpi_cpx.c:1284
SCIP_RETCODE SCIPlpiSolvePrimal(SCIP_LPI *lpi)
Definition: lpi_cpx.c:2089
SCIP_Bool SCIPlpiIsInfinity(SCIP_LPI *lpi, SCIP_Real val)
Definition: lpi_cpx.c:4350
unsigned int SCIP_DUALPACKET
Definition: lpi_grb.c:83
SCIP_RETCODE SCIPlpiSetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS *lpinorms)
Definition: lpi_cpx.c:3983
double dblparval[NUMDBLPARAM]
Definition: lpi_cpx.c:132
SCIP_RETCODE SCIPlpiGetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real *dval)
Definition: lpi_cpx.c:4237
SCIP_RETCODE SCIPlpiClearState(SCIP_LPI *lpi)
Definition: lpi_cpx.c:3834
SCIP_RETCODE SCIPlpiGetBInvARow(SCIP_LPI *lpi, int r, const SCIP_Real *binvrow, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_cpx.c:3576
enum SCIP_ObjSen SCIP_OBJSEN
Definition: type_lpi.h:36
#define NULL
Definition: lpi_spx.cpp:130
SCIP_RETCODE SCIPlpiFreeNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition: lpi_cpx.c:4016
#define CPX_SUBVERSION
Definition: lpi_cpx.c:41
#define NUMDBLPARAM
Definition: lpi_cpx.c:105
SCIP_DUALPACKET COLPACKET
Definition: lpi_cpx.c:78
interface methods for specific LP solvers
SCIP_Bool SCIPlpiIsIterlimExc(SCIP_LPI *lpi)
Definition: lpi_cpx.c:3090
SCIP_RETCODE SCIPlpiAddRows(SCIP_LPI *lpi, int nrows, const SCIP_Real *lhs, const SCIP_Real *rhs, char **rownames, int nnonz, const int *beg, const int *ind, const SCIP_Real *val)
Definition: lpi_cpx.c:1305
struct SCIP_Messagehdlr SCIP_MESSAGEHDLR
Definition: type_message.h:50
#define FALSE
Definition: def.h:53
#define EPSISINT(x, eps)
Definition: def.h:161
#define TRUE
Definition: def.h:52
SCIP_RETCODE SCIPlpiGetSides(SCIP_LPI *lpi, int firstrow, int lastrow, SCIP_Real *lhss, SCIP_Real *rhss)
Definition: lpi_cpx.c:2022
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
SCIP_Bool SCIPlpiHasPrimalRay(SCIP_LPI *lpi)
Definition: lpi_cpx.c:2855
SCIP_RETCODE SCIPlpiGetNNonz(SCIP_LPI *lpi, int *nnonz)
Definition: lpi_cpx.c:1748
SCIP_RETCODE SCIPlpiSetBase(SCIP_LPI *lpi, int *cstat, int *rstat)
Definition: lpi_cpx.c:3356
SCIP_Bool SCIPlpiIsDualFeasible(SCIP_LPI *lpi)
Definition: lpi_cpx.c:2998
#define NUMINTPARAM
Definition: lpi_cpx.c:85
enum SCIP_LPParam SCIP_LPPARAM
Definition: type_lpi.h:61
SCIP_RETCODE SCIPlpiReadState(SCIP_LPI *lpi, const char *fname)
Definition: lpi_cpx.c:3874
SCIP_RETCODE SCIPlpiGetBInvACol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_cpx.c:3647
SCIP_Bool SCIPlpiHasDualRay(SCIP_LPI *lpi)
Definition: lpi_cpx.c:2945
#define SCIPdebugMessage
Definition: pub_message.h:77
SCIP_Bool SCIPlpiIsDualInfeasible(SCIP_LPI *lpi)
Definition: lpi_cpx.c:2977
#define CHECK_ZERO(messagehdlr, x)
Definition: lpi_cpx.c:49
#define COLS_PER_PACKET
Definition: lpi_cpx.c:79
SCIP_RETCODE SCIPlpiGetRows(SCIP_LPI *lpi, int firstrow, int lastrow, SCIP_Real *lhs, SCIP_Real *rhs, int *nnonz, int *beg, int *ind, SCIP_Real *val)
Definition: lpi_cpx.c:1824
SCIP_Bool SCIPlpiHasStateBasis(SCIP_LPI *lpi, SCIP_LPISTATE *lpistate)
Definition: lpi_cpx.c:3865
enum SCIP_Pricing SCIP_PRICING
Definition: type_lpi.h:74
SCIP_Bool SCIPlpiIsPrimalInfeasible(SCIP_LPI *lpi)
Definition: lpi_cpx.c:2892
SCIP_RETCODE SCIPlpiStartStrongbranch(SCIP_LPI *lpi)
Definition: lpi_cpx.c:2569
SCIP_RETCODE SCIPlpiGetBInvRow(SCIP_LPI *lpi, int r, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_cpx.c:3434
SCIP_Bool SCIPlpiExistsDualRay(SCIP_LPI *lpi)
Definition: lpi_cpx.c:2932
int SCIPlpiGetInternalStatus(SCIP_LPI *lpi)
Definition: lpi_cpx.c:3112
void SCIPmessagePrintWarning(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
#define ROWS_PER_PACKET
Definition: lpi_cpx.c:81
SCIP_DUALPACKET COLPACKET
Definition: lpi_clp.cpp:115
SCIP_RETCODE SCIPlpiGetSol(SCIP_LPI *lpi, SCIP_Real *objval, SCIP_Real *primsol, SCIP_Real *dualsol, SCIP_Real *activity, SCIP_Real *redcost)
Definition: lpi_cpx.c:3175
SCIP_RETCODE SCIPlpiGetNRows(SCIP_LPI *lpi, int *nrows)
Definition: lpi_cpx.c:1714
#define ABORT_ZERO(x)
Definition: lpi_cpx.c:58
#define CPX_MAGICZEROCONSTANT
Definition: lpi_cpx.c:76
#define SCIPerrorMessage
Definition: pub_message.h:45
#define SCIPdebugPrintf
Definition: pub_message.h:80
SCIP_RETCODE SCIPlpiFree(SCIP_LPI **lpi)
Definition: lpi_cpx.c:1123
SCIP_RETCODE SCIPlpiGetSolFeasibility(SCIP_LPI *lpi, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
Definition: lpi_cpx.c:2814
SCIP_Bool SCIPlpiIsObjlimExc(SCIP_LPI *lpi)
Definition: lpi_cpx.c:3077
SCIP_Bool SCIPlpiExistsPrimalRay(SCIP_LPI *lpi)
Definition: lpi_cpx.c:2841
SCIP_DUALPACKET ROWPACKET
Definition: lpi_clp.cpp:117
SCIP_RETCODE SCIPlpiChgSides(SCIP_LPI *lpi, int nrows, const int *ind, const SCIP_Real *lhs, const SCIP_Real *rhs)
Definition: lpi_cpx.c:1480
SCIP_RETCODE SCIPlpiSetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real dval)
Definition: lpi_cpx.c:4283
struct SCIP_LPiState SCIP_LPISTATE
Definition: type_lpi.h:95
#define REALABS(x)
Definition: def.h:148
SCIP_Real SCIPlpiInfinity(SCIP_LPI *lpi)
Definition: lpi_cpx.c:4342
SCIP_RETCODE SCIPlpiStrongbranchInt(SCIP_LPI *lpi, int col, SCIP_Real psol, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, int *iter)
Definition: lpi_cpx.c:2717
SCIP_RETCODE SCIPlpiStrongbranchFrac(SCIP_LPI *lpi, int col, SCIP_Real psol, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, int *iter)
Definition: lpi_cpx.c:2587
#define SCIP_CALL(x)
Definition: def.h:263
SCIP_RETCODE SCIPlpiGetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lpi_cpx.c:3722
SCIP_Bool SCIPlpiIsOptimal(SCIP_LPI *lpi)
Definition: lpi_cpx.c:3017
SCIP_RETCODE SCIPlpiGetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int *ival)
Definition: lpi_cpx.c:4045
SCIP_RETCODE SCIPlpiLoadColLP(SCIP_LPI *lpi, SCIP_OBJSEN objsen, int ncols, const SCIP_Real *obj, const SCIP_Real *lb, const SCIP_Real *ub, char **colnames, int nrows, const SCIP_Real *lhs, const SCIP_Real *rhs, char **rownames, int nnonz, const int *beg, const int *ind, const SCIP_Real *val)
Definition: lpi_cpx.c:1169
SCIP_RETCODE SCIPlpiGetRowNames(SCIP_LPI *lpi, int firstrow, int lastrow, char **rownames, char *namestorage, int namestoragesize, int *storageleft)
Definition: lpi_cpx.c:1921
#define EPSCEIL(x, eps)
Definition: def.h:158
SCIP_RETCODE SCIPlpiScaleCol(SCIP_LPI *lpi, int col, SCIP_Real scaleval)
Definition: lpi_cpx.c:1640
SCIP_RETCODE SCIPlpiGetBase(SCIP_LPI *lpi, int *cstat, int *rstat)
Definition: lpi_cpx.c:3316
SCIP_RETCODE SCIPlpiStrongbranchesInt(SCIP_LPI *lpi, int *cols, int ncols, SCIP_Real *psols, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, int *iter)
Definition: lpi_cpx.c:2751
SCIP_RETCODE SCIPlpiGetBounds(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *lbs, SCIP_Real *ubs)
Definition: lpi_cpx.c:1993
SCIP_RETCODE SCIPlpiGetObjval(SCIP_LPI *lpi, SCIP_Real *objval)
Definition: lpi_cpx.c:3146
SCIP_Bool SCIPlpiIsTimelimExc(SCIP_LPI *lpi)
Definition: lpi_cpx.c:3101
#define SCIP_Bool
Definition: def.h:50
SCIP_RETCODE SCIPlpiCreate(SCIP_LPI **lpi, SCIP_MESSAGEHDLR *messagehdlr, const char *name, SCIP_OBJSEN objsen)
Definition: lpi_cpx.c:1043
#define MAX(x, y)
Definition: tclique_def.h:75
SCIP_RETCODE SCIPlpiChgBounds(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *lb, const SCIP_Real *ub)
Definition: lpi_cpx.c:1430
SCIP_RETCODE SCIPlpiChgObjsen(SCIP_LPI *lpi, SCIP_OBJSEN objsen)
Definition: lpi_cpx.c:1546
SCIP_DUALPACKET ROWPACKET
Definition: lpi_cpx.c:80
const char * SCIPlpiGetSolverName(void)
Definition: lpi_cpx.c:1000
SCIP_Bool SCIPlpiIsStable(SCIP_LPI *lpi)
Definition: lpi_cpx.c:3028
SCIP_RETCODE SCIPlpiScaleRow(SCIP_LPI *lpi, int row, SCIP_Real scaleval)
Definition: lpi_cpx.c:1584
SCIP_RETCODE SCIPlpiGetCoef(SCIP_LPI *lpi, int row, int col, SCIP_Real *val)
Definition: lpi_cpx.c:2058
int * head
Definition: lpi_cpx.c:195
#define SCIP_CALL_QUIET(x)
Definition: def.h:238
SCIP_RETCODE SCIPlpiReadLP(SCIP_LPI *lpi, const char *fname)
Definition: lpi_cpx.c:4371
SCIP_RETCODE SCIPlpiDelRows(SCIP_LPI *lpi, int firstrow, int lastrow)
Definition: lpi_cpx.c:1358
SCIP_Bool SCIPlpiWasSolved(SCIP_LPI *lpi)
Definition: lpi_cpx.c:2804
SCIP_RETCODE SCIPlpiGetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition: lpi_cpx.c:3923
SCIP_RETCODE SCIPlpiGetCols(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *lb, SCIP_Real *ub, int *nnonz, int *beg, int *ind, SCIP_Real *val)
Definition: lpi_cpx.c:1768
void * SCIPlpiGetSolverPointer(SCIP_LPI *lpi)
Definition: lpi_cpx.c:1024
SCIP_RETCODE SCIPlpiChgCoef(SCIP_LPI *lpi, int row, int col, SCIP_Real newval)
Definition: lpi_cpx.c:1525
#define CPX_REFACTORMAXITERS
Definition: lpi_cpx.c:72
SCIP_RETCODE SCIPlpiSetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE *lpistate)
Definition: lpi_cpx.c:3770
SCIP_RETCODE SCIPlpiGetObjsen(SCIP_LPI *lpi, SCIP_OBJSEN *objsen)
Definition: lpi_cpx.c:1955
SCIP_RETCODE SCIPlpiGetPrimalRay(SCIP_LPI *lpi, SCIP_Real *ray)
Definition: lpi_cpx.c:3205
double * norm
Definition: lpi_cpx.c:194
public methods for message output
struct SCIP_LPi SCIP_LPI
Definition: type_lpi.h:94
#define SCIP_Real
Definition: def.h:124
SCIP_RETCODE SCIPlpiAddCols(SCIP_LPI *lpi, int ncols, const SCIP_Real *obj, const SCIP_Real *lb, const SCIP_Real *ub, char **colnames, int nnonz, const int *beg, const int *ind, const SCIP_Real *val)
Definition: lpi_cpx.c:1229
SCIP_RETCODE SCIPlpiGetNCols(SCIP_LPI *lpi, int *ncols)
Definition: lpi_cpx.c:1731
SCIP_RETCODE SCIPlpiStrongbranchesFrac(SCIP_LPI *lpi, int *cols, int ncols, SCIP_Real *psols, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, int *iter)
Definition: lpi_cpx.c:2651
SCIP_RETCODE SCIPlpiSolveBarrier(SCIP_LPI *lpi, SCIP_Bool crossover)
Definition: lpi_cpx.c:2379
#define SCIP_INVALID
Definition: def.h:144
#define CPX_INT_MAX
Definition: lpi_cpx.c:67
SCIP_RETCODE SCIPlpiDelCols(SCIP_LPI *lpi, int firstcol, int lastcol)
Definition: lpi_cpx.c:1263
SCIP_RETCODE SCIPlpiFreeState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lpi_cpx.c:3847
SCIP_RETCODE SCIPlpiGetObj(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *vals)
Definition: lpi_cpx.c:1972
int intparval[NUMINTPARAM]
Definition: lpi_cpx.c:131
SCIP_RETCODE SCIPlpiWriteLP(SCIP_LPI *lpi, const char *fname)
Definition: lpi_cpx.c:4395
SCIP_RETCODE SCIPlpiDelRowset(SCIP_LPI *lpi, int *dstat)
Definition: lpi_cpx.c:1379
SCIP_RETCODE SCIPlpiIgnoreInstability(SCIP_LPI *lpi, SCIP_Bool *success)
Definition: lpi_cpx.c:3123
#define EPSFLOOR(x, eps)
Definition: def.h:157
SCIP_RETCODE SCIPlpiChgObj(SCIP_LPI *lpi, int ncols, int *ind, SCIP_Real *obj)
Definition: lpi_cpx.c:1565
SCIP_RETCODE SCIPlpiSolveDual(SCIP_LPI *lpi)
Definition: lpi_cpx.c:2194
SCIP_RETCODE SCIPlpiGetRealSolQuality(SCIP_LPI *lpi, SCIP_LPSOLQUALITY qualityindicator, SCIP_Real *quality)
Definition: lpi_cpx.c:3262
SCIP_RETCODE SCIPlpiGetBasisInd(SCIP_LPI *lpi, int *bind)
Definition: lpi_cpx.c:3400
SCIP_RETCODE SCIPlpiSetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int ival)
Definition: lpi_cpx.c:4135
#define SCIP_ALLOC(x)
Definition: def.h:274
#define SCIPABORT()
Definition: def.h:235
SCIP_RETCODE SCIPlpiGetIterations(SCIP_LPI *lpi, int *iterations)
Definition: lpi_cpx.c:3244
SCIP_RETCODE SCIPlpiGetColNames(SCIP_LPI *lpi, int firstcol, int lastcol, char **colnames, char *namestorage, int namestoragesize, int *storageleft)
Definition: lpi_cpx.c:1887
SCIP_RETCODE SCIPlpiEndStrongbranch(SCIP_LPI *lpi)
Definition: lpi_cpx.c:2578
SCIP_RETCODE SCIPlpiGetBInvCol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_cpx.c:3504
#define EPSZ(x, eps)
Definition: def.h:154
const char * SCIPlpiGetSolverDesc(void)
Definition: lpi_cpx.c:1013
SCIP_Bool SCIPlpiIsDualUnbounded(SCIP_LPI *lpi)
Definition: lpi_cpx.c:2958
SCIP_RETCODE SCIPlpiWriteState(SCIP_LPI *lpi, const char *fname)
Definition: lpi_cpx.c:3891