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-2016 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 
561 
562  return SCIP_OKAY;
563 }
564 
565 /** copies CPLEX parameters from source to dest */
566 static
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
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
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
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
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
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
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
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
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
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
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
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 #if (CPX_VERSION >= 12050000)
1560  CHECK_ZERO( lpi->messagehdlr, CPXchgobjsen(lpi->cpxenv, lpi->cpxlp, cpxObjsen(objsen)) );
1561 #else
1562  CPXchgobjsen(lpi->cpxenv, lpi->cpxlp, cpxObjsen(objsen));
1563 #endif
1564 
1565  return SCIP_OKAY;
1566 }
1567 
1568 /** changes objective values of columns in the LP */
1570  SCIP_LPI* lpi, /**< LP interface structure */
1571  int ncols, /**< number of columns to change objective value for */
1572  int* ind, /**< column indices to change objective value for */
1573  SCIP_Real* obj /**< new objective values for columns */
1574  )
1575 {
1576  assert(lpi != NULL);
1577  assert(lpi->cpxlp != NULL);
1578  assert(lpi->cpxenv != NULL);
1579 
1580  SCIPdebugMessage("changing %d objective values in CPLEX\n", ncols);
1581 
1582  CHECK_ZERO( lpi->messagehdlr, CPXchgobj(lpi->cpxenv, lpi->cpxlp, ncols, ind, obj) );
1583 
1584  return SCIP_OKAY;
1585 }
1586 
1587 /** multiplies a row with a non-zero scalar; for negative scalars, the row's sense is switched accordingly */
1589  SCIP_LPI* lpi, /**< LP interface structure */
1590  int row, /**< row number to scale */
1591  SCIP_Real scaleval /**< scaling multiplier */
1592  )
1593 {
1594  SCIP_Real lhs;
1595  SCIP_Real rhs;
1596  int nnonz;
1597  int beg;
1598  int i;
1599 
1600  assert(lpi != NULL);
1601  assert(lpi->cpxlp != NULL);
1602  assert(lpi->cpxenv != NULL);
1603  assert(scaleval != 0.0);
1604 
1605  SCIPdebugMessage("scaling row %d with factor %g in CPLEX\n", row, scaleval);
1606 
1607  invalidateSolution(lpi);
1608 
1609  SCIP_CALL( ensureValMem(lpi, CPXgetnumcols(lpi->cpxenv, lpi->cpxlp)) );
1610 
1611  /* get the row */
1612  SCIP_CALL( SCIPlpiGetRows(lpi, row, row, &lhs, &rhs, &nnonz, &beg, lpi->indarray, lpi->valarray) );
1613 
1614  /* scale row coefficients */
1615  for( i = 0; i < nnonz; ++i )
1616  {
1617  SCIP_CALL( SCIPlpiChgCoef(lpi, row, lpi->indarray[i], lpi->valarray[i] * scaleval) );
1618  }
1619 
1620  /* scale row sides */
1621  if( lhs > -CPX_INFBOUND )
1622  lhs *= scaleval;
1623  else if( scaleval < 0.0 )
1624  lhs = CPX_INFBOUND;
1625  if( rhs < CPX_INFBOUND )
1626  rhs *= scaleval;
1627  else if( scaleval < 0.0 )
1628  rhs = -CPX_INFBOUND;
1629  if( scaleval > 0.0 )
1630  {
1631  SCIP_CALL( SCIPlpiChgSides(lpi, 1, &row, &lhs, &rhs) );
1632  }
1633  else
1634  {
1635  SCIP_CALL( SCIPlpiChgSides(lpi, 1, &row, &rhs, &lhs) );
1636  }
1637 
1638  return SCIP_OKAY;
1639 }
1640 
1641 /** multiplies a column with a non-zero scalar; the objective value is multiplied with the scalar, and the bounds
1642  * are divided by the scalar; for negative scalars, the column's bounds are switched
1643  */
1645  SCIP_LPI* lpi, /**< LP interface structure */
1646  int col, /**< column number to scale */
1647  SCIP_Real scaleval /**< scaling multiplier */
1648  )
1649 {
1650  SCIP_Real lb;
1651  SCIP_Real ub;
1652  SCIP_Real obj;
1653  int nnonz;
1654  int beg;
1655  int i;
1656 
1657  assert(lpi != NULL);
1658  assert(lpi->cpxlp != NULL);
1659  assert(lpi->cpxenv != NULL);
1660  assert(scaleval != 0.0);
1661 
1662  SCIPdebugMessage("scaling column %d with factor %g in CPLEX\n", col, scaleval);
1663 
1664  invalidateSolution(lpi);
1665 
1666  SCIP_CALL( ensureValMem(lpi, CPXgetnumrows(lpi->cpxenv, lpi->cpxlp)) );
1667 
1668  /* get the column */
1669  SCIP_CALL( SCIPlpiGetCols(lpi, col, col, &lb, &ub, &nnonz, &beg, lpi->indarray, lpi->valarray) );
1670 
1671  /* get objective coefficient */
1672  SCIP_CALL( SCIPlpiGetObj(lpi, col, col, &obj) );
1673 
1674  /* scale column coefficients */
1675  for( i = 0; i < nnonz; ++i )
1676  {
1677  SCIP_CALL( SCIPlpiChgCoef(lpi, lpi->indarray[i], col, lpi->valarray[i] * scaleval) );
1678  }
1679 
1680  /* scale objective value */
1681  obj *= scaleval;
1682  SCIP_CALL( SCIPlpiChgObj(lpi, 1, &col, &obj) );
1683 
1684  /* scale column bounds */
1685  if( lb > -CPX_INFBOUND )
1686  lb /= scaleval;
1687  else if( scaleval < 0.0 )
1688  lb = CPX_INFBOUND;
1689  if( ub < CPX_INFBOUND )
1690  ub /= scaleval;
1691  else if( scaleval < 0.0 )
1692  ub = -CPX_INFBOUND;
1693  if( scaleval > 0.0 )
1694  {
1695  SCIP_CALL( SCIPlpiChgBounds(lpi, 1, &col, &lb, &ub) );
1696  }
1697  else
1698  {
1699  SCIP_CALL( SCIPlpiChgBounds(lpi, 1, &col, &ub, &lb) );
1700  }
1701 
1702  return SCIP_OKAY;
1703 }
1704 
1705 /**@} */
1706 
1707 
1708 
1709 
1710 /*
1711  * Data Accessing Methods
1712  */
1713 
1714 /**@name Data Accessing Methods */
1715 /**@{ */
1716 
1717 /** gets the number of rows in the LP */
1719  SCIP_LPI* lpi, /**< LP interface structure */
1720  int* nrows /**< pointer to store the number of rows */
1721  )
1722 {
1723  assert(lpi != NULL);
1724  assert(lpi->cpxenv != NULL);
1725  assert(nrows != NULL);
1726 
1727  SCIPdebugMessage("getting number of rows\n");
1728 
1729  *nrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
1730 
1731  return SCIP_OKAY;
1732 }
1733 
1734 /** gets the number of columns in the LP */
1736  SCIP_LPI* lpi, /**< LP interface structure */
1737  int* ncols /**< pointer to store the number of cols */
1738  )
1739 {
1740  assert(lpi != NULL);
1741  assert(lpi->cpxenv != NULL);
1742  assert(ncols != NULL);
1743 
1744  SCIPdebugMessage("getting number of columns\n");
1745 
1746  *ncols = CPXgetnumcols(lpi->cpxenv, lpi->cpxlp);
1747 
1748  return SCIP_OKAY;
1749 }
1750 
1751 /** gets the number of nonzero elements in the LP constraint matrix */
1753  SCIP_LPI* lpi, /**< LP interface structure */
1754  int* nnonz /**< pointer to store the number of nonzeros */
1755  )
1756 {
1757  assert(lpi != NULL);
1758  assert(lpi->cpxenv != NULL);
1759  assert(nnonz != NULL);
1760 
1761  SCIPdebugMessage("getting number of non-zeros\n");
1762 
1763  *nnonz = CPXgetnumnz(lpi->cpxenv, lpi->cpxlp);
1764 
1765  return SCIP_OKAY;
1766 }
1767 
1768 /** gets columns from LP problem object; the arrays have to be large enough to store all values
1769  * Either both, lb and ub, have to be NULL, or both have to be non-NULL,
1770  * either nnonz, beg, ind, and val have to be NULL, or all of them have to be non-NULL.
1771  */
1773  SCIP_LPI* lpi, /**< LP interface structure */
1774  int firstcol, /**< first column to get from LP */
1775  int lastcol, /**< last column to get from LP */
1776  SCIP_Real* lb, /**< buffer to store the lower bound vector, or NULL */
1777  SCIP_Real* ub, /**< buffer to store the upper bound vector, or NULL */
1778  int* nnonz, /**< pointer to store the number of nonzero elements returned, or NULL */
1779  int* beg, /**< buffer to store start index of each column in ind- and val-array, or NULL */
1780  int* ind, /**< buffer to store column indices of constraint matrix entries, or NULL */
1781  SCIP_Real* val /**< buffer to store values of constraint matrix entries, or NULL */
1782  )
1783 {
1784  assert(lpi != NULL);
1785  assert(lpi->cpxlp != NULL);
1786  assert(lpi->cpxenv != NULL);
1787  assert(0 <= firstcol && firstcol <= lastcol && lastcol < CPXgetnumcols(lpi->cpxenv, lpi->cpxlp));
1788 
1789  SCIPdebugMessage("getting columns %d to %d\n", firstcol, lastcol);
1790 
1791  if( lb != NULL )
1792  {
1793  assert(ub != NULL);
1794 
1795  CHECK_ZERO( lpi->messagehdlr, CPXgetlb(lpi->cpxenv, lpi->cpxlp, lb, firstcol, lastcol) );
1796  CHECK_ZERO( lpi->messagehdlr, CPXgetub(lpi->cpxenv, lpi->cpxlp, ub, firstcol, lastcol) );
1797  }
1798  else
1799  assert(ub == NULL);
1800 
1801  if( nnonz != NULL )
1802  {
1803  int surplus;
1804 
1805  assert(beg != NULL);
1806  assert(ind != NULL);
1807  assert(val != NULL);
1808 
1809  /* get matrix entries */
1810  CHECK_ZERO( lpi->messagehdlr, CPXgetcols(lpi->cpxenv, lpi->cpxlp, nnonz, beg, ind, val,
1811  CPXgetnumnz(lpi->cpxenv, lpi->cpxlp), &surplus, firstcol, lastcol) );
1812  assert(surplus >= 0);
1813  }
1814  else
1815  {
1816  assert(beg == NULL);
1817  assert(ind == NULL);
1818  assert(val == NULL);
1819  }
1820 
1821  return SCIP_OKAY;
1822 }
1823 
1824 /** gets rows from LP problem object; the arrays have to be large enough to store all values.
1825  * Either both, lhs and rhs, have to be NULL, or both have to be non-NULL,
1826  * either nnonz, beg, ind, and val have to be NULL, or all of them have to be non-NULL.
1827  */
1829  SCIP_LPI* lpi, /**< LP interface structure */
1830  int firstrow, /**< first row to get from LP */
1831  int lastrow, /**< last row to get from LP */
1832  SCIP_Real* lhs, /**< buffer to store left hand side vector, or NULL */
1833  SCIP_Real* rhs, /**< buffer to store right hand side vector, or NULL */
1834  int* nnonz, /**< pointer to store the number of nonzero elements returned, or NULL */
1835  int* beg, /**< buffer to store start index of each row in ind- and val-array, or NULL */
1836  int* ind, /**< buffer to store row indices of constraint matrix entries, or NULL */
1837  SCIP_Real* val /**< buffer to store values of constraint matrix entries, or NULL */
1838  )
1839 {
1840  int retcode;
1841 
1842  assert(lpi != NULL);
1843  assert(lpi->cpxlp != NULL);
1844  assert(lpi->cpxenv != NULL);
1845  assert(0 <= firstrow && firstrow <= lastrow && lastrow < CPXgetnumrows(lpi->cpxenv, lpi->cpxlp));
1846 
1847  SCIPdebugMessage("getting rows %d to %d\n", firstrow, lastrow);
1848 
1849  if( lhs != NULL || rhs != NULL )
1850  {
1851  /* get row sense, rhs, and ranges */
1852  SCIP_CALL( ensureSidechgMem(lpi, lastrow - firstrow + 1) );
1853  CHECK_ZERO( lpi->messagehdlr, CPXgetsense(lpi->cpxenv, lpi->cpxlp, lpi->senarray, firstrow, lastrow) );
1854  CHECK_ZERO( lpi->messagehdlr, CPXgetrhs(lpi->cpxenv, lpi->cpxlp, lpi->rhsarray, firstrow, lastrow) );
1855  retcode = CPXgetrngval(lpi->cpxenv, lpi->cpxlp, lpi->rngarray, firstrow, lastrow);
1856  if( retcode != CPXERR_NO_RNGVAL ) /* ignore "No range values" error */
1857  {
1858  CHECK_ZERO( lpi->messagehdlr, retcode );
1859  }
1860  else
1861  BMSclearMemoryArray(lpi->rngarray, lastrow-firstrow+1);
1862 
1863  /* convert sen/rhs/range into lhs/rhs tuples */
1864  reconvertSides(lpi, lastrow - firstrow + 1, lhs, rhs);
1865  }
1866 
1867  if( nnonz != NULL )
1868  {
1869  int surplus;
1870 
1871  assert(beg != NULL);
1872  assert(ind != NULL);
1873  assert(val != NULL);
1874 
1875  /* get matrix entries */
1876  CHECK_ZERO( lpi->messagehdlr, CPXgetrows(lpi->cpxenv, lpi->cpxlp, nnonz, beg, ind, val,
1877  CPXgetnumnz(lpi->cpxenv, lpi->cpxlp), &surplus, firstrow, lastrow) );
1878  assert(surplus >= 0);
1879  }
1880  else
1881  {
1882  assert(beg == NULL);
1883  assert(ind == NULL);
1884  assert(val == NULL);
1885  }
1886 
1887  return SCIP_OKAY;
1888 }
1889 
1890 /** gets column names */
1892  SCIP_LPI* lpi, /**< LP interface structure */
1893  int firstcol, /**< first column to get name from LP */
1894  int lastcol, /**< last column to get name from LP */
1895  char** colnames, /**< pointers to column names (of size at least lastcol-firstcol+1) */
1896  char* namestorage, /**< storage for col names */
1897  int namestoragesize, /**< size of namestorage (if 0, storageleft returns the storage needed) */
1898  int* storageleft /**< amount of storage left (if < 0 the namestorage was not big enough) */
1899  )
1900 {
1901  int retcode;
1902 
1903  assert(lpi != NULL);
1904  assert(lpi->cpxlp != NULL);
1905  assert(lpi->cpxenv != NULL);
1906  assert(colnames != NULL || namestoragesize == 0);
1907  assert(namestorage != NULL || namestoragesize == 0);
1908  assert(namestoragesize >= 0);
1909  assert(storageleft != NULL);
1910  assert(0 <= firstcol && firstcol <= lastcol && lastcol < CPXgetnumcols(lpi->cpxenv, lpi->cpxlp));
1911 
1912  SCIPdebugMessage("getting column names %d to %d\n", firstcol, lastcol);
1913 
1914  retcode = CPXgetcolname(lpi->cpxenv, lpi->cpxlp, colnames, namestorage, namestoragesize, storageleft, firstcol, lastcol);
1915  assert( namestoragesize != 0 || retcode == CPXERR_NEGATIVE_SURPLUS );
1916  if( namestoragesize != 0 )
1917  {
1918  CHECK_ZERO( lpi->messagehdlr, retcode );
1919  }
1920 
1921  return SCIP_OKAY;
1922 }
1923 
1924 /** gets row names */
1926  SCIP_LPI* lpi, /**< LP interface structure */
1927  int firstrow, /**< first row to get name from LP */
1928  int lastrow, /**< last row to get name from LP */
1929  char** rownames, /**< pointers to row names (of size at least lastrow-firstrow+1) */
1930  char* namestorage, /**< storage for row names */
1931  int namestoragesize, /**< size of namestorage (if 0, -storageleft returns the storage needed) */
1932  int* storageleft /**< amount of storage left (if < 0 the namestorage was not big enough) */
1933  )
1934 {
1935  int retcode;
1936 
1937  assert(lpi != NULL);
1938  assert(lpi->cpxlp != NULL);
1939  assert(lpi->cpxenv != NULL);
1940  assert(rownames != NULL || namestoragesize == 0);
1941  assert(namestorage != NULL || namestoragesize == 0);
1942  assert(namestoragesize >= 0);
1943  assert(storageleft != NULL);
1944  assert(0 <= firstrow && firstrow <= lastrow && lastrow < CPXgetnumrows(lpi->cpxenv, lpi->cpxlp));
1945 
1946  SCIPdebugMessage("getting row names %d to %d\n", firstrow, lastrow);
1947 
1948  retcode = CPXgetrowname(lpi->cpxenv, lpi->cpxlp, rownames, namestorage, namestoragesize, storageleft, firstrow, lastrow);
1949  assert( namestoragesize != 0 || retcode == CPXERR_NEGATIVE_SURPLUS );
1950  if( namestoragesize != 0 )
1951  {
1952  CHECK_ZERO( lpi->messagehdlr, retcode );
1953  }
1954 
1955  return SCIP_OKAY;
1956 }
1957 
1958 /** gets objective sense of the LP */
1960  SCIP_LPI* lpi, /**< LP interface structure */
1961  SCIP_OBJSEN* objsen /**< pointer to store objective sense */
1962  )
1963 {
1964  assert(lpi != NULL);
1965  assert(objsen != NULL);
1966  assert(CPXgetobjsen(lpi->cpxenv, lpi->cpxlp) == CPX_MIN || CPXgetobjsen(lpi->cpxenv, lpi->cpxlp) == CPX_MAX);
1967 
1968  SCIPdebugMessage("getting objective sense\n");
1969 
1970  *objsen = (CPXgetobjsen(lpi->cpxenv, lpi->cpxlp) == CPX_MIN) ? SCIP_OBJSEN_MINIMIZE : SCIP_OBJSEN_MAXIMIZE;
1971 
1972  return SCIP_OKAY;
1973 }
1974 
1975 /** gets objective coefficients from LP problem object */
1977  SCIP_LPI* lpi, /**< LP interface structure */
1978  int firstcol, /**< first column to get objective coefficient for */
1979  int lastcol, /**< last column to get objective coefficient for */
1980  SCIP_Real* vals /**< array to store objective coefficients */
1981  )
1982 {
1983  assert(lpi != NULL);
1984  assert(lpi->cpxlp != NULL);
1985  assert(lpi->cpxenv != NULL);
1986  assert(firstcol <= lastcol);
1987  assert(vals != NULL);
1988 
1989  SCIPdebugMessage("getting objective values %d to %d\n", firstcol, lastcol);
1990 
1991  CHECK_ZERO( lpi->messagehdlr, CPXgetobj(lpi->cpxenv, lpi->cpxlp, vals, firstcol, lastcol) );
1992 
1993  return SCIP_OKAY;
1994 }
1995 
1996 /** gets current bounds from LP problem object */
1998  SCIP_LPI* lpi, /**< LP interface structure */
1999  int firstcol, /**< first column to get bounds for */
2000  int lastcol, /**< last column to get bounds for */
2001  SCIP_Real* lbs, /**< array to store lower bound values, or NULL */
2002  SCIP_Real* ubs /**< array to store upper bound values, or NULL */
2003  )
2004 {
2005  assert(lpi != NULL);
2006  assert(lpi->cpxlp != NULL);
2007  assert(lpi->cpxenv != NULL);
2008  assert(firstcol <= lastcol);
2009 
2010  SCIPdebugMessage("getting bounds %d to %d\n", firstcol, lastcol);
2011 
2012  if( lbs != NULL )
2013  {
2014  CHECK_ZERO( lpi->messagehdlr, CPXgetlb(lpi->cpxenv, lpi->cpxlp, lbs, firstcol, lastcol) );
2015  }
2016 
2017  if( ubs != NULL )
2018  {
2019  CHECK_ZERO( lpi->messagehdlr, CPXgetub(lpi->cpxenv, lpi->cpxlp, ubs, firstcol, lastcol) );
2020  }
2021 
2022  return SCIP_OKAY;
2023 }
2024 
2025 /** gets current row sides from LP problem object */
2027  SCIP_LPI* lpi, /**< LP interface structure */
2028  int firstrow, /**< first row to get sides for */
2029  int lastrow, /**< last row to get sides for */
2030  SCIP_Real* lhss, /**< array to store left hand side values, or NULL */
2031  SCIP_Real* rhss /**< array to store right hand side values, or NULL */
2032  )
2033 {
2034  int retval;
2035 
2036  assert(lpi != NULL);
2037  assert(lpi->cpxlp != NULL);
2038  assert(lpi->cpxenv != NULL);
2039  assert(firstrow <= lastrow);
2040 
2041  SCIPdebugMessage("getting row sides %d to %d\n", firstrow, lastrow);
2042 
2043  /* get row sense, rhs, and ranges */
2044  SCIP_CALL( ensureSidechgMem(lpi, lastrow - firstrow + 1) );
2045  CHECK_ZERO( lpi->messagehdlr, CPXgetsense(lpi->cpxenv, lpi->cpxlp, lpi->senarray, firstrow, lastrow) );
2046  CHECK_ZERO( lpi->messagehdlr, CPXgetrhs(lpi->cpxenv, lpi->cpxlp, lpi->rhsarray, firstrow, lastrow) );
2047  retval = CPXgetrngval(lpi->cpxenv, lpi->cpxlp, lpi->rngarray, firstrow, lastrow);
2048  if( retval != CPXERR_NO_RNGVAL ) /* ignore "No range values" error */
2049  {
2050  CHECK_ZERO( lpi->messagehdlr, retval );
2051  }
2052  else
2053  BMSclearMemoryArray(lpi->rngarray, lastrow-firstrow+1);
2054 
2055  /* convert sen/rhs/range into lhs/rhs tuples */
2056  reconvertSides(lpi, lastrow - firstrow + 1, lhss, rhss);
2057 
2058  return SCIP_OKAY;
2059 }
2060 
2061 /** gets a single coefficient */
2063  SCIP_LPI* lpi, /**< LP interface structure */
2064  int row, /**< row number of coefficient */
2065  int col, /**< column number of coefficient */
2066  SCIP_Real* val /**< pointer to store the value of the coefficient */
2067  )
2068 {
2069  assert(lpi != NULL);
2070  assert(lpi->cpxlp != NULL);
2071  assert(lpi->cpxenv != NULL);
2072 
2073  SCIPdebugMessage("getting coefficient of row %d col %d\n", row, col);
2074 
2075  CHECK_ZERO( lpi->messagehdlr, CPXgetcoef(lpi->cpxenv, lpi->cpxlp, row, col, val) );
2076 
2077  return SCIP_OKAY;
2078 }
2079 
2080 /**@} */
2081 
2082 
2083 
2084 
2085 /*
2086  * Solving Methods
2087  */
2088 
2089 /**@name Solving Methods */
2090 /**@{ */
2091 
2092 /** calls primal simplex to solve the LP */
2094  SCIP_LPI* lpi /**< LP interface structure */
2095  )
2096 {
2097  int retval;
2098  int primalfeasible;
2099  int dualfeasible;
2100  int solntype;
2101 
2102  assert(lpi != NULL);
2103  assert(lpi->cpxlp != NULL);
2104  assert(lpi->cpxenv != NULL);
2105 
2106  SCIPdebugMessage("calling CPLEX primal simplex: %d cols, %d rows\n",
2107  CPXgetnumcols(lpi->cpxenv, lpi->cpxlp), CPXgetnumrows(lpi->cpxenv, lpi->cpxlp));
2108 
2109  invalidateSolution(lpi);
2110 
2111  setIntParam(lpi, CPX_PARAM_ADVIND, lpi->fromscratch || lpi->clearstate ? CPX_OFF : CPX_ON);
2112  lpi->clearstate = FALSE;
2113 
2114  SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
2115 
2116  SCIPdebugMessage("calling CPXprimopt()\n");
2117  retval = CPXprimopt(lpi->cpxenv, lpi->cpxlp);
2118  lpi->iterations = CPXgetphase1cnt(lpi->cpxenv, lpi->cpxlp) + CPXgetitcnt(lpi->cpxenv, lpi->cpxlp);
2119  switch( retval )
2120  {
2121  case 0:
2122  break;
2123  case CPXERR_NO_MEMORY:
2124  return SCIP_NOMEMORY;
2125  default:
2126  return SCIP_LPERROR;
2127  }
2128 
2129  lpi->solstat = CPXgetstat(lpi->cpxenv, lpi->cpxlp);
2130  lpi->instabilityignored = FALSE;
2131  CHECK_ZERO( lpi->messagehdlr, CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, NULL, &primalfeasible, &dualfeasible) );
2132  SCIPdebugMessage(" -> CPLEX returned solstat=%d, pfeas=%d, dfeas=%d (%d iterations)\n",
2133  lpi->solstat, primalfeasible, dualfeasible, lpi->iterations);
2134 
2135  if( lpi->solstat == CPX_STAT_INForUNBD
2136  || (lpi->solstat == CPX_STAT_INFEASIBLE && !dualfeasible)
2137  || (lpi->solstat == CPX_STAT_UNBOUNDED && !primalfeasible) )
2138  {
2139  if( getIntParam(lpi, CPX_PARAM_PREIND) == CPX_ON )
2140  {
2141  /* maybe the preprocessor solved the problem; but we need a solution, so solve again without preprocessing */
2142  SCIPdebugMessage("presolver may have solved the problem -> calling CPLEX primal simplex again without presolve\n");
2143 
2144  /* switch off preprocessing */
2145  setIntParam(lpi, CPX_PARAM_PREIND, CPX_OFF);
2146  SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
2147 
2148  retval = CPXprimopt(lpi->cpxenv, lpi->cpxlp);
2149  switch( retval )
2150  {
2151  case 0:
2152  break;
2153  case CPXERR_NO_MEMORY:
2154  return SCIP_NOMEMORY;
2155  default:
2156  return SCIP_LPERROR;
2157  }
2158 
2159  lpi->iterations += CPXgetphase1cnt(lpi->cpxenv, lpi->cpxlp) + CPXgetitcnt(lpi->cpxenv, lpi->cpxlp);
2160  lpi->solstat = CPXgetstat(lpi->cpxenv, lpi->cpxlp);
2161  lpi->instabilityignored = FALSE;
2162  SCIPdebugMessage(" -> CPLEX returned solstat=%d (%d iterations)\n", lpi->solstat, lpi->iterations);
2163 
2164  /* switch on preprocessing again */
2165  setIntParam(lpi, CPX_PARAM_PREIND, CPX_ON);
2166  }
2167 
2168  if( lpi->solstat == CPX_STAT_INForUNBD )
2169  {
2170  /* preprocessing was not the problem; issue a warning message and treat LP as infeasible */
2171  SCIPerrorMessage("CPLEX primal simplex returned CPX_STAT_INForUNBD after presolving was turned off\n");
2172  }
2173  }
2174 
2175  /* check whether the solution is basic: if Cplex, e.g., hits a time limit in data setup, this might not be the case,
2176  * also for some pathological cases of infeasibility, e.g., contradictory bounds
2177  */
2178  if( lpi->solstat == CPX_STAT_OPTIMAL )
2179  {
2180 #ifdef NDEBUG
2181  lpi->solisbasic = TRUE;
2182 #else
2183  CHECK_ZERO( lpi->messagehdlr, CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, &solntype, NULL, NULL) );
2184  lpi->solisbasic = (solntype == CPX_BASIC_SOLN);
2185  assert(lpi->solisbasic);
2186 #endif
2187  }
2188  else
2189  {
2190  CHECK_ZERO( lpi->messagehdlr, CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, &solntype, NULL, NULL) );
2191  lpi->solisbasic = (solntype == CPX_BASIC_SOLN);
2192  }
2193 
2194  return SCIP_OKAY;
2195 }
2196 
2197 /** calls dual simplex to solve the LP */
2199  SCIP_LPI* lpi /**< LP interface structure */
2200  )
2201 {
2202  int retval;
2203  int primalfeasible;
2204  int dualfeasible;
2205  int solntype;
2206 
2207  assert(lpi != NULL);
2208  assert(lpi->cpxlp != NULL);
2209  assert(lpi->cpxenv != NULL);
2210 
2211  SCIPdebugMessage("calling CPLEX dual simplex: %d cols, %d rows\n",
2212  CPXgetnumcols(lpi->cpxenv, lpi->cpxlp), CPXgetnumrows(lpi->cpxenv, lpi->cpxlp));
2213 
2214  invalidateSolution(lpi);
2215 
2216  setIntParam(lpi, CPX_PARAM_ADVIND, lpi->fromscratch || lpi->clearstate ? CPX_OFF : CPX_ON);
2217  lpi->clearstate = FALSE;
2218 
2219  SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
2220 
2221  SCIPdebugMessage("calling CPXdualopt()\n");
2222  retval = CPXdualopt(lpi->cpxenv, lpi->cpxlp);
2223  lpi->iterations = CPXgetphase1cnt(lpi->cpxenv, lpi->cpxlp) + CPXgetitcnt(lpi->cpxenv, lpi->cpxlp);
2224  switch( retval )
2225  {
2226  case 0:
2227  break;
2228  case CPXERR_NO_MEMORY:
2229  return SCIP_NOMEMORY;
2230  default:
2231  return SCIP_LPERROR;
2232  }
2233 
2234  CHECK_ZERO( lpi->messagehdlr, CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, &solntype, NULL, NULL) );
2235 
2236  lpi->solstat = CPXgetstat(lpi->cpxenv, lpi->cpxlp);
2237  lpi->instabilityignored = FALSE;
2238  CHECK_ZERO( lpi->messagehdlr, CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, NULL, &primalfeasible, &dualfeasible) );
2239  SCIPdebugMessage(" -> CPLEX returned solstat=%d, pfeas=%d, dfeas=%d (%d iterations)\n",
2240  lpi->solstat, primalfeasible, dualfeasible, lpi->iterations);
2241 
2242  if( lpi->solstat == CPX_STAT_INForUNBD
2243  || (lpi->solstat == CPX_STAT_INFEASIBLE && !dualfeasible)
2244  || (lpi->solstat == CPX_STAT_UNBOUNDED && !primalfeasible) )
2245  {
2246  if( getIntParam(lpi, CPX_PARAM_PREIND) == CPX_ON )
2247  {
2248  /* maybe the preprocessor solved the problem; but we need a solution, so solve again without preprocessing */
2249  SCIPdebugMessage("presolver may have solved the problem -> calling CPLEX dual simplex again without presolve\n");
2250 
2251  /* switch off preprocessing */
2252  setIntParam(lpi, CPX_PARAM_PREIND, CPX_OFF);
2253  SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
2254 
2255  retval = CPXdualopt(lpi->cpxenv, lpi->cpxlp);
2256  switch( retval )
2257  {
2258  case 0:
2259  break;
2260  case CPXERR_NO_MEMORY:
2261  return SCIP_NOMEMORY;
2262  default:
2263  return SCIP_LPERROR;
2264  }
2265 
2266  lpi->iterations += CPXgetphase1cnt(lpi->cpxenv, lpi->cpxlp) + CPXgetitcnt(lpi->cpxenv, lpi->cpxlp);
2267  lpi->solstat = CPXgetstat(lpi->cpxenv, lpi->cpxlp);
2268  lpi->instabilityignored = FALSE;
2269  CHECK_ZERO( lpi->messagehdlr, CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, NULL, &primalfeasible, &dualfeasible) );
2270  SCIPdebugMessage(" -> CPLEX returned solstat=%d (%d iterations)\n", lpi->solstat, lpi->iterations);
2271 
2272  /* switch on preprocessing again */
2273  setIntParam(lpi, CPX_PARAM_PREIND, CPX_ON);
2274  }
2275 
2276  if( lpi->solstat == CPX_STAT_INForUNBD )
2277  {
2278  /* preprocessing was not the problem; issue a warning message and treat LP as infeasible */
2279  SCIPerrorMessage("CPLEX dual simplex returned CPX_STAT_INForUNBD after presolving was turned off\n");
2280  }
2281  }
2282 
2283  /* check whether the solution is basic: if Cplex, e.g., hits a time limit in data setup, this might not be the case,
2284  * also for some pathological cases of infeasibility, e.g., contradictory bounds
2285  */
2286  if( lpi->solstat == CPX_STAT_OPTIMAL )
2287  {
2288 #ifdef NDEBUG
2289  lpi->solisbasic = TRUE;
2290 #else
2291  CHECK_ZERO( lpi->messagehdlr, CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, &solntype, NULL, NULL) );
2292  lpi->solisbasic = (solntype == CPX_BASIC_SOLN);
2293  assert(lpi->solisbasic);
2294 #endif
2295  }
2296  else
2297  {
2298  CHECK_ZERO( lpi->messagehdlr, CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, &solntype, NULL, NULL) );
2299  lpi->solisbasic = (solntype == CPX_BASIC_SOLN);
2300  }
2301 
2302 #if 0
2303  /* this fixes the strange behavior of CPLEX, that in case of the objective limit exceedance, it returns the
2304  * solution for the basis preceeding the one with exceeding objective limit
2305  * (using this "wrong" dual solution can cause column generation algorithms to fail to find an improving column)
2306  */
2307  if( SCIPlpiIsObjlimExc(lpi) )
2308  {
2309  SCIP_Real objval;
2310  SCIP_Real llim;
2311  SCIP_Real ulim;
2312  SCIP_Real eps;
2313 
2314  /* check, if the dual solution returned by CPLEX really exceeds the objective limit;
2315  * CPLEX usually returns the basis one iteration before the one that exceeds the limit
2316  */
2317  SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
2318  llim = getDblParam(lpi, CPX_PARAM_OBJLLIM);
2319  ulim = getDblParam(lpi, CPX_PARAM_OBJULIM);
2320  eps = getDblParam(lpi, CPX_PARAM_EPOPT);
2321  if( objval >= llim - eps && objval <= ulim + eps )
2322  {
2323  int itlim;
2324  int advind;
2325 
2326  /* perform one additional simplex iteration without objective limit */
2327  SCIPdebugMessage("dual solution %g does not exceed objective limit [%g,%g] (%d iterations) -> calling CPLEX dual simplex again for one iteration\n",
2328  objval, llim, ulim, lpi->iterations);
2329  itlim = getIntParam(lpi, CPX_PARAM_ITLIM);
2330  setIntParam(lpi, CPX_PARAM_ITLIM, 1);
2331  advind = getIntParam(lpi, CPX_PARAM_ADVIND);
2332  setIntParam(lpi, CPX_PARAM_ADVIND, CPX_ON);
2333  setDblParam(lpi, CPX_PARAM_OBJLLIM, -CPX_INFBOUND);
2334  setDblParam(lpi, CPX_PARAM_OBJULIM, CPX_INFBOUND);
2335  SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
2336  CHECK_ZERO( lpi->messagehdlr, CPXsetintparam(lpi->cpxenv, CPX_PARAM_FINALFACTOR, FALSE) );
2337 
2338  retval = CPXdualopt(lpi->cpxenv, lpi->cpxlp);
2339  switch( retval )
2340  {
2341  case 0:
2342  break;
2343  case CPXERR_NO_MEMORY:
2344  return SCIP_NOMEMORY;
2345  default:
2346  return SCIP_LPERROR;
2347  }
2348 
2349  lpi->iterations += CPXgetphase1cnt(lpi->cpxenv, lpi->cpxlp) + CPXgetitcnt(lpi->cpxenv, lpi->cpxlp);
2350 
2351  /* reset the iteration limit and objective bounds */
2352  setIntParam(lpi, CPX_PARAM_ITLIM, itlim);
2353  setIntParam(lpi, CPX_PARAM_ADVIND, advind);
2354  setDblParam(lpi, CPX_PARAM_OBJLLIM, llim);
2355  setDblParam(lpi, CPX_PARAM_OBJULIM, ulim);
2356  SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
2357  CHECK_ZERO( lpi->messagehdlr, CPXsetintparam(lpi->cpxenv, CPX_PARAM_FINALFACTOR, TRUE) );
2358 
2359  /* resolve LP again in order to restore the status of exceeded objective limit */
2360  retval = CPXdualopt(lpi->cpxenv, lpi->cpxlp);
2361  switch( retval )
2362  {
2363  case 0:
2364  break;
2365  case CPXERR_NO_MEMORY:
2366  return SCIP_NOMEMORY;
2367  default:
2368  return SCIP_LPERROR;
2369  }
2370 
2371  lpi->iterations += CPXgetphase1cnt(lpi->cpxenv, lpi->cpxlp) + CPXgetitcnt(lpi->cpxenv, lpi->cpxlp);
2372  lpi->solstat = CPXgetstat(lpi->cpxenv, lpi->cpxlp);
2373  lpi->instabilityignored = FALSE;
2374  SCIPdebugMessage(" -> CPLEX returned solstat=%d (%d iterations)\n", lpi->solstat, lpi->iterations);
2375  }
2376  }
2377 #endif
2378 
2379  return SCIP_OKAY;
2380 }
2381 
2382 /** calls barrier or interior point algorithm to solve the LP with crossover to simplex basis */
2384  SCIP_LPI* lpi, /**< LP interface structure */
2385  SCIP_Bool crossover /**< perform crossover */
2386  )
2387 {
2388  int solntype;
2389  int retval;
2390 
2391  assert(lpi != NULL);
2392  assert(lpi->cpxlp != NULL);
2393  assert(lpi->cpxenv != NULL);
2394 
2395  SCIPdebugMessage("calling CPLEX barrier: %d cols, %d rows\n",
2396  CPXgetnumcols(lpi->cpxenv, lpi->cpxlp), CPXgetnumrows(lpi->cpxenv, lpi->cpxlp));
2397 
2398  invalidateSolution(lpi);
2399 
2400  setIntParam(lpi, CPX_PARAM_ADVIND, lpi->fromscratch || lpi->clearstate ? CPX_OFF : CPX_ON);
2401  lpi->clearstate = FALSE;
2402 
2403  SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
2404 
2405  SCIPdebugMessage("calling CPXhybaropt()\n");
2406  retval = CPXhybbaropt(lpi->cpxenv, lpi->cpxlp, crossover ? 0 : CPX_ALG_NONE);
2407  lpi->iterations = CPXgetbaritcnt(lpi->cpxenv, lpi->cpxlp);
2408  switch( retval )
2409  {
2410  case 0:
2411  break;
2412  case CPXERR_NO_MEMORY:
2413  return SCIP_NOMEMORY;
2414  default:
2415  return SCIP_LPERROR;
2416  }
2417 
2418  CHECK_ZERO( lpi->messagehdlr, CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, &solntype, NULL, NULL) );
2419 
2420  lpi->solisbasic = (solntype == CPX_BASIC_SOLN);
2421  lpi->solstat = CPXgetstat(lpi->cpxenv, lpi->cpxlp);
2422  lpi->instabilityignored = FALSE;
2423  SCIPdebugMessage(" -> CPLEX returned solstat=%d (%d iterations)\n", lpi->solstat, lpi->iterations);
2424 
2425  if( lpi->solstat == CPX_STAT_INForUNBD )
2426  {
2427  /* maybe the preprocessor solved the problem; but we need a solution, so solve again without preprocessing */
2428  SCIPdebugMessage("CPLEX returned INForUNBD -> calling CPLEX barrier again without presolve\n");
2429 
2430  /* switch off preprocessing */
2431  setIntParam(lpi, CPX_PARAM_PREIND, CPX_OFF);
2432  SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
2433 
2434  retval = CPXhybbaropt(lpi->cpxenv, lpi->cpxlp, crossover ? 0 : CPX_ALG_NONE);
2435  switch( retval )
2436  {
2437  case 0:
2438  break;
2439  case CPXERR_NO_MEMORY:
2440  return SCIP_NOMEMORY;
2441  default:
2442  return SCIP_LPERROR;
2443  }
2444 
2445  CHECK_ZERO( lpi->messagehdlr, CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, &solntype, NULL, NULL) );
2446 
2447  lpi->solisbasic = (solntype == CPX_BASIC_SOLN);
2448  lpi->iterations += CPXgetbaritcnt(lpi->cpxenv, lpi->cpxlp);
2449  lpi->solstat = CPXgetstat(lpi->cpxenv, lpi->cpxlp);
2450  lpi->instabilityignored = FALSE;
2451  SCIPdebugMessage(" -> CPLEX returned solstat=%d\n", lpi->solstat);
2452 
2453  if( lpi->solstat == CPX_STAT_INForUNBD )
2454  {
2455  /* preprocessing was not the problem; issue a warning message and treat LP as infeasible */
2456  SCIPerrorMessage("CPLEX barrier returned CPX_STAT_INForUNBD after presolving was turned off\n");
2457  }
2458 
2459  setIntParam(lpi, CPX_PARAM_PREIND, CPX_ON);
2460  }
2461 
2462  return SCIP_OKAY;
2463 }
2464 
2465 /** manually performs strong branching on one integral variable */
2466 static
2468  SCIP_LPI* lpi, /**< LP interface structure */
2469  int col, /**< column to apply strong branching on */
2470  SCIP_Real psol, /**< current integral primal solution value of column */
2471  int itlim, /**< iteration limit for strong branchings */
2472  SCIP_Real* down, /**< stores dual bound after branching column down */
2473  SCIP_Real* up, /**< stores dual bound after branching column up */
2474  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
2475  * otherwise, it can only be used as an estimate value */
2476  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
2477  * otherwise, it can only be used as an estimate value */
2478  int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
2479  )
2480 {
2481  const char lbound = 'L';
2482  const char ubound = 'U';
2483  SCIP_Real oldlb;
2484  SCIP_Real oldub;
2485  SCIP_Real newlb;
2486  SCIP_Real newub;
2487  int objsen;
2488  int olditlim;
2489  int it;
2490 
2491  SCIPdebugMessage(" -> strong branching on integral variable %d\n", col);
2492 
2493  assert( EPSISINT(psol, lpi->feastol) );
2494 
2495  objsen = CPXgetobjsen(lpi->cpxenv, lpi->cpxlp);
2496 
2497  /* results of CPLEX are valid in any case */
2498  *downvalid = TRUE;
2499  *upvalid = TRUE;
2500 
2501  /* save current LP basis and bounds*/
2502  SCIP_CALL( getBase(lpi) );
2503  CHECK_ZERO( lpi->messagehdlr, CPXgetlb(lpi->cpxenv, lpi->cpxlp, &oldlb, col, col) );
2504  CHECK_ZERO( lpi->messagehdlr, CPXgetub(lpi->cpxenv, lpi->cpxlp, &oldub, col, col) );
2505 
2506  /* save old iteration limit and set iteration limit to strong branching limit */
2507  if( itlim > CPX_INT_MAX )
2508  itlim = CPX_INT_MAX;
2509  olditlim = getIntParam(lpi, CPX_PARAM_ITLIM);
2510  setIntParam(lpi, CPX_PARAM_ITLIM, itlim);
2511 
2512  /* down branch */
2513  newub = EPSCEIL(psol-1.0, lpi->feastol);
2514  if( newub >= oldlb - 0.5 )
2515  {
2516  CHECK_ZERO( lpi->messagehdlr, CPXchgbds(lpi->cpxenv, lpi->cpxlp, 1, &col, &ubound, &newub) );
2517  SCIP_CALL( SCIPlpiSolveDual(lpi) );
2519  *down = objsen == CPX_MIN ? getDblParam(lpi, CPX_PARAM_OBJULIM) : getDblParam(lpi, CPX_PARAM_OBJLLIM);
2520  else if( SCIPlpiIsOptimal(lpi) || SCIPlpiIsIterlimExc(lpi) )
2521  {
2522  SCIP_CALL( SCIPlpiGetObjval(lpi, down) );
2523  }
2524  else
2525  *down = objsen == CPX_MIN ? getDblParam(lpi, CPX_PARAM_OBJLLIM) : getDblParam(lpi, CPX_PARAM_OBJULIM);
2526  if( iter != NULL )
2527  {
2528  SCIP_CALL( SCIPlpiGetIterations(lpi, &it) );
2529  *iter += it;
2530  }
2531  SCIPdebugMessage(" -> down (x%d <= %g): %g\n", col, newub, *down);
2532 
2533  CHECK_ZERO( lpi->messagehdlr, CPXchgbds(lpi->cpxenv, lpi->cpxlp, 1, &col, &ubound, &oldub) );
2534  SCIP_CALL( setBase(lpi) );
2535  }
2536  else
2537  *down = objsen == CPX_MIN ? getDblParam(lpi, CPX_PARAM_OBJULIM) : getDblParam(lpi, CPX_PARAM_OBJLLIM);
2538 
2539  /* up branch */
2540  newlb = EPSFLOOR(psol+1.0, lpi->feastol);
2541  if( newlb <= oldub + 0.5 )
2542  {
2543  CHECK_ZERO( lpi->messagehdlr, CPXchgbds(lpi->cpxenv, lpi->cpxlp, 1, &col, &lbound, &newlb) );
2544  SCIP_CALL( SCIPlpiSolveDual(lpi) );
2546  *up = objsen == CPX_MIN ? getDblParam(lpi, CPX_PARAM_OBJULIM) : getDblParam(lpi, CPX_PARAM_OBJLLIM);
2547  else if( SCIPlpiIsOptimal(lpi) || SCIPlpiIsIterlimExc(lpi) )
2548  {
2549  SCIP_CALL( SCIPlpiGetObjval(lpi, up) );
2550  }
2551  else
2552  *up = objsen == CPX_MIN ? getDblParam(lpi, CPX_PARAM_OBJLLIM) : getDblParam(lpi, CPX_PARAM_OBJULIM);
2553  if( iter != NULL )
2554  {
2555  SCIP_CALL( SCIPlpiGetIterations(lpi, &it) );
2556  *iter += it;
2557  }
2558  SCIPdebugMessage(" -> up (x%d >= %g): %g\n", col, newlb, *up);
2559 
2560  CHECK_ZERO( lpi->messagehdlr, CPXchgbds(lpi->cpxenv, lpi->cpxlp, 1, &col, &lbound, &oldlb) );
2561  SCIP_CALL( setBase(lpi) );
2562  }
2563  else
2564  *up = objsen == CPX_MIN ? getDblParam(lpi, CPX_PARAM_OBJLLIM) : getDblParam(lpi, CPX_PARAM_OBJULIM);
2565 
2566  /* reset iteration limit */
2567  setIntParam(lpi, CPX_PARAM_ITLIM, olditlim);
2568 
2569  return SCIP_OKAY;
2570 }
2571 
2572 /** start strong branching */
2574  SCIP_LPI* lpi /**< LP interface structure */
2575  )
2576 { /*lint --e{715}*/
2577  /* no work necessary */
2578  return SCIP_OKAY;
2579 }
2580 
2581 /** end strong branching */
2583  SCIP_LPI* lpi /**< LP interface structure */
2584  )
2585 { /*lint --e{715}*/
2586  /* no work necessary */
2587  return SCIP_OKAY;
2588 }
2589 
2590 /** performs strong branching iterations on one @b fractional candidate */
2592  SCIP_LPI* lpi, /**< LP interface structure */
2593  int col, /**< column to apply strong branching on */
2594  SCIP_Real psol, /**< fractional current primal solution value of column */
2595  int itlim, /**< iteration limit for strong branchings */
2596  SCIP_Real* down, /**< stores dual bound after branching column down */
2597  SCIP_Real* up, /**< stores dual bound after branching column up */
2598  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
2599  * otherwise, it can only be used as an estimate value */
2600  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
2601  * otherwise, it can only be used as an estimate value */
2602  int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
2603  )
2604 {
2605  int retval;
2606 
2607  assert(lpi != NULL);
2608  assert(lpi->cpxlp != NULL);
2609  assert(lpi->cpxenv != NULL);
2610  assert(down != NULL);
2611  assert(up != NULL);
2612  assert(downvalid != NULL);
2613  assert(upvalid != NULL);
2614 
2615  SCIPdebugMessage("calling CPLEX strongbranching on fractional variable %d (%d iterations)\n", col, itlim);
2616 
2617  assert( !EPSISINT(psol, lpi->feastol) );
2618 
2619  /* results of CPLEX are valid in any case */
2620  *downvalid = TRUE;
2621  *upvalid = TRUE;
2622 
2623  setIntParam(lpi, CPX_PARAM_ADVIND, lpi->fromscratch || lpi->clearstate ? CPX_OFF : CPX_ON);
2624  lpi->clearstate = FALSE;
2625 
2626  SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
2627 
2628  retval = CPXstrongbranch(lpi->cpxenv, lpi->cpxlp, &col, 1, down, up, itlim);
2629  if( retval == CPXERR_NEED_OPT_SOLN )
2630  {
2631  SCIPdebugMessage(" -> no optimal solution available\n");
2632  return SCIP_LPERROR;
2633  }
2634  else if( retval == CPXERR_TILIM_STRONGBRANCH )
2635  {
2636  SCIPdebugMessage(" -> time limit exceeded during strong branching\n");
2637  return SCIP_LPERROR;
2638  }
2639  else if( retval == CPXERR_SINGULAR )
2640  {
2641  SCIPdebugMessage(" -> numerical troubles (basis singular)\n");
2642  return SCIP_LPERROR;
2643  }
2644  CHECK_ZERO( lpi->messagehdlr, retval );
2645  SCIPdebugMessage(" -> down: %g, up:%g\n", *down, *up);
2646 
2647  /* CPLEX is not able to return the iteration counts in strong branching */
2648  if( iter != NULL )
2649  *iter = -1;
2650 
2651  return SCIP_OKAY;
2652 }
2653 
2654 /** performs strong branching iterations on given @b fractional candidates */
2656  SCIP_LPI* lpi, /**< LP interface structure */
2657  int* cols, /**< columns to apply strong branching on */
2658  int ncols, /**< number of columns */
2659  SCIP_Real* psols, /**< fractional current primal solution values of columns */
2660  int itlim, /**< iteration limit for strong branchings */
2661  SCIP_Real* down, /**< stores dual bounds after branching columns down */
2662  SCIP_Real* up, /**< stores dual bounds after branching columns up */
2663  SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds;
2664  * otherwise, they can only be used as an estimate values */
2665  SCIP_Bool* upvalid, /**< stores whether the returned up values are a valid dual bounds;
2666  * otherwise, they can only be used as an estimate values */
2667  int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
2668  )
2669 {
2670  int retval;
2671  int j;
2672 
2673  assert(lpi != NULL);
2674  assert(lpi->cpxlp != NULL);
2675  assert(lpi->cpxenv != NULL);
2676  assert(cols != NULL);
2677  assert(psols != NULL);
2678  assert(down != NULL);
2679  assert(up != NULL);
2680  assert(downvalid != NULL);
2681  assert(upvalid != NULL);
2682 
2683  SCIPdebugMessage("calling CPLEX strongbranching on %d fractional variables (%d iterations)\n", ncols, itlim);
2684 
2685  setIntParam(lpi, CPX_PARAM_ADVIND, lpi->fromscratch || lpi->clearstate ? CPX_OFF : CPX_ON);
2686  lpi->clearstate = FALSE;
2687 
2688  SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
2689 
2690  /* initialize */
2691  for( j = 0; j < ncols; ++j )
2692  {
2693  /* results of CPLEX are valid in any case */
2694  *downvalid = TRUE;
2695  *upvalid = TRUE;
2696 
2697  assert( !EPSISINT(psols[j], lpi->feastol) );
2698  }
2699 
2700  retval = CPXstrongbranch(lpi->cpxenv, lpi->cpxlp, cols, ncols, down, up, itlim);
2701  if( retval == CPXERR_NEED_OPT_SOLN )
2702  {
2703  SCIPdebugMessage(" -> no optimal solution available\n");
2704  return SCIP_LPERROR;
2705  }
2706  else if( retval == CPXERR_TILIM_STRONGBRANCH )
2707  {
2708  SCIPdebugMessage(" -> time limit exceeded during strong branching\n");
2709  return SCIP_LPERROR;
2710  }
2711  CHECK_ZERO( lpi->messagehdlr, retval );
2712 
2713  /* CPLEX is not able to return the iteration counts in strong branching */
2714  if( iter != NULL )
2715  *iter = -1;
2716 
2717  return SCIP_OKAY;
2718 }
2719 
2720 /** performs strong branching iterations on one candidate with @b integral value */
2722  SCIP_LPI* lpi, /**< LP interface structure */
2723  int col, /**< column to apply strong branching on */
2724  SCIP_Real psol, /**< current integral primal solution value of column */
2725  int itlim, /**< iteration limit for strong branchings */
2726  SCIP_Real* down, /**< stores dual bound after branching column down */
2727  SCIP_Real* up, /**< stores dual bound after branching column up */
2728  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
2729  * otherwise, it can only be used as an estimate value */
2730  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
2731  * otherwise, it can only be used as an estimate value */
2732  int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
2733  )
2734 {
2735  assert(lpi != NULL);
2736  assert(lpi->cpxlp != NULL);
2737  assert(down != NULL);
2738  assert(up != NULL);
2739  assert(downvalid != NULL);
2740  assert(upvalid != NULL);
2741 
2742  SCIPdebugMessage("calling CPLEX strongbranching on variable %d with integral value (%d iterations)\n", col, itlim);
2743 
2744  assert( EPSISINT(psol, lpi->feastol) );
2745 
2746  if( iter != NULL )
2747  *iter = 0;
2748 
2749  SCIP_CALL( lpiStrongbranchIntegral(lpi, col, psol, itlim, down, up, downvalid, upvalid, iter) );
2750 
2751  return SCIP_OKAY;
2752 }
2753 
2754 /** performs strong branching iterations on given candidates with @b integral values */
2756  SCIP_LPI* lpi, /**< LP interface structure */
2757  int* cols, /**< columns to apply strong branching on */
2758  int ncols, /**< number of columns */
2759  SCIP_Real* psols, /**< current integral primal solution values of columns */
2760  int itlim, /**< iteration limit for strong branchings */
2761  SCIP_Real* down, /**< stores dual bounds after branching columns down */
2762  SCIP_Real* up, /**< stores dual bounds after branching columns up */
2763  SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds;
2764  * otherwise, they can only be used as an estimate values */
2765  SCIP_Bool* upvalid, /**< stores whether the returned up values are a valid dual bounds;
2766  * otherwise, they can only be used as an estimate values */
2767  int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
2768  )
2769 {
2770  int j;
2771 
2772  assert(lpi != NULL);
2773  assert(lpi->cpxlp != NULL);
2774  assert(cols != NULL);
2775  assert(psols != NULL);
2776  assert(down != NULL);
2777  assert(up != NULL);
2778  assert(downvalid != NULL);
2779  assert(upvalid != NULL);
2780 
2781  SCIPdebugMessage("calling CPLEX strongbranching on %d variables with integer values (%d iterations)\n", ncols, itlim);
2782 
2783  if( iter != NULL )
2784  *iter = 0;
2785 
2786  /* initialize */
2787  for( j = 0; j < ncols; ++j )
2788  {
2789  assert( EPSISINT(psols[j], lpi->feastol) );
2790  SCIP_CALL( lpiStrongbranchIntegral(lpi, cols[j], psols[j], itlim, &(down[j]), &(up[j]), &(downvalid[j]), &(upvalid[j]), iter) );
2791  }
2792 
2793  return SCIP_OKAY;
2794 }
2795 /**@} */
2796 
2797 
2798 
2799 
2800 /*
2801  * Solution Information Methods
2802  */
2803 
2804 /**@name Solution Information Methods */
2805 /**@{ */
2806 
2807 /** returns whether a solve method was called after the last modification of the LP */
2809  SCIP_LPI* lpi /**< LP interface structure */
2810  )
2811 {
2812  assert(lpi != NULL);
2813 
2814  return (lpi->solstat != -1);
2815 }
2816 
2817 /** gets information about primal and dual feasibility of the current LP solution */
2819  SCIP_LPI* lpi, /**< LP interface structure */
2820  SCIP_Bool* primalfeasible, /**< stores primal feasibility status */
2821  SCIP_Bool* dualfeasible /**< stores dual feasibility status */
2822  )
2823 {
2824  int pfeas;
2825  int dfeas;
2826 
2827  assert(lpi != NULL);
2828  assert(lpi->cpxlp != NULL);
2829  assert(lpi->cpxenv != NULL);
2830  assert(primalfeasible != NULL);
2831  assert(dualfeasible != NULL);
2832 
2833  SCIPdebugMessage("getting solution feasibility\n");
2834 
2835  CHECK_ZERO( lpi->messagehdlr, CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, NULL, &pfeas, &dfeas) );
2836  *primalfeasible = (SCIP_Bool)pfeas;
2837  *dualfeasible = (SCIP_Bool)dfeas;
2838 
2839  return SCIP_OKAY;
2840 }
2841 
2842 /** returns TRUE iff LP is proven to have a primal unbounded ray (but not necessary a primal feasible point);
2843  * this does not necessarily mean, that the solver knows and can return the primal ray
2844  */
2846  SCIP_LPI* lpi /**< LP interface structure */
2847  )
2848 {
2849  assert(lpi != NULL);
2850  assert(lpi->cpxlp != NULL);
2851  assert(lpi->solstat >= 0);
2852 
2853  return (lpi->solstat == CPX_STAT_UNBOUNDED || lpi->solstat == CPX_STAT_OPTIMAL_FACE_UNBOUNDED);
2854 }
2855 
2856 /** returns TRUE iff LP is proven to have a primal unbounded ray (but not necessary a primal feasible point),
2857  * and the solver knows and can return the primal ray
2858  */
2860  SCIP_LPI* lpi /**< LP interface structure */
2861  )
2862 {
2863  assert(lpi != NULL);
2864  assert(lpi->cpxlp != NULL);
2865  assert(lpi->cpxenv != NULL);
2866  assert(lpi->solstat >= 0);
2867 
2868  return (lpi->solstat == CPX_STAT_UNBOUNDED && CPXgetmethod(lpi->cpxenv, lpi->cpxlp) == CPX_ALG_PRIMAL);
2869 }
2870 
2871 /** returns TRUE iff LP is proven to be primal unbounded */
2873  SCIP_LPI* lpi /**< LP interface structure */
2874  )
2875 {
2876  int primalfeasible;
2877 
2878  assert(lpi != NULL);
2879  assert(lpi->cpxlp != NULL);
2880  assert(lpi->cpxenv != NULL);
2881  assert(lpi->solstat >= 0);
2882 
2883  SCIPdebugMessage("checking for primal unboundedness\n");
2884 
2885  ABORT_ZERO( CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, NULL, &primalfeasible, NULL) );
2886 
2887  /* If the solution status of CPLEX is CPX_STAT_UNBOUNDED, it only means, there is an unbounded ray,
2888  * but not necessarily a feasible primal solution. If primalfeasible == FALSE, we cannot conclude,
2889  * that the problem is unbounded
2890  */
2891  return ((primalfeasible && (lpi->solstat == CPX_STAT_UNBOUNDED || lpi->solstat == CPX_STAT_INForUNBD))
2892  || lpi->solstat == CPX_STAT_OPTIMAL_FACE_UNBOUNDED);
2893 }
2894 
2895 /** returns TRUE iff LP is proven to be primal infeasible */
2897  SCIP_LPI* lpi /**< LP interface structure */
2898  )
2899 {
2900  int dualfeasible;
2901 
2902  assert(lpi != NULL);
2903  assert(lpi->cpxlp != NULL);
2904  assert(lpi->cpxenv != NULL);
2905  assert(lpi->solstat >= 0);
2906 
2907  SCIPdebugMessage("checking for primal infeasibility\n");
2908 
2909  ABORT_ZERO( CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, NULL, NULL, &dualfeasible) );
2910 
2911  return (lpi->solstat == CPX_STAT_INFEASIBLE || (lpi->solstat == CPX_STAT_INForUNBD && dualfeasible));
2912 }
2913 
2914 /** returns TRUE iff LP is proven to be primal feasible */
2916  SCIP_LPI* lpi /**< LP interface structure */
2917  )
2918 {
2919  int primalfeasible;
2920 
2921  assert(lpi != NULL);
2922  assert(lpi->cpxlp != NULL);
2923  assert(lpi->cpxenv != NULL);
2924  assert(lpi->solstat >= 0);
2925 
2926  SCIPdebugMessage("checking for primal feasibility\n");
2927 
2928  ABORT_ZERO( CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, NULL, &primalfeasible, NULL) );
2929 
2930  return (SCIP_Bool)primalfeasible;
2931 }
2932 
2933 /** returns TRUE iff LP is proven to have a dual unbounded ray (but not necessary a dual feasible point);
2934  * this does not necessarily mean, that the solver knows and can return the dual ray
2935  */
2937  SCIP_LPI* lpi /**< LP interface structure */
2938  )
2939 {
2940  assert(lpi != NULL);
2941  assert(lpi->solstat >= 0);
2942 
2943  return (lpi->solstat == CPX_STAT_INFEASIBLE);
2944 }
2945 
2946 /** returns TRUE iff LP is proven to have a dual unbounded ray (but not necessary a dual feasible point),
2947  * and the solver knows and can return the dual ray
2948  */
2950  SCIP_LPI* lpi /**< LP interface structure */
2951  )
2952 {
2953  assert(lpi != NULL);
2954  assert(lpi->cpxlp != NULL);
2955  assert(lpi->cpxenv != NULL);
2956  assert(lpi->solstat >= 0);
2957 
2958  return (lpi->solstat == CPX_STAT_INFEASIBLE && CPXgetmethod(lpi->cpxenv, lpi->cpxlp) == CPX_ALG_DUAL);
2959 }
2960 
2961 /** returns TRUE iff LP is proven to be dual unbounded */
2963  SCIP_LPI* lpi /**< LP interface structure */
2964  )
2965 {
2966  int dualfeasible;
2967 
2968  assert(lpi != NULL);
2969  assert(lpi->cpxlp != NULL);
2970  assert(lpi->cpxenv != NULL);
2971  assert(lpi->solstat >= 0);
2972 
2973  SCIPdebugMessage("checking for dual unboundedness\n");
2974 
2975  ABORT_ZERO( CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, NULL, NULL, &dualfeasible) );
2976 
2977  return (dualfeasible && (lpi->solstat == CPX_STAT_INFEASIBLE || lpi->solstat == CPX_STAT_INForUNBD));
2978 }
2979 
2980 /** returns TRUE iff LP is proven to be dual infeasible */
2982  SCIP_LPI* lpi /**< LP interface structure */
2983  )
2984 {
2985  int primalfeasible;
2986 
2987  assert(lpi != NULL);
2988  assert(lpi->cpxlp != NULL);
2989  assert(lpi->cpxenv != NULL);
2990  assert(lpi->solstat >= 0);
2991 
2992  SCIPdebugMessage("checking for dual infeasibility\n");
2993 
2994  ABORT_ZERO( CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, NULL, &primalfeasible, NULL) );
2995 
2996  return (lpi->solstat == CPX_STAT_UNBOUNDED
2997  || lpi->solstat == CPX_STAT_OPTIMAL_FACE_UNBOUNDED
2998  || (lpi->solstat == CPX_STAT_INForUNBD && primalfeasible));
2999 }
3000 
3001 /** returns TRUE iff LP is proven to be dual feasible */
3003  SCIP_LPI* lpi /**< LP interface structure */
3004  )
3005 {
3006  int dualfeasible;
3007 
3008  assert(lpi != NULL);
3009  assert(lpi->cpxlp != NULL);
3010  assert(lpi->cpxenv != NULL);
3011  assert(lpi->solstat >= 0);
3012 
3013  SCIPdebugMessage("checking for dual feasibility\n");
3014 
3015  ABORT_ZERO( CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, NULL, NULL, &dualfeasible) );
3016 
3017  return (SCIP_Bool)dualfeasible;
3018 }
3019 
3020 /** returns TRUE iff LP was solved to optimality */
3022  SCIP_LPI* lpi /**< LP interface structure */
3023  )
3024 {
3025  assert(lpi != NULL);
3026  assert(lpi->solstat >= 0);
3027 
3028  return (lpi->solstat == CPX_STAT_OPTIMAL);
3029 }
3030 
3031 /** returns TRUE iff current LP basis is stable */
3033  SCIP_LPI* lpi /**< LP interface structure */
3034  )
3035 {
3036  assert(lpi != NULL);
3037  assert(lpi->cpxlp != NULL);
3038  assert(lpi->cpxenv != NULL);
3039  assert(lpi->solstat >= 0);
3040 
3041  SCIPdebugMessage("checking for stability: CPLEX solstat = %d\n", lpi->solstat);
3042 
3043  /* If the solution status of CPLEX is CPX_STAT_UNBOUNDED, it only means, there is an unbounded ray,
3044  * but not necessarily a feasible primal solution. If primalfeasible == FALSE, we interpret this
3045  * result as instability, s.t. the problem is resolved from scratch
3046  */
3047  if( lpi->solstat == CPX_STAT_UNBOUNDED )
3048  {
3049  int primalfeasible;
3050 
3051  ABORT_ZERO( CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, NULL, &primalfeasible, NULL) );
3052 
3053  if( !primalfeasible )
3054  return FALSE;
3055  }
3056 
3057  /* If the condition number of the basis should be checked, everything above the specified threshold is counted
3058  * as instable.
3059  */
3060  if( lpi->checkcondition && (SCIPlpiIsOptimal(lpi) || SCIPlpiIsObjlimExc(lpi)) )
3061  {
3062  SCIP_Real kappa;
3063  SCIP_RETCODE retcode;
3064 
3066  if ( retcode != SCIP_OKAY )
3067  {
3068  SCIPABORT();
3069  return FALSE; /*lint !e527*/
3070  }
3071 
3072  /* if the kappa could not be computed (e.g., because we do not have a basis), we cannot check the condition */
3073  if( kappa != SCIP_INVALID || kappa > lpi->conditionlimit ) /*lint !e777*/
3074  return FALSE;
3075  }
3076 
3077  return (lpi->solstat != CPX_STAT_NUM_BEST && lpi->solstat != CPX_STAT_OPTIMAL_INFEAS);
3078 }
3079 
3080 /** returns TRUE iff the objective limit was reached */
3082  SCIP_LPI* lpi /**< LP interface structure */
3083  )
3084 {
3085  assert(lpi != NULL);
3086  assert(lpi->solstat >= 0);
3087 
3088  return (lpi->solstat == CPX_STAT_ABORT_OBJ_LIM
3089  || lpi->solstat == CPX_STAT_ABORT_DUAL_OBJ_LIM
3090  || lpi->solstat == CPX_STAT_ABORT_PRIM_OBJ_LIM);
3091 }
3092 
3093 /** returns TRUE iff the iteration limit was reached */
3095  SCIP_LPI* lpi /**< LP interface structure */
3096  )
3097 {
3098  assert(lpi != NULL);
3099  assert(lpi->solstat >= 0);
3100 
3101  return (lpi->solstat == CPX_STAT_ABORT_IT_LIM);
3102 }
3103 
3104 /** returns TRUE iff the time limit was reached */
3106  SCIP_LPI* lpi /**< LP interface structure */
3107  )
3108 {
3109  assert(lpi != NULL);
3110  assert(lpi->solstat >= 0);
3111 
3112  return (lpi->solstat == CPX_STAT_ABORT_TIME_LIM);
3113 }
3114 
3115 /** returns the internal solution status of the solver */
3117  SCIP_LPI* lpi /**< LP interface structure */
3118  )
3119 {
3120  assert(lpi != NULL);
3121  assert(lpi->cpxlp != NULL);
3122 
3123  return lpi->solstat;
3124 }
3125 
3126 /** tries to reset the internal status of the LP solver in order to ignore an instability of the last solving call */
3128  SCIP_LPI* lpi, /**< LP interface structure */
3129  SCIP_Bool* success /**< pointer to store, whether the instability could be ignored */
3130  )
3131 {
3132  assert(lpi != NULL);
3133  assert(lpi->cpxlp != NULL);
3134  assert(success != NULL);
3135  assert(lpi->solstat == CPX_STAT_UNBOUNDED
3136  || lpi->solstat == CPX_STAT_NUM_BEST
3137  || lpi->solstat == CPX_STAT_OPTIMAL_INFEAS);
3138 
3139  /* replace instable status with optimal status */
3140  if( lpi->solstat == CPX_STAT_NUM_BEST || lpi->solstat == CPX_STAT_OPTIMAL_INFEAS )
3141  lpi->solstat = CPX_STAT_OPTIMAL;
3142 
3143  *success = TRUE;
3144  lpi->instabilityignored = TRUE;
3145 
3146  return SCIP_OKAY;
3147 }
3148 
3149 /** gets objective value of solution */
3151  SCIP_LPI* lpi, /**< LP interface structure */
3152  SCIP_Real* objval /**< stores the objective value */
3153  )
3154 {
3155  int retcode;
3156 
3157  assert(lpi != NULL);
3158  assert(lpi->cpxlp != NULL);
3159  assert(lpi->cpxenv != NULL);
3160 
3161  SCIPdebugMessage("getting solution's objective value\n");
3162 
3163  retcode = CPXgetobjval(lpi->cpxenv, lpi->cpxlp, objval);
3164 
3165  /* if CPLEX has no solution, e.g., because of a reached time limit, we return -infinity */
3166  if( retcode == CPXERR_NO_SOLN )
3167  {
3168  *objval = -SCIPlpiInfinity(lpi);
3169  }
3170  else
3171  {
3172  CHECK_ZERO( lpi->messagehdlr, retcode );
3173  }
3174 
3175  return SCIP_OKAY;
3176 }
3177 
3178 /** gets primal and dual solution vectors */
3180  SCIP_LPI* lpi, /**< LP interface structure */
3181  SCIP_Real* objval, /**< stores the objective value, may be NULL if not needed */
3182  SCIP_Real* primsol, /**< primal solution vector, may be NULL if not needed */
3183  SCIP_Real* dualsol, /**< dual solution vector, may be NULL if not needed */
3184  SCIP_Real* activity, /**< row activity vector, may be NULL if not needed */
3185  SCIP_Real* redcost /**< reduced cost vector, may be NULL if not needed */
3186  )
3187 {
3188  int dummy;
3189 
3190  assert(lpi != NULL);
3191  assert(lpi->cpxlp != NULL);
3192  assert(lpi->cpxenv != NULL);
3193  assert(lpi->solstat >= 0);
3194 
3195  SCIPdebugMessage("getting solution\n");
3196 
3197  CHECK_ZERO( lpi->messagehdlr, CPXsolution(lpi->cpxenv, lpi->cpxlp, &dummy, objval, primsol, dualsol, NULL, redcost) );
3198  assert(dummy == lpi->solstat || lpi->instabilityignored);
3199 
3200  if( activity != NULL )
3201  {
3202  CHECK_ZERO( lpi->messagehdlr, CPXgetax(lpi->cpxenv, lpi->cpxlp, activity, 0, CPXgetnumrows(lpi->cpxenv, lpi->cpxlp)-1) );
3203  }
3204 
3205  return SCIP_OKAY;
3206 }
3207 
3208 /** gets primal ray for unbounded LPs */
3210  SCIP_LPI* lpi, /**< LP interface structure */
3211  SCIP_Real* ray /**< primal ray */
3212  )
3213 {
3214  assert(lpi != NULL);
3215  assert(lpi->cpxlp != NULL);
3216  assert(lpi->cpxenv != NULL);
3217  assert(lpi->solstat >= 0);
3218 
3219  SCIPdebugMessage("calling CPLEX get primal ray: %d cols, %d rows\n",
3220  CPXgetnumcols(lpi->cpxenv, lpi->cpxlp), CPXgetnumrows(lpi->cpxenv, lpi->cpxlp));
3221 
3222  CHECK_ZERO( lpi->messagehdlr, CPXgetray(lpi->cpxenv, lpi->cpxlp, ray) );
3223 
3224  return SCIP_OKAY;
3225 }
3226 
3227 /** gets dual Farkas proof for infeasibility */
3229  SCIP_LPI* lpi, /**< LP interface structure */
3230  SCIP_Real* dualfarkas /**< dual Farkas row multipliers */
3231  )
3232 {
3233  assert(lpi != NULL);
3234  assert(lpi->cpxlp != NULL);
3235  assert(lpi->cpxenv != NULL);
3236  assert(lpi->solstat >= 0);
3237  assert(dualfarkas != NULL);
3238 
3239  SCIPdebugMessage("calling CPLEX dual Farkas: %d cols, %d rows\n",
3240  CPXgetnumcols(lpi->cpxenv, lpi->cpxlp), CPXgetnumrows(lpi->cpxenv, lpi->cpxlp));
3241 
3242  CHECK_ZERO( lpi->messagehdlr, CPXdualfarkas(lpi->cpxenv, lpi->cpxlp, dualfarkas, NULL) );
3243 
3244  return SCIP_OKAY;
3245 }
3246 
3247 /** gets the number of LP iterations of the last solve call */
3249  SCIP_LPI* lpi, /**< LP interface structure */
3250  int* iterations /**< pointer to store the number of iterations of the last solve call */
3251  )
3252 {
3253  assert(lpi != NULL);
3254  assert(iterations != NULL);
3255 
3256  *iterations = lpi->iterations;
3257 
3258  return SCIP_OKAY;
3259 }
3260 
3261 /** gets information about the quality of an LP solution
3262  *
3263  * Such information is usually only available, if also a (maybe not optimal) solution is available.
3264  * The LPI should return SCIP_INVALID for @p quality, if the requested quantity is not available.
3265  */
3267  SCIP_LPI* lpi, /**< LP interface structure */
3268  SCIP_LPSOLQUALITY qualityindicator, /**< indicates which quality should be returned */
3269  SCIP_Real* quality /**< pointer to store quality number */
3270  )
3271 {
3272  int solntype;
3273  int what;
3274 
3275  assert(lpi != NULL);
3276  assert(quality != NULL);
3277 
3278  *quality = SCIP_INVALID;
3279 
3280  SCIPdebugMessage("requesting solution quality from CPLEX: quality %d\n", qualityindicator);
3281 
3282  switch( qualityindicator )
3283  {
3285  what = CPX_KAPPA;
3286  break;
3287 
3289  what = CPX_EXACT_KAPPA;
3290  break;
3291 
3292  default:
3293  SCIPerrorMessage("Solution quality %d unknown.\n", qualityindicator);
3294  return SCIP_INVALIDDATA;
3295  }
3296 
3297  CHECK_ZERO( lpi->messagehdlr, CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, &solntype, NULL, NULL) );
3298 
3299  if( solntype == CPX_BASIC_SOLN )
3300  {
3301  CHECK_ZERO( lpi->messagehdlr, CPXgetdblquality(lpi->cpxenv, lpi->cpxlp, quality, what) );
3302  }
3303 
3304  return SCIP_OKAY;
3305 }
3306 
3307 /**@} */
3308 
3309 
3310 
3311 
3312 /*
3313  * LP Basis Methods
3314  */
3315 
3316 /**@name LP Basis Methods */
3317 /**@{ */
3318 
3319 /** gets current basis status for columns and rows; arrays must be large enough to store the basis status */
3321  SCIP_LPI* lpi, /**< LP interface structure */
3322  int* cstat, /**< array to store column basis status, or NULL */
3323  int* rstat /**< array to store row basis status, or NULL */
3324  )
3325 {
3326  int i;
3327  int nrows;
3328  char sense;
3329 
3330  assert(lpi != NULL);
3331  assert(lpi->cpxlp != NULL);
3332  assert(lpi->cpxenv != NULL);
3333 
3334  SCIPdebugMessage("saving CPLEX basis into %p/%p\n", (void *) cstat, (void *) rstat);
3335 
3336  CHECK_ZERO( lpi->messagehdlr, CPXgetbase(lpi->cpxenv, lpi->cpxlp, cstat, rstat) );
3337 
3338  /* correct rstat values for "<=" constraints: Here CPX_AT_LOWER bound means that the slack is 0, i.e., the upper bound is tight */
3339  nrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
3340  for (i = 0; i < nrows; ++i)
3341  {
3342  if ( rstat[i] == CPX_AT_LOWER )
3343  {
3344  CHECK_ZERO( lpi->messagehdlr, CPXgetsense(lpi->cpxenv, lpi->cpxlp, &sense, i, i) );
3345  if ( sense == 'L' )
3346  rstat[i] = (int) SCIP_BASESTAT_UPPER;
3347  }
3348  }
3349 
3350  /* because the basis status values are equally defined in SCIP and CPLEX, they don't need to be transformed */
3351  assert((int)SCIP_BASESTAT_LOWER == CPX_AT_LOWER);
3352  assert((int)SCIP_BASESTAT_BASIC == CPX_BASIC);
3353  assert((int)SCIP_BASESTAT_UPPER == CPX_AT_UPPER);
3354  assert((int)SCIP_BASESTAT_ZERO == CPX_FREE_SUPER);
3355 
3356  return SCIP_OKAY;
3357 }
3358 
3359 /** sets current basis status for columns and rows */
3361  SCIP_LPI* lpi, /**< LP interface structure */
3362  int* cstat, /**< array with column basis status */
3363  int* rstat /**< array with row basis status */
3364  )
3365 {
3366  int i;
3367  int nrows;
3368  char sense;
3369 
3370  assert(lpi != NULL);
3371  assert(lpi->cpxlp != NULL);
3372  assert(lpi->cpxenv != NULL);
3373  assert(cstat != NULL);
3374  assert(rstat != NULL);
3375 
3376  SCIPdebugMessage("loading basis %p/%p into CPLEX\n", (void *) cstat, (void *) rstat);
3377 
3378  invalidateSolution(lpi);
3379 
3380  /* because the basis status values are equally defined in SCIP and CPLEX, they don't need to be transformed */
3381  assert((int)SCIP_BASESTAT_LOWER == CPX_AT_LOWER);
3382  assert((int)SCIP_BASESTAT_BASIC == CPX_BASIC);
3383  assert((int)SCIP_BASESTAT_UPPER == CPX_AT_UPPER);
3384  assert((int)SCIP_BASESTAT_ZERO == CPX_FREE_SUPER);
3385 
3386  /* correct rstat values for ">=" constraints: Here CPX_AT_LOWER bound means that the slack is 0, i.e., the upper bound is tight */
3387  nrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
3388  for (i = 0; i < nrows; ++i)
3389  {
3390  if ( rstat[i] == (int) SCIP_BASESTAT_UPPER )
3391  {
3392  CHECK_ZERO( lpi->messagehdlr, CPXgetsense(lpi->cpxenv, lpi->cpxlp, &sense, i, i) );
3393  if ( sense == 'L' )
3394  rstat[i] = CPX_AT_LOWER;
3395  }
3396  }
3397 
3398  CHECK_ZERO( lpi->messagehdlr, CPXcopybase(lpi->cpxenv, lpi->cpxlp, cstat, rstat) );
3399 
3400  return SCIP_OKAY;
3401 }
3402 
3403 /** returns the indices of the basic columns and rows; basic column n gives value n, basic row m gives value -1-m */
3405  SCIP_LPI* lpi, /**< LP interface structure */
3406  int* bind /**< pointer to store basis indices ready to keep number of rows entries */
3407  )
3408 {
3409  int retval;
3410 
3411  assert(lpi != NULL);
3412  assert(lpi->cpxlp != NULL);
3413  assert(lpi->cpxenv != NULL);
3414 
3415  SCIPdebugMessage("getting basis information\n");
3416 
3417  /* this might be turned off if the user as called SCIPlpiClearState() or set SCIP_LPPAR_FROMSCRATCH to TRUE */
3418  setIntParam(lpi, CPX_PARAM_ADVIND, CPX_ON);
3419  SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
3420 
3421  retval = CPXgetbhead(lpi->cpxenv, lpi->cpxlp, bind, NULL);
3422  if( retval == CPXERR_NO_SOLN || retval == CPXERR_NO_LU_FACTOR || retval == CPXERR_NO_BASIC_SOLN || retval == CPXERR_NO_BASIS )
3423  {
3425  retval = CPXgetbhead(lpi->cpxenv, lpi->cpxlp, bind, NULL);
3426  }
3427  CHECK_ZERO( lpi->messagehdlr, retval );
3428 
3429  return SCIP_OKAY;
3430 }
3431 
3432 /** get dense row of inverse basis matrix B^-1
3433  *
3434  * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
3435  * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
3436  * see also the explanation in lpi.h.
3437  */
3439  SCIP_LPI* lpi, /**< LP interface structure */
3440  int r, /**< row number */
3441  SCIP_Real* coef, /**< pointer to store the coefficients of the row */
3442  int* inds, /**< array to store the non-zero indices */
3443  int* ninds /**< pointer to store the number of non-zero indices
3444  * (-1: if we do not store sparsity informations) */
3445  )
3446 { /*lint --e{715}*/
3447  int retval;
3448  int nrows;
3449 
3450  assert(lpi != NULL);
3451  assert(lpi->cpxlp != NULL);
3452  assert(lpi->cpxenv != NULL);
3453 
3454  SCIPdebugMessage("getting binv-row %d\n", r);
3455 
3456  /* can only return dense result */
3457  if ( ninds != NULL )
3458  *ninds = -1;
3459 
3460  /* this might be turned off if the user as called SCIPlpiClearState() or set SCIP_LPPAR_FROMSCRATCH to TRUE */
3461  setIntParam(lpi, CPX_PARAM_ADVIND, CPX_ON);
3462  SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
3463 
3464  retval = CPXbinvrow(lpi->cpxenv, lpi->cpxlp, r, coef);
3465  if( retval == CPXERR_NO_SOLN || retval == CPXERR_NO_LU_FACTOR || retval == CPXERR_NO_BASIC_SOLN || retval == CPXERR_NO_BASIS )
3466  {
3468  retval = CPXbinvrow(lpi->cpxenv, lpi->cpxlp, r, coef);
3469  }
3470  CHECK_ZERO( lpi->messagehdlr, retval );
3471 
3472  /* the LPi expects slack variables with coefficient +1; CPLEX adds slack variables with a coefficient -1 for 'G'
3473  * constraints, so we have to change the sign of the corresponding rows
3474  */
3475  nrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
3476  SCIP_CALL( ensureValMem(lpi, nrows) );
3477  CHECK_ZERO( lpi->messagehdlr, CPXgetbhead(lpi->cpxenv, lpi->cpxlp, lpi->indarray, NULL) );
3478 
3479  if( lpi->indarray[r] < 0 )
3480  {
3481  int basicrow;
3482  char rowsense;
3483 
3484  basicrow = -lpi->indarray[r] - 1;
3485  assert(basicrow >= 0);
3486  assert(basicrow < nrows);
3487 
3488  CHECK_ZERO( lpi->messagehdlr, CPXgetsense(lpi->cpxenv, lpi->cpxlp, &rowsense, basicrow, basicrow) );
3489 
3490  /* slacks for 'G' and 'R' rows are added with -1 in CPLEX */
3491  if( rowsense == 'G' || rowsense == 'R' )
3492  {
3493  int i;
3494 
3495  for( i = 0; i < nrows; i++ )
3496  coef[i] *= -1.0;
3497  }
3498  }
3499 
3500  return SCIP_OKAY;
3501 }
3502 
3503 /** get dense column of inverse basis matrix B^-1
3504  *
3505  * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
3506  * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
3507  * see also the explanation in lpi.h.
3508  */
3510  SCIP_LPI* lpi, /**< LP interface structure */
3511  int c, /**< column number of B^-1; this is NOT the number of the column in the LP;
3512  * you have to call SCIPlpiGetBasisInd() to get the array which links the
3513  * B^-1 column numbers to the row and column numbers of the LP!
3514  * c must be between 0 and nrows-1, since the basis has the size
3515  * nrows * nrows */
3516  SCIP_Real* coef, /**< pointer to store the coefficients of the column */
3517  int* inds, /**< array to store the non-zero indices */
3518  int* ninds /**< pointer to store the number of non-zero indices
3519  * (-1: if we do not store sparsity informations) */
3520  )
3521 {
3522  int retval;
3523  int nrows;
3524  int r;
3525 
3526  assert(lpi != NULL);
3527  assert(lpi->cpxlp != NULL);
3528  assert(lpi->cpxenv != NULL);
3529 
3530  SCIPdebugMessage("getting binv-col %d\n", c);
3531 
3532  /* can only return dense result */
3533  if ( ninds != NULL )
3534  *ninds = -1;
3535 
3536  /* this might be turned off if the user as called SCIPlpiClearState() or set SCIP_LPPAR_FROMSCRATCH to TRUE */
3537  setIntParam(lpi, CPX_PARAM_ADVIND, CPX_ON);
3538  SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
3539 
3540  retval = CPXbinvcol(lpi->cpxenv, lpi->cpxlp, c, coef);
3541  if( retval == CPXERR_NO_SOLN || retval == CPXERR_NO_LU_FACTOR || retval == CPXERR_NO_BASIC_SOLN || retval == CPXERR_NO_BASIS )
3542  {
3544  retval = CPXbinvcol(lpi->cpxenv, lpi->cpxlp, c, coef);
3545  }
3546  CHECK_ZERO( lpi->messagehdlr, retval );
3547 
3548  /* the LPi expects slack variables with coefficient +1; CPLEX adds slack variables with a coefficient -1 for 'G'
3549  * constraints, so we have to change the sign of the corresponding rows
3550  */
3551  nrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
3552  SCIP_CALL( ensureValMem(lpi, nrows) );
3553  CHECK_ZERO( lpi->messagehdlr, CPXgetbhead(lpi->cpxenv, lpi->cpxlp, lpi->indarray, NULL) );
3554  SCIP_CALL( ensureSidechgMem(lpi, nrows) );
3555  CHECK_ZERO( lpi->messagehdlr, CPXgetsense(lpi->cpxenv, lpi->cpxlp, lpi->senarray, 0, nrows - 1) );
3556 
3557  for( r = 0; r < nrows; r++ )
3558  {
3559  if( lpi->indarray[r] < 0 )
3560  {
3561  int basicrow;
3562 
3563  basicrow = -lpi->indarray[r] - 1;
3564  assert(basicrow >= 0);
3565  assert(basicrow < nrows);
3566 
3567  /* slacks for 'G' and 'R' rows are added with -1 in CPLEX */
3568  if( basicrow >= 0 && basicrow < nrows && (lpi->senarray[basicrow] == 'G' || lpi->senarray[basicrow] == 'R') )
3569  coef[r] *= -1.0;
3570  }
3571  }
3572 
3573  return SCIP_OKAY;
3574 }
3575 
3576 /** get dense row of inverse basis matrix times constraint matrix B^-1 * A
3577  *
3578  * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
3579  * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
3580  * see also the explanation in lpi.h.
3581  */
3583  SCIP_LPI* lpi, /**< LP interface structure */
3584  int r, /**< row number */
3585  const SCIP_Real* binvrow, /**< row in (A_B)^-1 from prior call to SCIPlpiGetBInvRow(), or NULL */
3586  SCIP_Real* coef, /**< vector to return coefficients */
3587  int* inds, /**< array to store the non-zero indices */
3588  int* ninds /**< pointer to store the number of non-zero indices
3589  * (-1: if we do not store sparsity informations) */
3590  )
3591 { /*lint --e{715}*/
3592  int retval;
3593  int nrows;
3594 
3595  assert(lpi != NULL);
3596  assert(lpi->cpxlp != NULL);
3597  assert(lpi->cpxenv != NULL);
3598 
3599  SCIPdebugMessage("getting binva-row %d\n", r);
3600 
3601  /* can only return dense result */
3602  if ( ninds != NULL )
3603  *ninds = -1;
3604 
3605  /* this might be turned off if the user as called SCIPlpiClearState() or set SCIP_LPPAR_FROMSCRATCH to TRUE */
3606  setIntParam(lpi, CPX_PARAM_ADVIND, CPX_ON);
3607  SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
3608 
3609  retval = CPXbinvarow(lpi->cpxenv, lpi->cpxlp, r, coef);
3610  if( retval == CPXERR_NO_SOLN || retval == CPXERR_NO_LU_FACTOR || retval == CPXERR_NO_BASIC_SOLN || retval == CPXERR_NO_BASIS )
3611  {
3613  retval = CPXbinvarow(lpi->cpxenv, lpi->cpxlp, r, coef);
3614  }
3615  CHECK_ZERO( lpi->messagehdlr, retval );
3616 
3617  /* the LPi expects slack variables with coefficient +1; CPLEX adds slack variables with a coefficient -1 for 'G'
3618  * constraints, so we have to change the sign of the corresponding rows
3619  */
3620  nrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
3621  SCIP_CALL( ensureValMem(lpi, nrows) );
3622  CHECK_ZERO( lpi->messagehdlr, CPXgetbhead(lpi->cpxenv, lpi->cpxlp, lpi->indarray, NULL) );
3623 
3624  if( lpi->indarray[r] < 0 )
3625  {
3626  int basicrow;
3627  char rowsense;
3628 
3629  basicrow = -lpi->indarray[r] - 1;
3630  assert(basicrow >= 0);
3631  assert(basicrow < nrows);
3632 
3633  CHECK_ZERO( lpi->messagehdlr, CPXgetsense(lpi->cpxenv, lpi->cpxlp, &rowsense, basicrow, basicrow) );
3634 
3635  /* slacks for 'G' and 'R' rows are added with -1 in CPLEX */
3636  if( rowsense == 'G' || rowsense == 'R' )
3637  {
3638  int i;
3639 
3640  for( i = 0; i < nrows; i++ )
3641  coef[i] *= -1.0;
3642  }
3643  }
3644 
3645  return SCIP_OKAY;
3646 }
3647 
3648 /** get dense column of inverse basis matrix times constraint matrix B^-1 * A
3649  *
3650  * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
3651  * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
3652  * see also the explanation in lpi.h.
3653  */
3655  SCIP_LPI* lpi, /**< LP interface structure */
3656  int c, /**< column number */
3657  SCIP_Real* coef, /**< vector to return coefficients */
3658  int* inds, /**< array to store the non-zero indices */
3659  int* ninds /**< pointer to store the number of non-zero indices
3660  * (-1: if we do not store sparsity informations) */
3661  )
3662 { /*lint --e{715}*/
3663  int retval;
3664  int nrows;
3665  int r;
3666 
3667  assert(lpi->cpxenv != NULL);
3668  assert(lpi != NULL);
3669  assert(lpi->cpxlp != NULL);
3670 
3671  SCIPdebugMessage("getting binva-col %d\n", c);
3672 
3673  /* can only return dense result */
3674  if ( ninds != NULL )
3675  *ninds = -1;
3676 
3677  /* this might be turned off if the user as called SCIPlpiClearState() or set SCIP_LPPAR_FROMSCRATCH to TRUE */
3678  setIntParam(lpi, CPX_PARAM_ADVIND, CPX_ON);
3679  SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
3680 
3681  retval = CPXbinvacol(lpi->cpxenv, lpi->cpxlp, c, coef);
3682  if( retval == CPXERR_NO_SOLN || retval == CPXERR_NO_LU_FACTOR || retval == CPXERR_NO_BASIC_SOLN || retval == CPXERR_NO_BASIS )
3683  {
3685  retval = CPXbinvacol(lpi->cpxenv, lpi->cpxlp, c, coef);
3686  }
3687  CHECK_ZERO( lpi->messagehdlr, retval );
3688 
3689  /* the LPi expects slack variables with coefficient +1; CPLEX adds slack variables with a coefficient -1 for 'G'
3690  * constraints, so we have to change the sign of the corresponding rows
3691  */
3692  nrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
3693  SCIP_CALL( ensureValMem(lpi, nrows) );
3694  CHECK_ZERO( lpi->messagehdlr, CPXgetbhead(lpi->cpxenv, lpi->cpxlp, lpi->indarray, NULL) );
3695  SCIP_CALL( ensureSidechgMem(lpi, nrows) );
3696  CHECK_ZERO( lpi->messagehdlr, CPXgetsense(lpi->cpxenv, lpi->cpxlp, lpi->senarray, 0, nrows - 1) );
3697 
3698  for( r = 0; r < nrows; r++ )
3699  {
3700  if( lpi->indarray[r] < 0 )
3701  {
3702  int basicrow;
3703 
3704  basicrow = -lpi->indarray[r] - 1;
3705  assert(basicrow >= 0);
3706  assert(basicrow < nrows);
3707 
3708  /* slacks for 'G' and 'R' rows are added with -1 in CPLEX */
3709  if( basicrow >= 0 && basicrow < nrows && (lpi->senarray[basicrow] == 'G' || lpi->senarray[basicrow] == 'R') )
3710  coef[r] *= -1.0;
3711  }
3712  }
3713 
3714  return SCIP_OKAY;
3715 }
3716 
3717 /**@} */
3718 
3719 
3720 
3721 
3722 /*
3723  * LP State Methods
3724  */
3725 
3726 /**@name LP State Methods */
3727 /**@{ */
3728 
3729 /** stores LPi state (like basis information) into lpistate object */
3731  SCIP_LPI* lpi, /**< LP interface structure */
3732  BMS_BLKMEM* blkmem, /**< block memory */
3733  SCIP_LPISTATE** lpistate /**< pointer to LPi state information (like basis information) */
3734  )
3735 {
3736  int ncols;
3737  int nrows;
3738 
3739  assert(blkmem != NULL);
3740  assert(lpi != NULL);
3741  assert(lpi->cpxlp != NULL);
3742  assert(lpi->cpxenv != NULL);
3743  assert(lpistate != NULL);
3744 
3745  /* if there is no basis information available (e.g. after barrier without crossover), or no state can be saved; if
3746  * SCIPlpiClearState() has been called, do not return the state
3747  */
3748  if( !lpi->solisbasic || lpi->clearstate )
3749  {
3750  *lpistate = NULL;
3751  return SCIP_OKAY;
3752  }
3753 
3754  ncols = CPXgetnumcols(lpi->cpxenv, lpi->cpxlp);
3755  nrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
3756  assert(ncols >= 0);
3757  assert(nrows >= 0);
3758 
3759  /* allocate lpistate data */
3760  SCIP_CALL( lpistateCreate(lpistate, blkmem, ncols, nrows) );
3761 
3762  SCIPdebugMessage("storing CPLEX LPI state in %p (%d cols, %d rows)\n", (void *) *lpistate, ncols, nrows);
3763 
3764  /* get unpacked basis information from CPLEX */
3765  SCIP_CALL( getBase(lpi) );
3766 
3767  /* pack LPi state data */
3768  (*lpistate)->ncols = ncols;
3769  (*lpistate)->nrows = nrows;
3770  lpistatePack(*lpistate, lpi->cstat, lpi->rstat);
3771 
3772  return SCIP_OKAY;
3773 }
3774 
3775 /** loads LPi state (like basis information) into solver; note that the LP might have been extended with additional
3776  * columns and rows since the state was stored with SCIPlpiGetState()
3777  */
3779  SCIP_LPI* lpi, /**< LP interface structure */
3780  BMS_BLKMEM* blkmem, /**< block memory */
3781  SCIP_LPISTATE* lpistate /**< LPi state information (like basis information) */
3782  )
3783 {
3784  int lpncols;
3785  int lpnrows;
3786  int i;
3787 
3788  assert(blkmem != NULL);
3789  assert(lpi != NULL);
3790  assert(lpi->cpxlp != NULL);
3791  assert(lpi->cpxenv != NULL);
3792 
3793  /* if there was no basis information available, the LPI state was not stored */
3794  if( lpistate == NULL )
3795  return SCIP_OKAY;
3796 
3797  lpncols = CPXgetnumcols(lpi->cpxenv, lpi->cpxlp);
3798  lpnrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
3799  assert(lpistate->ncols <= lpncols);
3800  assert(lpistate->nrows <= lpnrows);
3801 
3802  SCIPdebugMessage("loading LPI state %p (%d cols, %d rows) into CPLEX LP with %d cols and %d rows\n",
3803  (void *) lpistate, lpistate->ncols, lpistate->nrows, lpncols, lpnrows);
3804 
3805  if( lpistate->ncols == 0 || lpistate->nrows == 0 )
3806  return SCIP_OKAY;
3807 
3808  /* allocate enough memory for storing uncompressed basis information */
3809  SCIP_CALL( ensureCstatMem(lpi, lpncols) );
3810  SCIP_CALL( ensureRstatMem(lpi, lpnrows) );
3811 
3812  /* unpack LPi state data */
3813  lpistateUnpack(lpistate, lpi->cstat, lpi->rstat);
3814 
3815  /* extend the basis to the current LP beyond the previously existing columns */
3816  for( i = lpistate->ncols; i < lpncols; ++i )
3817  {
3818  SCIP_Real bnd;
3819  CHECK_ZERO( lpi->messagehdlr, CPXgetlb(lpi->cpxenv, lpi->cpxlp, &bnd, i, i) );
3820  if ( SCIPlpiIsInfinity(lpi, REALABS(bnd)) )
3821  {
3822  /* if lower bound is +/- infinity -> try upper bound */
3823  CHECK_ZERO( lpi->messagehdlr, CPXgetub(lpi->cpxenv, lpi->cpxlp, &bnd, i, i) );
3824  if ( SCIPlpiIsInfinity(lpi, REALABS(bnd)) )
3825  lpi->cstat[i] = (int) SCIP_BASESTAT_ZERO; /* variable is free -> super basic */
3826  else
3827  lpi->cstat[i] = (int) SCIP_BASESTAT_UPPER; /* use finite upper bound */
3828  }
3829  else
3830  lpi->cstat[i] = (int) SCIP_BASESTAT_LOWER; /* use finite lower bound */
3831  }
3832  for( i = lpistate->nrows; i < lpnrows; ++i )
3833  lpi->rstat[i] = (int) SCIP_BASESTAT_BASIC;
3834 
3835  /* load basis information into CPLEX */
3836  SCIP_CALL( setBase(lpi) );
3837 
3838  return SCIP_OKAY;
3839 }
3840 
3841 /** clears current LPi state (like basis information) of the solver */
3843  SCIP_LPI* lpi /**< LP interface structure */
3844  )
3845 {
3846  assert(lpi != NULL);
3847 
3848  /* set CPX_PARAM_ADVIND to CPX_OFF for the next solve */
3849  lpi->clearstate = TRUE;
3850 
3851  return SCIP_OKAY;
3852 }
3853 
3854 /** frees LPi state information */
3856  SCIP_LPI* lpi, /**< LP interface structure */
3857  BMS_BLKMEM* blkmem, /**< block memory */
3858  SCIP_LPISTATE** lpistate /**< pointer to LPi state information (like basis information) */
3859  )
3860 {
3861  assert(lpi != NULL);
3862  assert(lpistate != NULL);
3863 
3864  if( *lpistate != NULL )
3865  {
3866  lpistateFree(lpistate, blkmem);
3867  }
3868 
3869  return SCIP_OKAY;
3870 }
3871 
3872 /** checks, whether the given LP state contains simplex basis information */
3874  SCIP_LPI* lpi, /**< LP interface structure */
3875  SCIP_LPISTATE* lpistate /**< LP state information (like basis information) */
3876  )
3877 { /*lint --e{715}*/
3878  return (lpistate != NULL);
3879 }
3880 
3881 /** reads LP state (like basis information from a file */
3883  SCIP_LPI* lpi, /**< LP interface structure */
3884  const char* fname /**< file name */
3885  )
3886 {
3887  assert(lpi != NULL);
3888  assert(lpi->cpxlp != NULL);
3889  assert(lpi->cpxenv != NULL);
3890 
3891  SCIPdebugMessage("reading LP state from file <%s>\n", fname);
3892 
3893  CHECK_ZERO( lpi->messagehdlr, CPXreadcopybase(lpi->cpxenv, lpi->cpxlp, fname) );
3894 
3895  return SCIP_OKAY;
3896 }
3897 
3898 /** writes LP state (like basis information) to a file */
3900  SCIP_LPI* lpi, /**< LP interface structure */
3901  const char* fname /**< file name */
3902  )
3903 {
3904  assert(lpi != NULL);
3905  assert(lpi->cpxlp != NULL);
3906  assert(lpi->cpxenv != NULL);
3907 
3908  SCIPdebugMessage("writing LP state to file <%s>\n", fname);
3909 
3910  CHECK_ZERO( lpi->messagehdlr, CPXmbasewrite(lpi->cpxenv, lpi->cpxlp, fname) );
3911 
3912  return SCIP_OKAY;
3913 }
3914 
3915 /**@} */
3916 
3917 
3918 
3919 
3920 /*
3921  * LP Pricing Norms Methods
3922  */
3923 
3924 /**@name LP Pricing Norms Methods */
3925 /**@{ */
3926 
3927 /** stores LPi pricing norms information
3928  *
3929  * @todo store primal norms as well?
3930  */
3932  SCIP_LPI* lpi, /**< LP interface structure */
3933  BMS_BLKMEM* blkmem, /**< block memory */
3934  SCIP_LPINORMS** lpinorms /**< pointer to LPi pricing norms information */
3935  )
3936 {
3937  int nrows;
3938  int retval;
3939 
3940  assert(blkmem != NULL);
3941  assert(lpi != NULL);
3942  assert(lpi->cpxlp != NULL);
3943  assert(lpi->cpxenv != NULL);
3944  assert(lpi->messagehdlr != NULL);
3945  assert(lpinorms != NULL);
3946 
3947  /* if there is no basis information available (e.g. after barrier without crossover), norms cannot be saved; if
3948  * SCIPlpiClearState() has been called, do not return the state
3949  */
3950  if( !lpi->solisbasic || lpi->clearstate )
3951  {
3952  *lpinorms = NULL;
3953  return SCIP_OKAY;
3954  }
3955 
3956  nrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
3957  assert(nrows >= 0);
3958 
3959  /* allocate lpinorms data */
3960  SCIP_ALLOC( BMSallocBlockMemory(blkmem, lpinorms) );
3961  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpinorms)->norm, nrows) );
3962  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpinorms)->head, nrows) );
3963  (*lpinorms)->normlen = 0;
3964 
3965  SCIPdebugMessage("storing CPLEX LPI pricing norms in %p (%d rows)\n", (void *) *lpinorms, nrows);
3966 
3967  /* get dual norms */
3968  retval = CPXgetdnorms(lpi->cpxenv, lpi->cpxlp, (*lpinorms)->norm, (*lpinorms)->head, &((*lpinorms)->normlen));
3969 
3970  /* if CPLEX used the primal simplex in the last optimization call, we do not have dual norms (error 1264) */
3971  if( retval == 1264 )
3972  {
3973  /* no norms available, free lpinorms data */
3974  BMSfreeBlockMemoryArray(blkmem, &(*lpinorms)->head, nrows);
3975  BMSfreeBlockMemoryArray(blkmem, &(*lpinorms)->norm, nrows);
3976  BMSfreeBlockMemory(blkmem, lpinorms);
3977  assert(*lpinorms == NULL);
3978  }
3979  else
3980  {
3981  assert((*lpinorms)->normlen == nrows);
3982  CHECK_ZERO( lpi->messagehdlr, retval );
3983  }
3984 
3985  return SCIP_OKAY;
3986 }
3987 
3988 /** loads LPi pricing norms into solver; note that the LP might have been extended with additional
3989  * columns and rows since the state was stored with SCIPlpiGetNorms()
3990  */
3992  SCIP_LPI* lpi, /**< LP interface structure */
3993  BMS_BLKMEM* blkmem, /**< block memory */
3994  SCIP_LPINORMS* lpinorms /**< LPi pricing norms information */
3995  )
3996 {
3997  int lpnrows;
3998 
3999  assert(blkmem != NULL);
4000  assert(lpi != NULL);
4001  assert(lpi->cpxlp != NULL);
4002  assert(lpi->cpxenv != NULL);
4003 
4004  /* if there was no pricing norms information available, the LPI norms were not stored */
4005  if( lpinorms == NULL )
4006  return SCIP_OKAY;
4007 
4008  lpnrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
4009  assert(lpinorms->normlen <= lpnrows);
4010 
4011  SCIPdebugMessage("loading LPI simplex norms %p (%d rows) into CPLEX LP with %d rows\n",
4012  (void *) lpinorms, lpinorms->normlen, lpnrows);
4013 
4014  if( lpinorms->normlen == 0 )
4015  return SCIP_OKAY;
4016 
4017  /* load pricing norms information into CPLEX */
4018  CHECK_ZERO( lpi->messagehdlr, CPXcopydnorms(lpi->cpxenv, lpi->cpxlp, lpinorms->norm, lpinorms->head, lpinorms->normlen) );
4019 
4020  return SCIP_OKAY;
4021 }
4022 
4023 /** frees pricing norms information */
4025  SCIP_LPI* lpi, /**< LP interface structure */
4026  BMS_BLKMEM* blkmem, /**< block memory */
4027  SCIP_LPINORMS** lpinorms /**< pointer to LPi pricing norms information */
4028  )
4029 {
4030  assert(lpi != NULL);
4031  assert(lpinorms != NULL);
4032 
4033  BMSfreeBlockMemoryArray(blkmem, &(*lpinorms)->head, (*lpinorms)->normlen);
4034  BMSfreeBlockMemoryArray(blkmem, &(*lpinorms)->norm, (*lpinorms)->normlen);
4035  BMSfreeBlockMemory(blkmem, lpinorms);
4036 
4037  return SCIP_OKAY;
4038 }
4039 
4040 /**@} */
4041 
4042 
4043 
4044 
4045 /*
4046  * Parameter Methods
4047  */
4048 
4049 /**@name Parameter Methods */
4050 /**@{ */
4051 
4052 /** gets integer parameter of LP */
4054  SCIP_LPI* lpi, /**< LP interface structure */
4055  SCIP_LPPARAM type, /**< parameter number */
4056  int* ival /**< buffer to store the parameter value */
4057  )
4058 {
4059  assert(lpi != NULL);
4060  assert(lpi->cpxlp != NULL);
4061  assert(ival != NULL);
4062 
4063  SCIPdebugMessage("getting int parameter %d\n", type);
4064 
4065  switch( type )
4066  {
4068  *ival = (int) lpi->fromscratch;
4069  break;
4070 #if (CPX_VERSION < 12060100)
4071  case SCIP_LPPAR_FASTMIP:
4072  *ival = getIntParam(lpi, CPX_PARAM_FASTMIP);
4073  break;
4074 #endif
4075  case SCIP_LPPAR_SCALING:
4076 #if (CPX_VERSION <= 1100)
4077  if( lpi->rngfound )
4078  return SCIP_PARAMETERUNKNOWN;
4079 #endif
4080  *ival = (getIntParam(lpi, CPX_PARAM_SCAIND) == 0);
4081  break;
4082  case SCIP_LPPAR_PRESOLVING:
4083  *ival = (getIntParam(lpi, CPX_PARAM_PREIND) == CPX_ON);
4084  break;
4085  case SCIP_LPPAR_PRICING:
4086  *ival = (int)lpi->pricing; /* store pricing method in LPI struct */
4087  break;
4088 #if 0
4089  case SCIP_LPPAR_PRICING:
4090  switch( getIntParam(lpi, CPX_PARAM_PPRIIND) )
4091  {
4092  case CPX_PPRIIND_FULL:
4093  *ival = (int)SCIP_PRICING_FULL;
4094  break;
4095  case CPX_PPRIIND_PARTIAL:
4096  *ival = (int)SCIP_PRICING_PARTIAL;
4097  break;
4098  case CPX_PPRIIND_STEEP:
4099  *ival = (int)SCIP_PRICING_STEEP;
4100  break;
4101  case CPX_PPRIIND_STEEPQSTART:
4102  *ival = (int)SCIP_PRICING_STEEPQSTART;
4103  break;
4104 #if (CPX_VERSION >= 900)
4105  case CPX_PPRIIND_DEVEX:
4106  *ival = (int)SCIP_PRICING_DEVEX;
4107  break;
4108 #endif
4109  default:
4110  *ival = (int)SCIP_PRICING_AUTO;
4111  break;
4112  }
4113  break;
4114 #endif
4115  case SCIP_LPPAR_LPINFO:
4116  *ival = (getIntParam(lpi, CPX_PARAM_SCRIND) == CPX_ON);
4117  break;
4118  case SCIP_LPPAR_LPITLIM:
4119  *ival = getIntParam(lpi, CPX_PARAM_ITLIM);
4120 #if (CPX_VERSION <= 1230)
4121  if( *ival >= CPX_INT_MAX )
4122  *ival = INT_MAX;
4123 #endif
4124  break;
4125  case SCIP_LPPAR_THREADS:
4126 #if (CPX_VERSION == 1100 || (CPX_VERSION == 1220 && (CPX_SUBVERSION == 0 || CPX_SUBVERSION == 2)))
4127  /* Due to CPLEX bug, we always set the thread count to 1. In order to fulfill an assert in lp.c, we have to
4128  * return the value set by SCIP and not the real thread count */
4129  *ival = lpi->pseudonthreads;
4130  assert(getIntParam(lpi, CPX_PARAM_THREADS) == 1);
4131 #else
4132  *ival = getIntParam(lpi, CPX_PARAM_THREADS);
4133 #endif
4134  break;
4135  default:
4136  return SCIP_PARAMETERUNKNOWN;
4137  } /*lint !e788*/
4138 
4139  return SCIP_OKAY;
4140 }
4141 
4142 /** sets integer parameter of LP */
4144  SCIP_LPI* lpi, /**< LP interface structure */
4145  SCIP_LPPARAM type, /**< parameter number */
4146  int ival /**< parameter value */
4147  )
4148 {
4149  assert(lpi != NULL);
4150  assert(lpi->cpxlp != NULL);
4151 
4152  SCIPdebugMessage("setting int parameter %d to %d\n", type, ival);
4153 
4154  switch( type )
4155  {
4157  assert(ival == TRUE || ival == FALSE);
4158  lpi->fromscratch = ival;
4159  break;
4160 #if (CPX_VERSION < 12060100)
4161  case SCIP_LPPAR_FASTMIP:
4162  assert(0 <= ival && ival <= 1);
4163  setIntParam(lpi, CPX_PARAM_FASTMIP, ival);
4164  break;
4165 #endif
4166  case SCIP_LPPAR_SCALING:
4167  assert(ival == TRUE || ival == FALSE);
4168 #if (CPX_VERSION <= 1100)
4169  if( lpi->rngfound )
4170  return SCIP_PARAMETERUNKNOWN;
4171 #endif
4172  setIntParam(lpi, CPX_PARAM_SCAIND, ival == TRUE ? 0 : -1);
4173  break;
4174  case SCIP_LPPAR_PRESOLVING:
4175  assert(ival == TRUE || ival == FALSE);
4176  setIntParam(lpi, CPX_PARAM_PREIND, ival == TRUE ? CPX_ON : CPX_OFF);
4177  break;
4178  case SCIP_LPPAR_PRICING:
4179  lpi->pricing = (SCIP_PRICING)ival;
4180  switch( (SCIP_PRICING)ival )
4181  {
4182  case SCIP_PRICING_AUTO:
4183  setIntParam(lpi, CPX_PARAM_PPRIIND, CPX_PPRIIND_AUTO);
4184  setIntParam(lpi, CPX_PARAM_DPRIIND, CPX_DPRIIND_AUTO);
4185  break;
4186  case SCIP_PRICING_FULL:
4187  setIntParam(lpi, CPX_PARAM_PPRIIND, CPX_PPRIIND_FULL);
4188  setIntParam(lpi, CPX_PARAM_DPRIIND, CPX_DPRIIND_FULL);
4189  break;
4190  case SCIP_PRICING_PARTIAL:
4191  setIntParam(lpi, CPX_PARAM_PPRIIND, CPX_PPRIIND_PARTIAL);
4192  setIntParam(lpi, CPX_PARAM_DPRIIND, CPX_DPRIIND_AUTO);
4193  break;
4195  case SCIP_PRICING_STEEP:
4196  setIntParam(lpi, CPX_PARAM_PPRIIND, CPX_PPRIIND_STEEP);
4197  setIntParam(lpi, CPX_PARAM_DPRIIND, CPX_DPRIIND_STEEP);
4198  break;
4200  setIntParam(lpi, CPX_PARAM_PPRIIND, CPX_PPRIIND_STEEPQSTART);
4201  setIntParam(lpi, CPX_PARAM_DPRIIND, CPX_DPRIIND_STEEPQSTART);
4202  break;
4203 #if (CPX_VERSION >= 900)
4204  case SCIP_PRICING_DEVEX:
4205  setIntParam(lpi, CPX_PARAM_PPRIIND, CPX_PPRIIND_DEVEX);
4206  setIntParam(lpi, CPX_PARAM_DPRIIND, CPX_DPRIIND_DEVEX);
4207  break;
4208 #endif
4209  default:
4210  return SCIP_LPERROR;
4211  }
4212  break;
4213  case SCIP_LPPAR_LPINFO:
4214  assert(ival == TRUE || ival == FALSE);
4215  if( ival )
4216  setIntParam(lpi, CPX_PARAM_SCRIND, CPX_ON);
4217  else
4218  setIntParam(lpi, CPX_PARAM_SCRIND, CPX_OFF);
4219  break;
4220  case SCIP_LPPAR_LPITLIM:
4221 #if (CPX_VERSION <= 1230)
4222  ival = MIN(ival, CPX_INT_MAX);
4223 #endif
4224  setIntParam(lpi, CPX_PARAM_ITLIM, ival);
4225  break;
4226  case SCIP_LPPAR_THREADS:
4227 #if (CPX_VERSION == 1100 || (CPX_VERSION == 1220 && (CPX_SUBVERSION == 0 || CPX_SUBVERSION == 2)))
4228  /* Due to CPLEX bug, we always set the thread count to 1. In order to fulfill an assert in lp.c, we have to
4229  * store the value set by SCIP and return it later instead of the real thread count */
4230  lpi->pseudonthreads = ival;
4231  ival = 1;
4232 #else
4233  ival = MIN(ival, CPX_INT_MAX);
4234 #endif
4235  setIntParam(lpi, CPX_PARAM_THREADS, ival);
4236  break;
4237  default:
4238  return SCIP_PARAMETERUNKNOWN;
4239  } /*lint !e788*/
4240 
4241  return SCIP_OKAY;
4242 }
4243 
4244 /** gets floating point parameter of LP */
4246  SCIP_LPI* lpi, /**< LP interface structure */
4247  SCIP_LPPARAM type, /**< parameter number */
4248  SCIP_Real* dval /**< buffer to store the parameter value */
4249  )
4250 {
4251  assert(lpi != NULL);
4252  assert(lpi->cpxlp != NULL);
4253  assert(dval != NULL);
4254 
4255  SCIPdebugMessage("getting real parameter %d\n", type);
4256 
4257  switch( type )
4258  {
4259  case SCIP_LPPAR_FEASTOL:
4260  *dval = getDblParam(lpi, CPX_PARAM_EPRHS);
4261  break;
4263  *dval = getDblParam(lpi, CPX_PARAM_EPOPT);
4264  break;
4266  *dval = getDblParam(lpi, CPX_PARAM_BAREPCOMP);
4267  break;
4268  case SCIP_LPPAR_LOBJLIM:
4269  *dval = getDblParam(lpi, CPX_PARAM_OBJLLIM);
4270  break;
4271  case SCIP_LPPAR_UOBJLIM:
4272  *dval = getDblParam(lpi, CPX_PARAM_OBJULIM);
4273  break;
4274  case SCIP_LPPAR_LPTILIM:
4275  *dval = getDblParam(lpi, CPX_PARAM_TILIM);
4276  break;
4277  case SCIP_LPPAR_MARKOWITZ:
4278  *dval = getDblParam(lpi, CPX_PARAM_EPMRK);
4279  break;
4281  *dval = lpi->conditionlimit;
4282  break;
4283  default:
4284  return SCIP_PARAMETERUNKNOWN;
4285  } /*lint !e788*/
4286 
4287  return SCIP_OKAY;
4288 }
4289 
4290 /** sets floating point parameter of LP */
4292  SCIP_LPI* lpi, /**< LP interface structure */
4293  SCIP_LPPARAM type, /**< parameter number */
4294  SCIP_Real dval /**< parameter value */
4295  )
4296 {
4297  assert(lpi != NULL);
4298  assert(lpi->cpxlp != NULL);
4299 
4300  SCIPdebugMessage("setting real parameter %d to %.15g\n", type, dval);
4301 
4302  switch( type )
4303  {
4304  case SCIP_LPPAR_FEASTOL:
4305  setDblParam(lpi, CPX_PARAM_EPRHS, dval);
4306  lpi->feastol = dval;
4307  break;
4309  setDblParam(lpi, CPX_PARAM_EPOPT, dval);
4310  break;
4312  setDblParam(lpi, CPX_PARAM_BAREPCOMP, dval);
4313  break;
4314  case SCIP_LPPAR_LOBJLIM:
4315  setDblParam(lpi, CPX_PARAM_OBJLLIM, dval);
4316  break;
4317  case SCIP_LPPAR_UOBJLIM:
4318  setDblParam(lpi, CPX_PARAM_OBJULIM, dval);
4319  break;
4320  case SCIP_LPPAR_LPTILIM:
4321  setDblParam(lpi, CPX_PARAM_TILIM, dval);
4322  break;
4323  case SCIP_LPPAR_MARKOWITZ:
4324  setDblParam(lpi, CPX_PARAM_EPMRK, dval);
4325  break;
4327  lpi->conditionlimit = dval;
4328  lpi->checkcondition = (dval >= 0);
4329  break;
4330  default:
4331  return SCIP_PARAMETERUNKNOWN;
4332  } /*lint !e788*/
4333 
4334  return SCIP_OKAY;
4335 }
4336 
4337 /**@} */
4338 
4339 
4340 
4341 
4342 /*
4343  * Numerical Methods
4344  */
4345 
4346 /**@name Numerical Methods */
4347 /**@{ */
4348 
4349 /** returns value treated as infinity in the LP solver */
4351  SCIP_LPI* lpi /**< LP interface structure */
4352  )
4353 { /*lint --e{715}*/
4354  return CPX_INFBOUND;
4355 }
4356 
4357 /** checks if given value is treated as infinity in the LP solver */
4359  SCIP_LPI* lpi, /**< LP interface structure */
4360  SCIP_Real val /**< value to be checked for infinity */
4361  )
4362 { /*lint --e{715}*/
4363  return (val >= CPX_INFBOUND);
4364 }
4365 
4366 /**@} */
4367 
4368 
4369 
4370 
4371 /*
4372  * File Interface Methods
4373  */
4374 
4375 /**@name File Interface Methods */
4376 /**@{ */
4377 
4378 /** reads LP from a file */
4380  SCIP_LPI* lpi, /**< LP interface structure */
4381  const char* fname /**< file name */
4382  )
4383 {
4384  int restat;
4385 
4386  assert(lpi != NULL);
4387  assert(lpi->cpxlp != NULL);
4388  assert(lpi->cpxenv != NULL);
4389 
4390  SCIPdebugMessage("reading LP from file <%s>\n", fname);
4391 
4392  restat = CPXreadcopyprob(lpi->cpxenv, lpi->cpxlp, fname, NULL);
4393  if( restat != 0 )
4394  {
4395  SCIPerrorMessage("LP Error: CPLEX returned %d\n", restat);
4396  return SCIP_READERROR;
4397  }
4398 
4399  return SCIP_OKAY;
4400 }
4401 
4402 /** writes LP to a file */
4404  SCIP_LPI* lpi, /**< LP interface structure */
4405  const char* fname /**< file name */
4406  )
4407 {
4408  int restat;
4409 
4410  assert(lpi != NULL);
4411  assert(lpi->cpxlp != NULL);
4412  assert(lpi->cpxenv != NULL);
4413 
4414  SCIPdebugMessage("writing LP to file <%s>\n", fname);
4415 
4416  restat = CPXwriteprob(lpi->cpxenv, lpi->cpxlp, fname, NULL);
4417  if( restat != 0 )
4418  {
4419  SCIPerrorMessage("LP Error: CPLEX returned %d\n", restat);
4420  return SCIP_READERROR;
4421  }
4422 
4423  return SCIP_OKAY;
4424 }
4425 
4426 /**@} */
SCIP_Bool SCIPlpiIsPrimalUnbounded(SCIP_LPI *lpi)
Definition: lpi_cpx.c:2872
#define BMSfreeMemoryArray(ptr)
Definition: memory.h:102
SCIP_RETCODE SCIPlpiGetDualfarkas(SCIP_LPI *lpi, SCIP_Real *dualfarkas)
Definition: lpi_cpx.c:3228
enum SCIP_LPSolQuality SCIP_LPSOLQUALITY
Definition: type_lpi.h:92
#define BMSallocBlockMemory(mem, ptr)
Definition: memory.h:406
SCIP_Bool SCIPlpiIsPrimalFeasible(SCIP_LPI *lpi)
Definition: lpi_cpx.c:2915
SCIP_RETCODE SCIPlpiClear(SCIP_LPI *lpi)
Definition: lpi_cpx.c:1400
SCIP_Real conditionlimit
Definition: lpi_cpx.c:167
SCIP_RETCODE SCIPlpiDelColset(SCIP_LPI *lpi, int *dstat)
Definition: lpi_cpx.c:1284
SCIP_RETCODE SCIPlpiSolvePrimal(SCIP_LPI *lpi)
Definition: lpi_cpx.c:2093
SCIP_Bool solisbasic
Definition: lpi_cpx.c:162
SCIP_Bool SCIPlpiIsInfinity(SCIP_LPI *lpi, SCIP_Real val)
Definition: lpi_cpx.c:4358
static double getDblParam(SCIP_LPI *lpi, int const param)
Definition: lpi_cpx.c:604
ROWPACKET * packrstat
Definition: lpi_clp.cpp:126
SCIP_PRICING pricing
Definition: lpi_clp.cpp:102
SCIP_RETCODE SCIPlpiSetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS *lpinorms)
Definition: lpi_cpx.c:3991
double dblparval[NUMDBLPARAM]
Definition: lpi_cpx.c:132
SCIP_RETCODE SCIPlpiGetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real *dval)
Definition: lpi_cpx.c:4245
SCIP_CPXPARAM cpxparam
Definition: lpi_cpx.c:144
SCIP_CPXPARAM defparam
Definition: lpi_cpx.c:140
int sidechgsize
Definition: lpi_cpx.c:156
SCIP_RETCODE SCIPlpiClearState(SCIP_LPI *lpi)
Definition: lpi_cpx.c:3842
SCIP_RETCODE SCIPlpiGetBInvARow(SCIP_LPI *lpi, int r, const SCIP_Real *binvrow, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_cpx.c:3582
enum SCIP_ObjSen SCIP_OBJSEN
Definition: type_lpi.h:36
#define NULL
Definition: lpi_spx.cpp:130
static SCIP_RETCODE restoreLPData(SCIP_LPI *lpi)
Definition: lpi_cpx.c:957
SCIP_RETCODE SCIPlpiFreeNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition: lpi_cpx.c:4024
#define CPX_SUBVERSION
Definition: lpi_cpx.c:41
void SCIPdecodeDualBit(const SCIP_DUALPACKET *inp, int *out, int count)
Definition: bitencode.c:298
#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:3094
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
#define FALSE
Definition: def.h:56
static SCIP_RETCODE lpistateCreate(SCIP_LPISTATE **lpistate, BMS_BLKMEM *blkmem, int ncols, int nrows)
Definition: lpi_cpx.c:433
#define TRUE
Definition: def.h:55
SCIP_RETCODE SCIPlpiGetSides(SCIP_LPI *lpi, int firstrow, int lastrow, SCIP_Real *lhss, SCIP_Real *rhss)
Definition: lpi_cpx.c:2026
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
SCIP_Bool SCIPlpiHasPrimalRay(SCIP_LPI *lpi)
Definition: lpi_cpx.c:2859
int rstatsize
Definition: lpi_clp.cpp:99
#define SCIP_CALL(x)
Definition: def.h:266
SCIP_Bool checkcondition
Definition: lpi_cpx.c:168
int valsize
Definition: lpi_cpx.c:157
SCIP_RETCODE SCIPlpiGetNNonz(SCIP_LPI *lpi, int *nnonz)
Definition: lpi_cpx.c:1752
SCIP_RETCODE SCIPlpiSetBase(SCIP_LPI *lpi, int *cstat, int *rstat)
Definition: lpi_cpx.c:3360
SCIP_Real * rhsarray
Definition: lpi_cpx.c:148
SCIP_Bool SCIPlpiIsDualFeasible(SCIP_LPI *lpi)
Definition: lpi_cpx.c:3002
static SCIP_RETCODE ensureSidechgMem(SCIP_LPI *lpi, int num)
Definition: lpi_cpx.c:234
#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:3882
SCIP_RETCODE SCIPlpiGetBInvACol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_cpx.c:3654
CPXENVptr cpxenv
Definition: lpi_cpx.c:139
SCIP_Bool SCIPlpiHasDualRay(SCIP_LPI *lpi)
Definition: lpi_cpx.c:2949
#define SCIPdebugMessage
Definition: pub_message.h:77
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:85
SCIP_Bool SCIPlpiIsDualInfeasible(SCIP_LPI *lpi)
Definition: lpi_cpx.c:2981
static void lpistatePack(SCIP_LPISTATE *lpistate, const int *cstat, const int *rstat)
Definition: lpi_cpx.c:401
#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:1828
SCIP_Bool SCIPlpiHasStateBasis(SCIP_LPI *lpi, SCIP_LPISTATE *lpistate)
Definition: lpi_cpx.c:3873
static void reconvertBothSides(SCIP_LPI *lpi, int nrows, SCIP_Real *lhs, SCIP_Real *rhs)
Definition: lpi_cpx.c:786
enum SCIP_Pricing SCIP_PRICING
Definition: type_lpi.h:74
SCIP_Bool SCIPlpiIsPrimalInfeasible(SCIP_LPI *lpi)
Definition: lpi_cpx.c:2896
SCIP_RETCODE SCIPlpiStartStrongbranch(SCIP_LPI *lpi)
Definition: lpi_cpx.c:2573
SCIP_RETCODE SCIPlpiGetBInvRow(SCIP_LPI *lpi, int r, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_cpx.c:3438
SCIP_Bool SCIPlpiExistsDualRay(SCIP_LPI *lpi)
Definition: lpi_cpx.c:2936
int SCIPlpiGetInternalStatus(SCIP_LPI *lpi)
Definition: lpi_cpx.c:3116
static int colpacketNum(int ncols)
Definition: lpi_cpx.c:383
#define ROWS_PER_PACKET
Definition: lpi_cpx.c:81
#define EPSISINT(x, eps)
Definition: def.h:164
SCIP_DUALPACKET COLPACKET
Definition: lpi_clp.cpp:115
static SCIP_RETCODE getParameterValues(SCIP_LPI *lpi, SCIP_CPXPARAM *cpxparam)
Definition: lpi_cpx.c:476
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:3179
char * larray
Definition: lpi_cpx.c:145
SCIP_RETCODE SCIPlpiGetNRows(SCIP_LPI *lpi, int *nrows)
Definition: lpi_cpx.c:1718
SCIP_Real feastol
Definition: lpi_cpx.c:166
#define ABORT_ZERO(x)
Definition: lpi_cpx.c:58
#define CPX_MAGICZEROCONSTANT
Definition: lpi_cpx.c:76
static SCIP_RETCODE setParameterValues(SCIP_LPI *const lpi, SCIP_CPXPARAM *const cpxparam)
Definition: lpi_cpx.c:526
packing single and dual bit values
static SCIP_RETCODE ensureValMem(SCIP_LPI *lpi, int num)
Definition: lpi_cpx.c:259
#define SCIPerrorMessage
Definition: pub_message.h:45
#define SCIPdebugPrintf
Definition: pub_message.h:80
static void lpistateUnpack(const SCIP_LPISTATE *lpistate, int *cstat, int *rstat)
Definition: lpi_cpx.c:417
int * rngindarray
Definition: lpi_cpx.c:151
char * senarray
Definition: lpi_cpx.c:147
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:2818
SCIP_Bool SCIPlpiIsObjlimExc(SCIP_LPI *lpi)
Definition: lpi_cpx.c:3081
static int getIntParam(SCIP_LPI *lpi, int const param)
Definition: lpi_cpx.c:582
SCIP_Bool SCIPlpiExistsPrimalRay(SCIP_LPI *lpi)
Definition: lpi_cpx.c:2845
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
#define BMSallocMemory(ptr)
Definition: memory.h:74
SCIP_RETCODE SCIPlpiSetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real dval)
Definition: lpi_cpx.c:4291
void SCIPmessagePrintWarning(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
Definition: message.c:411
#define EPSFLOOR(x, eps)
Definition: def.h:160
static SCIP_RETCODE lpiStrongbranchIntegral(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:2467
int * rstat
Definition: lpi_clp.cpp:97
SCIP_Real SCIPlpiInfinity(SCIP_LPI *lpi)
Definition: lpi_cpx.c:4350
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:2721
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:2591
SCIP_Bool rngfound
Definition: lpi_cpx.c:170
int cstatsize
Definition: lpi_clp.cpp:98
static SCIP_RETCODE ensureCstatMem(SCIP_LPI *lpi, int num)
Definition: lpi_cpx.c:282
SCIP_RETCODE SCIPlpiGetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lpi_cpx.c:3730
SCIP_Bool fromscratch
Definition: lpi_cpx.c:164
static void setIntParam(SCIP_LPI *lpi, int const param, int const parval)
Definition: lpi_cpx.c:635
SCIP_Bool SCIPlpiIsOptimal(SCIP_LPI *lpi)
Definition: lpi_cpx.c:3021
#define BMSreallocMemoryArray(ptr, num)
Definition: memory.h:82
#define BMSfreeMemory(ptr)
Definition: memory.h:100
SCIP_RETCODE SCIPlpiGetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int *ival)
Definition: lpi_cpx.c:4053
static void invalidateSolution(SCIP_LPI *const lpi)
Definition: lpi_cpx.c:690
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:1925
void SCIPencodeDualBit(const int *inp, SCIP_DUALPACKET *out, int count)
Definition: bitencode.c:228
int * indarray
Definition: lpi_cpx.c:154
SCIP_RETCODE SCIPlpiScaleCol(SCIP_LPI *lpi, int col, SCIP_Real scaleval)
Definition: lpi_cpx.c:1644
SCIP_RETCODE SCIPlpiGetBase(SCIP_LPI *lpi, int *cstat, int *rstat)
Definition: lpi_cpx.c:3320
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:2755
#define BMSfreeMemoryArrayNull(ptr)
Definition: memory.h:103
COLPACKET * packcstat
Definition: lpi_clp.cpp:125
static SCIP_RETCODE getBase(SCIP_LPI *lpi)
Definition: lpi_cpx.c:326
unsigned int SCIP_DUALPACKET
Definition: bitencode.h:33
SCIP_RETCODE SCIPlpiGetBounds(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *lbs, SCIP_Real *ubs)
Definition: lpi_cpx.c:1997
SCIP_RETCODE SCIPlpiGetObjval(SCIP_LPI *lpi, SCIP_Real *objval)
Definition: lpi_cpx.c:3150
SCIP_Bool SCIPlpiIsTimelimExc(SCIP_LPI *lpi)
Definition: lpi_cpx.c:3105
#define SCIP_Bool
Definition: def.h:53
int solstat
Definition: lpi_cpx.c:143
SCIP_RETCODE SCIPlpiCreate(SCIP_LPI **lpi, SCIP_MESSAGEHDLR *messagehdlr, const char *name, SCIP_OBJSEN objsen)
Definition: lpi_cpx.c:1043
#define BMSallocBlockMemoryArray(mem, ptr, num)
Definition: memory.h:408
static void setDblParam(SCIP_LPI *lpi, int const param, double parval)
Definition: lpi_cpx.c:660
#define EPSZ(x, eps)
Definition: def.h:157
#define BMSfreeBlockMemoryArray(mem, ptr, num)
Definition: memory.h:421
#define MAX(x, y)
Definition: tclique_def.h:75
static int cpxObjsen(SCIP_OBJSEN const objsen)
Definition: lpi_cpx.c:701
#define SCIP_CALL_QUIET(x)
Definition: def.h:241
SCIP_Bool instabilityignored
Definition: lpi_cpx.c:163
SCIP_RETCODE SCIPlpiChgBounds(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *lb, const SCIP_Real *ub)
Definition: lpi_cpx.c:1430
static SCIP_RETCODE setBase(SCIP_LPI *lpi)
Definition: lpi_cpx.c:353
#define BMSfreeBlockMemory(mem, ptr)
Definition: memory.h:419
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:3032
SCIP_RETCODE SCIPlpiScaleRow(SCIP_LPI *lpi, int row, SCIP_Real scaleval)
Definition: lpi_cpx.c:1588
int iterations
Definition: lpi_cpx.c:160
SCIP_Real * rngarray
Definition: lpi_cpx.c:149
static const double dblparammin[NUMDBLPARAM]
Definition: lpi_cpx.c:117
SCIP_RETCODE SCIPlpiGetCoef(SCIP_LPI *lpi, int row, int col, SCIP_Real *val)
Definition: lpi_cpx.c:2062
int * head
Definition: lpi_cpx.c:195
SCIP_RETCODE SCIPlpiReadLP(SCIP_LPI *lpi, const char *fname)
Definition: lpi_cpx.c:4379
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:2808
SCIP_RETCODE SCIPlpiGetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition: lpi_cpx.c:3931
CPXLPptr cpxlp
Definition: lpi_cpx.c:142
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:1772
static SCIP_RETCODE checkParameterValues(SCIP_LPI *const lpi)
Definition: lpi_cpx.c:502
SCIP_Real * valarray
Definition: lpi_cpx.c:150
int boundchgsize
Definition: lpi_cpx.c:155
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:3778
static void copyParameterValues(SCIP_CPXPARAM *dest, SCIP_CPXPARAM *const source)
Definition: lpi_cpx.c:567
#define REALABS(x)
Definition: def.h:151
#define EPSCEIL(x, eps)
Definition: def.h:161
SCIP_RETCODE SCIPlpiGetObjsen(SCIP_LPI *lpi, SCIP_OBJSEN *objsen)
Definition: lpi_cpx.c:1959
SCIP_RETCODE SCIPlpiGetPrimalRay(SCIP_LPI *lpi, SCIP_Real *ray)
Definition: lpi_cpx.c:3209
double * norm
Definition: lpi_cpx.c:194
public methods for message output
static SCIP_RETCODE ensureBoundchgMem(SCIP_LPI *lpi, int num)
Definition: lpi_cpx.c:205
static const int dblparam[NUMDBLPARAM]
Definition: lpi_cpx.c:106
SCIP_Bool clearstate
Definition: lpi_cpx.c:165
#define SCIP_Real
Definition: def.h:127
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
#define MIN(x, y)
Definition: memory.c:67
SCIP_RETCODE SCIPlpiGetNCols(SCIP_LPI *lpi, int *ncols)
Definition: lpi_cpx.c:1735
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:2655
SCIP_RETCODE SCIPlpiSolveBarrier(SCIP_LPI *lpi, SCIP_Bool crossover)
Definition: lpi_cpx.c:2383
#define SCIP_INVALID
Definition: def.h:147
static int rowpacketNum(int nrows)
Definition: lpi_cpx.c:392
static void convertSides(SCIP_LPI *lpi, int nrows, const SCIP_Real *lhs, const SCIP_Real *rhs, int indoffset, int *rngcount)
Definition: lpi_cpx.c:720
static SCIP_RETCODE ensureRstatMem(SCIP_LPI *lpi, int num)
Definition: lpi_cpx.c:304
#define CPX_INT_MAX
Definition: lpi_cpx.c:67
SCIP_RETCODE SCIPlpiDelCols(SCIP_LPI *lpi, int firstcol, int lastcol)
Definition: lpi_cpx.c:1263
static void reconvertSides(SCIP_LPI *lpi, int nrows, SCIP_Real *lhs, SCIP_Real *rhs)
Definition: lpi_cpx.c:939
char * uarray
Definition: lpi_cpx.c:146
static void reconvertLhs(SCIP_LPI *lpi, int nrows, SCIP_Real *lhs)
Definition: lpi_cpx.c:843
SCIP_RETCODE SCIPlpiFreeState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lpi_cpx.c:3855
SCIP_RETCODE SCIPlpiGetObj(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *vals)
Definition: lpi_cpx.c:1976
int intparval[NUMINTPARAM]
Definition: lpi_cpx.c:131
SCIP_MESSAGEHDLR * messagehdlr
Definition: lpi_cpx.c:178
static const int intparam[NUMINTPARAM]
Definition: lpi_cpx.c:89
static void reconvertRhs(SCIP_LPI *lpi, int nrows, SCIP_Real *rhs)
Definition: lpi_cpx.c:891
SCIP_RETCODE SCIPlpiWriteLP(SCIP_LPI *lpi, const char *fname)
Definition: lpi_cpx.c:4403
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:3127
#define BMSallocMemoryArray(ptr, num)
Definition: memory.h:78
static char cpxname[100]
Definition: lpi_cpx.c:994
SCIP_RETCODE SCIPlpiChgObj(SCIP_LPI *lpi, int ncols, int *ind, SCIP_Real *obj)
Definition: lpi_cpx.c:1569
SCIP_RETCODE SCIPlpiSolveDual(SCIP_LPI *lpi)
Definition: lpi_cpx.c:2198
struct BMS_BlkMem BMS_BLKMEM
Definition: memory.h:392
SCIP_RETCODE SCIPlpiGetRealSolQuality(SCIP_LPI *lpi, SCIP_LPSOLQUALITY qualityindicator, SCIP_Real *quality)
Definition: lpi_cpx.c:3266
SCIP_RETCODE SCIPlpiGetBasisInd(SCIP_LPI *lpi, int *bind)
Definition: lpi_cpx.c:3404
SCIP_RETCODE SCIPlpiSetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int ival)
Definition: lpi_cpx.c:4143
#define SCIP_ALLOC(x)
Definition: def.h:277
SCIP_CPXPARAM curparam
Definition: lpi_cpx.c:141
#define SCIPABORT()
Definition: def.h:238
SCIP_RETCODE SCIPlpiGetIterations(SCIP_LPI *lpi, int *iterations)
Definition: lpi_cpx.c:3248
SCIP_RETCODE SCIPlpiGetColNames(SCIP_LPI *lpi, int firstcol, int lastcol, char **colnames, char *namestorage, int namestoragesize, int *storageleft)
Definition: lpi_cpx.c:1891
static void lpistateFree(SCIP_LPISTATE **lpistate, BMS_BLKMEM *blkmem)
Definition: lpi_cpx.c:454
SCIP_RETCODE SCIPlpiEndStrongbranch(SCIP_LPI *lpi)
Definition: lpi_cpx.c:2582
int * cstat
Definition: lpi_clp.cpp:96
SCIP_RETCODE SCIPlpiGetBInvCol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_cpx.c:3509
const char * SCIPlpiGetSolverDesc(void)
Definition: lpi_cpx.c:1013
SCIP_Bool SCIPlpiIsDualUnbounded(SCIP_LPI *lpi)
Definition: lpi_cpx.c:2962
SCIP_RETCODE SCIPlpiWriteState(SCIP_LPI *lpi, const char *fname)
Definition: lpi_cpx.c:3899