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