Scippy

SCIP

Solving Constraint Integer Programs

lpi_grb.c
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the program and library */
4 /* SCIP --- Solving Constraint Integer Programs */
5 /* */
6 /* Copyright (C) 2002-2020 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SCIP is distributed under the terms of the ZIB Academic License. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SCIP; see the file COPYING. If not visit scipopt.org. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file lpi_grb.c
17  * @ingroup LPIS
18  * @brief LP interface for Gurobi
19  * @author Marc Pfetsch
20  * @author Tobias Achterberg
21  * @author Michael Winkler
22  *
23  * This LPI only works with Gurobi versions >= 7.0.2.
24  *
25  * @todo Try quad-precision and concurrent runs.
26  *
27  * @todo Make this lpi thread safe.
28  */
29 
30 /*--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
31 
32 #include <assert.h>
33 #include <string.h>
34 
35 #include "gurobi_c.h"
36 #include "lpi/lpi.h"
37 #include "scip/pub_message.h"
38 #include "scip/pub_misc_sort.h"
39 
40 #ifdef _WIN32
41 #define snprintf _snprintf
42 #endif
43 
44 #if ( GRB_VERSION_MAJOR < 6 || ( GRB_VERSION_MAJOR == 7 && GRB_VERSION_MINOR == 0 && GRB_VERSION_TECHNICAL < 2 ) )
45 #error "The Gurobi intreface only works for Gurobi versions at least 7.0.2"
46 #endif
47 
48 /* define infinity value of Gurobi */
49 #define GRB_INFBOUND 1e+20
50 
51 #define CHECK_ZERO(messagehdlr, x) do { int _restat_; \
52  if( (_restat_ = (x)) != 0 ) \
53  { \
54  SCIPmessagePrintWarning((messagehdlr), "Gurobi error %d: %s\n", _restat_, GRBgeterrormsg(grbenv)); \
55  return SCIP_LPERROR; \
56  } \
57  } while(0)
58 
59 #ifndef SVECTOR
60 #define SVECTOR GRBsvec
61 #endif
62 
63 typedef unsigned int SCIP_DUALPACKET; /**< storing bit pairs in packed format */
64 #define SCIP_DUALPACKETSIZE (sizeof(SCIP_DUALPACKET)*4) /**< each entry needs two bits of information */
65 
66 typedef SCIP_DUALPACKET COLPACKET; /**< each column needs two bits of information (basic/on_lower/on_upper) */
67 #define COLS_PER_PACKET SCIP_DUALPACKETSIZE
68 typedef SCIP_DUALPACKET ROWPACKET; /**< each row needs two bit of information (basic/on_lower/on_upper) */
69 #define ROWS_PER_PACKET SCIP_DUALPACKETSIZE
70 
71 
72 /* At several places we need to guarantee to have a factorization of an optimal basis and call the simplex to produce
73  * it. In a numerical perfect world, this should need no iterations. However, due to numerical inaccuracies after
74  * refactorization, it might be necessary to do a few extra pivot steps. */
75 #define GRB_REFACTORMAXITERS 50 /**< maximal number of iterations allowed for producing a refactorization of the basis */
76 
77 
78 /** number of Gurobi integer parameters that can be changed */
79 #define NUMINTPARAM 6
80 
81 static const char* intparam[NUMINTPARAM] =
82 {
83  GRB_INT_PAR_SCALEFLAG,
84  GRB_INT_PAR_PRESOLVE,
85  GRB_INT_PAR_SIMPLEXPRICING,
86  GRB_INT_PAR_OUTPUTFLAG,
87  GRB_INT_PAR_THREADS,
88  GRB_INT_PAR_SEED
89 };
90 
91 /** number of Gurobi double parameters that can be changed */
92 #define NUMDBLPARAM 7
93 
94 static const char* dblparam[NUMDBLPARAM] =
95 {
96  GRB_DBL_PAR_FEASIBILITYTOL,
97  GRB_DBL_PAR_OPTIMALITYTOL,
98  GRB_DBL_PAR_BARCONVTOL,
99  GRB_DBL_PAR_CUTOFF,
100  GRB_DBL_PAR_TIMELIMIT,
101  GRB_DBL_PAR_ITERATIONLIMIT,
102  GRB_DBL_PAR_MARKOWITZTOL
103 };
104 
105 /** minimal values for double parameters */
106 static const double dblparammin[NUMDBLPARAM] =
107 {
108  +1e-09, /* GRB_DBL_PAR_FEASIBILITYTOL */
109  +1e-09, /* GRB_DBL_PAR_OPTIMALITYTOL */
110  0.0, /* GRB_DBL_PAR_BARCONVTOL */
111  -GRB_INFINITY, /* GRB_DBL_PAR_CUTOFF */
112  0, /* GRB_DBL_PAR_TIMELIMIT */
113  0, /* GRB_DBL_PAR_ITERATIONLIMIT */
114  1e-04 /* GRB_DBL_PAR_MARKOWITZTOL */
115 };
116 
117 /** Gurobi parameter settings */
118 struct GRBParam
119 {
120  int intparval[NUMINTPARAM]; /**< integer parameter values */
121  double dblparval[NUMDBLPARAM]; /**< double parameter values */
122 };
123 typedef struct GRBParam GRBPARAM;
124 
125 
126 /** LP interface */
127 struct SCIP_LPi
128 {
129  GRBmodel* grbmodel; /**< Gurobi model pointer */
130  GRBenv* grbenv; /**< environment corresponding to model */
131  int solstat; /**< solution status of last optimization call */
132  GRBPARAM defparam; /**< default parameter values */
133  GRBPARAM curparam; /**< current parameter values stored in Gurobi LP */
134  GRBPARAM grbparam; /**< current parameter values for this LP */
135  char* senarray; /**< array for storing row senses */
136  SCIP_Real* rhsarray; /**< array for storing rhs values */
137  SCIP_Real* rngarray; /**< array for storing range values */
138  int* rngidxarray; /**< array for storing the indices of ranged rows in sen/rhs/rngarray */
139  SCIP_Real* valarray; /**< array for storing coefficient values */
140  int* cstat; /**< array for storing column basis status */
141  int* rstat; /**< array for storing row basis status */
142  int* indarray; /**< array for storing coefficient indices */
143  int sidechgsize; /**< size of senarray */
144  int valsize; /**< size of valarray and indarray */
145  int cstatsize; /**< size of cstat array */
146  int rstatsize; /**< size of rstat array */
147  int iterations; /**< number of iterations used in the last solving call */
148  SCIP_Bool solisbasic; /**< is current LP solution a basic solution? */
149  SCIP_Bool fromscratch; /**< should each solve be performed without previous basis state? */
150  SCIP_PRICING pricing; /**< SCIP pricing setting */
151  SCIP_Real conditionlimit; /**< maximum condition number of LP basis counted as stable (-1.0: no limit) */
152  SCIP_Bool checkcondition; /**< should condition number of LP basis be checked for stability? */
153  SCIP_MESSAGEHDLR* messagehdlr; /**< messagehdlr handler to printing messages, or NULL */
154  int* rngrowmap; /**< maps row id to rngrows array position, or -1 if not a ranged row
155  * (can be NULL, which means that no ranged rows exist) */
156  int* rngrows; /**< indices of ranged rows */
157  SCIP_Real* rngvals; /**< range values of ranged rows */
158  int rngrowmapsize; /**< size of rngrowmap array */
159  int nrngrows; /**< number of ranged rows in the LP */
160  int rngrowssize; /**< size of rngrows and rngvals arrays */
161  SCIP_Bool rngvarsadded; /**< did we add the range variables to the Gurobi model? */
162 };
163 
164 /** LPi state stores basis information */
165 struct SCIP_LPiState
166 {
167  int ncols; /**< number of LP columns */
168  int nrows; /**< number of LP rows */
169  int nrngrows; /**< number of ranged rows in LP */
170  COLPACKET* packcstat; /**< column basis status in compressed form */
171  ROWPACKET* packrstat; /**< row basis status in compressed form */
172 };
173 
174 /** LPi norms stores pricing norms */
175 struct SCIP_LPiNorms
176 {
177  int ncols; /**< number of columns for which dual norm is stored */
178  int nrows; /**< number of rows for which dual norm is stored */
179  double* colnorm; /**< dual norms for columns */
180  double* rownorm; /**< dual norms for rows */
181 };
182 
183 /* global variables for Gurobi environment */
184 static GRBenv* grbenv = NULL; /**< Gurobi environment (only needed for initialization) */
185 static int numlp = 0; /**< number of open LP objects */
186 
187 
188 
189 /*
190  * dynamic memory arrays
191  */
192 
193 /** resizes senarray to have at least num entries */
194 static
196  SCIP_LPI* lpi, /**< LP interface structure */
197  int num /**< minimal number of entries in array */
198  )
199 {
200  assert(lpi != NULL);
201 
202  if( num > lpi->sidechgsize )
203  {
204  int newsize;
205 
206  newsize = MAX(2*lpi->sidechgsize, num);
207  SCIP_ALLOC( BMSreallocMemoryArray(&lpi->senarray, newsize) );
208  SCIP_ALLOC( BMSreallocMemoryArray(&lpi->rhsarray, newsize) );
209  SCIP_ALLOC( BMSreallocMemoryArray(&lpi->rngarray, newsize) );
210  SCIP_ALLOC( BMSreallocMemoryArray(&lpi->rngidxarray, newsize) );
211  lpi->sidechgsize = newsize;
212  }
213  assert(num <= lpi->sidechgsize);
214 
215  return SCIP_OKAY;
216 }
217 
218 /** resizes valarray and indarray to have at least num entries */
219 static
221  SCIP_LPI* lpi, /**< LP interface structure */
222  int num /**< minimal number of entries in array */
223  )
224 {
225  assert(lpi != NULL);
226 
227  if( num > lpi->valsize )
228  {
229  int newsize;
230 
231  newsize = MAX(2*lpi->valsize, num);
232  SCIP_ALLOC( BMSreallocMemoryArray(&lpi->valarray, newsize) );
233  SCIP_ALLOC( BMSreallocMemoryArray(&lpi->indarray, newsize) );
234  lpi->valsize = newsize;
235  }
236  assert(num <= lpi->valsize);
237 
238  return SCIP_OKAY;
239 }
240 
241 /** resizes cstat array to have at least num entries */
242 static
244  SCIP_LPI* lpi, /**< LP interface structure */
245  int num /**< minimal number of entries in array */
246  )
247 {
248  assert(lpi != NULL);
249 
250  if( num > lpi->cstatsize )
251  {
252  int newsize;
253 
254  newsize = MAX(2*lpi->cstatsize, num);
255  SCIP_ALLOC( BMSreallocMemoryArray(&lpi->cstat, newsize) );
256  lpi->cstatsize = newsize;
257  }
258  assert(num <= lpi->cstatsize);
259 
260  return SCIP_OKAY;
261 }
262 
263 /** resizes rstat array 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->rstatsize )
273  {
274  int newsize;
275 
276  newsize = MAX(2*lpi->rstatsize, num);
277  SCIP_ALLOC( BMSreallocMemoryArray(&lpi->rstat, newsize) );
278  lpi->rstatsize = newsize;
279  }
280  assert(num <= lpi->rstatsize);
281 
282  return SCIP_OKAY;
283 }
284 
285 /** resizes rngrowmap array to have at least num entries */
286 static
288  SCIP_LPI* lpi, /**< LP interface structure */
289  int num /**< minimal number of entries in array */
290  )
291 {
292  assert(lpi != NULL);
293 
294  if( num > lpi->rngrowmapsize )
295  {
296  int newsize;
297  int r;
298 
299  newsize = MAX(2*lpi->rngrowmapsize, num);
300  SCIP_ALLOC( BMSreallocMemoryArray(&lpi->rngrowmap, newsize) );
301  for (r = lpi->rngrowmapsize; r < newsize; r++)
302  lpi->rngrowmap[r] = -1;
303  lpi->rngrowmapsize = newsize;
304  }
305  assert(num <= lpi->rngrowmapsize);
306 
307  return SCIP_OKAY;
308 }
309 
310 /** resizes rngrows and rngvals arrays to have at least num entries */
311 static
313  SCIP_LPI* lpi, /**< LP interface structure */
314  int num /**< minimal number of entries in array */
315  )
316 {
317  assert(lpi != NULL);
318 
319  if( num > lpi->rngrowssize )
320  {
321  int newsize;
322 
323  newsize = MAX(2*lpi->rngrowssize, num);
324  SCIP_ALLOC( BMSreallocMemoryArray(&lpi->rngrows, newsize) );
325  SCIP_ALLOC( BMSreallocMemoryArray(&lpi->rngvals, newsize) );
326  lpi->rngrowssize = newsize;
327  }
328  assert(num <= lpi->rngrowssize);
329 
330  return SCIP_OKAY;
331 }
332 
333 /** stores current basis in internal arrays of LPI data structure */
334 static
336  SCIP_LPI* lpi, /**< LP interface structure */
337  SCIP_Bool* success /**< whether basis information has successfully been obtained */
338  )
339 {
340  int ncols;
341  int nrows;
342  int res;
343 
344  assert( lpi != NULL );
345  assert( lpi->grbmodel != NULL );
346  assert( lpi->grbenv != NULL );
347 
348  SCIPdebugMessage("getBase()\n");
349  if ( success != NULL )
350  *success = TRUE;
351 
352  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_NUMVARS, &ncols) );
353  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_NUMCONSTRS, &nrows) );
354 
355  /* allocate enough memory for storing uncompressed basis information */
356  SCIP_CALL( ensureCstatMem(lpi, ncols) );
357  SCIP_CALL( ensureRstatMem(lpi, nrows) );
358 
359  /* get unpacked basis information from Gurobi */
360  res = GRBgetintattrarray(lpi->grbmodel, GRB_INT_ATTR_VBASIS, 0, ncols, lpi->cstat);
361  if ( res == GRB_ERROR_DATA_NOT_AVAILABLE )
362  {
363  /* if the model is infeasible, Gurobi does not currently return basis information */
364  if ( success != NULL )
365  *success = FALSE;
366  return SCIP_OKAY;
367  }
368  else if ( res != 0 )
369  {
370  SCIPerrorMessage("Gurobi error %d: %s\n", res, GRBgeterrormsg(lpi->grbenv));
371  return SCIP_LPERROR;
372  }
373 
374  res = GRBgetintattrarray(lpi->grbmodel, GRB_INT_ATTR_CBASIS, 0, nrows, lpi->rstat);
375  if ( res == GRB_ERROR_DATA_NOT_AVAILABLE )
376  {
377  /* if the model is infeasible Gurobi does not currently return basis information */
378  if ( success != NULL )
379  *success = FALSE;
380  return SCIP_OKAY;
381  }
382  else if ( res != 0 )
383  {
384  SCIPerrorMessage("Gurobi error %d: %s\n", res, GRBgeterrormsg(lpi->grbenv));
385  return SCIP_LPERROR;
386  }
387 
388  return SCIP_OKAY;
389 }
390 
391 /** loads basis stored in internal arrays of LPI data structure into Gurobi */
392 static
394  SCIP_LPI* lpi /**< LP interface structure */
395  )
396 {
397  int ncols;
398  int nrows;
399 
400  assert( lpi != NULL );
401  assert( lpi->grbmodel != NULL );
402 
403  SCIPdebugMessage("setBase()\n");
404 
405  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_NUMVARS, &ncols) );
406  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_NUMCONSTRS, &nrows) );
407 
408  /* load basis information into Gurobi */
409  CHECK_ZERO( lpi->messagehdlr, GRBsetintattrarray(lpi->grbmodel, GRB_INT_ATTR_VBASIS, 0, ncols, lpi->cstat) );
410  CHECK_ZERO( lpi->messagehdlr, GRBsetintattrarray(lpi->grbmodel, GRB_INT_ATTR_CBASIS, 0, nrows, lpi->rstat) );
411 
412  CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
413 
414  return SCIP_OKAY;
415 }
416 
417 
418 
419 
420 /*
421  * LPi state methods
422  */
423 
424 /** returns the number of packets needed to store column packet information */
425 static
427  int ncols /**< number of columns to store */
428  )
429 {
430  return (ncols+(int)COLS_PER_PACKET-1)/(int)COLS_PER_PACKET;
431 }
432 
433 /** returns the number of packets needed to store row packet information */
434 static
436  int nrows /**< number of rows to store */
437  )
438 {
439  return (nrows+(int)ROWS_PER_PACKET-1)/(int)ROWS_PER_PACKET;
440 }
441 
442 
443 /* The basis information for Gurobi is negative. So we cannot use the functions in bitencode.h/c. The functions below are a modified copy. */
444 
445 /** encode a negated dual bit vector into packed format */
446 static
448  const int* inp, /**< unpacked input vector */
449  SCIP_DUALPACKET* out, /**< buffer to store the packed vector */
450  int count /**< number of elements */
451  )
452 {
453  static const SCIP_DUALPACKET mask[SCIP_DUALPACKETSIZE][4] = { /* if the packet size changes, the mask has to be updated */
454  {0x00000000, 0x00000001, 0x00000002, 0x00000003},
455  {0x00000000, 0x00000004, 0x00000008, 0x0000000C},
456  {0x00000000, 0x00000010, 0x00000020, 0x00000030},
457  {0x00000000, 0x00000040, 0x00000080, 0x000000C0},
458  {0x00000000, 0x00000100, 0x00000200, 0x00000300},
459  {0x00000000, 0x00000400, 0x00000800, 0x00000C00},
460  {0x00000000, 0x00001000, 0x00002000, 0x00003000},
461  {0x00000000, 0x00004000, 0x00008000, 0x0000C000},
462  {0x00000000, 0x00010000, 0x00020000, 0x00030000},
463  {0x00000000, 0x00040000, 0x00080000, 0x000C0000},
464  {0x00000000, 0x00100000, 0x00200000, 0x00300000},
465  {0x00000000, 0x00400000, 0x00800000, 0x00C00000},
466  {0x00000000, 0x01000000, 0x02000000, 0x03000000},
467  {0x00000000, 0x04000000, 0x08000000, 0x0C000000},
468  {0x00000000, 0x10000000, 0x20000000, 0x30000000},
469  {0x00000000, 0x40000000, 0x80000000, 0xC0000000}
470  };
471  int i;
472  int rest;
473  int nfull;
474 
475  assert(inp != NULL || count == 0);
476  assert(out != NULL || count == 0);
477  assert(count >= 0);
478  assert(SCIP_DUALPACKETSIZE == 16);
479 
480  rest = count % (int)SCIP_DUALPACKETSIZE;
481  nfull = count - rest;
482 
483  for( i = 0; i < nfull; i += (int)SCIP_DUALPACKETSIZE, inp += (int)SCIP_DUALPACKETSIZE )
484  {
485  assert(inp != NULL);
486  assert(out != NULL);
487 
488 #ifndef NDEBUG
489  {
490  unsigned int j;
491  for( j = 0; j < SCIP_DUALPACKETSIZE; ++j )
492  assert(0 <= -inp[j] && -inp[j] <= 3);
493  }
494 #endif
495  *out++ =
496  mask[0][-inp[0]] | mask[1][-inp[1]] | mask[2][-inp[2]] | mask[3][-inp[3]]
497  | mask[4][-inp[4]] | mask[5][-inp[5]] | mask[6][-inp[6]]
498  | mask[7][-inp[7]] | mask[8][-inp[8]] | mask[9][-inp[9]]
499  | mask[10][-inp[10]] | mask[11][-inp[11]] | mask[12][-inp[12]]
500  | mask[13][-inp[13]] | mask[14][-inp[14]] | mask[15][-inp[15]];
501  }
502 
503  if( rest > 0 )
504  {
506 
507  assert(inp != NULL);
508  assert(out != NULL);
509 
510  for( i = 0; i < rest; i++ )
511  m |= mask[i][-inp[i]];
512  *out = m;
513  }
514 }
515 
516 /** decode a packed dual bit vector into negated unpacked format */
517 static
519  const SCIP_DUALPACKET* inp, /**< packed input vector */
520  int* out, /**< buffer to store unpacked vector */
521  int count /**< number of elements */
522  )
523 {
524  SCIP_DUALPACKET m;
525  int rest;
526  int nfull;
527  int i;
528 
529  assert(inp != NULL || count == 0);
530  assert(out != NULL || count == 0);
531  assert(count >= 0);
532  assert(SCIP_DUALPACKETSIZE == 16);
533 
534  rest = count % (int)SCIP_DUALPACKETSIZE;
535  nfull = count - rest;
536 
537  for( i = 0; i < nfull; i += (int)SCIP_DUALPACKETSIZE )
538  {
539  assert(inp != NULL);
540  assert(out != NULL);
541 
542  m = *inp++;
543 
544  *out++ = -(int)(m & 3);
545  m >>= 2;
546  *out++ = -(int)(m & 3);
547  m >>= 2;
548  *out++ = -(int)(m & 3);
549  m >>= 2;
550  *out++ = -(int)(m & 3);
551  m >>= 2;
552  *out++ = -(int)(m & 3);
553  m >>= 2;
554  *out++ = -(int)(m & 3);
555  m >>= 2;
556  *out++ = -(int)(m & 3);
557  m >>= 2;
558  *out++ = -(int)(m & 3);
559  m >>= 2;
560  *out++ = -(int)(m & 3);
561  m >>= 2;
562  *out++ = -(int)(m & 3);
563  m >>= 2;
564  *out++ = -(int)(m & 3);
565  m >>= 2;
566  *out++ = -(int)(m & 3);
567  m >>= 2;
568  *out++ = -(int)(m & 3);
569  m >>= 2;
570  *out++ = -(int)(m & 3);
571  m >>= 2;
572  *out++ = -(int)(m & 3);
573  m >>= 2;
574  *out++ = -(int)(m & 3);
575  assert(m >> 2 == 0);
576  }
577 
578  if( rest > 0 )
579  {
580  assert(inp != NULL);
581  assert(out != NULL);
582 
583  m = *inp;
584  for( i = 0; i < rest; i++ )
585  {
586  *out++ = -(int)(m & 3);
587  m >>= 2;
588  }
589  }
590 }
591 
592 /** store row and column basis status in a packed LPi state object */
593 static
595  SCIP_LPISTATE* lpistate, /**< pointer to LPi state data */
596  const int* cstat, /**< basis status of columns in unpacked format */
597  const int* rstat /**< basis status of rows in unpacked format */
598  )
599 {
600  assert(lpistate != NULL);
601  assert(lpistate->packcstat != NULL);
602  assert(lpistate->packrstat != NULL);
603 
604  SCIPencodeDualBitNeg(cstat, lpistate->packcstat, lpistate->ncols + lpistate->nrngrows);
605  SCIPencodeDualBitNeg(rstat, lpistate->packrstat, lpistate->nrows);
606 }
607 
608 /** unpacks row and column basis status from a packed LPi state object */
609 static
611  const SCIP_LPISTATE* lpistate, /**< pointer to LPi state data */
612  int* cstat, /**< buffer for storing basis status of columns in unpacked format */
613  int* rstat /**< buffer for storing basis status of rows in unpacked format */
614  )
615 {
616  assert(lpistate != NULL);
617  assert(lpistate->packcstat != NULL);
618  assert(lpistate->packrstat != NULL);
619 
620  SCIPdecodeDualBitNeg(lpistate->packcstat, cstat, lpistate->ncols + lpistate->nrngrows);
621  SCIPdecodeDualBitNeg(lpistate->packrstat, rstat, lpistate->nrows);
622 }
623 
624 /** creates LPi state information object */
625 static
627  SCIP_LPISTATE** lpistate, /**< pointer to LPi state */
628  BMS_BLKMEM* blkmem, /**< block memory */
629  int ncols, /**< number of columns to store */
630  int nrows, /**< number of rows to store */
631  int nrngrows /**< number of ranged rows */
632  )
633 {
634  assert(lpistate != NULL);
635  assert(blkmem != NULL);
636  assert(ncols >= 0);
637  assert(nrows >= 0);
638 
639  SCIP_ALLOC( BMSallocBlockMemory(blkmem, lpistate) );
640  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpistate)->packcstat, colpacketNum(ncols + nrngrows)) );
641  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpistate)->packrstat, rowpacketNum(nrows)) );
642 
643  return SCIP_OKAY;
644 }
645 
646 /** frees LPi state information */
647 static
649  SCIP_LPISTATE** lpistate, /**< pointer to LPi state information (like basis information) */
650  BMS_BLKMEM* blkmem /**< block memory */
651  )
652 {
653  assert(blkmem != NULL);
654  assert(lpistate != NULL);
655  assert(*lpistate != NULL);
656 
657  BMSfreeBlockMemoryArrayNull(blkmem, &(*lpistate)->packcstat, colpacketNum((*lpistate)->ncols + (*lpistate)->nrngrows));
658  BMSfreeBlockMemoryArrayNull(blkmem, &(*lpistate)->packrstat, rowpacketNum((*lpistate)->nrows));
659  BMSfreeBlockMemory(blkmem, lpistate);
660 }
661 
662 
663 
664 /*
665  * local methods
666  */
667 
668 /** gets all Gurobi parameters used in LPI */
669 static
671  SCIP_LPI* lpi, /**< LP interface structure */
672  GRBPARAM* grbparam /**< Gurobi parameters */
673  )
674 {
675  int i;
676 
677  assert( lpi != NULL );
678  assert( lpi->grbenv != NULL );
679  assert( grbparam != NULL );
680 
681  SCIPdebugMessage("getParameterValues()\n");
682 
683  for( i = 0; i < NUMINTPARAM; ++i )
684  {
685  CHECK_ZERO( lpi->messagehdlr, GRBgetintparam(lpi->grbenv, intparam[i], &(grbparam->intparval[i])) );
686  }
687  for( i = 0; i < NUMDBLPARAM; ++i )
688  {
689  CHECK_ZERO( lpi->messagehdlr, GRBgetdblparam(lpi->grbenv, dblparam[i], &(grbparam->dblparval[i])) );
690  }
691 
692  return SCIP_OKAY;
693 }
694 
695 /** in debug mode, checks validity of Gurobi parameters */
696 static
698  SCIP_LPI* lpi /**< LP interface structure */
699  )
700 {
701 #ifndef NDEBUG
702  GRBPARAM par;
703  int i;
704 
705  SCIP_CALL( getParameterValues(lpi, &par) );
706  for (i = 0; i < NUMINTPARAM; ++i)
707  assert( lpi->curparam.intparval[i] == par.intparval[i] );
708  for (i = 0; i < NUMDBLPARAM; ++i)
709  assert(MAX(lpi->curparam.dblparval[i], dblparammin[i]) == par.dblparval[i]); /*lint !e777*/
710 #endif
711 
712  return SCIP_OKAY;
713 }
714 
715 /** sets all Gurobi parameters used in LPI */
716 static
718  SCIP_LPI* lpi, /**< LP interface structure */
719  GRBPARAM* grbparam /**< Gurobi parameters */
720  )
721 {
722  int i;
723 
724  assert( lpi != NULL );
725  assert( lpi->grbenv != NULL );
726  assert( grbparam != NULL );
727 
728  SCIPdebugMessage("setParameterValues()\n");
729 
730  for( i = 0; i < NUMINTPARAM; ++i )
731  {
732  if( lpi->curparam.intparval[i] != grbparam->intparval[i] )
733  {
734  SCIPdebugMessage("setting Gurobi int parameter %s from %d to %d\n",
735  intparam[i], lpi->curparam.intparval[i], grbparam->intparval[i]);
736  lpi->curparam.intparval[i] = grbparam->intparval[i];
737  CHECK_ZERO( lpi->messagehdlr, GRBsetintparam(lpi->grbenv, intparam[i], lpi->curparam.intparval[i]) );
738  }
739  }
740  for( i = 0; i < NUMDBLPARAM; ++i )
741  {
742  if( lpi->curparam.dblparval[i] != grbparam->dblparval[i] ) /*lint !e777*/
743  {
744  SCIPdebugMessage("setting Gurobi dbl parameter %s from %g to %g\n",
745  dblparam[i], lpi->curparam.dblparval[i], MAX(grbparam->dblparval[i], dblparammin[i]));
746  lpi->curparam.dblparval[i] = MAX(grbparam->dblparval[i], dblparammin[i]);
747  CHECK_ZERO( lpi->messagehdlr, GRBsetdblparam(lpi->grbenv, dblparam[i], lpi->curparam.dblparval[i]) );
748  }
749  }
750 
752 
753  return SCIP_OKAY;
754 }
755 
756 /** copies Gurobi parameters from source to dest */
757 static
759  GRBPARAM* dest, /**< destination Gurobi parameters */
760  const GRBPARAM* source /**< original Gurobi parameters */
761  )
762 {
763  int i;
764 
765  for( i = 0; i < NUMINTPARAM; ++i )
766  dest->intparval[i] = source->intparval[i];
767  for( i = 0; i < NUMDBLPARAM; ++i )
768  dest->dblparval[i] = source->dblparval[i];
769 }
770 
771 /** gets a single integer parameter value */
772 static
774  SCIP_LPI* lpi, /**< LP interface structure */
775  const char* param, /**< parameter name */
776  int* p /**< value of parameter */
777  )
778 {
779  int i;
780 
781  assert( lpi != NULL );
782 
783  for( i = 0; i < NUMINTPARAM; ++i )
784  {
785  if( strcmp(intparam[i], param) == 0 )
786  {
787  *p = lpi->grbparam.intparval[i];
788  return SCIP_OKAY;
789  }
790  }
791 
792  SCIPerrorMessage("unknown Gurobi integer parameter <%s>.\n", param);
793  return SCIP_LPERROR;
794 }
795 
796 /** sets a single integer parameter value */
797 static
799  SCIP_LPI* lpi, /**< LP interface structure */
800  const char* param, /**< parameter name */
801  int parval /**< value of parameter */
802  )
803 {
804  int i;
805 
806  assert( lpi != NULL );
807 
808  for( i = 0; i < NUMINTPARAM; ++i )
809  {
810  if( strcmp(intparam[i], param) == 0 )
811  {
812  lpi->grbparam.intparval[i] = parval;
813  return SCIP_OKAY;
814  }
815  }
816 
817  SCIPerrorMessage("unknown Gurobi integer parameter <%s>.\n", param);
818  return SCIP_LPERROR;
819 }
820 
821 /** gets a single double parameter value */
822 static
824  SCIP_LPI* lpi, /**< LP interface structure */
825  const char* param, /**< parameter name */
826  double* p /**< value of parameter */
827  )
828 {
829  int i;
830 
831  assert(lpi != NULL);
832 
833  for( i = 0; i < NUMDBLPARAM; ++i )
834  {
835  if( strcmp(dblparam[i], param) == 0 )
836  {
837  *p = lpi->grbparam.dblparval[i];
838  return SCIP_OKAY;
839  }
840  }
841 
842  SCIPerrorMessage("unknown Gurobi double parameter <%s>.\n", param);
843  return SCIP_LPERROR;
844 }
845 
846 /** sets a single double parameter value */
847 static
849  SCIP_LPI* lpi, /**< LP interface structure */
850  const char* param, /**< parameter name */
851  double parval /**< value of parameter */
852  )
853 {
854  int i;
855 
856  assert( lpi != NULL );
857 
858  for( i = 0; i < NUMDBLPARAM; ++i )
859  {
860  if( strcmp(dblparam[i], param) == 0 )
861  {
862  lpi->grbparam.dblparval[i] = parval;
863  return SCIP_OKAY;
864  }
865  }
866 
867  SCIPerrorMessage("unknown Gurobi double parameter <%s>.\n", param);
868  return SCIP_LPERROR;
869 }
870 
871 /** marks the current LP to be unsolved */
872 static
874  SCIP_LPI* lpi /**< LP interface structure */
875  )
876 {
877  assert(lpi != NULL);
878  lpi->solstat = -1;
879 }
880 
881 /** converts SCIP's lhs/rhs pairs into Gurobi's sen/rhs */
882 static
884  SCIP_LPI* lpi, /**< LP interface structure */
885  int nrows, /**< number of rows */
886  const SCIP_Real* lhs, /**< left hand side vector */
887  const SCIP_Real* rhs, /**< right hand side vector */
888  int* rngcount /**< number of ranged rows found */
889  )
890 {
891  int i;
892 
893  assert(lpi != NULL);
894  assert(nrows >= 0);
895  assert(lhs != NULL);
896  assert(rhs != NULL);
897  assert(rngcount != NULL);
898 
899  /* convert lhs/rhs into sen/rhs */
900  *rngcount = 0;
901  for( i = 0; i < nrows; ++i )
902  {
903  assert(lhs[i] <= rhs[i]);
904 
905  if( lhs[i] == rhs[i] ) /*lint !e777*/
906  {
907  assert(-GRB_INFINITY < rhs[i] && rhs[i] < GRB_INFINITY);
908  lpi->senarray[i] = GRB_EQUAL;
909  lpi->rhsarray[i] = rhs[i];
910  lpi->rngarray[i] = 0.0;
911  }
912  else if( lhs[i] <= -GRB_INFINITY )
913  {
914  /* this includes the case of free rows */
915  assert(-GRB_INFINITY < rhs[i]);
916  lpi->senarray[i] = GRB_LESS_EQUAL;
917  lpi->rhsarray[i] = rhs[i];
918  }
919  else if( rhs[i] >= GRB_INFINITY )
920  {
921  assert(-GRB_INFINITY < lhs[i] && lhs[i] < GRB_INFINITY);
922  lpi->senarray[i] = GRB_GREATER_EQUAL;
923  lpi->rhsarray[i] = lhs[i];
924  }
925  else
926  {
927  /* we treat ranged rows as equations with an extra slack variable */
928  assert(-GRB_INFINITY < lhs[i] && lhs[i] < GRB_INFINITY);
929  assert(-GRB_INFINITY < rhs[i] && rhs[i] < GRB_INFINITY);
930  lpi->senarray[i] = GRB_EQUAL;
931  lpi->rhsarray[i] = lhs[i];
932  lpi->rngarray[i] = rhs[i] - lhs[i];
933  lpi->rngidxarray[(*rngcount)++] = i;
934  }
935  }
936  return SCIP_OKAY;
937 }
938 
939 /** converts Gurobi's sen/rhs pairs into SCIP's lhs/rhs pairs */
940 static
942  SCIP_LPI* lpi, /**< LP interface structure */
943  int firstrow, /**< first row to get sides for */
944  int lastrow, /**< last row to get sides for */
945  SCIP_Real* lhs, /**< buffer to store the left hand side vector, or NULL */
946  SCIP_Real* rhs /**< buffer to store the right hand side vector, or NULL */
947  )
948 {
949  int nrows;
950  int i;
951 
952  nrows = lastrow-firstrow+1;
953 
954  assert(lpi != NULL);
955  assert(nrows >= 0);
956 
957  for (i = 0; i < nrows; ++i)
958  {
959  switch( lpi->senarray[i] )
960  {
961  case GRB_EQUAL:
962  if ( lhs != NULL )
963  lhs[i] = lpi->rhsarray[i];
964  if ( rhs != NULL )
965  {
966  int row;
967 
968  rhs[i] = lpi->rhsarray[i];
969  row = firstrow+i;
970  if ( lpi->rngrowmap != NULL && lpi->rngrowmap[row] >= 0 )
971  {
972  assert(lpi->rngrowmap[row] < lpi->nrngrows);
973  rhs[i] += lpi->rngvals[lpi->rngrowmap[row]];
974  }
975  }
976  break;
977 
978  case GRB_LESS_EQUAL:
979  if ( lhs != NULL )
980  lhs[i] = -GRB_INFINITY;
981  if ( rhs != NULL )
982  rhs[i] = lpi->rhsarray[i];
983  break;
984 
985  case GRB_GREATER_EQUAL:
986  if ( lhs != NULL )
987  lhs[i] = lpi->rhsarray[i];
988  if ( rhs != NULL )
989  rhs[i] = GRB_INFINITY;
990  break;
991 
992  default:
993  SCIPerrorMessage("invalid row sense\n");
994  SCIPABORT();
995  return SCIP_LPERROR; /*lint !e527*/
996  }
997  assert(lhs == NULL || rhs == NULL || lhs[i] <= rhs[i]);
998  }
999  return SCIP_OKAY;
1000 }
1001 
1002 /** after restoring old LP data, need to resolve the LP to be able to retrieve correct information */
1003 static
1005  SCIP_LPI* lpi /**< LP interface structure */
1006  )
1007 {
1008  assert( lpi != NULL );
1009 
1010  /* set dual simplex */
1011  CHECK_ZERO( lpi->messagehdlr, GRBsetintparam(lpi->grbenv, GRB_INT_PAR_METHOD, GRB_METHOD_DUAL) );
1012  CHECK_ZERO( lpi->messagehdlr, GRBoptimize(lpi->grbmodel) );
1013 
1014 #ifndef NDEBUG
1015  {
1016  double cnt;
1017 
1018  /* modifying the LP, restoring the old LP, and loading the old basis is not enough for Gurobi to be able to return
1019  * the basis -> we have to resolve the LP;
1020  *
1021  * In a numerical perfect world, GRB_REFACTORMAXITERS below should be zero. However, due to numerical inaccuracies
1022  * after refactorization, it might be necessary to do a few extra pivot steps.
1023  */
1024  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_ITERCOUNT, &cnt) );
1025  if ( cnt > (double) GRB_REFACTORMAXITERS )
1026  SCIPmessagePrintWarning(lpi->messagehdlr, "Gurobi needed %d iterations to restore optimal basis.\n", (int) cnt);
1027  }
1028 #endif
1029 
1030  return SCIP_OKAY;
1031 }
1032 
1033 #ifndef NDEBUG
1034 /** verifies in debug mode that ranged row information is consistent */
1035 static
1037  SCIP_LPI* lpi /**< LP interface structure */
1038  )
1039 {
1040  assert(lpi->rngrowssize >= lpi->nrngrows);
1041 
1042  if ( lpi->nrngrows > 0 )
1043  {
1044  int nrngrows = 0;
1045  int nrows;
1046  int i;
1047 
1048  assert(lpi->rngrowmap != NULL);
1049  assert(lpi->rngrows != NULL);
1050  assert(lpi->rngvals != NULL);
1051 
1052  SCIP_CALL_ABORT( SCIPlpiGetNRows(lpi, &nrows) );
1053 
1054  assert(lpi->rngrowmapsize >= nrows);
1055 
1056  for (i = 0; i < nrows; i++)
1057  {
1058  int rngrow;
1059 
1060  rngrow = lpi->rngrowmap[i];
1061  assert(-1 <= rngrow && rngrow < lpi->nrngrows);
1062  if ( rngrow >= 0 )
1063  {
1064  assert(lpi->rngrows[rngrow] == i);
1065  assert(lpi->rngvals[rngrow] > 0.0);
1066  nrngrows++;
1067  }
1068  }
1069  assert(lpi->nrngrows == nrngrows);
1070  }
1071 }
1072 #else
1073 #define checkRangeInfo(lpi) /**/
1074 #endif
1075 
1076 /** adds range variables to Gurobi LP */
1077 static
1079  SCIP_LPI* lpi /**< LP interface structure */
1080  )
1081 {
1082  int i;
1083 
1084  assert(!lpi->rngvarsadded);
1085  assert(lpi->nrngrows > 0);
1086  assert(lpi->rngrowmap != NULL);
1087  assert(lpi->rngrows != NULL);
1088 
1089  for (i = 0; i < lpi->nrngrows; i++)
1090  {
1091  double coeff = -1.0;
1092  int row;
1093 
1094  row = lpi->rngrows[i];
1095 
1096  CHECK_ZERO( lpi->messagehdlr, GRBaddvar(lpi->grbmodel, 1, &row, &coeff, 0.0, 0.0, lpi->rngvals[i], GRB_CONTINUOUS, NULL) );
1097  }
1098 
1099  /* flush model changes */
1100  CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
1101 
1102  lpi->rngvarsadded = TRUE;
1103 
1104  return SCIP_OKAY;
1105 }
1106 
1107 /** deletes range variables from Gurobi LP */
1108 static
1110  SCIP_LPI* lpi /**< LP interface structure */
1111  )
1112 {
1113  int* which;
1114  int ncols;
1115  int i;
1116 
1117  assert(lpi->rngvarsadded);
1118  assert(lpi->nrngrows > 0);
1119 
1120  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
1121 
1122  /* Gurobi can't delete a range of columns, we have to set up an index array */
1123  SCIP_ALLOC( BMSallocMemoryArray(&which, lpi->nrngrows) );
1124  for (i = 0; i < lpi->nrngrows; i++)
1125  which[i] = ncols+i;
1126 
1127  CHECK_ZERO( lpi->messagehdlr, GRBdelvars(lpi->grbmodel, lpi->nrngrows, which) );
1128  CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
1129 
1130  BMSfreeMemoryArray( &which );
1131 
1132  lpi->rngvarsadded = FALSE;
1133 
1134  return SCIP_OKAY;
1135 }
1136 
1137 /** clear ranged row information */
1138 static
1140  SCIP_LPI* lpi /**< LP interface structure */
1141  )
1142 {
1143  assert(!lpi->rngvarsadded);
1144 
1148 
1149  lpi->nrngrows = 0;
1150  lpi->rngrowssize = 0;
1151  lpi->rngrowmapsize = 0;
1152 }
1153 
1154 /** creates or updates maps for ranged rows after new rows have been added */
1155 static
1157  SCIP_LPI* lpi, /**< LP interface structure */
1158  int rngcount, /**< number of ranged rows added */
1159  int firstrow /**< index of first row that was added */
1160  )
1161 {
1162  int ncols;
1163  int nrows;
1164  int r;
1165  int i;
1166 
1167  assert( lpi != NULL );
1168 
1169  /* get rid of range variables */
1170  if ( lpi->rngvarsadded )
1171  {
1172  SCIP_CALL( delRangeVars(lpi) );
1173  }
1174  assert( !lpi->rngvarsadded );
1175 
1176  /* query problem size in terms of SCIP's view */
1177  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
1178  SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
1179 
1180  /* set up and extend rngrowmap array */
1181  SCIP_CALL( ensureRngrowmapMem(lpi, nrows) );
1182  for (r = firstrow; r < nrows; r++)
1183  lpi->rngrowmap[r] = -1;
1184 
1185  /* extend rngrows and rngvals arrays */
1186  SCIP_CALL( ensureRngrowsMem(lpi, lpi->nrngrows + rngcount) );
1187 
1188  /* update maps for ranged rows */
1189  for (i = 0; i < rngcount; i++)
1190  {
1191  int pos;
1192  int row;
1193 
1194  pos = lpi->rngidxarray[i];
1195  row = firstrow + pos;
1196 
1197  lpi->rngrowmap[row] = lpi->nrngrows;
1198  lpi->rngrows[lpi->nrngrows] = row;
1199  lpi->rngvals[lpi->nrngrows] = lpi->rngarray[pos];
1200  lpi->nrngrows++;
1201  }
1202 
1203  return SCIP_OKAY;
1204 }
1205 
1206 
1207 
1208 /*
1209  * LP Interface Methods
1210  */
1211 
1212 
1213 /*
1214  * Miscellaneous Methods
1215  */
1216 
1217 static char grbname[100];
1218 
1219 /**@name Miscellaneous Methods */
1220 /**@{ */
1221 
1222 /** gets name and version of LP solver */
1224  void
1225  )
1226 {
1227  int majorversion;
1228  int minorversion;
1229  int technical;
1230 
1231  GRBversion(&majorversion, &minorversion, &technical);
1232  sprintf(grbname, "Gurobi %d.%d.%d", majorversion, minorversion, technical);
1233  return grbname;
1234 }
1235 
1236 /** gets description of LP solver (developer, webpage, ...) */
1238  void
1239  )
1240 {
1241  return "Linear Programming Solver developed by Gurobi Optimization (www.gurobi.com)";
1242 }
1243 
1244 /** gets pointer for LP solver - use only with great care
1245  *
1246  * Here we return the pointer to the model.
1247  */
1249  SCIP_LPI* lpi /**< pointer to an LP interface structure */
1250  )
1251 {
1252  return (void*) lpi->grbmodel;
1253 }
1254 
1255 /** pass integrality information to LP solver */
1257  SCIP_LPI* lpi, /**< pointer to an LP interface structure */
1258  int ncols, /**< length of integrality array */
1259  int* intInfo /**< integrality array (0: continuous, 1: integer). May be NULL iff ncols is 0. */
1260  )
1261 { /*lint --e{715}*/
1262  SCIPerrorMessage("SCIPlpiSetIntegralityInformation() has not been implemented yet.\n");
1263  return SCIP_LPERROR;
1264 }
1265 
1266 /** informs about availability of a primal simplex solving method */
1268  void
1269  )
1270 {
1271  return TRUE;
1272 }
1273 
1274 /** informs about availability of a dual simplex solving method */
1276  void
1277  )
1278 {
1279  return TRUE;
1280 }
1281 
1282 /** informs about availability of a barrier solving method */
1284  void
1285  )
1286 {
1287  return TRUE;
1288 }
1289 
1290 /**@} */
1291 
1292 
1293 
1294 
1295 /*
1296  * LPI Creation and Destruction Methods
1297  */
1298 
1299 /**@name LPI Creation and Destruction Methods */
1300 /**@{ */
1301 
1302 /** creates an LP problem object */
1304  SCIP_LPI** lpi, /**< pointer to an LP interface structure */
1305  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler to use for printing messages, or NULL */
1306  const char* name, /**< problem name */
1307  SCIP_OBJSEN objsen /**< objective sense */
1308  )
1309 {
1310  assert(sizeof(SCIP_Real) == sizeof(double)); /* Gurobi only works with doubles as floating points */
1311  assert(sizeof(SCIP_Bool) == sizeof(int)); /* Gurobi only works with ints as bools */
1312  assert(lpi != NULL);
1313  assert(name != NULL);
1314  assert(numlp >= 0);
1315 
1316  SCIPdebugMessage("SCIPlpiCreate()\n");
1317 
1318  /* create environment
1319  *
1320  * Each problem will get a copy of the original environment. Thus, grbenv is only needed once.
1321  */
1322  if ( grbenv == NULL )
1323  {
1324  /* initialize environment - no log file */
1325  CHECK_ZERO( messagehdlr, GRBloadenv(&grbenv, NULL) );
1326 
1327  /* turn off output for all models */
1328  CHECK_ZERO( messagehdlr, GRBsetintparam(grbenv, GRB_INT_PAR_OUTPUTFLAG, 0) );
1329 
1330  /* turn on that basis information for infeasible and unbounded models is available */
1331  CHECK_ZERO( messagehdlr, GRBsetintparam(grbenv, GRB_INT_PAR_INFUNBDINFO, 1) );
1332  }
1333  assert( grbenv != NULL );
1334 
1335  /* create empty LPI */
1336  SCIP_ALLOC( BMSallocMemory(lpi) );
1337  CHECK_ZERO( messagehdlr, GRBnewmodel(grbenv, &(*lpi)->grbmodel, name, 0, NULL, NULL, NULL, NULL, NULL) );
1338 
1339  /* get local copy of environment */
1340  (*lpi)->grbenv = GRBgetenv((*lpi)->grbmodel);
1341  (*lpi)->senarray = NULL;
1342  (*lpi)->rhsarray = NULL;
1343  (*lpi)->rngarray = NULL;
1344  (*lpi)->rngidxarray = NULL;
1345  (*lpi)->valarray = NULL;
1346  (*lpi)->cstat = NULL;
1347  (*lpi)->rstat = NULL;
1348  (*lpi)->indarray = NULL;
1349  (*lpi)->rngrowmap = NULL;
1350  (*lpi)->rngrows = NULL;
1351  (*lpi)->rngvals = NULL;
1352  (*lpi)->sidechgsize = 0;
1353  (*lpi)->valsize = 0;
1354  (*lpi)->cstatsize = 0;
1355  (*lpi)->rstatsize = 0;
1356  (*lpi)->rngrowmapsize = 0;
1357  (*lpi)->nrngrows = 0;
1358  (*lpi)->rngrowssize = 0;
1359  (*lpi)->rngvarsadded = FALSE;
1360  (*lpi)->iterations = 0;
1361  (*lpi)->solisbasic = FALSE;
1362  (*lpi)->fromscratch = FALSE;
1363  (*lpi)->conditionlimit = -1.0;
1364  (*lpi)->checkcondition = FALSE;
1365  (*lpi)->pricing = SCIP_PRICING_LPIDEFAULT;
1366  (*lpi)->messagehdlr = messagehdlr;
1367  invalidateSolution(*lpi);
1368 
1369  /* get default parameter values */
1370  SCIP_CALL( getParameterValues((*lpi), &((*lpi)->defparam)) );
1371  copyParameterValues(&((*lpi)->curparam), &((*lpi)->defparam));
1372  copyParameterValues(&((*lpi)->grbparam), &((*lpi)->defparam));
1373  ++numlp;
1374 
1375  /* set objective sense */
1376  SCIP_CALL( SCIPlpiChgObjsen(*lpi, objsen) );
1377 
1378  /* set default pricing */
1379  SCIP_CALL( SCIPlpiSetIntpar(*lpi, SCIP_LPPAR_PRICING, (int) (*lpi)->pricing) );
1380 
1381  checkRangeInfo(*lpi);
1382 
1383  return SCIP_OKAY;
1384 }
1385 
1386 /** deletes an LP problem object */
1388  SCIP_LPI** lpi /**< pointer to an LP interface structure */
1389  )
1390 {
1391  assert(grbenv != NULL);
1392  assert(lpi != NULL);
1393  assert(*lpi != NULL);
1394 
1395  SCIPdebugMessage("SCIPlpiFree()\n");
1396 
1397  /* free model */
1398  CHECK_ZERO( (*lpi)->messagehdlr, GRBfreemodel((*lpi)->grbmodel) );
1399 
1400  /* free memory */
1401  BMSfreeMemoryArrayNull(&(*lpi)->senarray);
1402  BMSfreeMemoryArrayNull(&(*lpi)->rhsarray);
1403  BMSfreeMemoryArrayNull(&(*lpi)->rngarray);
1404  BMSfreeMemoryArrayNull(&(*lpi)->rngidxarray);
1405  BMSfreeMemoryArrayNull(&(*lpi)->cstat);
1406  BMSfreeMemoryArrayNull(&(*lpi)->rstat);
1407  BMSfreeMemoryArrayNull(&(*lpi)->rngrowmap);
1408  BMSfreeMemoryArrayNull(&(*lpi)->rngrows);
1409  BMSfreeMemoryArrayNull(&(*lpi)->rngvals);
1410  BMSfreeMemoryArrayNull(&(*lpi)->indarray);
1411  BMSfreeMemoryArrayNull(&(*lpi)->valarray);
1412  BMSfreeMemory(lpi);
1413 
1414  /* free environment */
1415  --numlp;
1416  if( numlp == 0 )
1417  {
1418  GRBfreeenv(grbenv);
1419  grbenv = NULL;
1420  }
1421 
1422  return SCIP_OKAY;
1423 }
1424 
1425 /**@} */
1426 
1427 
1428 
1429 
1430 /*
1431  * Modification Methods
1432  */
1433 
1434 /**@name Modification Methods */
1435 /**@{ */
1436 
1437 /** copies LP data with column matrix into LP solver */
1439  SCIP_LPI* lpi, /**< LP interface structure */
1440  SCIP_OBJSEN objsen, /**< objective sense */
1441  int ncols, /**< number of columns */
1442  const SCIP_Real* obj, /**< objective function values of columns */
1443  const SCIP_Real* lb, /**< lower bounds of columns */
1444  const SCIP_Real* ub, /**< upper bounds of columns */
1445  char** colnames, /**< column names, or NULL */
1446  int nrows, /**< number of rows */
1447  const SCIP_Real* lhs, /**< left hand sides of rows */
1448  const SCIP_Real* rhs, /**< right hand sides of rows */
1449  char** rownames, /**< row names, or NULL */
1450  int nnonz, /**< number of nonzero elements in the constraint matrix */
1451  const int* beg, /**< start index of each column in ind- and val-array */
1452  const int* ind, /**< row indices of constraint matrix entries */
1453  const SCIP_Real* val /**< values of constraint matrix entries */
1454  )
1455 {
1456  int grbobjsen;
1457  int* cnt;
1458  int rngcount;
1459  int c;
1460 
1461 #ifndef NDEBUG
1462  {
1463  int j;
1464  for( j = 0; j < nnonz; j++ )
1465  assert( val[j] != 0 );
1466  }
1467 #endif
1468 
1469  assert(lpi != NULL);
1470  assert(lpi->grbmodel != NULL);
1471  assert(lpi->grbenv != NULL);
1472  assert(obj != NULL);
1473  assert(lb != NULL);
1474  assert(ub != NULL);
1475  assert(beg != NULL);
1476  assert(ind != NULL);
1477  assert(val != NULL);
1478 
1479  assert(objsen == SCIP_OBJSEN_MAXIMIZE || objsen == SCIP_OBJSEN_MINIMIZE);
1480 
1481  SCIPdebugMessage("loading LP in column format into Gurobi: %d cols, %d rows\n", ncols, nrows);
1482 
1483  invalidateSolution(lpi);
1484 
1485  SCIP_CALL( ensureSidechgMem(lpi, nrows) );
1486 
1487  /* convert objective sense */
1488  grbobjsen = (objsen == SCIP_OBJSEN_MINIMIZE) ? GRB_MINIMIZE : GRB_MAXIMIZE;
1489 
1490  /* convert lhs/rhs into sen/rhs/range tuples */
1491  SCIP_CALL( convertSides(lpi, nrows, lhs, rhs, &rngcount) );
1492 
1493  /* calculate column lengths */
1494  SCIP_ALLOC( BMSallocMemoryArray(&cnt, ncols) );
1495  for( c = 0; c < ncols-1; ++c )
1496  {
1497  cnt[c] = beg[c+1] - beg[c];
1498  assert(cnt[c] >= 0);
1499  }
1500  cnt[ncols-1] = nnonz - beg[ncols-1];
1501  assert(cnt[ncols-1] >= 0);
1502 
1503  /* load model - all variables are continuous */
1504  CHECK_ZERO( lpi->messagehdlr, GRBloadmodel(lpi->grbenv, &(lpi->grbmodel), NULL, ncols, nrows, grbobjsen, 0.0, (SCIP_Real*)obj,
1505  lpi->senarray, lpi->rhsarray, (int*)beg, cnt, (int*)ind, (SCIP_Real*)val, (SCIP_Real*)lb, (SCIP_Real*)ub, NULL, colnames, rownames) );
1506 
1507  CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
1508 
1509  /* free temporary memory */
1510  BMSfreeMemoryArray(&cnt);
1511 
1512  /* update maps for ranged rows */
1513  if ( rngcount > 0 )
1514  {
1515  SCIP_CALL( addRangeInfo(lpi, rngcount, 0) );
1516  }
1517 
1518 #ifndef NDEBUG
1519  {
1520  int temp;
1521 
1522  SCIP_CALL( SCIPlpiGetNCols(lpi, &temp) );
1523  assert(temp == ncols);
1524 
1525  SCIP_CALL( SCIPlpiGetNRows(lpi, &temp) );
1526  assert(temp == nrows);
1527 
1528  SCIP_CALL( SCIPlpiGetNNonz(lpi, &temp) );
1529  assert(temp == nnonz);
1530  }
1531 #endif
1532 
1533  checkRangeInfo(lpi);
1534 
1535  return SCIP_OKAY;
1536 }
1537 
1538 /** adds columns to the LP */
1540  SCIP_LPI* lpi, /**< LP interface structure */
1541  int ncols, /**< number of columns to be added */
1542  const SCIP_Real* obj, /**< objective function values of new columns */
1543  const SCIP_Real* lb, /**< lower bounds of new columns */
1544  const SCIP_Real* ub, /**< upper bounds of new columns */
1545  char** colnames, /**< column names, or NULL */
1546  int nnonz, /**< number of nonzero elements to be added to the constraint matrix */
1547  const int* beg, /**< start index of each column in ind- and val-array, or NULL if nnonz == 0 */
1548  const int* ind, /**< row indices of constraint matrix entries, or NULL if nnonz == 0 */
1549  const SCIP_Real* val /**< values of constraint matrix entries, or NULL if nnonz == 0 */
1550  )
1551 {
1552 
1553  assert(lpi != NULL);
1554  assert(lpi->grbmodel != NULL);
1555  assert(obj != NULL);
1556  assert(lb != NULL);
1557  assert(ub != NULL);
1558  assert(nnonz == 0 || beg != NULL);
1559  assert(nnonz == 0 || ind != NULL);
1560  assert(nnonz == 0 || val != NULL);
1561  assert(nnonz >= 0);
1562  assert(ncols >= 0);
1563 
1564  SCIPdebugMessage("adding %d columns with %d nonzeros to Gurobi\n", ncols, nnonz);
1565 
1566  invalidateSolution(lpi);
1567 
1568 #ifndef NDEBUG
1569  if ( nnonz > 0 )
1570  {
1571  /* perform check that no new rows are added - this is forbidden */
1572  int nrows;
1573  int j;
1574 
1575  SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
1576  for (j = 0; j < nnonz; ++j)
1577  {
1578  assert( 0 <= ind[j] && ind[j] < nrows );
1579  assert( val[j] != 0.0 );
1580  }
1581  }
1582 #endif
1583 
1584  /* delete range variables from Gurobi LP, so that structural variables always come first */
1585  if ( lpi->nrngrows > 0 && lpi->rngvarsadded )
1586  {
1587  /**@todo Save and restore basis - currently, the basis is destroyed if we discard (and later re-add) range variables */
1588  SCIP_CALL( delRangeVars(lpi) );
1589  }
1590 
1591  /* add columns - all new variables are continuous */
1592  CHECK_ZERO( lpi->messagehdlr, GRBaddvars(lpi->grbmodel, ncols, nnonz, (int*)beg, (int*)ind, (SCIP_Real*)val,
1593  (SCIP_Real*)obj, (SCIP_Real*)lb, (SCIP_Real*)ub, NULL, colnames) );
1594  CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
1595 
1596  checkRangeInfo(lpi);
1597 
1598  return SCIP_OKAY;
1599 }
1600 
1601 /** deletes all columns in the given range from LP */
1603  SCIP_LPI* lpi, /**< LP interface structure */
1604  int firstcol, /**< first column to be deleted */
1605  int lastcol /**< last column to be deleted */
1606  )
1607 {
1608  int ndelcols;
1609  int* which;
1610  int j;
1611 
1612  ndelcols = lastcol-firstcol+1;
1613 
1614  assert(lpi != NULL);
1615  assert(lpi->grbmodel != NULL);
1616 #ifndef NDEBUG
1617  {
1618  int temp;
1619 
1620  SCIP_CALL( SCIPlpiGetNCols(lpi, &temp) );
1621  assert(0 <= firstcol && firstcol <= lastcol && lastcol < temp);
1622  }
1623 #endif
1624 
1625  SCIPdebugMessage("deleting %d columns from Gurobi\n", lastcol - firstcol + 1);
1626 
1627  invalidateSolution(lpi);
1628 
1629  /* Gurobi can't delete a range of columns, we have to set up an index array */
1630  SCIP_ALLOC( BMSallocMemoryArray(&which, ndelcols) );
1631  for( j = firstcol; j <= lastcol; ++j )
1632  which[j - firstcol] = j;
1633 
1634  CHECK_ZERO( lpi->messagehdlr, GRBdelvars(lpi->grbmodel, ndelcols, which) );
1635  CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
1636 
1637  BMSfreeMemoryArray( &which );
1638 
1639  checkRangeInfo(lpi);
1640 
1641  return SCIP_OKAY;
1642 }
1643 
1644 /** deletes columns from LP; the new position of a column must not be greater that its old position */
1646  SCIP_LPI* lpi, /**< LP interface structure */
1647  int* dstat /**< deletion status of columns
1648  * input: 1 if column should be deleted, 0 if not
1649  * output: new position of column, -1 if column was deleted */
1650  )
1651 {
1652  int* which;
1653  int ncols;
1654  int num;
1655  int j;
1656 
1657  assert(lpi != NULL);
1658  assert(lpi->grbmodel != NULL);
1659  assert(dstat != NULL);
1660 
1661  SCIPdebugMessage("deleting a column set from Gurobi\n");
1662 
1663  invalidateSolution(lpi);
1664 
1665  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
1666 
1667  /* Gurobi can't delete a set of marked columns, we have to set up an index array */
1668  SCIP_ALLOC( BMSallocMemoryArray(&which, ncols) );
1669  num = 0;
1670  for( j = 0; j < ncols; ++j )
1671  {
1672  if( dstat[j] )
1673  which[num++] = j;
1674  }
1675 
1676  CHECK_ZERO( lpi->messagehdlr, GRBdelvars(lpi->grbmodel, num, which) );
1677  CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
1678 
1679  /* update dstat */
1680  num = 0;
1681  for( j = 0; j < ncols; ++j )
1682  {
1683  if( dstat[j] )
1684  {
1685  dstat[j] = -1;
1686  ++num;
1687  }
1688  else
1689  dstat[j] = j - num;
1690  }
1691 
1692  BMSfreeMemoryArray( &which );
1693 
1694  checkRangeInfo(lpi);
1695 
1696  return SCIP_OKAY;
1697 }
1698 
1699 /** adds rows to the LP */
1701  SCIP_LPI* lpi, /**< LP interface structure */
1702  int nrows, /**< number of rows to be added */
1703  const SCIP_Real* lhs, /**< left hand sides of new rows */
1704  const SCIP_Real* rhs, /**< right hand sides of new rows */
1705  char** rownames, /**< row names, or NULL */
1706  int nnonz, /**< number of nonzero elements to be added to the constraint matrix */
1707  const int* beg, /**< start index of each row in ind- and val-array, or NULL if nnonz == 0 */
1708  const int* ind, /**< column indices of constraint matrix entries, or NULL if nnonz == 0 */
1709  const SCIP_Real* val /**< values of constraint matrix entries, or NULL if nnonz == 0 */
1710  )
1711 {
1712  int rngcount;
1713  int oldnrows = -1;
1714 
1715  assert(lpi != NULL);
1716  assert(lpi->grbmodel != NULL);
1717  assert((lpi->nrngrows > 0) == (lpi->rngrowmap != NULL));
1718  assert(lhs != NULL);
1719  assert(rhs != NULL);
1720  assert(nnonz == 0 || beg != NULL);
1721  assert(nnonz == 0 || ind != NULL);
1722  assert(nnonz == 0 || val != NULL);
1723 
1724  SCIPdebugMessage("adding %d rows with %d nonzeros to Gurobi\n", nrows, nnonz);
1725 
1726  invalidateSolution(lpi);
1727 
1728 #ifndef NDEBUG
1729  if ( nnonz > 0 )
1730  {
1731  /* perform check that no new cols are added - this is forbidden */
1732  int ncols;
1733  int j;
1734 
1735  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
1736  for (j = 0; j < nnonz; ++j) {
1737  assert( 0 <= ind[j] && ind[j] < ncols );
1738  assert( val[j] != 0.0 );
1739  }
1740  }
1741 #endif
1742 
1743  SCIP_CALL( ensureSidechgMem(lpi, nrows) );
1744 
1745  /* convert lhs/rhs into sen/rhs/range tuples */
1746  SCIP_CALL( convertSides(lpi, nrows, lhs, rhs, &rngcount) );
1747  if ( lpi->nrngrows > 0 || rngcount > 0 )
1748  {
1749  SCIP_CALL( SCIPlpiGetNRows(lpi, &oldnrows) );
1750  }
1751 
1752  /* add rows to LP */
1753  CHECK_ZERO( lpi->messagehdlr, GRBaddconstrs(lpi->grbmodel, nrows, nnonz, (int*)beg, (int*)ind, (SCIP_Real*)val, lpi->senarray, lpi->rhsarray, rownames) );
1754  CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
1755 
1756  /* update maps for ranged rows */
1757  if ( rngcount > 0 )
1758  {
1759  SCIP_CALL( addRangeInfo(lpi, rngcount, oldnrows) );
1760  }
1761  else if ( lpi->nrngrows > 0 )
1762  {
1763  int r;
1764 
1765  /* extend existing rngrowmap array */
1766  assert(lpi->rngrowmap != NULL);
1767  assert(lpi->rngrows != NULL);
1768  SCIP_CALL( ensureRngrowmapMem(lpi, oldnrows+nrows) );
1769  for (r = oldnrows; r < oldnrows+nrows; r++)
1770  lpi->rngrowmap[r] = -1;
1771  }
1772 
1773  checkRangeInfo(lpi);
1774 
1775  return SCIP_OKAY;
1776 }
1777 
1778 /** deletes all rows in the given range from LP */
1780  SCIP_LPI* lpi, /**< LP interface structure */
1781  int firstrow, /**< first row to be deleted */
1782  int lastrow /**< last row to be deleted */
1783  )
1784 {
1785  int ndelrows;
1786  int* which;
1787  int i;
1788 
1789  ndelrows = lastrow-firstrow+1;
1790 
1791  assert(lpi != NULL);
1792  assert(lpi->grbmodel != NULL);
1793 #ifndef NDEBUG
1794  {
1795  int nrows;
1796  SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
1797  assert(0 <= firstrow && firstrow <= lastrow && lastrow < nrows);
1798  }
1799 #endif
1800 
1801  SCIPdebugMessage("deleting %d rows from Gurobi\n", ndelrows);
1802 
1803  invalidateSolution(lpi);
1804 
1805  /* Gurobi can't delete a range of rows, we have to set up an index array */
1806  SCIP_ALLOC( BMSallocMemoryArray(&which, ndelrows) );
1807  for( i = firstrow; i <= lastrow; ++i )
1808  which[i - firstrow] = i;
1809 
1810  CHECK_ZERO( lpi->messagehdlr, GRBdelconstrs(lpi->grbmodel, ndelrows, which) );
1811  CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
1812 
1813  BMSfreeMemoryArray( &which );
1814 
1815  /* update ranged row info */
1816  if ( lpi->nrngrows > 0 )
1817  {
1818  int nrngrows;
1819  int nrows;
1820 
1821  assert(lpi->rngrowmap != NULL);
1822  assert(lpi->rngrows != NULL);
1823 
1824  /* find first ranged row that has been deleted */
1825  for (i = 0; i < lpi->nrngrows; i++)
1826  {
1827  if ( lpi->rngrows[i] >= firstrow )
1828  break;
1829  }
1830  nrngrows = i;
1831 
1832  /* skip all deleted ranged rows */
1833  for (; i < lpi->nrngrows; i++)
1834  {
1835  if ( lpi->rngrows[i] > lastrow )
1836  break;
1837  }
1838 
1839  /* move remaining ranged rows to the front */
1840  for (; i < lpi->nrngrows; i++)
1841  {
1842  int oldrow = lpi->rngrows[i];
1843  lpi->rngrowmap[oldrow] = nrngrows; /* store at old place for now */
1844  lpi->rngrows[nrngrows] = oldrow - ndelrows;
1845  lpi->rngvals[nrngrows] = lpi->rngvals[i];
1846  nrngrows++;
1847  }
1848 
1849  if ( nrngrows < lpi->nrngrows && lpi->rngvarsadded )
1850  {
1851  /* For simplicity, just delete all range variables from Gurobi LP - it would suffice to only delete those
1852  * corresponding to deleted ranged rows, but this should not matter much. */
1853  SCIP_CALL( delRangeVars(lpi) );
1854  }
1855 
1856  lpi->nrngrows = nrngrows;
1857 
1858  if ( nrngrows == 0 )
1859  clearRangeInfo(lpi);
1860  else
1861  {
1862  /* move rngrowmap entries */
1863  SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
1864  for (i = firstrow; i < nrows; i++)
1865  {
1866  lpi->rngrowmap[i] = lpi->rngrowmap[i+ndelrows];
1867  assert(-1 <= lpi->rngrowmap[i] && lpi->rngrowmap[i] < lpi->nrngrows);
1868  }
1869  }
1870  }
1871 
1872  checkRangeInfo(lpi);
1873 
1874  return SCIP_OKAY;
1875 }
1876 
1877 /** deletes rows from SCIP_LP; the new position of a row must not be greater that its old position */
1879  SCIP_LPI* lpi, /**< LP interface structure */
1880  int* dstat /**< deletion status of rows
1881  * input: 1 if row should be deleted, 0 if not
1882  * output: new position of row, -1 if row was deleted */
1883  )
1884 {
1885  int i;
1886  int num = 0;
1887  int nrows;
1888  int* which;
1889 
1890  assert(lpi != NULL);
1891  assert(lpi->grbmodel != NULL);
1892 
1893  SCIPdebugMessage("deleting a row set from Gurobi\n");
1894 
1895  invalidateSolution(lpi);
1896 
1897  /* Gurobi can't delete a range of rows, we have to set up an index array */
1898  SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
1899  SCIP_ALLOC( BMSallocMemoryArray(&which, nrows) );
1900  for( i = 0; i < nrows; ++i )
1901  {
1902  if( dstat[i] )
1903  which[num++] = i;
1904  }
1905  CHECK_ZERO( lpi->messagehdlr, GRBdelconstrs(lpi->grbmodel, num, which) );
1906  CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
1907 
1908  /* update dstat */
1909  num = 0;
1910  for( i = 0; i < nrows; ++i )
1911  {
1912  if( dstat[i] )
1913  {
1914  dstat[i] = -1;
1915  ++num;
1916  }
1917  else
1918  dstat[i] = i - num;
1919  }
1920 
1921  /* update ranged row info */
1922  if ( lpi->nrngrows > 0 )
1923  {
1924  int nrngrows = 0;
1925 
1926  assert(lpi->rngrowmap != NULL);
1927  assert(lpi->rngrows != NULL);
1928 
1929  for (i = 0; i < lpi->nrngrows; i++)
1930  {
1931  int oldrow = lpi->rngrows[i];
1932  int newrow = dstat[oldrow];
1933  if ( newrow >= 0 )
1934  {
1935  lpi->rngrowmap[oldrow] = nrngrows; /* store at old place for now */
1936  lpi->rngrows[nrngrows] = newrow;
1937  lpi->rngvals[nrngrows] = lpi->rngvals[i];
1938  nrngrows++;
1939  }
1940  }
1941 
1942  if ( nrngrows < lpi->nrngrows && lpi->rngvarsadded )
1943  {
1944  /* for simplicity, just delete all range variables from
1945  * Gurobi LP - it would suffice to only delete those
1946  * corresponding to deleted ranged rows, but this should
1947  * not matter much
1948  */
1949  SCIP_CALL( delRangeVars(lpi) );
1950  }
1951 
1952  lpi->nrngrows = nrngrows;
1953 
1954  if ( nrngrows == 0 )
1955  clearRangeInfo(lpi);
1956  else
1957  {
1958  /* move rngrowmap entries */
1959  for (i = 0; i < nrows; i++)
1960  {
1961  int newrow = dstat[i];
1962  assert(newrow <= i);
1963  if ( newrow >= 0 )
1964  {
1965  lpi->rngrowmap[newrow] = lpi->rngrowmap[i];
1966  assert(-1 <= lpi->rngrowmap[newrow] && lpi->rngrowmap[newrow] < lpi->nrngrows);
1967  }
1968  }
1969  }
1970  }
1971 
1972  BMSfreeMemoryArray( &which );
1973 
1974  checkRangeInfo(lpi);
1975 
1976  return SCIP_OKAY;
1977 }
1978 
1979 /** clears the whole LP */
1981  SCIP_LPI* lpi /**< LP interface structure */
1982  )
1983 {
1984  int nrows;
1985  int ncols;
1986 
1987  assert( lpi != NULL );
1988  assert( lpi->grbmodel != NULL );
1989  assert( lpi->grbenv != NULL );
1990 
1991  SCIPdebugMessage("clearing Gurobi LP\n");
1992 
1993  invalidateSolution(lpi);
1994 
1995  SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
1996  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
1997 
1998  if ( nrows >= 1 )
1999  {
2000  SCIP_CALL( SCIPlpiDelRows(lpi, 0, nrows-1) );
2001  }
2002  if ( ncols >= 1 )
2003  {
2004  SCIP_CALL( SCIPlpiDelCols(lpi, 0, ncols-1) );
2005  }
2006 
2007 #ifdef SCIP_DISABLED_CODE
2008  /* the following seems to be slower */
2009  CHECK_ZERO( lpi->messagehdlr, GRBfreemodel(lpi->grbmodel) );
2010  CHECK_ZERO( lpi->messagehdlr, GRBnewmodel(lpi->grbenv, &(lpi->grbmodel), "", 0, NULL, NULL, NULL, NULL, NULL) );
2011  CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
2012 #endif
2013 
2014  /* clear ranged row info */
2015  clearRangeInfo(lpi);
2016 
2017  checkRangeInfo(lpi);
2018 
2019  return SCIP_OKAY;
2020 }
2021 
2022 /** changes lower and upper bounds of columns */
2024  SCIP_LPI* lpi, /**< LP interface structure */
2025  int ncols, /**< number of columns to change bounds for */
2026  const int* ind, /**< column indices or NULL if ncols is zero */
2027  const SCIP_Real* lb, /**< values for the new lower bounds or NULL if ncols is zero */
2028  const SCIP_Real* ub /**< values for the new upper bounds or NULL if ncols is zero*/
2029  )
2030 {
2031  int i;
2032 
2033  assert(lpi != NULL);
2034  assert(lpi->grbmodel != NULL);
2035  assert(ncols == 0 || (ind != NULL && lb != NULL && ub != NULL));
2036 
2037  SCIPdebugMessage("changing %d bounds in Gurobi\n", ncols);
2038  if( ncols <= 0 )
2039  return SCIP_OKAY;
2040 
2041  for (i = 0; i < ncols; ++i)
2042  {
2043  SCIPdebugPrintf(" col %d: [%g,%g]\n", ind[i], lb[i], ub[i]);
2044 
2045  if ( SCIPlpiIsInfinity(lpi, lb[i]) )
2046  {
2047  SCIPerrorMessage("LP Error: fixing lower bound for variable %d to infinity.\n", ind[i]);
2048  return SCIP_LPERROR;
2049  }
2050  if ( SCIPlpiIsInfinity(lpi, -ub[i]) )
2051  {
2052  SCIPerrorMessage("LP Error: fixing upper bound for variable %d to -infinity.\n", ind[i]);
2053  return SCIP_LPERROR;
2054  }
2055  }
2056 
2057  invalidateSolution(lpi);
2058 
2059  CHECK_ZERO( lpi->messagehdlr, GRBsetdblattrlist(lpi->grbmodel, GRB_DBL_ATTR_LB, ncols, (int*)ind, (SCIP_Real*)lb) );
2060  CHECK_ZERO( lpi->messagehdlr, GRBsetdblattrlist(lpi->grbmodel, GRB_DBL_ATTR_UB, ncols, (int*)ind, (SCIP_Real*)ub) );
2061 
2062  CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
2063 
2064  checkRangeInfo(lpi);
2065 
2066  return SCIP_OKAY;
2067 }
2068 
2069 /** changes left and right hand sides of rows */
2071  SCIP_LPI* lpi, /**< LP interface structure */
2072  int nrows, /**< number of rows to change sides for */
2073  const int* ind, /**< row indices */
2074  const SCIP_Real* lhs, /**< new values for left hand sides */
2075  const SCIP_Real* rhs /**< new values for right hand sides */
2076  )
2077 {
2078  int rngcount;
2079 
2080  assert(lpi != NULL);
2081  assert(lpi->grbmodel != NULL);
2082  assert(ind != NULL);
2083 
2084  SCIPdebugMessage("changing %d sides in Gurobi\n", nrows);
2085  if( nrows <= 0)
2086  return SCIP_OKAY;
2087 
2088  invalidateSolution(lpi);
2089 
2090  /* convert lhs/rhs into sen/rhs/range tuples */
2091  SCIP_CALL( ensureSidechgMem(lpi, nrows) );
2092  SCIP_CALL( convertSides(lpi, nrows, lhs, rhs, &rngcount) );
2093 
2094  /* change row sides */
2095  CHECK_ZERO( lpi->messagehdlr, GRBsetdblattrlist(lpi->grbmodel, GRB_DBL_ATTR_RHS, nrows, (int*)ind, lpi->rhsarray) );
2096  CHECK_ZERO( lpi->messagehdlr, GRBsetcharattrlist(lpi->grbmodel, GRB_CHAR_ATTR_SENSE, nrows, (int*)ind, lpi->senarray) );
2097 
2098  CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
2099 
2100  /* update ranged row info */
2101  if ( rngcount > 0 || lpi->nrngrows > 0 )
2102  {
2103  int modified = 0;
2104  int nnewrngrows = 0;
2105  int ntotrows;
2106  int ncols;
2107  int i;
2108 
2109  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
2110  SCIP_CALL( SCIPlpiGetNRows(lpi, &ntotrows) );
2111 
2112  SCIP_CALL( ensureRngrowmapMem(lpi, ntotrows) );
2113 
2114  for (i = 0; i < nrows; i++)
2115  {
2116  int rngrowidx;
2117  int row;
2118 
2119  row = ind[i];
2120  rngrowidx = lpi->rngrowmap[row];
2121 
2122  assert(-1 <= rngrowidx && rngrowidx < lpi->nrngrows);
2123 
2124  if ( lpi->senarray[i] == GRB_EQUAL && lpi->rngarray[i] > 0.0 )
2125  {
2126  /* row is (now) a ranged row */
2127  if ( rngrowidx >= 0 )
2128  {
2129  /* row was already a ranged row: just update rngval and ub of associated column */
2130  lpi->rngvals[rngrowidx] = lpi->rngarray[i];
2131  if ( !modified && lpi->rngvarsadded )
2132  {
2133  CHECK_ZERO( lpi->messagehdlr, GRBsetdblattrelement(lpi->grbmodel, GRB_DBL_ATTR_UB, ncols+rngrowidx, lpi->rngvals[rngrowidx]) );
2134  }
2135  }
2136  else
2137  {
2138  /* row was not ranged before: we need to reset range variables */
2139  modified = 1;
2140 
2141  /* for now, add row to end of rngrows/rngvals arrays */
2142  SCIP_CALL( ensureRngrowsMem(lpi, lpi->nrngrows + nnewrngrows + 1) );
2143  lpi->rngrowmap[row] = lpi->nrngrows + nnewrngrows;
2144  lpi->rngrows[lpi->nrngrows + nnewrngrows] = row;
2145  lpi->rngvals[lpi->nrngrows + nnewrngrows] = lpi->rngarray[i];
2146  nnewrngrows++;
2147  }
2148  }
2149  else
2150  {
2151  /* row is not (no longer) a ranged row */
2152  if ( rngrowidx >= 0 )
2153  {
2154  /* row was a ranged row before: we need to reset range variables */
2155  modified = 1;
2156  lpi->rngrowmap[row] = -1;
2157  }
2158  }
2159  }
2160 
2161  if ( modified )
2162  {
2163  int nrngrows = 0;
2164 
2165  /* the range status of at least one row changed: discard range variables */
2166  if ( lpi->rngvarsadded )
2167  {
2168  /**@todo Save and restore basis - currently, the basis is destroyed if we discard (and later re-add) range variables */
2169  SCIP_CALL( delRangeVars(lpi) );
2170  }
2171  assert(!lpi->rngvarsadded);
2172 
2173  if ( nnewrngrows > 0 )
2174  {
2175  /* integrate new ranged rows into arrays */
2176  lpi->nrngrows += nnewrngrows;
2177  SCIPsortIntReal(lpi->rngrows, lpi->rngvals, lpi->nrngrows);
2178  }
2179 
2180  /* update rngrowmap and discard rows that are no longer ranged */
2181  for (i = 0; i < lpi->nrngrows; i++)
2182  {
2183  int row = lpi->rngrows[i];
2184  if ( lpi->rngrowmap[row] >= 0 )
2185  {
2186  lpi->rngrowmap[row] = nrngrows;
2187  lpi->rngrows[nrngrows] = row;
2188  lpi->rngvals[nrngrows] = lpi->rngvals[i];
2189  nrngrows++;
2190  }
2191  }
2192  lpi->nrngrows = nrngrows;
2193 
2194  /* discard ranged row info if no ranged rows remain */
2195  if ( nrngrows == 0 )
2196  clearRangeInfo(lpi);
2197  }
2198  }
2199 
2200  checkRangeInfo(lpi);
2201 
2202  return SCIP_OKAY;
2203 }
2204 
2205 /** changes a single coefficient */
2207  SCIP_LPI* lpi, /**< LP interface structure */
2208  int row, /**< row number of coefficient to change */
2209  int col, /**< column number of coefficient to change */
2210  SCIP_Real newval /**< new value of coefficient */
2211  )
2212 {
2213  assert(lpi != NULL);
2214  assert(lpi->grbmodel != NULL);
2215 
2216  SCIPdebugMessage("changing coefficient row %d, column %d in Gurobi to %g\n", row, col, newval);
2217 
2218  invalidateSolution(lpi);
2219 
2220  CHECK_ZERO( lpi->messagehdlr, GRBchgcoeffs(lpi->grbmodel, 1, &row, &col, &newval) );
2221  CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
2222 
2223  return SCIP_OKAY;
2224 }
2225 
2226 /** changes the objective sense */
2228  SCIP_LPI* lpi, /**< LP interface structure */
2229  SCIP_OBJSEN objsen /**< new objective sense */
2230  )
2231 {
2232  int grbobjsen;
2233 
2234  assert(lpi != NULL);
2235  assert(lpi->grbmodel != NULL);
2236  assert(objsen == SCIP_OBJSEN_MAXIMIZE || objsen == SCIP_OBJSEN_MINIMIZE);
2237 
2238  /* convert objective sense */
2239  grbobjsen = (objsen == SCIP_OBJSEN_MINIMIZE) ? GRB_MINIMIZE : GRB_MAXIMIZE;
2240 
2241  SCIPdebugMessage("changing objective sense in Gurobi to %d\n", grbobjsen);
2242 
2243  invalidateSolution(lpi);
2244 
2245  /* The objective sense of Gurobi and SCIP are equal */
2246  CHECK_ZERO( lpi->messagehdlr, GRBsetintattr(lpi->grbmodel, GRB_INT_ATTR_MODELSENSE, grbobjsen) );
2247  CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
2248 
2249  return SCIP_OKAY;
2250 }
2251 
2252 /** changes objective values of columns in the LP */
2254  SCIP_LPI* lpi, /**< LP interface structure */
2255  int ncols, /**< number of columns to change objective value for */
2256  const int* ind, /**< column indices to change objective value for */
2257  const SCIP_Real* obj /**< new objective values for columns */
2258  )
2259 {
2260  assert(lpi != NULL);
2261  assert(lpi->grbmodel != NULL);
2262  assert(ind != NULL);
2263  assert(obj != NULL);
2264 
2265  SCIPdebugMessage("changing %d objective values in Gurobi\n", ncols);
2266 
2267  invalidateSolution(lpi);
2268 
2269  CHECK_ZERO( lpi->messagehdlr, GRBsetdblattrlist(lpi->grbmodel, GRB_DBL_ATTR_OBJ, ncols, (int*)ind, (SCIP_Real*)obj) );
2270  CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
2271 
2272  return SCIP_OKAY;
2273 }
2274 
2275 /** multiplies a row with a non-zero scalar; for negative scalars, the row's sense is switched accordingly */
2277  SCIP_LPI* lpi, /**< LP interface structure */
2278  int row, /**< row number to scale */
2279  SCIP_Real scaleval /**< scaling multiplier */
2280  )
2281 {
2282  SCIP_Real lhs;
2283  SCIP_Real rhs;
2284  int nnonz;
2285  int ncols;
2286  int beg;
2287  int i;
2288 
2289  assert(lpi != NULL);
2290  assert(lpi->grbmodel != NULL);
2291  assert(scaleval != 0.0);
2292 
2293  SCIPdebugMessage("scaling row %d with factor %g in Gurobi\n", row, scaleval);
2294 
2295  invalidateSolution(lpi);
2296 
2297  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
2298  SCIP_CALL( ensureValMem(lpi, ncols+1) ); /* +1 for range variable */
2299 
2300  /* get the row */
2301  SCIP_CALL( SCIPlpiGetRows(lpi, row, row, &lhs, &rhs, &nnonz, &beg, lpi->indarray, lpi->valarray) );
2302 
2303  /* scale row coefficients */
2304  for ( i = 0; i < nnonz; ++i )
2305  {
2306  SCIP_CALL( SCIPlpiChgCoef(lpi, row, lpi->indarray[i], lpi->valarray[i] * scaleval) );
2307  }
2308 
2309  /* scale row sides */
2310  if( lhs > -GRB_INFBOUND )
2311  lhs *= scaleval;
2312  else if( scaleval < 0.0 )
2313  lhs = GRB_INFBOUND;
2314  if( rhs < GRB_INFBOUND )
2315  rhs *= scaleval;
2316  else if( scaleval < 0.0 )
2317  rhs = -GRB_INFBOUND;
2318  if( scaleval > 0.0 )
2319  {
2320  SCIP_CALL( SCIPlpiChgSides(lpi, 1, &row, &lhs, &rhs) );
2321  }
2322  else
2323  {
2324  SCIP_CALL( SCIPlpiChgSides(lpi, 1, &row, &rhs, &lhs) );
2325  }
2326 
2327  checkRangeInfo(lpi);
2328 
2329  return SCIP_OKAY;
2330 }
2331 
2332 /** multiplies a column with a non-zero scalar; the objective value is multiplied with the scalar, and the bounds
2333  * are divided by the scalar; for negative scalars, the column's bounds are switched
2334  */
2336  SCIP_LPI* lpi, /**< LP interface structure */
2337  int col, /**< column number to scale */
2338  SCIP_Real scaleval /**< scaling multiplier */
2339  )
2340 {
2341  SCIP_Real lb;
2342  SCIP_Real ub;
2343  SCIP_Real obj;
2344  int nnonz;
2345  int nrows;
2346  int beg;
2347  int i;
2348 
2349  assert(lpi != NULL);
2350  assert(lpi->grbmodel != NULL);
2351  assert(scaleval != 0.0);
2352 
2353  SCIPdebugMessage("scaling column %d with factor %g in Gurobi\n", col, scaleval);
2354 
2355  invalidateSolution(lpi);
2356 
2357  SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
2358  SCIP_CALL( ensureValMem(lpi, nrows) );
2359 
2360  /* get the column */
2361  SCIP_CALL( SCIPlpiGetCols(lpi, col, col, &lb, &ub, &nnonz, &beg, lpi->indarray, lpi->valarray) );
2362 
2363  /* get objective coefficient */
2364  SCIP_CALL( SCIPlpiGetObj(lpi, col, col, &obj) );
2365 
2366  /* scale column coefficients */
2367  for( i = 0; i < nnonz; ++i )
2368  {
2369  SCIP_CALL( SCIPlpiChgCoef(lpi, lpi->indarray[i], col, lpi->valarray[i] * scaleval) );
2370  }
2371 
2372  /* scale objective value */
2373  obj *= scaleval;
2374  SCIP_CALL( SCIPlpiChgObj(lpi, 1, &col, &obj) );
2375 
2376  /* scale column bounds */
2377  if( lb > -GRB_INFINITY )
2378  lb /= scaleval;
2379  else if( scaleval < 0.0 )
2380  lb = GRB_INFINITY;
2381  if( ub < GRB_INFINITY )
2382  ub /= scaleval;
2383  else if( scaleval < 0.0 )
2384  ub = -GRB_INFINITY;
2385  if( scaleval > 0.0 )
2386  {
2387  SCIP_CALL( SCIPlpiChgBounds(lpi, 1, &col, &lb, &ub) );
2388  }
2389  else
2390  {
2391  SCIP_CALL( SCIPlpiChgBounds(lpi, 1, &col, &ub, &lb) );
2392  }
2393 
2394  checkRangeInfo(lpi);
2395 
2396  return SCIP_OKAY;
2397 }
2398 
2399 /**@} */
2400 
2401 
2402 
2403 
2404 /*
2405  * Data Accessing Methods
2406  */
2407 
2408 /**@name Data Accessing Methods */
2409 /**@{ */
2410 
2411 /** gets the number of rows in the LP */
2413  SCIP_LPI* lpi, /**< LP interface structure */
2414  int* nrows /**< pointer to store the number of rows */
2415  )
2416 {
2417  assert(lpi != NULL);
2418  assert(lpi->grbmodel != NULL);
2419  assert(nrows != NULL);
2420 
2421  SCIPdebugMessage("getting number of rows\n");
2422 
2423  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_NUMCONSTRS, nrows) );
2424 
2425  return SCIP_OKAY;
2426 }
2427 
2428 /** gets the number of columns in the LP */
2430  SCIP_LPI* lpi, /**< LP interface structure */
2431  int* ncols /**< pointer to store the number of cols */
2432  )
2433 {
2434  assert(lpi != NULL);
2435  assert(lpi->grbmodel != NULL);
2436  assert(ncols != NULL);
2437 
2438  SCIPdebugMessage("getting number of columns\n");
2439 
2440  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_NUMVARS, ncols) );
2441 
2442  /* subtract number of ranged rows, as these are the LPI internal columns */
2443  if ( lpi->rngvarsadded )
2444  (*ncols) -= lpi->nrngrows;
2445 
2446  return SCIP_OKAY;
2447 }
2448 
2449 /** gets the number of nonzero elements in the LP constraint matrix */
2451  SCIP_LPI* lpi, /**< LP interface structure */
2452  int* nnonz /**< pointer to store the number of nonzeros */
2453  )
2454 {
2455  assert(lpi != NULL);
2456  assert(lpi->grbmodel != NULL);
2457  assert(nnonz != NULL);
2458 
2459  SCIPdebugMessage("getting number of non-zeros\n");
2460 
2461  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_NUMNZS, nnonz) );
2462 
2463  /* subtract number of ranged rows, as these are non-zeros for the LPI internal columns */
2464  if ( lpi->rngvarsadded )
2465  (*nnonz) -= lpi->nrngrows;
2466 
2467  return SCIP_OKAY;
2468 }
2469 
2470 /** gets columns from LP problem object; the arrays have to be large enough to store all values;
2471  * Either both, lb and ub, have to be NULL, or both have to be non-NULL,
2472  * either nnonz, beg, ind, and val have to be NULL, or all of them have to be non-NULL.
2473  */
2475  SCIP_LPI* lpi, /**< LP interface structure */
2476  int firstcol, /**< first column to get from LP */
2477  int lastcol, /**< last column to get from LP */
2478  SCIP_Real* lb, /**< buffer to store the lower bound vector, or NULL */
2479  SCIP_Real* ub, /**< buffer to store the upper bound vector, or NULL */
2480  int* nnonz, /**< pointer to store the number of nonzero elements returned, or NULL */
2481  int* beg, /**< buffer to store start index of each column in ind- and val-array, or NULL */
2482  int* ind, /**< buffer to store row indices of constraint matrix entries, or NULL */
2483  SCIP_Real* val /**< buffer to store values of constraint matrix entries, or NULL */
2484  )
2485 {
2486  assert(lpi != NULL);
2487  assert(lpi->grbmodel != NULL);
2488  assert((lb != NULL && ub != NULL) || (lb == NULL && ub == NULL));
2489  assert((nnonz != NULL && beg != NULL && ind != NULL && val != NULL) || (nnonz == NULL && beg == NULL && ind == NULL && val == NULL));
2490 #ifndef NDEBUG
2491  {
2492  int ncols;
2493  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
2494  assert(0 <= firstcol && firstcol <= lastcol && lastcol < ncols);
2495  }
2496 #endif
2497 
2498  SCIPdebugMessage("getting columns %d to %d\n", firstcol, lastcol);
2499 
2500  if( lb != NULL )
2501  {
2502  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_LB, firstcol, lastcol-firstcol+1, lb) );
2503  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_UB, firstcol, lastcol-firstcol+1, ub) );
2504  }
2505 
2506  if( nnonz != NULL )
2507  {
2508  /* get matrix entries */
2509  CHECK_ZERO( lpi->messagehdlr, GRBgetvars(lpi->grbmodel, nnonz, beg, ind, val, firstcol, lastcol-firstcol+1) );
2510  }
2511 
2512  return SCIP_OKAY;
2513 }
2514 
2515 /** gets rows from LP problem object; the arrays have to be large enough to store all values.
2516  * Either both, lhs and rhs, have to be NULL, or both have to be non-NULL,
2517  * either nnonz, beg, ind, and val have to be NULL, or all of them have to be non-NULL.
2518  */
2520  SCIP_LPI* lpi, /**< LP interface structure */
2521  int firstrow, /**< first row to get from LP */
2522  int lastrow, /**< last row to get from LP */
2523  SCIP_Real* lhs, /**< buffer to store left hand side vector, or NULL */
2524  SCIP_Real* rhs, /**< buffer to store right hand side vector, or NULL */
2525  int* nnonz, /**< pointer to store the number of nonzero elements returned, or NULL */
2526  int* beg, /**< buffer to store start index of each row in ind- and val-array, or NULL */
2527  int* ind, /**< buffer to store column indices of constraint matrix entries, or NULL */
2528  SCIP_Real* val /**< buffer to store values of constraint matrix entries, or NULL */
2529  )
2530 {
2531  assert(lpi != NULL);
2532  assert(lpi->grbmodel != NULL);
2533  assert((lhs == NULL && rhs == NULL) || (rhs != NULL && lhs != NULL));
2534  assert((nnonz != NULL && beg != NULL && ind != NULL && val != NULL) || (nnonz == NULL && beg == NULL && ind == NULL && val == NULL));
2535 
2536 #ifndef NDEBUG
2537  {
2538  int nrows;
2539  SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
2540  assert(0 <= firstrow && firstrow <= lastrow && lastrow < nrows);
2541  }
2542 #endif
2543 
2544  SCIPdebugMessage("getting rows %d to %d\n", firstrow, lastrow);
2545 
2546  if( lhs != NULL )
2547  {
2548  /* get row sense and rhs */
2549  SCIP_CALL( ensureSidechgMem(lpi, lastrow - firstrow + 1) );
2550  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_RHS, firstrow, lastrow-firstrow+1, lpi->rhsarray) );
2551  CHECK_ZERO( lpi->messagehdlr, GRBgetcharattrarray(lpi->grbmodel, GRB_CHAR_ATTR_SENSE, firstrow, lastrow-firstrow+1, lpi->senarray) );
2552 
2553  /* convert sen and rhs into lhs/rhs tuples */
2554  SCIP_CALL( reconvertSides(lpi, firstrow, lastrow, lhs, rhs) );
2555  }
2556 
2557  if( nnonz != NULL )
2558  {
2559  assert(beg != NULL && ind != NULL && val != NULL); /* for lint */
2560 
2561  /* get matrix entries */
2562  CHECK_ZERO( lpi->messagehdlr, GRBgetconstrs(lpi->grbmodel, nnonz, beg, ind, val, firstrow, lastrow-firstrow+1) );
2563 
2564  if ( lpi->rngvarsadded )
2565  {
2566  int i;
2567 
2568  assert(lpi->rngrowmap != NULL);
2569  assert(lpi->rngrows != NULL);
2570 
2571  /* remove non-zeros for range variables from rows */
2572  for (i = firstrow; i <= lastrow; i++)
2573  {
2574  assert(-1 <= lpi->rngrowmap[i] && lpi->rngrowmap[i] < lpi->nrngrows);
2575  if ( lpi->rngrowmap[i] >= 0 )
2576  break;
2577  }
2578  if ( i <= lastrow )
2579  {
2580  /* skip last non-zero of this first ranged row */
2581  int newnz = (i < lastrow ? beg[i - firstrow +1]-1 : (*nnonz)-1); /*lint !e661*/
2582 
2583  /* process remaining rows, moving non-zeros to the front */
2584  for (; i <= lastrow; i++)
2585  {
2586  int thebeg;
2587  int theend;
2588 
2589  thebeg = beg[i - firstrow]; /*lint !e661*/
2590  theend = (i < lastrow ? beg[i - firstrow +1] : *nnonz);
2591 
2592  assert(-1 <= lpi->rngrowmap[i] && lpi->rngrowmap[i] < lpi->nrngrows);
2593  if ( lpi->rngrowmap[i] >= 0 )
2594  theend--;
2595 
2596  memmove(&ind[newnz], &ind[thebeg], (theend - thebeg) * sizeof(*ind)); /*lint !e776*/
2597  memmove(&val[newnz], &val[thebeg], (theend - thebeg) * sizeof(*val)); /*lint !e776*/
2598  beg[i - firstrow] = newnz; /*lint !e661*/
2599  newnz += theend - thebeg;
2600  }
2601  assert(newnz < *nnonz);
2602  *nnonz = newnz;
2603  }
2604  }
2605  }
2606 
2607  return SCIP_OKAY;
2608 }
2609 
2610 /** gets column names */
2612  SCIP_LPI* lpi, /**< LP interface structure */
2613  int firstcol, /**< first column to get name from LP */
2614  int lastcol, /**< last column to get name from LP */
2615  char** colnames, /**< pointers to column names (of size at least lastcol-firstcol+1) or NULL if namestoragesize is zero */
2616  char* namestorage, /**< storage for col names or NULL if namestoragesize is zero */
2617  int namestoragesize, /**< size of namestorage (if 0, storageleft returns the storage needed) */
2618  int* storageleft /**< amount of storage left (if < 0 the namestorage was not big enough) or NULL if namestoragesize is zero */
2619  )
2620 { /*lint --e{715}*/
2621  assert(lpi != NULL);
2622  assert(lpi->grbmodel != NULL);
2623  assert(colnames != NULL || namestoragesize == 0);
2624  assert(namestorage != NULL || namestoragesize == 0);
2625  assert(namestoragesize >= 0);
2626  assert(storageleft != NULL);
2627  SCIPerrorMessage("SCIPlpiGetColNames() has not been implemented yet.\n");
2628  return SCIP_LPERROR;
2629 }
2630 
2631 /** gets row names */
2633  SCIP_LPI* lpi, /**< LP interface structure */
2634  int firstrow, /**< first row to get name from LP */
2635  int lastrow, /**< last row to get name from LP */
2636  char** rownames, /**< pointers to row names (of size at least lastrow-firstrow+1) or NULL if namestoragesize is zero */
2637  char* namestorage, /**< storage for row names or NULL if namestoragesize is zero */
2638  int namestoragesize, /**< size of namestorage (if 0, -storageleft returns the storage needed) */
2639  int* storageleft /**< amount of storage left (if < 0 the namestorage was not big enough) or NULL if namestoragesize is zero */
2640  )
2641 { /*lint --e{715}*/
2642  assert(lpi != NULL);
2643  assert(lpi->grbmodel != NULL);
2644  assert(rownames != NULL || namestoragesize == 0);
2645  assert(namestorage != NULL || namestoragesize == 0);
2646  assert(namestoragesize >= 0);
2647  assert(storageleft != NULL);
2648  SCIPerrorMessage("SCIPlpiGetRowNames() has not been implemented yet.\n");
2649  return SCIP_LPERROR;
2650 }
2651 
2652 /** gets the objective sense of the LP */
2654  SCIP_LPI* lpi, /**< LP interface structure */
2655  SCIP_OBJSEN* objsen /**< pointer to store objective sense */
2656  )
2657 {
2658  int grbobjsen;
2659 
2660  assert( lpi != NULL );
2661  assert( lpi->grbmodel != NULL );
2662  assert( objsen != NULL );
2663 
2664  SCIPdebugMessage("getting objective sense\n");
2665 
2666  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_MODELSENSE, &grbobjsen) );
2667  assert(grbobjsen == GRB_MINIMIZE || grbobjsen == GRB_MAXIMIZE);
2668 
2669  *objsen = (grbobjsen == GRB_MINIMIZE) ? SCIP_OBJSEN_MINIMIZE : SCIP_OBJSEN_MAXIMIZE;
2670 
2671  return SCIP_OKAY;
2672 }
2673 
2674 /** gets objective coefficients from LP problem object */
2676  SCIP_LPI* lpi, /**< LP interface structure */
2677  int firstcol, /**< first column to get objective coefficient for */
2678  int lastcol, /**< last column to get objective coefficient for */
2679  SCIP_Real* vals /**< array to store objective coefficients */
2680  )
2681 {
2682  assert(lpi != NULL);
2683  assert(lpi->grbmodel != NULL);
2684  assert(firstcol <= lastcol);
2685  assert(vals != NULL);
2686 
2687  SCIPdebugMessage("getting objective values %d to %d\n", firstcol, lastcol);
2688 
2689  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_OBJ, firstcol, lastcol-firstcol+1, vals) );
2690 
2691  return SCIP_OKAY;
2692 }
2693 
2694 /** gets current bounds from LP problem object */
2696  SCIP_LPI* lpi, /**< LP interface structure */
2697  int firstcol, /**< first column to get bounds for */
2698  int lastcol, /**< last column to get bounds for */
2699  SCIP_Real* lbs, /**< array to store lower bound values, or NULL */
2700  SCIP_Real* ubs /**< array to store upper bound values, or NULL */
2701  )
2702 {
2703  assert(lpi != NULL);
2704  assert(lpi->grbmodel != NULL);
2705 #ifndef NDEBUG
2706  {
2707  int ncols;
2708  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
2709  assert(0 <= firstcol && firstcol <= lastcol && lastcol < ncols);
2710  }
2711 #endif
2712 
2713  SCIPdebugMessage("getting bounds %d to %d\n", firstcol, lastcol);
2714 
2715  if( lbs != NULL )
2716  {
2717  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_LB, firstcol, lastcol-firstcol+1, lbs) );
2718  }
2719 
2720  if( ubs != NULL )
2721  {
2722  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_UB, firstcol, lastcol-firstcol+1, ubs) );
2723  }
2724 
2725  return SCIP_OKAY;
2726 }
2727 
2728 /** gets current row sides from LP problem object */
2730  SCIP_LPI* lpi, /**< LP interface structure */
2731  int firstrow, /**< first row to get sides for */
2732  int lastrow, /**< last row to get sides for */
2733  SCIP_Real* lhss, /**< array to store left hand side values, or NULL */
2734  SCIP_Real* rhss /**< array to store right hand side values, or NULL */
2735  )
2736 {
2737  assert(lpi != NULL);
2738  assert(lpi->grbmodel != NULL);
2739  assert(firstrow <= lastrow);
2740 
2741  SCIPdebugMessage("getting row sides %d to %d\n", firstrow, lastrow);
2742 
2743  /* get row sense, rhs, and ranges */
2744  SCIP_CALL( ensureSidechgMem(lpi, lastrow - firstrow + 1) );
2745 
2746  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_RHS, firstrow, lastrow-firstrow+1, lpi->rhsarray) );
2747  CHECK_ZERO( lpi->messagehdlr, GRBgetcharattrarray(lpi->grbmodel, GRB_CHAR_ATTR_SENSE, firstrow, lastrow-firstrow+1, lpi->senarray) );
2748 
2749  /* convert sen and rhs into lhs/rhs tuples */
2750  SCIP_CALL( reconvertSides(lpi, firstrow, lastrow, lhss, rhss) );
2751 
2752  return SCIP_OKAY;
2753 }
2754 
2755 /** gets a single coefficient */
2757  SCIP_LPI* lpi, /**< LP interface structure */
2758  int row, /**< row number of coefficient */
2759  int col, /**< column number of coefficient */
2760  SCIP_Real* val /**< pointer to store the value of the coefficient */
2761  )
2762 {
2763  assert(lpi != NULL);
2764  assert(lpi->grbmodel != NULL);
2765  assert(val != NULL);
2766 
2767  SCIPdebugMessage("getting coefficient of row %d col %d\n", row, col);
2768 
2769  CHECK_ZERO( lpi->messagehdlr, GRBgetcoeff(lpi->grbmodel, row, col, val) );
2770 
2771  return SCIP_OKAY;
2772 }
2773 
2774 /**@} */
2775 
2776 
2777 
2778 
2779 /*
2780  * Solving Methods
2781  */
2782 
2783 /**@name Solving Methods */
2784 /**@{ */
2785 
2786 /** calls primal simplex to solve the LP
2787  *
2788  * @todo Check concurrent (GRB_METHOD_CONCURRENT or GRB_METHOD_DETERMINISTIC_CONCURRENT)
2789  */
2791  SCIP_LPI* lpi /**< LP interface structure */
2792  )
2793 {
2794  double cnt;
2795  int retval;
2796 
2797  assert( lpi != NULL );
2798  assert( lpi->grbmodel != NULL );
2799  assert( lpi->grbenv != NULL );
2800 
2801 #ifdef SCIP_DEBUG
2802  {
2803  int ncols, nrows;
2804  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
2805  SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
2806  SCIPdebugMessage("calling Gurobi primal simplex: %d cols, %d rows\n", ncols, nrows);
2807  }
2808 #endif
2809 
2810  invalidateSolution(lpi);
2811 
2812  if ( lpi->fromscratch )
2813  {
2814  CHECK_ZERO( lpi->messagehdlr, GRBresetmodel(lpi->grbmodel) );
2815  }
2816 
2817  SCIPdebugMessage("calling GRBoptimize() - primal\n");
2818 
2819  /* set primal simplex */
2820  SCIP_CALL( setParameterValues(lpi, &(lpi->grbparam)) );
2821  CHECK_ZERO( lpi->messagehdlr, GRBsetintparam(lpi->grbenv, GRB_INT_PAR_METHOD, GRB_METHOD_PRIMAL) );
2822 
2823  /* add range variables */
2824  if ( lpi->nrngrows > 0 && !lpi->rngvarsadded )
2825  {
2826  SCIP_CALL( addRangeVars(lpi) );
2827  }
2828 
2829  retval = GRBoptimize(lpi->grbmodel);
2830  switch( retval )
2831  {
2832  case 0:
2833  break;
2834  case GRB_ERROR_OUT_OF_MEMORY:
2835  return SCIP_NOMEMORY;
2836  default:
2837  return SCIP_LPERROR;
2838  }
2839 
2840  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_ITERCOUNT, &cnt) );
2841  lpi->iterations = (int) cnt;
2842 
2843  lpi->solisbasic = TRUE;
2844  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_STATUS, &lpi->solstat) );
2845 
2846  SCIPdebugMessage("Gurobi primal simplex needed %d iterations to gain LP status %d\n", (int) cnt, lpi->solstat);
2847 
2848  /* maybe the preprocessor solved the problem; but we need a solution, so solve again without preprocessing */
2849  assert( lpi->solstat != GRB_INF_OR_UNBD );
2850  if( lpi->solstat == GRB_INFEASIBLE )
2851  {
2852  int presolve;
2853 
2854  CHECK_ZERO( lpi->messagehdlr, GRBgetintparam(lpi->grbenv, GRB_INT_PAR_PRESOLVE, &presolve) );
2855 
2856  if( presolve != GRB_PRESOLVE_OFF )
2857  {
2858  SCIPdebugMessage("presolver may have solved the problem -> calling Gurobi primal simplex again without presolve\n");
2859 
2860  /* switch off preprocessing */
2861  CHECK_ZERO( lpi->messagehdlr, GRBsetintparam(lpi->grbenv, GRB_INT_PAR_PRESOLVE, GRB_PRESOLVE_OFF) );
2862 
2863  retval = GRBoptimize(lpi->grbmodel);
2864  switch( retval )
2865  {
2866  case 0:
2867  break;
2868  case GRB_ERROR_OUT_OF_MEMORY:
2869  return SCIP_NOMEMORY;
2870  default:
2871  return SCIP_LPERROR;
2872  }
2873 
2874  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_ITERCOUNT, &cnt) );
2875  lpi->iterations += (int) cnt;
2876  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_STATUS, &lpi->solstat) );
2877  SCIPdebugMessage(" -> Gurobi returned solstat=%d (%d iterations)\n", lpi->solstat, lpi->iterations);
2878 
2879  /* reset parameters */
2880  CHECK_ZERO( lpi->messagehdlr, GRBsetintparam(lpi->grbenv, GRB_INT_PAR_PRESOLVE, presolve) );
2881  }
2882 
2883  if( lpi->solstat == GRB_INF_OR_UNBD )
2884  {
2885  /* preprocessing was not the problem; issue a warning message and treat LP as infeasible */
2886  SCIPerrorMessage("Gurobi primal simplex returned GRB_INF_OR_UNBD after presolving was turned off\n");
2887  return SCIP_LPERROR;
2888  }
2889  }
2890  else if ( lpi->solstat == GRB_UNBOUNDED )
2891  {
2892  /* Unbounded means that there exists an unbounded primal ray. However, this does not state whether the problem is
2893  * feasible. Thus, we temporarily set the objective to 0 and solve again. */
2894  SCIP_Real* zeroobjcoefs;
2895  SCIP_Real* objcoefs;
2896  SCIP_Real oldobjcutoff;
2897  int grbobjsen;
2898  int status;
2899  int ncols;
2900 
2901  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
2902  SCIP_ALLOC( BMSallocMemoryArray(&objcoefs, ncols) );
2903  SCIP_ALLOC( BMSallocClearMemoryArray(&zeroobjcoefs, ncols) );
2904 
2905  /* preserve objective coefficients */
2906  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_OBJ, 0, ncols, objcoefs) );
2907 
2908  /* set objective to 0 */
2909  CHECK_ZERO( lpi->messagehdlr, GRBsetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_OBJ, 0, ncols, zeroobjcoefs) );
2910 
2911  /* disable cutoff */
2912  CHECK_ZERO( lpi->messagehdlr, GRBgetdblparam(lpi->grbenv, GRB_DBL_PAR_CUTOFF, &oldobjcutoff) );
2913 
2914  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_MODELSENSE, &grbobjsen) );
2915  if ( grbobjsen == GRB_MINIMIZE )
2916  {
2917  CHECK_ZERO( lpi->messagehdlr, GRBsetdblparam(lpi->grbenv, GRB_DBL_PAR_CUTOFF, GRB_INFINITY) );
2918  }
2919  else
2920  {
2921  CHECK_ZERO( lpi->messagehdlr, GRBsetdblparam(lpi->grbenv, GRB_DBL_PAR_CUTOFF, -GRB_INFINITY) );
2922  assert( grbobjsen == GRB_MAXIMIZE );
2923  }
2924 
2925  /* solve problem again */
2926  CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
2927  CHECK_ZERO( lpi->messagehdlr, GRBoptimize(lpi->grbmodel) );
2928 
2929  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_ITERCOUNT, &cnt) );
2930  lpi->iterations += (int) cnt;
2931 
2932  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_STATUS, &status) );
2933 
2934  /* restore objective */
2935  CHECK_ZERO( lpi->messagehdlr, GRBsetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_OBJ, 0, ncols, objcoefs) );
2936  CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
2937 
2938  /* restore objective limit */
2939  CHECK_ZERO( lpi->messagehdlr, GRBsetdblparam(lpi->grbenv, GRB_DBL_PAR_CUTOFF, oldobjcutoff) );
2940 
2941  BMSfreeMemoryArray(&zeroobjcoefs);
2942  BMSfreeMemoryArray(&objcoefs);
2943 
2944  /* possibly correct status */
2945  switch ( status )
2946  {
2947  case GRB_INF_OR_UNBD:
2948  case GRB_INFEASIBLE:
2949  lpi->solstat = GRB_INFEASIBLE;
2950  break;
2951 
2952  case GRB_OPTIMAL:
2953  /* We again have to solve the problem to restore possible unbounded rays. */
2954  CHECK_ZERO( lpi->messagehdlr, GRBoptimize(lpi->grbmodel) );
2955  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_ITERCOUNT, &cnt) );
2956  lpi->iterations += (int) cnt;
2957  break;
2958 
2959  case GRB_ITERATION_LIMIT:
2960  case GRB_TIME_LIMIT:
2961  /* do nothing */
2962  break;
2963 
2964  /* GRB_LOADED, GRB_NODE_LIMIT, GRB_CUTOFF, GRB_SOLUTION_LIMIT, GRB_INTERRUPTED, GRB_NUMERIC, GRB_SUBOPTIMAL, GRB_INPROGRESS, GRB_USER_OBJ_LIMIT */
2965  default:
2966  SCIPerrorMessage("Gurobi returned wrong status %d.\n", status);
2967  return SCIP_LPERROR;
2968  }
2969  }
2970 
2971  checkRangeInfo(lpi);
2972 
2973  return SCIP_OKAY;
2974 }
2975 
2976 /** calls dual simplex to solve the LP
2977  *
2978  * @todo Check concurrent (GRB_METHOD_CONCURRENT or GRB_METHOD_DETERMINISTIC_CONCURRENT)
2979  */
2981  SCIP_LPI* lpi /**< LP interface structure */
2982  )
2983 {
2984  int oldprimdual = 0;
2985  int oldpresolve = GRB_PRESOLVE_OFF;
2986  int retval;
2987  double cnt;
2988  double itlim;
2989 
2990  assert( lpi != NULL );
2991  assert( lpi->grbmodel != NULL );
2992  assert( lpi->grbenv != NULL );
2993 
2994 #ifdef SCIP_DEBUG
2995  {
2996  int ncols, nrows;
2997  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
2998  SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
2999  SCIPdebugMessage("calling Gurobi dual simplex: %d cols, %d rows\n", ncols, nrows);
3000  }
3001 #endif
3002 
3003  invalidateSolution(lpi);
3004 
3005  if ( lpi->fromscratch )
3006  {
3007  CHECK_ZERO( lpi->messagehdlr, GRBresetmodel(lpi->grbmodel) );
3008  }
3009 
3010  SCIPdebugMessage("calling GRBoptimize() - dual\n");
3011 
3012  SCIP_CALL( setParameterValues(lpi, &(lpi->grbparam)) );
3013 
3014  /* set dual simplex */
3015  CHECK_ZERO( lpi->messagehdlr, GRBsetintparam(lpi->grbenv, GRB_INT_PAR_METHOD, GRB_METHOD_DUAL) );
3016 
3017  /* add range variables */
3018  if ( lpi->nrngrows > 0 && !lpi->rngvarsadded )
3019  {
3020  SCIP_CALL( addRangeVars(lpi) );
3021  }
3022 
3023  SCIP_CALL( getDblParam(lpi, GRB_DBL_PAR_ITERATIONLIMIT, &itlim) );
3024  if ( itlim < GRB_INFINITY )
3025  {
3026  /* turn off primal-dual switching for an LP solve that might be a strong branching LP solve */
3027  CHECK_ZERO( lpi->messagehdlr, GRBgetintparam(lpi->grbenv, "GURO_PAR_PRIMDUALSWITCH", &oldprimdual) );
3028  if ( oldprimdual != 0 )
3029  {
3030  CHECK_ZERO( lpi->messagehdlr, GRBsetintparam(lpi->grbenv, "GURO_PAR_PRIMDUALSWITCH", 0) );
3031  }
3032 
3033  /* turn off presolve to avoid the case where the iteration limit is reached
3034  * and we do not get a valid dual bound installed for the original model */
3035  CHECK_ZERO( lpi->messagehdlr, GRBgetintparam(lpi->grbenv, GRB_INT_PAR_PRESOLVE, &oldpresolve) );
3036  if ( oldpresolve != GRB_PRESOLVE_OFF )
3037  {
3038  CHECK_ZERO( lpi->messagehdlr, GRBsetintparam(lpi->grbenv, GRB_INT_PAR_PRESOLVE, GRB_PRESOLVE_OFF) );
3039  }
3040  }
3041 
3042  retval = GRBoptimize(lpi->grbmodel);
3043  switch( retval )
3044  {
3045  case 0:
3046  break;
3047  case GRB_ERROR_OUT_OF_MEMORY:
3048  return SCIP_NOMEMORY;
3049  default:
3050  return SCIP_LPERROR;
3051  }
3052 
3053  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_ITERCOUNT, &cnt) );
3054  lpi->iterations = (int) cnt;
3055 
3056  lpi->solisbasic = TRUE;
3057  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_STATUS, &lpi->solstat) );
3058 
3059  SCIPdebugMessage("Gurobi dual simplex needed %d iterations to gain LP status %d\n", (int) cnt, lpi->solstat);
3060 
3061  if( lpi->solstat == GRB_INF_OR_UNBD )
3062  {
3063  int presolve;
3064  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_PAR_PRESOLVE, &presolve) );
3065 
3066  if( presolve != GRB_PRESOLVE_OFF )
3067  {
3068  /* maybe the preprocessor solved the problem; but we need a solution, so solve again without preprocessing */
3069  SCIPdebugMessage("presolver may have solved the problem -> calling Gurobi dual simplex again without presolve\n");
3070 
3071  /* switch off preprocessing */
3072  CHECK_ZERO( lpi->messagehdlr, GRBsetintattr(lpi->grbmodel, GRB_INT_PAR_PRESOLVE, GRB_PRESOLVE_OFF) );
3073  SCIP_CALL( setParameterValues(lpi, &(lpi->grbparam)) );
3074 
3075  retval = GRBoptimize(lpi->grbmodel);
3076  switch( retval )
3077  {
3078  case 0:
3079  break;
3080  case GRB_ERROR_OUT_OF_MEMORY:
3081  return SCIP_NOMEMORY;
3082  default:
3083  return SCIP_LPERROR;
3084  }
3085 
3086  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_ITERCOUNT, &cnt) );
3087  lpi->iterations += (int) cnt;
3088  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_STATUS, &lpi->solstat) );
3089  SCIPdebugMessage(" -> Gurobi returned solstat=%d (%d iterations)\n", lpi->solstat, lpi->iterations);
3090 
3091  /* switch on preprocessing again */
3092  CHECK_ZERO( lpi->messagehdlr, GRBsetintattr(lpi->grbmodel, GRB_INT_PAR_PRESOLVE, GRB_PRESOLVE_AUTO) );
3093  }
3094 
3095  if( lpi->solstat == GRB_INF_OR_UNBD )
3096  {
3097  /* preprocessing was not the problem; issue a warning message and treat LP as infeasible */
3098  SCIPerrorMessage("Gurobi dual simplex returned GRB_INF_OR_UNBD after presolving was turned off.\n");
3099  return SCIP_LPERROR;
3100  }
3101  }
3102 
3103  checkRangeInfo(lpi);
3104 
3105  /* reset parameters to their original values */
3106  if ( oldprimdual != 0 )
3107  {
3108  CHECK_ZERO( lpi->messagehdlr, GRBsetintparam(lpi->grbenv, "GURO_PAR_PRIMDUALSWITCH", oldprimdual) );
3109  }
3110  if ( oldpresolve != GRB_PRESOLVE_OFF )
3111  {
3112  CHECK_ZERO( lpi->messagehdlr, GRBsetintparam(lpi->grbenv, GRB_INT_PAR_PRESOLVE, oldpresolve) );
3113  }
3114 
3115  return SCIP_OKAY;
3116 }
3117 
3118 /** calls barrier or interior point algorithm to solve the LP with crossover to simplex basis */
3120  SCIP_LPI* lpi, /**< LP interface structure */
3121  SCIP_Bool crossover /**< perform crossover */
3122  )
3123 {
3124  int retval;
3125  double cnt;
3126 
3127  assert( lpi != NULL );
3128  assert( lpi->grbmodel != NULL );
3129  assert( lpi->grbenv != NULL );
3130 
3131 #ifdef SCIP_DEBUG
3132  {
3133  int ncols, nrows;
3134  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
3135  SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
3136  SCIPdebugMessage("calling Gurobi barrier: %d cols, %d rows\n", ncols, nrows);
3137  }
3138 #endif
3139 
3140  invalidateSolution(lpi);
3141 
3142  if ( lpi->fromscratch )
3143  {
3144  CHECK_ZERO( lpi->messagehdlr, GRBresetmodel(lpi->grbmodel) );
3145  }
3146 
3147  SCIPdebugMessage("calling GRBoptimize() - barrier\n");
3148 
3149  /* set barrier */
3150  SCIP_CALL( setParameterValues(lpi, &(lpi->grbparam)) );
3151 
3152  if( crossover )
3153  {
3154  /* turn on crossover to automatic setting (-1) */
3155  CHECK_ZERO( lpi->messagehdlr, GRBsetintparam(lpi->grbenv, GRB_INT_PAR_CROSSOVER, -1) );
3156  }
3157  else
3158  {
3159  /* turn off crossover */
3160  CHECK_ZERO( lpi->messagehdlr, GRBsetintparam(lpi->grbenv, GRB_INT_PAR_CROSSOVER, 0) );
3161  }
3162 
3163  CHECK_ZERO( lpi->messagehdlr, GRBsetintparam(lpi->grbenv, GRB_INT_PAR_METHOD, GRB_METHOD_BARRIER) );
3164 
3165  /* add range variables */
3166  if ( lpi->nrngrows > 0 && !lpi->rngvarsadded )
3167  {
3168  SCIP_CALL( addRangeVars(lpi) );
3169  }
3170 
3171  retval = GRBoptimize(lpi->grbmodel);
3172  switch( retval )
3173  {
3174  case 0:
3175  break;
3176  case GRB_ERROR_OUT_OF_MEMORY:
3177  return SCIP_NOMEMORY;
3178  default:
3179  return SCIP_LPERROR;
3180  }
3181 
3182  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_ITERCOUNT, &cnt) );
3183  lpi->iterations = (int) cnt;
3184 
3185  lpi->solisbasic = crossover;
3186  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_STATUS, &lpi->solstat) );
3187 
3188  SCIPdebugMessage("Gurobi barrier needed %d iterations to gain LP status %d\n", (int) cnt, lpi->solstat);
3189 
3190  if( lpi->solstat == GRB_INF_OR_UNBD )
3191  {
3192  int presolve;
3193  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_PAR_PRESOLVE, &presolve) );
3194 
3195  if( presolve != GRB_PRESOLVE_OFF )
3196  {
3197  /* maybe the preprocessor solved the problem; but we need a solution, so solve again without preprocessing */
3198  SCIPdebugMessage("presolver may have solved the problem -> calling Gurobi barrier again without presolve\n");
3199 
3200  /* switch off preprocessing */
3201  CHECK_ZERO( lpi->messagehdlr, GRBsetintattr(lpi->grbmodel, GRB_INT_PAR_PRESOLVE, GRB_PRESOLVE_OFF) );
3202  SCIP_CALL( setParameterValues(lpi, &(lpi->grbparam)) );
3203 
3204  retval = GRBoptimize(lpi->grbmodel);
3205  switch( retval )
3206  {
3207  case 0:
3208  break;
3209  case GRB_ERROR_OUT_OF_MEMORY:
3210  return SCIP_NOMEMORY;
3211  default:
3212  return SCIP_LPERROR;
3213  }
3214 
3215  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_ITERCOUNT, &cnt) );
3216  lpi->iterations += (int) cnt;
3217  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_STATUS, &lpi->solstat) );
3218  SCIPdebugMessage(" -> Gurobi returned solstat=%d (%d iterations)\n", lpi->solstat, lpi->iterations);
3219 
3220  /* switch on preprocessing again */
3221  CHECK_ZERO( lpi->messagehdlr, GRBsetintattr(lpi->grbmodel, GRB_INT_PAR_PRESOLVE, GRB_PRESOLVE_AUTO) );
3222  }
3223 
3224  if( lpi->solstat == GRB_INF_OR_UNBD )
3225  {
3226  /* preprocessing was not the problem; issue a warning message and treat LP as infeasible */
3227  SCIPerrorMessage("Gurobi barrier returned GRB_INF_OR_UNBD after presolving was turned off\n");
3228  return SCIP_LPERROR;
3229  }
3230  }
3231 
3232  checkRangeInfo(lpi);
3233 
3234  return SCIP_OKAY;
3235 }
3236 
3237 /** start strong branching - call before any strong branching */
3239  SCIP_LPI* lpi /**< LP interface structure */
3240  )
3241 { /*lint --e{715}*/
3242  assert( lpi != NULL );
3243  assert( lpi->grbmodel != NULL );
3244  assert( lpi->grbenv != NULL );
3245 
3246  /* currently do nothing */
3247  return SCIP_OKAY;
3248 }
3249 
3250 /** end strong branching - call after any strong branching */
3252  SCIP_LPI* lpi /**< LP interface structure */
3253  )
3254 { /*lint --e{715}*/
3255  assert( lpi != NULL );
3256  assert( lpi->grbmodel != NULL );
3257  assert( lpi->grbenv != NULL );
3258 
3259  /* currently do nothing */
3260  return SCIP_OKAY;
3261 }
3262 
3263 /** performs strong branching iterations on one candidate */
3264 static
3266  SCIP_LPI* lpi, /**< LP interface structure */
3267  int col, /**< column to apply strong branching on */
3268  SCIP_Real psol, /**< current primal solution value of column */
3269  int itlim, /**< iteration limit for strong branchings */
3270  SCIP_Real* down, /**< stores dual bound after branching column down */
3271  SCIP_Real* up, /**< stores dual bound after branching column up */
3272  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
3273  * otherwise, it can only be used as an estimate value */
3274  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
3275  * otherwise, it can only be used as an estimate value */
3276  int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
3277  )
3278 {
3279  SCIP_Real oldlb;
3280  SCIP_Real oldub;
3281  SCIP_Real newlb;
3282  SCIP_Real newub;
3283  SCIP_Real olditlim;
3284  SCIP_Bool error = FALSE;
3285  SCIP_Bool success;
3286  int it;
3287 
3288  assert( lpi != NULL );
3289  assert( lpi->grbmodel != NULL );
3290  assert( lpi->grbenv != NULL );
3291  assert( down != NULL );
3292  assert( up != NULL );
3293  assert( downvalid != NULL );
3294  assert( upvalid != NULL );
3295 
3296  SCIPdebugMessage("performing strong branching on variable %d (%d iterations)\n", col, itlim);
3297 
3298  SCIP_CALL( setParameterValues(lpi, &(lpi->grbparam)) );
3299 
3300  *downvalid = FALSE;
3301  *upvalid = FALSE;
3302  if( iter != NULL )
3303  *iter = 0;
3304 
3305  /* save current LP basis and bounds*/
3306  SCIP_CALL( getBase(lpi, &success) );
3307  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrelement(lpi->grbmodel, GRB_DBL_ATTR_LB, col, &oldlb) );
3308  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrelement(lpi->grbmodel, GRB_DBL_ATTR_UB, col, &oldub) );
3309 
3310  if ( lpi->fromscratch )
3311  {
3312  CHECK_ZERO( lpi->messagehdlr, GRBresetmodel(lpi->grbmodel) );
3313  }
3314 
3315  /* save old iteration limit and set iteration limit to strong branching limit */
3316  if( itlim < 0 )
3317  itlim = INT_MAX;
3318 
3319  SCIP_CALL( getDblParam(lpi, GRB_DBL_PAR_ITERATIONLIMIT, &olditlim) );
3320  SCIP_CALL( setDblParam(lpi, GRB_DBL_PAR_ITERATIONLIMIT, (double) itlim) );
3321 
3322  /* add range variables */
3323  if ( lpi->nrngrows > 0 && !lpi->rngvarsadded )
3324  {
3325  SCIP_CALL( addRangeVars(lpi) );
3326  }
3327 
3328  /* down branch */
3329  newub = EPSCEIL(psol-1.0, 1e-06);
3330  if( newub >= oldlb - 0.5 )
3331  {
3332  SCIPdebugMessage("strong branching down (%g) on x%d (%g) with %d iterations\n", newub, col, psol, itlim);
3333 
3334  CHECK_ZERO( lpi->messagehdlr, GRBsetdblattrelement(lpi->grbmodel, GRB_DBL_ATTR_UB, col, newub) );
3335 
3336  SCIP_CALL( SCIPlpiSolveDual(lpi) );
3337  /* when iteration limit was reached the objective value is not computed */
3338  if( SCIPlpiIsOptimal(lpi) ) /*|| SCIPlpiIsIterlimExc(lpi) ) */
3339  {
3340  SCIP_CALL( SCIPlpiGetObjval(lpi, down) );
3341  *downvalid = TRUE;
3342  }
3343  else if( SCIPlpiIsPrimalInfeasible(lpi) || SCIPlpiIsObjlimExc(lpi) )
3344  {
3345  CHECK_ZERO( lpi->messagehdlr, GRBgetdblparam(lpi->grbenv, GRB_DBL_PAR_CUTOFF, down) );
3346  }
3347  else if( !SCIPlpiIsIterlimExc(lpi) )
3348  error = TRUE;
3349 
3350  if( iter != NULL )
3351  {
3352  SCIP_CALL( SCIPlpiGetIterations(lpi, &it) );
3353  *iter += it;
3354  }
3355  SCIPdebugMessage(" -> down (x%d <= %g): %g\n", col, newub, *down);
3356 
3357  CHECK_ZERO( lpi->messagehdlr, GRBsetdblattrelement(lpi->grbmodel, GRB_DBL_ATTR_UB, col, oldub) );
3358  CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
3359 #ifdef SCIP_DEBUG
3360  {
3361  double b;
3362  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrelement(lpi->grbmodel, GRB_DBL_ATTR_UB, col, &b) );
3363  assert( b == oldub );
3364  }
3365 #endif
3366 
3367  if ( success )
3368  {
3369  SCIP_CALL( setBase(lpi) );
3370  }
3371  }
3372  else
3373  {
3374  CHECK_ZERO( lpi->messagehdlr, GRBgetdblparam(lpi->grbenv, GRB_DBL_PAR_CUTOFF, down) );
3375  *downvalid = TRUE;
3376  }
3377 
3378  /* up branch */
3379  if( !error )
3380  {
3381  newlb = EPSFLOOR(psol+1.0, 1e-06);
3382  if( newlb <= oldub + 0.5 )
3383  {
3384  SCIPdebugMessage("strong branching up (%g) on x%d (%g) with %d iterations\n", newlb, col, psol, itlim);
3385 
3386  CHECK_ZERO( lpi->messagehdlr, GRBsetdblattrelement(lpi->grbmodel, GRB_DBL_ATTR_LB, col, newlb) );
3387 
3388  SCIP_CALL( SCIPlpiSolveDual(lpi) );
3389  /* when iteration limit was reached the objective value is not computed */
3390  if( SCIPlpiIsOptimal(lpi) ) /*|| SCIPlpiIsIterlimExc(lpi) ) */
3391  {
3392  SCIP_CALL( SCIPlpiGetObjval(lpi, up) );
3393  *upvalid = TRUE;
3394  }
3395  else if( SCIPlpiIsPrimalInfeasible(lpi) || SCIPlpiIsObjlimExc(lpi) )
3396  {
3397  CHECK_ZERO( lpi->messagehdlr, GRBgetdblparam(lpi->grbenv, GRB_DBL_PAR_CUTOFF, up) );
3398  }
3399  else if( !SCIPlpiIsIterlimExc(lpi) )
3400  error = TRUE;
3401 
3402  if( iter != NULL )
3403  {
3404  SCIP_CALL( SCIPlpiGetIterations(lpi, &it) );
3405  *iter += it;
3406  }
3407  SCIPdebugMessage(" -> up (x%d >= %g): %g\n", col, newlb, *up);
3408 
3409  CHECK_ZERO( lpi->messagehdlr, GRBsetdblattrelement(lpi->grbmodel, GRB_DBL_ATTR_LB, col, oldlb) );
3410  CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
3411 #ifdef SCIP_DEBUG
3412  {
3413  double b;
3414  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrelement(lpi->grbmodel, GRB_DBL_ATTR_LB, col, &b) );
3415  assert( b == oldlb );
3416  }
3417 #endif
3418 
3419  if ( success )
3420  {
3421  SCIP_CALL( setBase(lpi) );
3422  }
3423  }
3424  else
3425  {
3426  CHECK_ZERO( lpi->messagehdlr, GRBgetdblparam(lpi->grbenv, GRB_DBL_PAR_CUTOFF, up) );
3427  *upvalid = TRUE;
3428  }
3429  }
3430 
3431  /* reset iteration limit */
3432  SCIP_CALL( setDblParam(lpi, GRB_DBL_PAR_ITERATIONLIMIT, olditlim) );
3433  /* CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) ); */
3434 
3435  if( error )
3436  {
3437  SCIPerrorMessage("LP error in strong branching.\n");
3438  return SCIP_LPERROR;
3439  }
3440 
3441  return SCIP_OKAY;
3442 }
3443 
3444 /** performs strong branching iterations on one @b fractional candidate */
3446  SCIP_LPI* lpi, /**< LP interface structure */
3447  int col, /**< column to apply strong branching on */
3448  SCIP_Real psol, /**< fractional current primal solution value of column */
3449  int itlim, /**< iteration limit for strong branchings */
3450  SCIP_Real* down, /**< stores dual bound after branching column down */
3451  SCIP_Real* up, /**< stores dual bound after branching column up */
3452  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
3453  * otherwise, it can only be used as an estimate value */
3454  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
3455  * otherwise, it can only be used as an estimate value */
3456  int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
3457  )
3458 {
3459  /* pass call on to lpiStrongbranch() */
3460  SCIP_CALL( lpiStrongbranch(lpi, col, psol, itlim, down, up, downvalid, upvalid, iter) );
3461 
3462  checkRangeInfo(lpi);
3463 
3464  return SCIP_OKAY;
3465 }
3466 
3467 /** performs strong branching iterations on given @b fractional candidates */
3469  SCIP_LPI* lpi, /**< LP interface structure */
3470  int* cols, /**< columns to apply strong branching on */
3471  int ncols, /**< number of columns */
3472  SCIP_Real* psols, /**< fractional current primal solution values of columns */
3473  int itlim, /**< iteration limit for strong branchings */
3474  SCIP_Real* down, /**< stores dual bounds after branching columns down */
3475  SCIP_Real* up, /**< stores dual bounds after branching columns up */
3476  SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds;
3477  * otherwise, they can only be used as an estimate values */
3478  SCIP_Bool* upvalid, /**< stores whether the returned up values are a valid dual bounds;
3479  * otherwise, they can only be used as an estimate values */
3480  int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
3481  )
3482 {
3483  int j;
3484 
3485  assert( cols != NULL );
3486  assert( psols != NULL );
3487  assert( down != NULL );
3488  assert( up != NULL );
3489  assert( downvalid != NULL );
3490  assert( upvalid != NULL );
3491  assert( down != NULL );
3492 
3493  if( iter != NULL )
3494  *iter = 0;
3495 
3496  for( j = 0; j < ncols; ++j )
3497  {
3498  /* pass call on to lpiStrongbranch() */
3499  SCIP_CALL( lpiStrongbranch(lpi, cols[j], psols[j], itlim, &(down[j]), &(up[j]), &(downvalid[j]), &(upvalid[j]), iter) );
3500  }
3501 
3502  checkRangeInfo(lpi);
3503 
3504  return SCIP_OKAY;
3505 }
3506 
3507 /** performs strong branching iterations on one candidate with @b integral value */
3509  SCIP_LPI* lpi, /**< LP interface structure */
3510  int col, /**< column to apply strong branching on */
3511  SCIP_Real psol, /**< current integral primal solution value of column */
3512  int itlim, /**< iteration limit for strong branchings */
3513  SCIP_Real* down, /**< stores dual bound after branching column down */
3514  SCIP_Real* up, /**< stores dual bound after branching column up */
3515  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
3516  * otherwise, it can only be used as an estimate value */
3517  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
3518  * otherwise, it can only be used as an estimate value */
3519  int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
3520  )
3521 {
3522  /* pass call on to lpiStrongbranch() */
3523  SCIP_CALL( lpiStrongbranch(lpi, col, psol, itlim, down, up, downvalid, upvalid, iter) );
3524 
3525  checkRangeInfo(lpi);
3526 
3527  return SCIP_OKAY;
3528 }
3529 
3530 /** performs strong branching iterations on given candidates with @b integral values */
3532  SCIP_LPI* lpi, /**< LP interface structure */
3533  int* cols, /**< columns to apply strong branching on */
3534  int ncols, /**< number of columns */
3535  SCIP_Real* psols, /**< current integral primal solution values of columns */
3536  int itlim, /**< iteration limit for strong branchings */
3537  SCIP_Real* down, /**< stores dual bounds after branching columns down */
3538  SCIP_Real* up, /**< stores dual bounds after branching columns up */
3539  SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds;
3540  * otherwise, they can only be used as an estimate values */
3541  SCIP_Bool* upvalid, /**< stores whether the returned up values are a valid dual bounds;
3542  * otherwise, they can only be used as an estimate values */
3543  int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
3544  )
3545 {
3546  int j;
3547 
3548  assert( cols != NULL );
3549  assert( psols != NULL );
3550  assert( down != NULL );
3551  assert( up != NULL );
3552  assert( downvalid != NULL );
3553  assert( upvalid != NULL );
3554  assert( down != NULL );
3555 
3556  if( iter != NULL )
3557  *iter = 0;
3558 
3559  for( j = 0; j < ncols; ++j )
3560  {
3561  /* pass call on to lpiStrongbranch() */
3562  SCIP_CALL( lpiStrongbranch(lpi, cols[j], psols[j], itlim, &(down[j]), &(up[j]), &(downvalid[j]), &(upvalid[j]), iter) );
3563  }
3564 
3565  checkRangeInfo(lpi);
3566 
3567  return SCIP_OKAY;
3568 }
3569 /**@} */
3570 
3571 
3572 
3573 
3574 /*
3575  * Solution Information Methods
3576  */
3577 
3578 /**@name Solution Information Methods */
3579 /**@{ */
3580 
3581 /** returns whether a solve method was called after the last modification of the LP */
3583  SCIP_LPI* lpi /**< LP interface structure */
3584  )
3585 {
3586  assert(lpi != NULL);
3587 
3588  return (lpi->solstat != -1);
3589 }
3590 
3591 /** gets information about primal and dual feasibility of the current LP solution
3592  *
3593  * The feasibility information is with respect to the last solving call and it is only relevant if SCIPlpiWasSolved()
3594  * returns true. If the LP is changed, this information might be invalidated.
3595  *
3596  * Note that @a primalfeasible and @a dualfeasible should only return true if the solver has proved the respective LP to
3597  * be feasible. Thus, the return values should be equal to the values of SCIPlpiIsPrimalFeasible() and
3598  * SCIPlpiIsDualFeasible(), respectively. Note that if feasibility cannot be proved, they should return false (even if
3599  * the problem might actually be feasible).
3600  */
3602  SCIP_LPI* lpi, /**< LP interface structure */
3603  SCIP_Bool* primalfeasible, /**< pointer to store primal feasibility status */
3604  SCIP_Bool* dualfeasible /**< pointer to store dual feasibility status */
3605  )
3606 {
3607  assert( lpi != NULL );
3608  assert( lpi->grbmodel != NULL );
3609  assert( lpi->grbenv != NULL );
3610  assert( lpi->solstat >= 1 );
3611  assert( primalfeasible != NULL );
3612  assert( dualfeasible != NULL );
3613 
3614  SCIPdebugMessage("getting solution feasibility\n");
3615 
3616  *primalfeasible = SCIPlpiIsPrimalFeasible(lpi);
3617  *dualfeasible = SCIPlpiIsDualFeasible(lpi);
3618 
3619  return SCIP_OKAY;
3620 }
3621 
3622 /** returns TRUE iff LP is proven to have a primal unbounded ray (but not necessary a primal feasible point);
3623  * this does not necessarily mean, that the solver knows and can return the primal ray
3624  */
3626  SCIP_LPI* lpi /**< LP interface structure */
3627  )
3628 {
3629  assert(lpi != NULL);
3630  assert(lpi->grbmodel != NULL);
3631  assert(lpi->solstat >= 0);
3632 
3633  return (lpi->solstat == GRB_UNBOUNDED);
3634 }
3635 
3636 /** returns TRUE iff LP is proven to have a primal unbounded ray (but not necessary a primal feasible point),
3637  * and the solver knows and can return the primal ray
3638  */
3640  SCIP_LPI* lpi /**< LP interface structure */
3641  )
3642 {
3643  int algo;
3644  int res;
3645 
3646  assert( lpi != NULL );
3647  assert( lpi->grbmodel != NULL );
3648  assert( lpi->grbenv != NULL );
3649  assert( lpi->solstat >= 0 );
3650 
3651  res = GRBgetintparam(lpi->grbenv, GRB_INT_PAR_METHOD, &algo);
3652  if ( res != 0 )
3653  {
3654  SCIPABORT();
3655  return FALSE; /*lint !e527*/
3656  }
3657 
3658  return (lpi->solstat == GRB_UNBOUNDED && algo == GRB_METHOD_PRIMAL);
3659 }
3660 
3661 /** returns TRUE iff LP is proven to be primal unbounded */
3663  SCIP_LPI* lpi /**< LP interface structure */
3664  )
3665 {
3666  int algo;
3667  int res;
3668 
3669  assert( lpi != NULL );
3670  assert( lpi->grbmodel != NULL );
3671  assert( lpi->grbenv != NULL );
3672  assert( lpi->solstat >= 0 );
3673 
3674  res = GRBgetintparam(lpi->grbenv, GRB_INT_PAR_METHOD, &algo);
3675  if ( res != 0 )
3676  {
3677  SCIPABORT();
3678  return FALSE; /*lint !e527*/
3679  }
3680 
3681  /* GRB_UNBOUNDED means that there exists a primal ray. SCIPlpiSolvePrimal() will determine whether the problem is
3682  * actually infeasible or (feasible and) unbounded. In the latter case, the status will be GRB_UNBOUNDED.
3683  */
3684  return (lpi->solstat == GRB_UNBOUNDED && algo == GRB_METHOD_PRIMAL);
3685 }
3686 
3687 /** returns TRUE iff LP is proven to be primal infeasible */
3689  SCIP_LPI* lpi /**< LP interface structure */
3690  )
3691 {
3692  assert(lpi != NULL);
3693  assert(lpi->grbmodel != NULL);
3694  assert(lpi->solstat >= 0);
3695 
3696  SCIPdebugMessage("checking for primal infeasibility\n");
3697 
3698  assert( lpi->solstat != GRB_INF_OR_UNBD );
3699  return (lpi->solstat == GRB_INFEASIBLE);
3700 }
3701 
3702 /** returns TRUE iff LP is proven to be primal feasible */
3704  SCIP_LPI* lpi /**< LP interface structure */
3705  )
3706 {
3707  int algo;
3708  int res;
3709 
3710  assert( lpi != NULL );
3711  assert( lpi->grbmodel != NULL );
3712  assert( lpi->grbenv != NULL );
3713  assert( lpi->solstat >= 0 );
3714 
3715  SCIPdebugMessage("checking for primal feasibility\n");
3716 
3717  if ( lpi->solstat == GRB_OPTIMAL )
3718  return TRUE;
3719 
3720  res = GRBgetintparam(lpi->grbenv, GRB_INT_PAR_METHOD, &algo);
3721  if ( res != 0 )
3722  {
3723  SCIPABORT();
3724  return FALSE; /*lint !e527*/
3725  }
3726  if ( algo != GRB_METHOD_PRIMAL )
3727  return FALSE;
3728 
3729  if( lpi->solstat == GRB_ITERATION_LIMIT )
3730  {
3731  double consviol;
3732  double boundviol;
3733  double eps;
3734 
3735  /* get feasibility tolerance */
3736  res = GRBgetdblparam(lpi->grbenv, GRB_DBL_PAR_FEASIBILITYTOL, &eps);
3737  if ( res != 0 )
3738  {
3739  SCIPABORT();
3740  return FALSE; /*lint !e527*/
3741  }
3742  res = GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_CONSTR_VIO, &consviol);
3743  if ( res != 0 )
3744  {
3745  /* If Gurobi cannot return the constraint violation, there is no feasible solution available. */
3746  return FALSE;
3747  }
3748  res = GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_BOUND_VIO, &boundviol);
3749  if ( res != 0 )
3750  {
3751  /* If Gurobi cannot return the bound violation, there is no feasible solution available. */
3752  return FALSE;
3753  }
3754 
3755  if ( consviol <= eps && boundviol <= eps )
3756  return TRUE;
3757  }
3758 
3759  return FALSE;
3760 }
3761 
3762 /** returns TRUE iff LP is proven to have a dual unbounded ray (but not necessary a dual feasible point);
3763  * this does not necessarily mean, that the solver knows and can return the dual ray
3764  */
3766  SCIP_LPI* lpi /**< LP interface structure */
3767  )
3768 {
3769  assert(lpi != NULL);
3770  assert(lpi->grbmodel != NULL);
3771  assert(lpi->solstat >= 0);
3772 
3773  return (lpi->solstat == GRB_INFEASIBLE);
3774 }
3775 
3776 /** returns TRUE iff LP is proven to have a dual unbounded ray (but not necessary a dual feasible point),
3777  * and the solver knows and can return the dual ray
3778  */
3780  SCIP_LPI* lpi /**< LP interface structure */
3781  )
3782 {
3783  int algo;
3784  int res;
3785 
3786  assert( lpi != NULL );
3787  assert( lpi->grbmodel != NULL );
3788  assert( lpi->grbenv != NULL );
3789  assert( lpi->solstat >= 0 );
3790 
3791  res = GRBgetintparam(lpi->grbenv, GRB_INT_PAR_METHOD, &algo);
3792  if ( res != 0 )
3793  {
3794  SCIPABORT();
3795  return FALSE; /*lint !e527*/
3796  }
3797 
3798  return (lpi->solstat == GRB_INFEASIBLE && algo == GRB_METHOD_DUAL);
3799 }
3800 
3801 /** returns TRUE iff LP is proven to be dual unbounded */
3803  SCIP_LPI* lpi /**< LP interface structure */
3804  )
3805 {
3806  int algo;
3807  int res;
3808 
3809  assert( lpi != NULL );
3810  assert( lpi->grbmodel != NULL );
3811  assert( lpi->grbenv != NULL );
3812  assert( lpi->solstat >= 0 );
3813 
3814  SCIPdebugMessage("checking for dual unboundedness\n");
3815 
3816  res = GRBgetintparam(lpi->grbenv, GRB_INT_PAR_METHOD, &algo);
3817  if ( res != 0 )
3818  {
3819  SCIPABORT();
3820  return FALSE; /*lint !e527*/
3821  }
3822 
3823  return (lpi->solstat == GRB_INFEASIBLE && algo == GRB_METHOD_DUAL);
3824 }
3825 
3826 /** returns TRUE iff LP is proven to be dual infeasible */
3828  SCIP_LPI* lpi /**< LP interface structure */
3829  )
3830 {
3831  assert( lpi != NULL );
3832  assert( lpi->grbmodel != NULL );
3833  assert( lpi->solstat >= 0 );
3834 
3835  SCIPdebugMessage("checking for dual infeasibility\n");
3836 
3837  return (lpi->solstat == GRB_UNBOUNDED);
3838 }
3839 
3840 /** returns TRUE iff LP is proven to be dual feasible */
3842  SCIP_LPI* lpi /**< LP interface structure */
3843  )
3844 {
3845  int algo;
3846  int res;
3847 
3848  assert( lpi != NULL );
3849  assert( lpi->grbmodel != NULL );
3850  assert( lpi->grbenv != NULL );
3851  assert( lpi->solstat >= 0 );
3852 
3853  SCIPdebugMessage("checking for dual feasibility\n");
3854 
3855  res = GRBgetintparam(lpi->grbenv, GRB_INT_PAR_METHOD, &algo);
3856  if ( res != 0 )
3857  {
3858  SCIPABORT();
3859  return FALSE; /*lint !e527*/
3860  }
3861 
3862  return (lpi->solstat == GRB_OPTIMAL ||
3863  (lpi->solstat == GRB_INFEASIBLE && algo == GRB_METHOD_DUAL) ||
3864  (lpi->solstat == GRB_ITERATION_LIMIT && algo == GRB_METHOD_DUAL) );
3865 }
3866 
3867 /** returns TRUE iff LP was solved to optimality */
3869  SCIP_LPI* lpi /**< LP interface structure */
3870  )
3871 {
3872  assert(lpi != NULL);
3873  assert(lpi->grbmodel != NULL);
3874  assert(lpi->solstat >= 0);
3875 
3876  return (lpi->solstat == GRB_OPTIMAL);
3877 }
3878 
3879 /** returns TRUE iff current LP solution is stable
3880  *
3881  * This function should return true if the solution is reliable, i.e., feasible and optimal (or proven
3882  * infeasible/unbounded) with respect to the original problem. The optimality status might be with respect to a scaled
3883  * version of the problem, but the solution might not be feasible to the unscaled original problem; in this case,
3884  * SCIPlpiIsStable() should return false.
3885  */
3887  SCIP_LPI* lpi /**< LP interface structure */
3888  )
3889 {
3890  double consviol;
3891  double boundviol;
3892  double dualviol;
3893  double feastol;
3894  double optimalitytol;
3895  int res;
3896 
3897  assert(lpi != NULL);
3898  assert(lpi->grbmodel != NULL);
3899  assert(lpi->solstat >= 0);
3900 
3901  SCIPdebugMessage("checking for stability: Gurobi solstat = %d\n", lpi->solstat);
3902 
3903  /* If the condition number of the basis should be checked, everything above the specified threshold is counted as
3904  * instable. */
3905  if ( lpi->checkcondition && (SCIPlpiIsOptimal(lpi) || SCIPlpiIsObjlimExc(lpi)) )
3906  {
3907  SCIP_Real kappa;
3908  SCIP_RETCODE retcode;
3909 
3911  if ( retcode != SCIP_OKAY )
3912  {
3913  SCIPABORT();
3914  return FALSE; /*lint !e527*/
3915  }
3916 
3917  /* if the kappa could not be computed (e.g., because we do not have a basis), we cannot check the condition */
3918  if ( kappa != SCIP_INVALID || kappa > lpi->conditionlimit ) /*lint !e777*/
3919  return FALSE;
3920  }
3921 
3922  /* test whether we have unscaled infeasibilities */
3923  if ( SCIPlpiIsOptimal(lpi) )
3924  {
3925  /* first get tolerances */
3926  res = GRBgetdblparam(lpi->grbenv, GRB_DBL_PAR_FEASIBILITYTOL, &feastol);
3927  if ( res != 0 )
3928  {
3929  SCIPABORT();
3930  return FALSE; /*lint !e527*/
3931  }
3932  res = GRBgetdblparam(lpi->grbenv, GRB_DBL_PAR_OPTIMALITYTOL, &optimalitytol);
3933  if ( res != 0 )
3934  {
3935  SCIPABORT();
3936  return FALSE; /*lint !e527*/
3937  }
3938 
3939  /* next get constraint, bound, and reduced cost violations */
3940  res = GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_CONSTR_VIO, &consviol);
3941  if ( res != 0 )
3942  {
3943  SCIPABORT();
3944  return FALSE; /*lint !e527*/
3945  }
3946  res = GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_BOUND_VIO, &boundviol);
3947  if ( res != 0 )
3948  {
3949  SCIPABORT();
3950  return FALSE; /*lint !e527*/
3951  }
3952  res = GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_DUAL_VIO, &dualviol);
3953  if ( res != 0 )
3954  {
3955  SCIPABORT();
3956  return FALSE; /*lint !e527*/
3957  }
3958 
3959  return ( consviol <= feastol && boundviol <= feastol && dualviol <= optimalitytol );
3960  }
3961 
3962  return (lpi->solstat != GRB_NUMERIC);
3963 }
3964 
3965 /** returns TRUE iff the objective limit was reached */
3967  SCIP_LPI* lpi /**< LP interface structure */
3968  )
3969 {
3970  assert(lpi != NULL);
3971  assert(lpi->grbmodel != NULL);
3972  assert(lpi->solstat >= 0);
3973 
3974  return (lpi->solstat == GRB_CUTOFF);
3975 }
3976 
3977 /** returns TRUE iff the iteration limit was reached */
3979  SCIP_LPI* lpi /**< LP interface structure */
3980  )
3981 {
3982  assert(lpi != NULL);
3983  assert(lpi->grbmodel != NULL);
3984  assert(lpi->solstat >= 0);
3985 
3986  return (lpi->solstat == GRB_ITERATION_LIMIT);
3987 }
3988 
3989 /** returns TRUE iff the time limit was reached */
3991  SCIP_LPI* lpi /**< LP interface structure */
3992  )
3993 {
3994  assert(lpi != NULL);
3995  assert(lpi->grbmodel != NULL);
3996  assert(lpi->solstat >= 0);
3997 
3998  return (lpi->solstat == GRB_TIME_LIMIT);
3999 }
4000 
4001 /** returns the internal solution status of the solver */
4003  SCIP_LPI* lpi /**< LP interface structure */
4004  )
4005 {
4006  assert(lpi != NULL);
4007  assert(lpi->grbmodel != NULL);
4008 
4009  return lpi->solstat;
4010 }
4011 
4012 /** tries to reset the internal status of the LP solver in order to ignore an instability of the last solving call */
4014  SCIP_LPI* lpi, /**< LP interface structure */
4015  SCIP_Bool* success /**< pointer to store, whether the instability could be ignored */
4016  )
4017 {
4018  assert(lpi != NULL);
4019  assert(lpi->grbmodel != NULL);
4020  assert(success != NULL);
4021 
4022  *success = FALSE;
4023 
4024  return SCIP_OKAY;
4025 }
4026 
4027 /** gets objective value of solution
4028  *
4029  * @note if the solution status is iteration limit reached (GRB_ITERATION_LIMIT), the objective value was not computed
4030  */
4032  SCIP_LPI* lpi, /**< LP interface structure */
4033  SCIP_Real* objval /**< stores the objective value */
4034  )
4035 {
4036  int ret;
4037 
4038 #ifndef NDEBUG
4039  double oval = GRB_INFINITY;
4040  double obnd = -GRB_INFINITY;
4041 #endif
4042 
4043  assert(lpi != NULL);
4044  assert(lpi->grbmodel != NULL);
4045  assert(objval != NULL);
4046 
4047  SCIPdebugMessage("getting solution's objective value\n");
4048 
4049 #ifndef NDEBUG
4050  (void)GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_OBJVAL, &oval);
4051  (void)GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_OBJBOUND, &obnd);
4052 
4053  assert(lpi->solstat != GRB_OPTIMAL || oval == obnd); /*lint !e777*/
4054 #endif
4055 
4056  ret = GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_OBJBOUND, objval);
4057 
4058  if( ret == GRB_ERROR_DATA_NOT_AVAILABLE )
4059  {
4060  /* return minus infinity if value not available and we reached an iteration limit (see lpi_cpx) */
4061  if( lpi->solstat == GRB_ITERATION_LIMIT )
4062  *objval = -SCIPlpiInfinity(lpi);
4063  /**@todo The following is some kind of hack which works with the current SCIP implementation and should be fixed. In
4064  * the case that the LP status is GRB_CUTOFF it might be that certain attributes cannot be queries (e.g., objval,
4065  * primal and dual solution), in this case we just return the installed cutoff value minus some epsilon. This is some
4066  * kind of hack for the code in conflict.c:7595 were some extra code handles CPLEX' FASTMIP case that is similar to
4067  * this case.
4068  */
4069  else if( lpi->solstat == GRB_CUTOFF )
4070  {
4071  SCIP_Real dval;
4072  SCIP_OBJSEN objsense;
4073 
4074  SCIP_CALL( SCIPlpiGetObjsen(lpi, &objsense) );
4075  SCIP_CALL( getDblParam(lpi, GRB_DBL_PAR_CUTOFF, &dval) );
4076 
4077  if( objsense == SCIP_OBJSEN_MINIMIZE )
4078  *objval = dval - 1e-06;
4079  else
4080  *objval = dval + 1e-06;
4081  }
4082  }
4083  else
4084  {
4085  CHECK_ZERO( lpi->messagehdlr, ret );
4086  }
4087 
4088  return SCIP_OKAY;
4089 }
4090 
4091 /** gets primal and dual solution vectors for feasible LPs
4092  *
4093  * Before calling this function, the caller must ensure that the LP has been solved to optimality, i.e., that
4094  * SCIPlpiIsOptimal() returns true.
4095  */
4097  SCIP_LPI* lpi, /**< LP interface structure */
4098  SCIP_Real* objval, /**< stores the objective value, may be NULL if not needed */
4099  SCIP_Real* primsol, /**< primal solution vector, may be NULL if not needed */
4100  SCIP_Real* dualsol, /**< dual solution vector, may be NULL if not needed */
4101  SCIP_Real* activity, /**< row activity vector, may be NULL if not needed */
4102  SCIP_Real* redcost /**< reduced cost vector, may be NULL if not needed */
4103  )
4104 {
4105  int ncols;
4106  int nrows;
4107 
4108  assert(lpi != NULL);
4109  assert(lpi->grbmodel != NULL);
4110  assert(lpi->solstat >= 0);
4111 
4112  SCIPdebugMessage("getting solution\n");
4113 
4114  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
4115  SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
4116  assert( ncols >= 0 && nrows >= 0 );
4117 
4118  if( objval != NULL )
4119  {
4120  SCIP_CALL( SCIPlpiGetObjval(lpi, objval) );
4121  }
4122 
4123  if( primsol != NULL )
4124  {
4125  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_X, 0, ncols, primsol) );
4126  }
4127 
4128  if( dualsol != NULL )
4129  {
4130  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_PI, 0, nrows, dualsol) );
4131  }
4132 
4133  if( activity != NULL )
4134  {
4135  int i;
4136 
4137  /* first get the values of the slack variables */
4138  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_SLACK, 0, nrows, activity) );
4139 
4140  SCIP_CALL( ensureSidechgMem(lpi, nrows) );
4141 
4142  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_RHS, 0, nrows, lpi->rhsarray) );
4143  CHECK_ZERO( lpi->messagehdlr, GRBgetcharattrarray(lpi->grbmodel, GRB_CHAR_ATTR_SENSE, 0, nrows, lpi->senarray) );
4144 
4145  for( i = 0; i < nrows; ++i )
4146  {
4147  switch(lpi->senarray[i])
4148  {
4149  case GRB_EQUAL:
4150  if ( lpi->rngrowmap != NULL && lpi->rngrowmap[i] >= 0 )
4151  {
4152  /* get solution value of range variable */
4153  SCIP_Real solval;
4154  assert(lpi->rngrowmap[i] < lpi->nrngrows);
4155  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrelement(lpi->grbmodel, GRB_DBL_ATTR_X, ncols + lpi->rngrowmap[i], &solval) );
4156  activity[i] = lpi->rhsarray[i] + solval;
4157  }
4158  else
4159  {
4160  activity[i] = lpi->rhsarray[i] - activity[i];
4161  }
4162  break;
4163  case GRB_LESS_EQUAL:
4164  activity[i] = lpi->rhsarray[i] - activity[i];
4165  break;
4166  case GRB_GREATER_EQUAL:
4167  activity[i] = lpi->rhsarray[i] - activity[i];
4168  break;
4169  default:
4170  SCIPerrorMessage("Unkown sense %c.\n", lpi->senarray[i]);
4171  SCIPABORT();
4172  return SCIP_INVALIDDATA; /*lint !e527*/
4173  }
4174  }
4175  }
4176 
4177  if( redcost != NULL )
4178  {
4179  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_RC, 0, ncols, redcost) );
4180  }
4181 
4182  return SCIP_OKAY;
4183 }
4184 
4185 /** gets primal ray for unbounded LPs */
4187  SCIP_LPI* lpi, /**< LP interface structure */
4188  SCIP_Real* ray /**< primal ray */
4189  )
4190 {
4191  int ncols;
4192 
4193  assert(lpi != NULL);
4194  assert(lpi->grbmodel != NULL);
4195  assert(lpi->solstat >= 0);
4196  assert(ray != NULL);
4197 
4198  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
4199  assert( ncols >= 0 );
4200 
4201  SCIPdebugMessage("calling Gurobi get primal ray: %d cols\n", ncols);
4202 
4203  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_UNBDRAY, 0, ncols, ray) );
4204 
4205  return SCIP_OKAY;
4206 }
4207 
4208 /** gets dual Farkas proof for infeasibility */
4210  SCIP_LPI* lpi, /**< LP interface structure */
4211  SCIP_Real* dualfarkas /**< dual Farkas row multipliers */
4212  )
4213 {
4214  int nrows;
4215  int i;
4216 
4217  assert(lpi != NULL);
4218  assert(lpi->grbmodel != NULL);
4219  assert(lpi->solstat >= 0);
4220  assert(dualfarkas != NULL);
4221 
4222  SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
4223  assert( nrows >= 0 );
4224 
4225  SCIPdebugMessage("calling Gurobi dual Farkas: %d rows\n", nrows);
4226 
4227  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_FARKASDUAL, 0, nrows, dualfarkas) );
4228 
4229  /* correct sign of ray */
4230  for (i = 0; i < nrows; ++i)
4231  dualfarkas[i] *= -1.0;
4232 
4233  return SCIP_OKAY;
4234 }
4235 
4236 /** gets the number of LP iterations of the last solve call */
4238  SCIP_LPI* lpi, /**< LP interface structure */
4239  int* iterations /**< pointer to store the number of iterations of the last solve call */
4240  )
4241 {
4242  assert(lpi != NULL);
4243  assert(lpi->grbmodel != NULL);
4244  assert(iterations != NULL);
4245 
4246  *iterations = lpi->iterations;
4247 
4248  return SCIP_OKAY;
4249 }
4250 
4251 /** gets information about the quality of an LP solution
4252  *
4253  * Such information is usually only available, if also a (maybe not optimal) solution is available.
4254  * The LPI should return SCIP_INVALID for @p quality, if the requested quantity is not available.
4255  */
4257  SCIP_LPI* lpi, /**< LP interface structure */
4258  SCIP_LPSOLQUALITY qualityindicator, /**< indicates which quality should be returned */
4259  SCIP_Real* quality /**< pointer to store quality number */
4260  )
4261 { /*lint --e{715}*/
4262  const char* what;
4263  int ret;
4264 
4265  assert(lpi != NULL);
4266  assert(lpi->grbmodel != NULL);
4267  assert(quality != NULL);
4268 
4269  SCIPdebugMessage("requesting solution quality from Gurobi: quality %d\n", qualityindicator);
4270 
4271  switch( qualityindicator )
4272  {
4274  what = GRB_DBL_ATTR_KAPPA;
4275  break;
4276 
4278  what = GRB_DBL_ATTR_KAPPA_EXACT;
4279  break;
4280 
4281  default:
4282  SCIPerrorMessage("Solution quality %d unknown.\n", qualityindicator);
4283  return SCIP_INVALIDDATA;
4284  }
4285 
4286  ret = GRBgetdblattr(lpi->grbmodel, what, quality);
4287  if( ret != 0 )
4288  *quality = SCIP_INVALID;
4289 
4290  return SCIP_OKAY;
4291 }
4292 
4293 /**@} */
4294 
4295 
4296 
4297 
4298 /*
4299  * LP Basis Methods
4300  */
4301 
4302 /**@name LP Basis Methods */
4303 /**@{ */
4304 
4305 /** gets current basis status for columns and rows; arrays must be large enough to store the basis status */
4307  SCIP_LPI* lpi, /**< LP interface structure */
4308  int* cstat, /**< array to store column basis status, or NULL */
4309  int* rstat /**< array to store row basis status, or NULL */
4310  )
4311 {
4312  int nrows;
4313  int ncols;
4314 
4315  assert(lpi != NULL);
4316  assert(lpi->grbmodel != NULL);
4317 
4318  SCIPdebugMessage("saving Gurobi basis into %p/%p\n", (void*) cstat, (void*) rstat);
4319 
4320  SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
4321  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
4322 
4323  if( rstat != NULL )
4324  {
4325  int i;
4326 
4327  SCIP_CALL( ensureSidechgMem(lpi, nrows) );
4328 
4329  CHECK_ZERO( lpi->messagehdlr, GRBgetintattrarray(lpi->grbmodel, GRB_INT_ATTR_CBASIS, 0, nrows, rstat) );
4330  CHECK_ZERO( lpi->messagehdlr, GRBgetcharattrarray(lpi->grbmodel, GRB_CHAR_ATTR_SENSE, 0, nrows, lpi->senarray) );
4331 
4332  for( i = 0; i < nrows; ++i )
4333  {
4334  if ( lpi->rngrowmap != NULL && lpi->rngrowmap[i] >= 0 && rstat[i] != GRB_BASIC )
4335  {
4336  int idx;
4337 
4338  /* get range row basis status from corresponding range variable */
4339  idx = ncols + lpi->rngrowmap[i];
4340  assert(lpi->rngrowmap[i] < lpi->nrngrows);
4341  CHECK_ZERO( lpi->messagehdlr, GRBgetintattrelement(lpi->grbmodel, GRB_INT_ATTR_VBASIS, idx, &rstat[i]) );
4342 
4343  switch( rstat[i] )
4344  {
4345  case GRB_BASIC:
4346  rstat[i] = (int) SCIP_BASESTAT_BASIC;
4347  break;
4348 
4349  case GRB_NONBASIC_LOWER:
4350  rstat[i] = (int) SCIP_BASESTAT_LOWER;
4351  break;
4352 
4353  case GRB_NONBASIC_UPPER:
4354  rstat[i] = (int) SCIP_BASESTAT_UPPER;
4355  break;
4356 
4357  /*lint -fallthrough*/
4358  case GRB_SUPERBASIC:
4359  default:
4360  SCIPerrorMessage("invalid basis status %d for ranged row.\n", rstat[i]);
4361  SCIPABORT();
4362  return SCIP_INVALIDDATA; /*lint !e527*/
4363  }
4364  }
4365  else
4366  {
4367  /* Slack variables can only be basic or at their lower bounds in Gurobi. */
4368  switch( rstat[i] )
4369  {
4370  case GRB_BASIC:
4371  rstat[i] = (int) SCIP_BASESTAT_BASIC;
4372  break;
4373 
4374  case GRB_NONBASIC_LOWER:
4375  if ( lpi->senarray[i] == '>' || lpi->senarray[i] == '=' )
4376  rstat[i] = (int) SCIP_BASESTAT_LOWER;
4377  else
4378  {
4379  assert( lpi->senarray[i] == '<' );
4380  rstat[i] = (int) SCIP_BASESTAT_UPPER;
4381  }
4382  break;
4383 
4384  /*lint -fallthrough*/
4385  case GRB_NONBASIC_UPPER:
4386  case GRB_SUPERBASIC:
4387  default:
4388  SCIPerrorMessage("invalid basis status %d for row.\n", rstat[i]);
4389  SCIPABORT();
4390  return SCIP_INVALIDDATA; /*lint !e527*/
4391  }
4392  }
4393  }
4394  }
4395 
4396  if( cstat != 0 )
4397  {
4398  int j;
4399 
4400  CHECK_ZERO( lpi->messagehdlr, GRBgetintattrarray(lpi->grbmodel, GRB_INT_ATTR_VBASIS, 0, ncols, cstat) );
4401 
4402  for( j = 0; j < ncols; ++j )
4403  {
4404  switch( cstat[j] )
4405  {
4406  case GRB_BASIC:
4407  cstat[j] = (int) SCIP_BASESTAT_BASIC;
4408  break;
4409 
4410  case GRB_NONBASIC_LOWER:
4411  cstat[j] = (int) SCIP_BASESTAT_LOWER;
4412  break;
4413 
4414  case GRB_NONBASIC_UPPER:
4415  cstat[j] = (int) SCIP_BASESTAT_UPPER;
4416  break;
4417 
4418  case GRB_SUPERBASIC:
4419  cstat[j] = (int) SCIP_BASESTAT_ZERO;
4420  break;
4421 
4422  default:
4423  SCIPerrorMessage("invalid basis status %d for column.\n", cstat[j]);
4424  SCIPABORT();
4425  return SCIP_INVALIDDATA; /*lint !e527*/
4426  }
4427  }
4428  }
4429 
4430  return SCIP_OKAY;
4431 }
4432 
4433 /** sets current basis status for columns and rows */
4435  SCIP_LPI* lpi, /**< LP interface structure */
4436  const int* cstat, /**< array with column basis status */
4437  const int* rstat /**< array with row basis status */
4438  )
4439 {
4440  int i, j;
4441  int nrows, ncols;
4442 #ifndef NDEBUG
4443  int nrngsfound = 0;
4444 #endif
4445 
4446  assert(lpi != NULL);
4447  assert(lpi->grbmodel != NULL);
4448 
4449  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
4450  SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
4451 
4452  assert(cstat != NULL || ncols == 0);
4453  assert(rstat != NULL || nrows == 0);
4454 
4455  SCIPdebugMessage("loading basis %p/%p into Gurobi\n", (void*) cstat, (void*) rstat);
4456 
4457  invalidateSolution(lpi);
4458 
4459  SCIP_CALL( ensureCstatMem(lpi, ncols+lpi->nrngrows) );
4460  SCIP_CALL( ensureRstatMem(lpi, nrows) );
4461 
4462  for( i = 0; i < nrows; ++i )
4463  {
4464  if ( lpi->rngrowmap != NULL && lpi->rngrowmap[i] >= 0 )
4465  {
4466  int idx;
4467 
4468  /* set basis status of corresponding range variable; ranged row is always non-basic */
4469  idx = ncols + lpi->rngrowmap[i];
4470  assert(lpi->rngrowmap[i] < lpi->nrngrows);
4471  lpi->cstat[idx] = lpi->rstat[i];
4472  lpi->rstat[i] = GRB_NONBASIC_LOWER;
4473 #ifndef NDEBUG
4474  nrngsfound++;
4475 #endif
4476  }
4477  else
4478  {
4479  switch( rstat[i] ) /*lint !e613*/
4480  {
4481  case SCIP_BASESTAT_BASIC:
4482  lpi->rstat[i] = GRB_BASIC;
4483  break;
4484 
4485  case SCIP_BASESTAT_UPPER:
4486  {
4487 #ifndef NDEBUG
4488  char sense;
4489  CHECK_ZERO( lpi->messagehdlr, GRBgetcharattrarray(lpi->grbmodel, GRB_CHAR_ATTR_SENSE, i, 1, &sense) );
4490  assert( sense == '<' );
4491 #endif
4492  /* Slack variables can only be basic or at their lower bounds in Gurobi. */
4493  lpi->rstat[i] = GRB_NONBASIC_LOWER;
4494  break;
4495  }
4496 
4497  case SCIP_BASESTAT_LOWER:
4498  {
4499 #ifndef NDEBUG
4500  char sense;
4501  CHECK_ZERO( lpi->messagehdlr, GRBgetcharattrarray(lpi->grbmodel, GRB_CHAR_ATTR_SENSE, i, 1, &sense) );
4502  assert( sense == '>' || sense == '=' );
4503 #endif
4504  lpi->rstat[i] = GRB_NONBASIC_LOWER;
4505  break;
4506  }
4507 
4508  case SCIP_BASESTAT_ZERO:
4509  default:
4510  SCIPerrorMessage("invalid basis status %d for row.\n", rstat[i]); /*lint !e613*/
4511  SCIPABORT();
4512  return SCIP_INVALIDDATA; /*lint !e527*/
4513  }
4514  }
4515  }
4516 
4517  for( j = 0; j < ncols; ++j )
4518  {
4519  switch( cstat[j] ) /*lint !e613*/
4520  {
4521  case SCIP_BASESTAT_BASIC:
4522  lpi->cstat[j] = GRB_BASIC;
4523  break;
4524 
4525  case SCIP_BASESTAT_LOWER:
4526  lpi->cstat[j] = GRB_NONBASIC_LOWER;
4527  break;
4528 
4529  case SCIP_BASESTAT_UPPER:
4530  lpi->cstat[j] = GRB_NONBASIC_UPPER;
4531  break;
4532 
4533  case SCIP_BASESTAT_ZERO:
4534  lpi->cstat[j] = GRB_SUPERBASIC;
4535  break;
4536 
4537  default:
4538  SCIPerrorMessage("invalid basis status %d\n", cstat[j]); /*lint !e613*/
4539  SCIPABORT();
4540  return SCIP_INVALIDDATA; /*lint !e527*/
4541  }
4542  }
4543 
4544 #ifndef NDEBUG
4545  assert(nrngsfound == lpi->nrngrows);
4546 #endif
4547 
4548  CHECK_ZERO( lpi->messagehdlr, GRBsetintattrarray(lpi->grbmodel, GRB_INT_ATTR_CBASIS, 0, nrows, lpi->rstat) );
4549  CHECK_ZERO( lpi->messagehdlr, GRBsetintattrarray(lpi->grbmodel, GRB_INT_ATTR_VBASIS, 0, ncols+lpi->nrngrows, lpi->cstat) );
4550 
4551  return SCIP_OKAY;
4552 }
4553 
4554 /** returns the indices of the basic columns and rows; basic column n gives value n, basic row m gives value -1-m */
4556  SCIP_LPI* lpi, /**< LP interface structure */
4557  int* bind /**< pointer to store basis indices ready to keep number of rows entries */
4558  )
4559 {
4560  int i;
4561  int nrows;
4562  int ncols;
4563  int ngrbcols;
4564  int* bhead;
4565  int status;
4566 
4567  assert(lpi != NULL);
4568  assert(lpi->grbmodel != NULL);
4569  assert(bind != NULL);
4570 
4571  SCIPdebugMessage("getting basis information\n");
4572 
4573  /* check whether we have to reoptimize */
4574  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_STATUS, &status) );
4575  if ( status == GRB_LOADED || status == GRB_INTERRUPTED || status == GRB_INPROGRESS )
4576  {
4578  }
4579 
4580  SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
4581  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
4582  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_NUMVARS, &ngrbcols) );
4583 
4584  /**@todo avoid memory allocation by using bind directly */
4585  /* get space for bhead */
4586  SCIP_ALLOC( BMSallocMemoryArray(&bhead, nrows) );
4587 
4588  /* get basis indices */
4589  CHECK_ZERO( lpi->messagehdlr, GRBgetBasisHead(lpi->grbmodel, bhead) );
4590 
4591  for (i = 0; i < nrows; ++i)
4592  {
4593  /* entries >= ncols refer to slack variables */
4594  if ( bhead[i] < ncols )
4595  bind[i] = bhead[i];
4596  else if ( bhead[i] < ngrbcols )
4597  {
4598  /* a range variable: use corresponding ranged row */
4599  int rngrow = bhead[i]-ncols;
4600  assert(rngrow < lpi->nrngrows);
4601  assert(lpi->rngrowmap != NULL);
4602  assert(lpi->rngrows != NULL);
4603  assert(lpi->rngrowmap[lpi->rngrows[rngrow]] == rngrow);
4604  bind[i] = -1 - lpi->rngrows[rngrow];
4605  }
4606  else
4607  {
4608  /* a regular slack variable */
4609  bind[i] = -1 - (bhead[i] - ngrbcols);
4610  }
4611  }
4612  BMSfreeMemoryArray(&bhead);
4613 
4614  return SCIP_OKAY;
4615 }
4616 
4617 /** get row of inverse basis matrix B^-1
4618  *
4619  * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
4620  * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
4621  * see also the explanation in lpi.h.
4622  *
4623  * @todo check that the result is in terms of the LP interface definition
4624  */
4626  SCIP_LPI* lpi, /**< LP interface structure */
4627  int r, /**< row number */
4628  SCIP_Real* coef, /**< pointer to store the coefficients of the row */
4629  int* inds, /**< array to store the non-zero indices, or NULL */
4630  int* ninds /**< pointer to store the number of non-zero indices, or NULL
4631  * (-1: if we do not store sparsity information) */
4632  )
4633 {
4634  SVECTOR x;
4635  SVECTOR b;
4636  int nrows;
4637  double val;
4638  int ind;
4639  int status;
4640 
4641  assert(lpi != NULL);
4642  assert(lpi->grbmodel != NULL);
4643  assert(coef != NULL);
4644 
4645  SCIPdebugMessage("getting binv-row %d\n", r);
4646 
4647  /* check whether we have to reoptimize */
4648  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_STATUS, &status) );
4649  if ( status == GRB_LOADED || status == GRB_INTERRUPTED || status == GRB_INPROGRESS )
4650  {
4652  }
4653 
4654  SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
4655 
4656  /* set up solution vector */
4657  x.len = 0;
4658  SCIP_ALLOC( BMSallocMemoryArray(&(x.ind), nrows) );
4659  SCIP_ALLOC( BMSallocMemoryArray(&(x.val), nrows) );
4660 
4661  /* get basis indices, temporarily using memory of x.ind */
4662  SCIP_CALL( SCIPlpiGetBasisInd(lpi, x.ind) );
4663 
4664  /* set up rhs */
4665  b.len = 1;
4666  ind = r;
4667  val = (x.ind)[r] >= 0 ? 1.0 : -1.0;
4668  b.ind = &ind;
4669  b.val = &val;
4670 
4671  /* solve B^T x = e_r, which results in the r-th row of the basis inverse */
4672  CHECK_ZERO( lpi->messagehdlr, GRBBSolve(lpi->grbmodel, &b, &x) );
4673 
4674  /* size should be at most the number of rows */
4675  assert( x.len <= nrows );
4676 
4677  /* check whether we require a dense or sparse result vector */
4678  if ( ninds != NULL && inds != NULL )
4679  {
4680  int idx;
4681  int i;
4682 
4683  /* copy sparse solution */
4684  for (i = 0; i < x.len; ++i)
4685  {
4686  idx = (x.ind)[i];
4687  assert( idx >= 0 && idx < nrows );
4688  inds[i] = idx;
4689  coef[idx] = (x.val)[i];
4690  }
4691  *ninds = x.len;
4692  }
4693  else
4694  {
4695  int idx;
4696  int i;
4697 
4698  /* copy solution to dense vector */
4699  BMSclearMemoryArray(coef, nrows);
4700  for (i = 0; i < x.len; ++i)
4701  {
4702  idx = (x.ind)[i];
4703  assert( idx >= 0 && idx < nrows );
4704  coef[idx] = (x.val)[i];
4705  }
4706  }
4707 
4708  /* free solution space */
4709  BMSfreeMemoryArray(&(x.val));
4710  BMSfreeMemoryArray(&(x.ind));
4711 
4712  return SCIP_OKAY;
4713 }
4714 
4715 /** get column of inverse basis matrix B^-1
4716  *
4717  * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
4718  * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
4719  * see also the explanation in lpi.h.
4720  *
4721  * @todo check that the result is in terms of the LP interface definition
4722  */
4724  SCIP_LPI* lpi, /**< LP interface structure */
4725  int c, /**< column number of B^-1; this is NOT the number of the column in the LP;
4726  * you have to call SCIPlpiGetBasisInd() to get the array which links the
4727  * B^-1 column numbers to the row and column numbers of the LP!
4728  * c must be between 0 and nrows-1, since the basis has the size
4729  * nrows * nrows */
4730  SCIP_Real* coef, /**< pointer to store the coefficients of the column */
4731  int* inds, /**< array to store the non-zero indices, or NULL */
4732  int* ninds /**< pointer to store the number of non-zero indices, or NULL
4733  * (-1: if we do not store sparsity information) */
4734  )
4735 {
4736  SVECTOR x;
4737  SVECTOR b;
4738  int* bind;
4739  int nrows;
4740  double val;
4741  int ind;
4742  int status;
4743 
4744  assert(lpi != NULL);
4745  assert(lpi->grbmodel != NULL);
4746  assert(coef != NULL);
4747 
4748  SCIPdebugMessage("getting binv-col %d\n", c);
4749 
4750  /* check whether we have to reoptimize */
4751  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_STATUS, &status) );
4752  if ( status == GRB_LOADED || status == GRB_INTERRUPTED || status == GRB_INPROGRESS )
4753  {
4755  }
4756 
4757  SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
4758 
4759  /* set up solution vector */
4760  x.len = 0;
4761  SCIP_ALLOC( BMSallocMemoryArray(&(x.ind), nrows) );
4762  SCIP_ALLOC( BMSallocMemoryArray(&(x.val), nrows) );
4763 
4764  /* set up rhs */
4765  b.len = 1;
4766  ind = c;
4767  val = 1.0;
4768  b.ind = &ind;
4769  b.val = &val;
4770 
4771  /* solve B x = e_c, which results in the c-th columns of the basis inverse */
4772  CHECK_ZERO( lpi->messagehdlr, GRBFSolve(lpi->grbmodel, &b, &x) );
4773 
4774  /* size should be at most the number of rows */
4775  assert( x.len <= nrows );
4776 
4777  /* get basis indices: entries that correspond to slack variables with coefficient -1 must be negated */
4778  SCIP_ALLOC( BMSallocMemoryArray(&bind, nrows) );
4779  SCIP_CALL( SCIPlpiGetBasisInd(lpi, bind) );
4780 
4781  /* check whether we require a dense or sparse result vector */
4782  if ( ninds != NULL && inds != NULL )
4783  {
4784  int idx;
4785  int i;
4786 
4787  /* copy sparse solution */
4788  for (i = 0; i < x.len; ++i)
4789  {
4790  idx = (x.ind)[i];
4791  assert( idx >= 0 && idx < nrows );
4792  inds[i] = idx;
4793  coef[idx] = (x.val)[i];
4794  if( bind[idx] < 0 )
4795  coef[idx] *= -1.0;
4796  }
4797  *ninds = x.len;
4798  }
4799  else
4800  {
4801  int idx;
4802  int i;
4803 
4804  /* copy solution to dense vector */
4805  BMSclearMemoryArray(coef, nrows);
4806  for (i = 0; i < x.len; ++i)
4807  {
4808  idx = (x.ind)[i];
4809  assert( idx >= 0 && idx < nrows );
4810  coef[idx] = (x.val)[i];
4811  if( bind[idx] < 0 )
4812  coef[idx] *= -1.0;
4813  }
4814  }
4815 
4816  /* free solution space and basis index array */
4817  BMSfreeMemoryArray(&bind);
4818  BMSfreeMemoryArray(&(x.val));
4819  BMSfreeMemoryArray(&(x.ind));
4820 
4821  return SCIP_OKAY;
4822 }
4823 
4824 /** get row of inverse basis matrix times constraint matrix B^-1 * A
4825  *
4826  * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
4827  * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
4828  * see also the explanation in lpi.h.
4829  *
4830  * @todo check that the result is in terms of the LP interface definition
4831  */
4833  SCIP_LPI* lpi, /**< LP interface structure */
4834  int r, /**< row number */
4835  const SCIP_Real* binvrow, /**< row in (A_B)^-1 from prior call to SCIPlpiGetBInvRow(), or NULL */
4836  SCIP_Real* coef, /**< vector to return coefficients of the row */
4837  int* inds, /**< array to store the non-zero indices, or NULL */
4838  int* ninds /**< pointer to store the number of non-zero indices, or NULL
4839  * (-1: if we do not store sparsity information) */
4840  )
4841 { /*lint --e{715}*/
4842  SVECTOR x;
4843  int nrows;
4844  int ncols;
4845  int ngrbcols;
4846  int status;
4847  SCIP_Bool isslackvar;
4848 
4849  assert(lpi != NULL);
4850  assert(lpi->grbmodel != NULL);
4851  assert(coef != NULL);
4852 
4853  SCIPdebugMessage("getting binv-row %d\n", r);
4854 
4855  /* check whether we have to reoptimize */
4856  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_STATUS, &status) );
4857  if ( status == GRB_LOADED || status == GRB_INTERRUPTED || status == GRB_INPROGRESS )
4858  {
4860  }
4861 
4862  SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
4863  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
4864  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_NUMVARS, &ngrbcols) );
4865  assert( r >= 0 && r < nrows );
4866 
4867  x.len = 0;
4868  SCIP_ALLOC( BMSallocMemoryArray(&(x.ind), ngrbcols + nrows) );
4869  SCIP_ALLOC( BMSallocMemoryArray(&(x.val), ngrbcols + nrows) );
4870 
4871  /* get basis indices, temporarily using memory of x.ind: if r corresponds to a slack variable with coefficient -1 we
4872  * have to negate all values
4873  */
4874  SCIP_CALL( SCIPlpiGetBasisInd(lpi, x.ind) );
4875  isslackvar = ((x.ind)[r] < 0);
4876 
4877  /* retrieve row */
4878  CHECK_ZERO( lpi->messagehdlr, GRBBinvRowi(lpi->grbmodel, r, &x) );
4879 
4880  /* size should be at most the number of columns plus rows for slack variables */
4881  assert( x.len <= ngrbcols + nrows );
4882 
4883  /* check whether we require a dense or sparse result vector */
4884  if ( ninds != NULL && inds != NULL )
4885  {
4886  int idx;
4887  int k;
4888  int j;
4889 
4890  /* Copy sparse solution: Column indices ngrbcols and larger correspond to slack variables artificially introduced
4891  * by Gurobi; column indices ncols, ncols+1, ..., ngrbcols-1 correspond to slack variables introduced by the LPI
4892  * implementation. Both must simply be ignored.
4893  */
4894  k = 0;
4895  for (j = 0; j < x.len; ++j)
4896  {
4897  idx = (x.ind)[j];
4898  assert( idx >= 0 && idx < ngrbcols+nrows );
4899  if ( idx < ncols )
4900  {
4901  inds[k++] = idx;
4902  coef[idx] = (x.val)[j];
4903  if( isslackvar )
4904  coef[idx] *= -1.0;
4905  }
4906  }
4907  *ninds = k;
4908  }
4909  else
4910  {
4911  int idx;
4912  int j;
4913 
4914  /* Copy dense solution (see comment above). */
4915  BMSclearMemoryArray(coef, ncols);
4916  for (j = 0; j < x.len; ++j)
4917  {
4918  idx = (x.ind)[j];
4919  assert( idx >= 0 && idx < ngrbcols+nrows );
4920  if ( idx < ncols )
4921  {
4922  coef[idx] = (x.val)[j];
4923  if( isslackvar )
4924  coef[idx] *= -1.0;
4925  }
4926  }
4927  }
4928 
4929  /* free solution space */
4930  BMSfreeMemoryArray(&(x.val));
4931  BMSfreeMemoryArray(&(x.ind));
4932 
4933  return SCIP_OKAY;
4934 }
4935 
4936 /** get column of inverse basis matrix times constraint matrix B^-1 * A
4937  *
4938  * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
4939  * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
4940  * see also the explanation in lpi.h.
4941  *
4942  * @todo check that the result is in terms of the LP interface definition
4943  */
4945  SCIP_LPI* lpi, /**< LP interface structure */
4946  int c, /**< column number */
4947  SCIP_Real* coef, /**< vector to return coefficients of the column */
4948  int* inds, /**< array to store the non-zero indices, or NULL */
4949  int* ninds /**< pointer to store the number of non-zero indices, or NULL
4950  * (-1: if we do not store sparsity information) */
4951  )
4952 { /*lint --e{715}*/
4953  SVECTOR x;
4954  int* bind;
4955  int nrows;
4956  int status;
4957 
4958  assert(lpi != NULL);
4959  assert(lpi->grbmodel != NULL);
4960  assert(coef != NULL);
4961 
4962  SCIPdebugMessage("getting binv-col %d\n", c);
4963 
4964  /* check whether we have to reoptimize */
4965  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_STATUS, &status) );
4966  if ( status == GRB_LOADED || status == GRB_INTERRUPTED || status == GRB_INPROGRESS )
4967  {
4969  }
4970 
4971  SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
4972 
4973  x.len = 0;
4974  SCIP_ALLOC( BMSallocMemoryArray(&(x.ind), nrows) );
4975  SCIP_ALLOC( BMSallocMemoryArray(&(x.val), nrows) );
4976 
4977  CHECK_ZERO( lpi->messagehdlr, GRBBinvColj(lpi->grbmodel, c, &x) );
4978 
4979  /* size should be at most the number of rows */
4980  assert( x.len <= nrows );
4981 
4982  /* get basis indices: entries that correspond to slack variables with coefficient -1 must be negated */
4983  SCIP_ALLOC( BMSallocMemoryArray(&bind, nrows) );
4984  SCIP_CALL( SCIPlpiGetBasisInd(lpi, bind) );
4985 
4986  /* check whether we require a dense or sparse result vector */
4987  if ( ninds != NULL && inds != NULL )
4988  {
4989  int idx;
4990  int j;
4991 
4992  /* copy sparse solution */
4993  for (j = 0; j < x.len; ++j)
4994  {
4995  idx = (x.ind)[j];
4996  assert( idx >= 0 && idx < nrows );
4997  inds[j] = idx;
4998  coef[idx] = (x.val)[j];
4999  if( bind[idx] < 0 )
5000  coef[idx] *= -1.0;
5001  }
5002  *ninds = x.len;
5003  }
5004  else
5005  {
5006  int idx;
5007  int j;
5008 
5009  /* copy dense solution */
5010  BMSclearMemoryArray(coef, nrows);
5011  for (j = 0; j < x.len; ++j)
5012  {
5013  idx = (x.ind)[j];
5014  assert( idx >= 0 && idx < nrows );
5015  coef[idx] = (x.val)[j];
5016  if( bind[idx] < 0 )
5017  coef[idx] *= -1.0;
5018  }
5019  }
5020 
5021  /* free solution space and basis index array */
5022  BMSfreeMemoryArray(&bind);
5023  BMSfreeMemoryArray(&(x.val));
5024  BMSfreeMemoryArray(&(x.ind));
5025 
5026  return SCIP_OKAY;
5027 }
5028 
5029 /**@} */
5030 
5031 
5032 
5033 
5034 /*
5035  * LP State Methods
5036  */
5037 
5038 /**@name LP State Methods */
5039 /**@{ */
5040 
5041 /** stores LPi state (like basis information) into lpistate object */
5043  SCIP_LPI* lpi, /**< LP interface structure */
5044  BMS_BLKMEM* blkmem, /**< block memory */
5045  SCIP_LPISTATE** lpistate /**< pointer to LPi state information (like basis information) */
5046  )
5047 {
5048  SCIP_Bool success;
5049  int ncols;
5050  int nrows;
5051 
5052  assert(blkmem != NULL);
5053  assert(lpi != NULL);
5054  assert(lpi->grbmodel != NULL);
5055  assert(lpistate != NULL);
5056 
5057  /* if there is no basis information available, no state can be saved */
5058  if( !lpi->solisbasic )
5059  {
5060  *lpistate = NULL;
5061  return SCIP_OKAY;
5062  }
5063 
5064  SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
5065  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
5066  assert(ncols >= 0);
5067  assert(nrows >= 0);
5068 
5069  /* get unpacked basis information from Gurobi */
5070  SCIP_CALL( getBase(lpi, &success) );
5071 
5072  if ( success )
5073  {
5074  /* allocate lpistate data */
5075  SCIP_CALL( lpistateCreate(lpistate, blkmem, ncols, nrows, lpi->nrngrows) );
5076  (*lpistate)->ncols = ncols;
5077  (*lpistate)->nrows = nrows;
5078  (*lpistate)->nrngrows = lpi->nrngrows;
5079 
5080  SCIPdebugMessage("stored Gurobi LPI state in %p (%d cols, %d rows, %d ranged rows)\n",
5081  (void*) *lpistate, ncols, nrows, lpi->nrngrows);
5082 
5083  /* pack LPi state data */
5084  lpistatePack(*lpistate, lpi->cstat, lpi->rstat);
5085  }
5086  else
5087  {
5088  /* In this case no basis information is available. Since SCIP expects the information to work in any case, we
5089  * allocate the lpistate, but do not use the packed information. This might happen if the model is infeasible,
5090  * since Gurobi currently does not return basis information in this case. */
5091  SCIP_ALLOC( BMSallocBlockMemory(blkmem, lpistate) );
5092  (*lpistate)->ncols = ncols;
5093  (*lpistate)->nrows = nrows;
5094  (*lpistate)->nrngrows = lpi->nrngrows;
5095  (*lpistate)->packrstat = NULL;
5096  (*lpistate)->packcstat = NULL;
5097  }
5098 
5099  return SCIP_OKAY;
5100 }
5101 
5102 /** loads LPi state (like basis information) into solver; note that the LP might have been extended with additional
5103  * columns and rows since the state was stored with SCIPlpiGetState()
5104  */
5106  SCIP_LPI* lpi, /**< LP interface structure */
5107  BMS_BLKMEM* blkmem, /**< block memory */
5108  const SCIP_LPISTATE* lpistate /**< LPi state information (like basis information), or NULL */
5109  )
5110 {
5111  int ncols;
5112  int nrows;
5113  int i;
5114 
5115  assert(blkmem != NULL);
5116  assert(lpi != NULL);
5117  assert(lpi->grbmodel != NULL);
5118 
5119  /* if there was no basis information available, the LPI state was not stored */
5120  if( lpistate == NULL || lpistate->packrstat == NULL || lpistate->packcstat == NULL )
5121  return SCIP_OKAY;
5122 
5123  SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
5124  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
5125  assert(lpistate->ncols <= ncols);
5126  assert(lpistate->nrows <= nrows);
5127  assert(lpistate->nrngrows <= lpi->nrngrows);
5128 
5129  SCIPdebugMessage("loading LPI state %p (%d cols, %d rows, %d ranged rows) into Gurobi LP with %d cols, %d rows, and %d ranged rows\n",
5130  (void*) lpistate, lpistate->ncols, lpistate->nrows, lpistate->nrngrows, ncols, nrows, lpi->nrngrows);
5131 
5132  if( lpistate->ncols == 0 || lpistate->nrows == 0 )
5133  return SCIP_OKAY;
5134 
5135  /* allocate enough memory for storing uncompressed basis information */
5136  SCIP_CALL( ensureCstatMem(lpi, ncols + lpi->nrngrows) );
5137  SCIP_CALL( ensureRstatMem(lpi, nrows) );
5138 
5139  /* unpack LPi state data */
5140  lpistateUnpack(lpistate, lpi->cstat, lpi->rstat);
5141 
5142  if ( lpistate->nrngrows > 0 && lpistate->ncols < ncols )
5143  {
5144  /* New columns have been added: need to move range variable information */
5145  memmove(&lpi->cstat[ncols], &lpi->cstat[lpistate->ncols], lpistate->nrngrows * sizeof(*lpi->cstat));
5146  }
5147 
5148  /* extend the basis to the current LP beyond the previously existing columns */
5149  for( i = lpistate->ncols; i < ncols; ++i )
5150  {
5151  SCIP_Real bnd;
5152  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrelement(lpi->grbmodel, GRB_DBL_ATTR_LB, i, &bnd) );
5153  if ( SCIPlpiIsInfinity(lpi, REALABS(bnd)) )
5154  {
5155  /* if lower bound is +/- infinity -> try upper bound */
5156  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrelement(lpi->grbmodel, GRB_DBL_ATTR_UB, i, &bnd) );
5157  if ( SCIPlpiIsInfinity(lpi, REALABS(bnd)) )
5158  lpi->cstat[i] = (int) SCIP_BASESTAT_ZERO; /* variable is free */
5159  else
5160  lpi->cstat[i] = (int) SCIP_BASESTAT_UPPER; /* use finite upper bound */
5161  }
5162  else
5163  lpi->cstat[i] = (int) SCIP_BASESTAT_LOWER; /* use finite lower bound */
5164  }
5165  for( i = lpistate->nrngrows; i < lpi->nrngrows; ++i )
5166  lpi->cstat[ncols + i] = (int) SCIP_BASESTAT_LOWER;
5167  for( i = lpistate->nrows; i < nrows; ++i )
5168  lpi->rstat[i] = (int) SCIP_BASESTAT_BASIC;
5169 
5170  /* load basis information into Gurobi */
5171  SCIP_CALL( setBase(lpi) );
5172 
5173  return SCIP_OKAY;
5174 }
5175 
5176 /** clears current LPi state (like basis information) of the solver */
5178  SCIP_LPI* lpi /**< LP interface structure */
5179  )
5180 {
5181  assert(lpi != NULL);
5182  assert(lpi->grbmodel != NULL);
5183 
5184  CHECK_ZERO( lpi->messagehdlr, GRBresetmodel(lpi->grbmodel) );
5185 
5186  return SCIP_OKAY;
5187 }
5188 
5189 /** frees LPi state information */
5191  SCIP_LPI* lpi, /**< LP interface structure */
5192  BMS_BLKMEM* blkmem, /**< block memory */
5193  SCIP_LPISTATE** lpistate /**< pointer to LPi state information (like basis information) */
5194  )
5195 {
5196  assert(lpi != NULL);
5197  assert(lpistate != NULL);
5198  assert(blkmem != NULL);
5199 
5200  if( *lpistate != NULL )
5201  lpistateFree(lpistate, blkmem);
5202 
5203  return SCIP_OKAY;
5204 }
5205 
5206 /** checks, whether the given LP state contains simplex basis information */
5208  SCIP_LPI* lpi, /**< LP interface structure */
5209  SCIP_LPISTATE* lpistate /**< LP state information (like basis information), or NULL */
5210  )
5211 { /*lint --e{715}*/
5212  assert(lpi != NULL);
5213  return (lpistate != NULL && lpistate->packcstat != NULL);
5214 }
5215 
5216 /** reads LP state (like basis information from a file */
5218  SCIP_LPI* lpi, /**< LP interface structure */
5219  const char* fname /**< file name */
5220  )
5221 {
5222  size_t l;
5223 
5224  assert(lpi != NULL);
5225  assert(lpi->grbmodel != NULL);
5226  assert(fname != NULL);
5227 
5228  SCIPdebugMessage("reading LP state from file <%s>\n", fname);
5229 
5230  /* gurobi reads a basis if the extension is ".bas" */
5231  l = strlen(fname);
5232  if ( l > 4 && fname[l-4] == '.' && fname[l-3] == 'b' && fname[l-2] == 'a' && fname[l-1] == 's' )
5233  {
5234  CHECK_ZERO( lpi->messagehdlr, GRBread(lpi->grbmodel, fname) );
5235  }
5236  else
5237  {
5238  SCIPerrorMessage("To read a basis with gurobi, the extension has to be '.bas'.\n");
5239  return SCIP_LPERROR;
5240  }
5241 
5242  return SCIP_OKAY;
5243 }
5244 
5245 /** writes LPi state (i.e. basis information) to a file */
5247  SCIP_LPI* lpi, /**< LP interface structure */
5248  const char* fname /**< file name */
5249  )
5250 {
5251  size_t l;
5252 
5253  assert(lpi != NULL);
5254  assert(lpi->grbmodel != NULL);
5255  assert(fname != NULL);
5256 
5257  SCIPdebugMessage("writing basis state to file <%s>\n", fname);
5258 
5259  /* gurobi writes the basis if the extension is ".bas" */
5260  l = strlen(fname);
5261  if ( l > 4 && fname[l-4] == '.' && fname[l-3] == 'b' && fname[l-2] == 'a' && fname[l-1] == 's' )
5262  {
5263  CHECK_ZERO( lpi->messagehdlr, GRBwrite(lpi->grbmodel, fname) );
5264  }
5265  else
5266  {
5267  char name[SCIP_MAXSTRLEN];
5268 
5269  /* force extension to be ".bas" */
5270  if ( strlen(fname) > SCIP_MAXSTRLEN-4)
5271  {
5272  SCIPerrorMessage("Basis file name too long.\n");
5273  return SCIP_LPERROR;
5274  }
5275  snprintf(name, SCIP_MAXSTRLEN, "%s.bas", fname);
5276  CHECK_ZERO( lpi->messagehdlr, GRBwrite(lpi->grbmodel, fname) );
5277  }
5278 
5279  return SCIP_OKAY;
5280 }
5281 
5282 /**@} */
5283 
5284 
5285 
5286 
5287 /*
5288  * LP Pricing Norms Methods
5289  */
5290 
5291 /**@name LP Pricing Norms Methods */
5292 /**@{ */
5293 
5294 /** stores LPi pricing norms information */
5296  SCIP_LPI* lpi, /**< LP interface structure */
5297  BMS_BLKMEM* blkmem, /**< block memory */
5298  SCIP_LPINORMS** lpinorms /**< pointer to LPi pricing norms information */
5299  )
5300 { /*lint --e{715}*/
5301  int hasnorm;
5302  int ncols;
5303  int nrows;
5304 
5305  assert(blkmem != NULL);
5306  assert(lpi != NULL);
5307  assert(lpi->grbmodel != NULL);
5308  assert(lpinorms != NULL);
5309 
5310  *lpinorms = NULL;
5311 
5312  /* if there is no basis information available (e.g. after barrier without crossover), norms cannot be saved */
5313  if( !lpi->solisbasic )
5314  return SCIP_OKAY;
5315 
5316  /* check if dual norms are available:
5317  * value 0: no basis, so no norms available
5318  * value 1: basis exists, so norms can be computed
5319  * value 2: norms are available
5320  */
5321  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_HASDUALNORM, &hasnorm) );
5322  if( hasnorm <= 1 )
5323  return SCIP_OKAY;
5324 
5325  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_NUMVARS, &ncols) );
5326  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_NUMCONSTRS, &nrows) );
5327 
5328  /* allocate lpinorms data */
5329  SCIP_ALLOC( BMSallocBlockMemory(blkmem, lpinorms) );
5330  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpinorms)->colnorm, ncols) );
5331  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpinorms)->rownorm, nrows) );
5332  (*lpinorms)->ncols = ncols;
5333  (*lpinorms)->nrows = nrows;
5334 
5335  /* query dual norms from Gurobi */
5336  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_VDUALNORM, 0, ncols, (*lpinorms)->colnorm) );
5337  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_CDUALNORM, 0, nrows, (*lpinorms)->rownorm) );
5338 
5339  return SCIP_OKAY;
5340 }
5341 
5342 /** loads LPi pricing norms into solver; note that the LP might have been extended with additional
5343  * columns and rows since the state was stored with SCIPlpiGetNorms()
5344  */
5346  SCIP_LPI* lpi, /**< LP interface structure */
5347  BMS_BLKMEM* blkmem, /**< block memory */
5348  const SCIP_LPINORMS* lpinorms /**< LPi pricing norms information, or NULL */
5349  )
5350 { /*lint --e{715}*/
5351  int error;
5352 
5353  assert(blkmem != NULL);
5354  assert(lpi != NULL);
5355 
5356  /* if there was no pricing norms information available, the LPI norms were not stored */
5357  if( lpinorms == NULL )
5358  return SCIP_OKAY;
5359 
5360  /* store dual norms in Gurobi */
5361  error = GRBsetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_VDUALNORM, 0, lpinorms->ncols, lpinorms->colnorm);
5362  /* it can fail to set the norms if no basis was previously set, e.g.,
5363  * this can happen if flushing an LP did not change anything and
5364  * therefore no basis was set, as a result Gurobi has no extra user
5365  * warmstart information and cannot set norms */
5366 #ifdef SCIP_DEBUG
5367  if( error )
5368  SCIPmessagePrintWarning(lpi->messagehdlr, "Warning: setting dual variable norms failed with Gurobi error %d\n", error);
5369 #else
5370  (void)error;
5371 #endif
5372 
5373  error = GRBsetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_CDUALNORM, 0, lpinorms->nrows, lpinorms->rownorm);
5374  /* it can fail to set the norms if no basis was previously set, e.g.,
5375  * this can happen if flushing an LP did not change anything and
5376  * therefore no basis was set, as a result Gurobi has no extra user
5377  * warmstart information and cannot set norms */
5378 #ifdef SCIP_DEBUG
5379  if( error )
5380  SCIPmessagePrintWarning(lpi->messagehdlr, "Warning: setting dual constraint norms failed with Gurobi error %d\n", error);
5381 #else
5382  (void)error;
5383 #endif
5384 
5385  return SCIP_OKAY;
5386 }
5387 
5388 /** frees pricing norms information */
5390  SCIP_LPI* lpi, /**< LP interface structure */
5391  BMS_BLKMEM* blkmem, /**< block memory */
5392  SCIP_LPINORMS** lpinorms /**< pointer to LPi pricing norms information, or NULL */
5393  )
5394 { /*lint --e{715}*/
5395  assert(lpi != NULL);
5396  assert(lpinorms != NULL);
5397 
5398  if ( *lpinorms != NULL )
5399  {
5400  BMSfreeBlockMemoryArray(blkmem, &(*lpinorms)->colnorm, (*lpinorms)->ncols);
5401  BMSfreeBlockMemoryArray(blkmem, &(*lpinorms)->rownorm, (*lpinorms)->nrows);
5402  BMSfreeBlockMemory(blkmem, lpinorms);
5403  }
5404 
5405  return SCIP_OKAY;
5406 }
5407 
5408 /**@} */
5409 
5410 
5411 
5412 
5413 /*
5414  * Parameter Methods
5415  */
5416 
5417 /**@name Parameter Methods */
5418 /**@{ */
5419 
5420 /** gets integer parameter of LP */
5422  SCIP_LPI* lpi, /**< LP interface structure */
5423  SCIP_LPPARAM type, /**< parameter number */
5424  int* ival /**< buffer to store the parameter value */
5425  )
5426 {
5427  int temp;
5428  SCIP_Real dtemp;
5429 
5430  assert(lpi != NULL);
5431  assert(lpi->grbmodel != NULL);
5432  assert(ival != NULL);
5433 
5434  SCIPdebugMessage("getting int parameter %d\n", type);
5435 
5436  switch( type )
5437  {
5439  *ival = (int) lpi->fromscratch;
5440  break;
5441  case SCIP_LPPAR_FASTMIP:
5442  /* maybe set perturbation */
5443  return SCIP_PARAMETERUNKNOWN;
5444  case SCIP_LPPAR_SCALING:
5445  SCIP_CALL( getIntParam(lpi, GRB_INT_PAR_SCALEFLAG, &temp) );
5446  assert(temp >= -1 && temp <= 3);
5447  if( temp == -1 )
5448  *ival = 1;
5449  else
5450  *ival = temp;
5451  break;
5452  case SCIP_LPPAR_PRESOLVING:
5453  SCIP_CALL( getIntParam(lpi, GRB_INT_PAR_PRESOLVE, &temp) );
5454  assert( temp == GRB_PRESOLVE_AUTO || temp == GRB_PRESOLVE_OFF || temp == GRB_PRESOLVE_CONSERVATIVE || temp == GRB_PRESOLVE_AGGRESSIVE );
5455  *ival = (temp == GRB_PRESOLVE_OFF) ? FALSE : TRUE;
5456  break;
5457  case SCIP_LPPAR_PRICING:
5458  *ival = (int) lpi->pricing;
5459  break;
5460  case SCIP_LPPAR_LPINFO:
5461  SCIP_CALL( getIntParam(lpi, GRB_INT_PAR_OUTPUTFLAG, &temp) );
5462  assert( temp == 0 || temp == 1 );
5463  *ival = (temp == 1) ? TRUE : FALSE;
5464  break;
5465  case SCIP_LPPAR_LPITLIM:
5466  SCIP_CALL( getDblParam(lpi, GRB_DBL_PAR_ITERATIONLIMIT, &dtemp) );
5467  assert( dtemp >= 0.0 );
5468  if( dtemp >= INT_MAX )
5469  *ival = INT_MAX;
5470  else
5471  *ival = (int) dtemp;
5472  break;
5473  case SCIP_LPPAR_THREADS:
5474  SCIP_CALL( getIntParam(lpi, GRB_INT_PAR_THREADS, ival) );
5475  break;
5476  case SCIP_LPPAR_RANDOMSEED:
5477  SCIP_CALL( getIntParam(lpi, GRB_INT_PAR_SEED, ival) );
5478  break;
5479  default:
5480  return SCIP_PARAMETERUNKNOWN;
5481  } /*lint !e788*/
5482 
5483  return SCIP_OKAY;
5484 }
5485 
5486 /** sets integer parameter of LP */
5488  SCIP_LPI* lpi, /**< LP interface structure */
5489  SCIP_LPPARAM type, /**< parameter number */
5490  int ival /**< parameter value */
5491  )
5492 {
5493  assert(lpi != NULL);
5494  assert(lpi->grbmodel != NULL);
5495 
5496  SCIPdebugMessage("setting int parameter %d to %d\n", type, ival);
5497 
5498  switch( type )
5499  {
5501  assert(ival == TRUE || ival == FALSE);
5502  lpi->fromscratch = (SCIP_Bool) ival;
5503  break;
5504  case SCIP_LPPAR_FASTMIP:
5505  assert(ival == TRUE || ival == FALSE);
5506  return SCIP_PARAMETERUNKNOWN;
5507  case SCIP_LPPAR_SCALING:
5508  if( ival == 1 )
5509  SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_SCALEFLAG, -1) );
5510  else
5511  SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_SCALEFLAG, ival) );
5512  break;
5513  case SCIP_LPPAR_PRESOLVING:
5514  assert(ival == TRUE || ival == FALSE);
5515  if( ival )
5516  SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_PRESOLVE, GRB_PRESOLVE_AUTO) );
5517  else
5518  SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_PRESOLVE, GRB_PRESOLVE_OFF) );
5519  break;
5520  case SCIP_LPPAR_PRICING:
5521  lpi->pricing = (SCIP_PRICING)ival;
5522  switch( (SCIP_PRICING)ival )
5523  {
5525  case SCIP_PRICING_AUTO:
5526  SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_SIMPLEXPRICING, GRB_SIMPLEXPRICING_AUTO) );
5527  break;
5528  case SCIP_PRICING_FULL:
5529  /* full does not seem to exist -> use auto */
5530  SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_SIMPLEXPRICING, GRB_SIMPLEXPRICING_AUTO) );
5531  break;
5532  case SCIP_PRICING_PARTIAL:
5533  SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_SIMPLEXPRICING, GRB_SIMPLEXPRICING_PARTIAL) );
5534  break;
5535  case SCIP_PRICING_STEEP:
5536  SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_SIMPLEXPRICING, GRB_SIMPLEXPRICING_STEEPEST_EDGE) );
5537  break;
5539  SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_SIMPLEXPRICING, GRB_SIMPLEXPRICING_STEEPEST_QUICK) );
5540  break;
5541  case SCIP_PRICING_DEVEX:
5542  SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_SIMPLEXPRICING, GRB_SIMPLEXPRICING_DEVEX) );
5543  break;
5544  default:
5545  return SCIP_PARAMETERUNKNOWN;
5546  }
5547  break;
5548  case SCIP_LPPAR_LPINFO:
5549  assert(ival == TRUE || ival == FALSE);
5550  if( ival )
5551  SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_OUTPUTFLAG, 1) );
5552  else
5553  SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_OUTPUTFLAG, 0) );
5554  break;
5555  case SCIP_LPPAR_LPITLIM:
5556  assert( ival >= 0 );
5557  /* 0 <= ival, 0 stopping immediately */
5558  {
5559  double itlim;
5560  itlim = (ival >= INT_MAX ? GRB_INFINITY : ival);
5561  SCIP_CALL( setDblParam(lpi, GRB_DBL_PAR_ITERATIONLIMIT, itlim) );
5562  }
5563  break;
5564  case SCIP_LPPAR_THREADS:
5565  assert( ival >= 0 );
5566  SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_THREADS, ival) );
5567  break;
5568  case SCIP_LPPAR_RANDOMSEED:
5569  assert( ival >= 0 );
5570  SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_SEED, ival) );
5571  break;
5572  default:
5573  return SCIP_PARAMETERUNKNOWN;
5574  } /*lint !e788*/
5575 
5576  return SCIP_OKAY;
5577 }
5578 
5579 /** gets floating point parameter of LP */
5581  SCIP_LPI* lpi, /**< LP interface structure */
5582  SCIP_LPPARAM type, /**< parameter number */
5583  SCIP_Real* dval /**< buffer to store the parameter value */
5584  )
5585 {
5586  assert(lpi != NULL);
5587  assert(lpi->grbmodel != NULL);
5588  assert(dval != NULL);
5589 
5590  SCIPdebugMessage("getting real parameter %d\n", type);
5591 
5592  switch( type )
5593  {
5594  case SCIP_LPPAR_FEASTOL:
5595  SCIP_CALL( getDblParam(lpi, GRB_DBL_PAR_FEASIBILITYTOL, dval) );
5596  break;
5598  SCIP_CALL( getDblParam(lpi, GRB_DBL_PAR_OPTIMALITYTOL, dval) );
5599  break;
5601  SCIP_CALL( getDblParam(lpi, GRB_DBL_PAR_BARCONVTOL, dval) );
5602  break;
5603  case SCIP_LPPAR_OBJLIM:
5604  SCIP_CALL( getDblParam(lpi, GRB_DBL_PAR_CUTOFF, dval) );
5605  break;
5606  case SCIP_LPPAR_LPTILIM:
5607  SCIP_CALL( getDblParam(lpi, GRB_DBL_PAR_TIMELIMIT, dval) );
5608  break;
5609  case SCIP_LPPAR_MARKOWITZ:
5610  SCIP_CALL( getDblParam(lpi, GRB_DBL_PAR_MARKOWITZTOL, dval) );
5611  break;
5613  *dval = lpi->conditionlimit;
5614  break;
5615  default:
5616  return SCIP_PARAMETERUNKNOWN;
5617  } /*lint !e788*/
5618 
5619  return SCIP_OKAY;
5620 }
5621 
5622 /** sets floating point parameter of LP */
5624  SCIP_LPI* lpi, /**< LP interface structure */
5625  SCIP_LPPARAM type, /**< parameter number */
5626  SCIP_Real dval /**< parameter value */
5627  )
5628 {
5629  assert(lpi != NULL);
5630  assert(lpi->grbmodel != NULL);
5631 
5632  SCIPdebugMessage("setting real parameter %d to %g\n", type, dval);
5633 
5634  switch( type )
5635  {
5636  case SCIP_LPPAR_FEASTOL:
5637  assert( dval > 0.0 );
5638  /* 1e-9 <= dval <= 1e-2 */
5639  if( dval < 1e-9 )
5640  dval = 1e-9;
5641  else if( dval > 1e-2 )
5642  dval = 1e-2;
5643 
5644  SCIP_CALL( setDblParam(lpi, GRB_DBL_PAR_FEASIBILITYTOL, dval) );
5645  break;
5647  assert( dval > 0.0 );
5648  /* 1e-9 <= dval <= 1e-2 */
5649  if (dval < 1e-9)
5650  dval = 1e-9;
5651  else if( dval > 1e-2 )
5652  dval = 1e-2;
5653 
5654  SCIP_CALL( setDblParam(lpi, GRB_DBL_PAR_OPTIMALITYTOL, dval) );
5655  break;
5657  /* 0 <= dval <= 1 */
5658  assert( dval >= 0.0 );
5659  if( dval > 1.0 )
5660  dval = 1.0;
5661 
5662  SCIP_CALL( setDblParam(lpi, GRB_DBL_PAR_BARCONVTOL, dval) );
5663  break;
5664  case SCIP_LPPAR_OBJLIM:
5665  /* no restriction on dval */
5666 
5667  SCIP_CALL( setDblParam(lpi, GRB_DBL_PAR_CUTOFF, dval) );
5668  break;
5669  case SCIP_LPPAR_LPTILIM:
5670  assert( dval > 0.0 );
5671  /* gurobi requires 0 <= dval
5672  *
5673  * However for consistency we assert the timelimit to be strictly positive.
5674  */
5675 
5676  SCIP_CALL( setDblParam(lpi, GRB_DBL_PAR_TIMELIMIT, dval) );
5677  break;
5678  case SCIP_LPPAR_MARKOWITZ:
5679  /* 1e-4 <= dval <= 0.999 */
5680  if( dval < 1e-4 )
5681  dval = 1e-4;
5682  else if( dval > 0.999 )
5683  dval = 0.999;
5684 
5685  SCIP_CALL( setDblParam(lpi, GRB_DBL_PAR_MARKOWITZTOL, dval) );
5686  break;
5688  lpi->conditionlimit = dval;
5689  lpi->checkcondition = (dval >= 0.0) ? TRUE : FALSE;
5690  break;
5691  default:
5692  return SCIP_PARAMETERUNKNOWN;
5693  } /*lint !e788*/
5694 
5695  return SCIP_OKAY;
5696 }
5697 
5698 /**@} */
5699 
5700 
5701 
5702 
5703 /*
5704  * Numerical Methods
5705  */
5706 
5707 /**@name Numerical Methods */
5708 /**@{ */
5709 
5710 /** returns value treated as infinity in the LP solver */
5712  SCIP_LPI* lpi /**< LP interface structure */
5713  )
5714 { /*lint --e{715}*/
5715  assert(lpi != NULL);
5716  return GRB_INFINITY;
5717 }
5718 
5719 /** checks if given value is treated as infinity in the LP solver */
5721  SCIP_LPI* lpi, /**< LP interface structure */
5722  SCIP_Real val /**< value to be checked for infinity */
5723  )
5724 { /*lint --e{715}*/
5725  assert(lpi != NULL);
5726  return (val >= GRB_INFINITY);
5727 }
5728 
5729 /**@} */
5730 
5731 
5732 
5733 
5734 /*
5735  * File Interface Methods
5736  */
5737 
5738 /**@name File Interface Methods */
5739 /**@{ */
5740 
5741 /** reads LP from a file */
5743  SCIP_LPI* lpi, /**< LP interface structure */
5744  const char* fname /**< file name */
5745  )
5746 {
5747  assert(lpi != NULL);
5748  assert(lpi->grbmodel != NULL);
5749  assert(fname != NULL);
5750 
5751  SCIPdebugMessage("reading LP from file <%s>\n", fname);
5752 
5753  CHECK_ZERO( lpi->messagehdlr, GRBreadmodel(lpi->grbenv, fname, &lpi->grbmodel) );
5754 
5755  /* the model name seems to be empty, use filename */
5756  CHECK_ZERO( lpi->messagehdlr, GRBsetstrattr(lpi->grbmodel, GRB_STR_ATTR_MODELNAME, fname) );
5757 
5758  return SCIP_OKAY;
5759 }
5760 
5761 /** writes LP to a file */
5763  SCIP_LPI* lpi, /**< LP interface structure */
5764  const char* fname /**< file name */
5765  )
5766 {
5767  assert(lpi != NULL);
5768  assert(lpi->grbmodel != NULL);
5769  assert(fname != NULL);
5770 
5771  SCIPdebugMessage("writing LP to file <%s>\n", fname);
5772 
5773  /* if range rows were not added, add, print and remove them; otherwise, just print */
5774  if ( lpi->nrngrows > 0 && !lpi->rngvarsadded )
5775  {
5776  SCIP_CALL( addRangeVars(lpi) );
5777  CHECK_ZERO( lpi->messagehdlr, GRBwrite(lpi->grbmodel, fname) );
5778  SCIP_CALL( delRangeVars(lpi) );
5779  }
5780  else
5781  {
5782  CHECK_ZERO( lpi->messagehdlr, GRBwrite(lpi->grbmodel, fname) );
5783  }
5784 
5785  return SCIP_OKAY;
5786 }
5787 
5788 /**@} */
SCIP_RETCODE SCIPlpiCreate(SCIP_LPI **lpi, SCIP_MESSAGEHDLR *messagehdlr, const char *name, SCIP_OBJSEN objsen)
Definition: lpi_grb.c:1303
static SCIP_RETCODE setParameterValues(SCIP_LPI *lpi, GRBPARAM *grbparam)
Definition: lpi_grb.c:717
SCIP_RETCODE SCIPlpiSetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int ival)
Definition: lpi_grb.c:5487
static SCIP_RETCODE restoreLPData(SCIP_LPI *lpi)
Definition: lpi_grb.c:1004
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_grb.c:3468
enum SCIP_LPSolQuality SCIP_LPSOLQUALITY
Definition: type_lpi.h:95
static SCIP_RETCODE addRangeVars(SCIP_LPI *lpi)
Definition: lpi_grb.c:1078
SCIP_Real SCIPlpiInfinity(SCIP_LPI *lpi)
Definition: lpi_grb.c:5711
#define BMSfreeBlockMemoryArrayNull(mem, ptr, num)
Definition: memory.h:459
static SCIP_RETCODE getDblParam(SCIP_LPI *lpi, const char *param, double *p)
Definition: lpi_grb.c:823
#define NUMINTPARAM
Definition: lpi_grb.c:79
const char * SCIPlpiGetSolverName(void)
Definition: lpi_grb.c:1223
SCIP_Real conditionlimit
Definition: lpi_cpx.c:164
int rngrowssize
Definition: lpi_grb.c:160
GRBPARAM grbparam
Definition: lpi_grb.c:134
SCIP_DUALPACKET COLPACKET
Definition: lpi_grb.c:66
GRBenv * grbenv
Definition: lpi_grb.c:130
#define BMSfreeMemoryArrayNull(ptr)
Definition: memory.h:140
SCIP_Bool solisbasic
Definition: lpi_cpx.c:159
SCIP_RETCODE SCIPlpiGetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int *ival)
Definition: lpi_grb.c:5421
SCIP_RETCODE SCIPlpiSetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, const SCIP_LPINORMS *lpinorms)
Definition: lpi_grb.c:5345
SCIP_RETCODE SCIPlpiGetDualfarkas(SCIP_LPI *lpi, SCIP_Real *dualfarkas)
Definition: lpi_grb.c:4209
static void lpistateUnpack(const SCIP_LPISTATE *lpistate, int *cstat, int *rstat)
Definition: lpi_grb.c:610
static char grbname[100]
Definition: lpi_grb.c:1217
unsigned int SCIP_DUALPACKET
Definition: lpi_grb.c:63
SCIP_RETCODE SCIPlpiChgCoef(SCIP_LPI *lpi, int row, int col, SCIP_Real newval)
Definition: lpi_grb.c:2206
ROWPACKET * packrstat
Definition: lpi_clp.cpp:128