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