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