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