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