Scippy

SCIP

Solving Constraint Integer Programs

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