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