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-2021 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); /*lint !e506*/
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 ) /*lint !e679*/
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]]; /*lint !e661*/
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); /*lint !e506*/
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  (void) snprintf(grbname, 100, "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  assert( lpi != NULL );
1263  assert( ncols >= 0 );
1264  assert( ncols == 0 || intInfo != NULL );
1265 
1266  SCIPerrorMessage("SCIPlpiSetIntegralityInformation() has not been implemented yet.\n");
1267  return SCIP_LPERROR;
1268 }
1269 
1270 /** informs about availability of a primal simplex solving method */
1272  void
1273  )
1274 {
1275  return TRUE;
1276 }
1277 
1278 /** informs about availability of a dual simplex solving method */
1280  void
1281  )
1282 {
1283  return TRUE;
1284 }
1285 
1286 /** informs about availability of a barrier solving method */
1288  void
1289  )
1290 {
1291  return TRUE;
1292 }
1293 
1294 /**@} */
1295 
1296 
1297 
1298 
1299 /*
1300  * LPI Creation and Destruction Methods
1301  */
1302 
1303 /**@name LPI Creation and Destruction Methods */
1304 /**@{ */
1305 
1306 /** creates an LP problem object */
1308  SCIP_LPI** lpi, /**< pointer to an LP interface structure */
1309  SCIP_MESSAGEHDLR* messagehdlr, /**< message handler to use for printing messages, or NULL */
1310  const char* name, /**< problem name */
1311  SCIP_OBJSEN objsen /**< objective sense */
1312  )
1313 {
1314  assert(sizeof(SCIP_Real) == sizeof(double)); /*lint !e506*/ /* Gurobi only works with doubles as floating points */
1315  assert(sizeof(SCIP_Bool) == sizeof(int)); /*lint !e506*/ /* Gurobi only works with ints as bools */
1316  assert(lpi != NULL);
1317  assert(name != NULL);
1318  assert(numlp >= 0);
1319 
1320  SCIPdebugMessage("SCIPlpiCreate()\n");
1321 
1322  /* create environment
1323  *
1324  * Each problem will get a copy of the original environment. Thus, grbenv is only needed once.
1325  */
1326  if ( grbenv == NULL )
1327  {
1328  /* initialize environment - no log file */
1329  CHECK_ZERO( messagehdlr, GRBloadenv(&grbenv, NULL) );
1330 
1331  /* turn off output for all models */
1332  CHECK_ZERO( messagehdlr, GRBsetintparam(grbenv, GRB_INT_PAR_OUTPUTFLAG, 0) );
1333 
1334  /* turn on that basis information for infeasible and unbounded models is available */
1335  CHECK_ZERO( messagehdlr, GRBsetintparam(grbenv, GRB_INT_PAR_INFUNBDINFO, 1) );
1336  }
1337  assert( grbenv != NULL );
1338 
1339  /* create empty LPI */
1340  SCIP_ALLOC( BMSallocMemory(lpi) );
1341  CHECK_ZERO( messagehdlr, GRBnewmodel(grbenv, &(*lpi)->grbmodel, name, 0, NULL, NULL, NULL, NULL, NULL) );
1342 
1343  /* get local copy of environment */
1344  (*lpi)->grbenv = GRBgetenv((*lpi)->grbmodel);
1345  (*lpi)->senarray = NULL;
1346  (*lpi)->rhsarray = NULL;
1347  (*lpi)->rngarray = NULL;
1348  (*lpi)->rngidxarray = NULL;
1349  (*lpi)->valarray = NULL;
1350  (*lpi)->cstat = NULL;
1351  (*lpi)->rstat = NULL;
1352  (*lpi)->indarray = NULL;
1353  (*lpi)->rngrowmap = NULL;
1354  (*lpi)->rngrows = NULL;
1355  (*lpi)->rngvals = NULL;
1356  (*lpi)->sidechgsize = 0;
1357  (*lpi)->valsize = 0;
1358  (*lpi)->cstatsize = 0;
1359  (*lpi)->rstatsize = 0;
1360  (*lpi)->rngrowmapsize = 0;
1361  (*lpi)->nrngrows = 0;
1362  (*lpi)->rngrowssize = 0;
1363  (*lpi)->rngvarsadded = FALSE;
1364  (*lpi)->iterations = 0;
1365  (*lpi)->solisbasic = FALSE;
1366  (*lpi)->fromscratch = FALSE;
1367  (*lpi)->conditionlimit = -1.0;
1368  (*lpi)->checkcondition = FALSE;
1369  (*lpi)->pricing = SCIP_PRICING_LPIDEFAULT;
1370  (*lpi)->messagehdlr = messagehdlr;
1371  invalidateSolution(*lpi);
1372 
1373  /* get default parameter values */
1374  SCIP_CALL( getParameterValues((*lpi), &((*lpi)->defparam)) );
1375  copyParameterValues(&((*lpi)->curparam), &((*lpi)->defparam));
1376  copyParameterValues(&((*lpi)->grbparam), &((*lpi)->defparam));
1377  ++numlp;
1378 
1379  /* set objective sense */
1380  SCIP_CALL( SCIPlpiChgObjsen(*lpi, objsen) );
1381 
1382  /* set default pricing */
1383  SCIP_CALL( SCIPlpiSetIntpar(*lpi, SCIP_LPPAR_PRICING, (int) (*lpi)->pricing) );
1384 
1385  checkRangeInfo(*lpi);
1386 
1387  return SCIP_OKAY;
1388 }
1389 
1390 /** deletes an LP problem object */
1392  SCIP_LPI** lpi /**< pointer to an LP interface structure */
1393  )
1394 {
1395  assert(grbenv != NULL);
1396  assert(lpi != NULL);
1397  assert(*lpi != NULL);
1398 
1399  SCIPdebugMessage("SCIPlpiFree()\n");
1400 
1401  /* free model */
1402  CHECK_ZERO( (*lpi)->messagehdlr, GRBfreemodel((*lpi)->grbmodel) );
1403 
1404  /* free memory */
1405  BMSfreeMemoryArrayNull(&(*lpi)->senarray);
1406  BMSfreeMemoryArrayNull(&(*lpi)->rhsarray);
1407  BMSfreeMemoryArrayNull(&(*lpi)->rngarray);
1408  BMSfreeMemoryArrayNull(&(*lpi)->rngidxarray);
1409  BMSfreeMemoryArrayNull(&(*lpi)->cstat);
1410  BMSfreeMemoryArrayNull(&(*lpi)->rstat);
1411  BMSfreeMemoryArrayNull(&(*lpi)->rngrowmap);
1412  BMSfreeMemoryArrayNull(&(*lpi)->rngrows);
1413  BMSfreeMemoryArrayNull(&(*lpi)->rngvals);
1414  BMSfreeMemoryArrayNull(&(*lpi)->indarray);
1415  BMSfreeMemoryArrayNull(&(*lpi)->valarray);
1416  BMSfreeMemory(lpi);
1417 
1418  /* free environment */
1419  --numlp;
1420  if( numlp == 0 )
1421  {
1422  GRBfreeenv(grbenv);
1423  grbenv = NULL;
1424  }
1425 
1426  return SCIP_OKAY;
1427 }
1428 
1429 /**@} */
1430 
1431 
1432 
1433 
1434 /*
1435  * Modification Methods
1436  */
1437 
1438 /**@name Modification Methods */
1439 /**@{ */
1440 
1441 /** copies LP data with column matrix into LP solver */
1443  SCIP_LPI* lpi, /**< LP interface structure */
1444  SCIP_OBJSEN objsen, /**< objective sense */
1445  int ncols, /**< number of columns */
1446  const SCIP_Real* obj, /**< objective function values of columns */
1447  const SCIP_Real* lb, /**< lower bounds of columns */
1448  const SCIP_Real* ub, /**< upper bounds of columns */
1449  char** colnames, /**< column names, or NULL */
1450  int nrows, /**< number of rows */
1451  const SCIP_Real* lhs, /**< left hand sides of rows */
1452  const SCIP_Real* rhs, /**< right hand sides of rows */
1453  char** rownames, /**< row names, or NULL */
1454  int nnonz, /**< number of nonzero elements in the constraint matrix */
1455  const int* beg, /**< start index of each column in ind- and val-array */
1456  const int* ind, /**< row indices of constraint matrix entries */
1457  const SCIP_Real* val /**< values of constraint matrix entries */
1458  )
1459 {
1460  int grbobjsen;
1461  int* cnt;
1462  int rngcount;
1463  int c;
1464 
1465 #ifndef NDEBUG
1466  {
1467  int j;
1468  for( j = 0; j < nnonz; j++ )
1469  assert( val[j] != 0 );
1470  }
1471 #endif
1472 
1473  assert(lpi != NULL);
1474  assert(lpi->grbmodel != NULL);
1475  assert(lpi->grbenv != NULL);
1476  assert(obj != NULL);
1477  assert(lb != NULL);
1478  assert(ub != NULL);
1479  assert(beg != NULL);
1480  assert(ind != NULL);
1481  assert(val != NULL);
1482 
1483  assert(objsen == SCIP_OBJSEN_MAXIMIZE || objsen == SCIP_OBJSEN_MINIMIZE);
1484 
1485  SCIPdebugMessage("loading LP in column format into Gurobi: %d cols, %d rows\n", ncols, nrows);
1486 
1487  invalidateSolution(lpi);
1488 
1489  SCIP_CALL( ensureSidechgMem(lpi, nrows) );
1490 
1491  /* convert objective sense */
1492  grbobjsen = (objsen == SCIP_OBJSEN_MINIMIZE) ? GRB_MINIMIZE : GRB_MAXIMIZE;
1493 
1494  /* convert lhs/rhs into sen/rhs/range tuples */
1495  SCIP_CALL( convertSides(lpi, nrows, lhs, rhs, &rngcount) );
1496 
1497  /* calculate column lengths */
1498  SCIP_ALLOC( BMSallocMemoryArray(&cnt, ncols) );
1499  for( c = 0; c < ncols-1; ++c )
1500  {
1501  cnt[c] = beg[c+1] - beg[c];
1502  assert(cnt[c] >= 0);
1503  }
1504  cnt[ncols-1] = nnonz - beg[ncols-1];
1505  assert(cnt[ncols-1] >= 0);
1506 
1507  /* load model - all variables are continuous */
1508  CHECK_ZERO( lpi->messagehdlr, GRBloadmodel(lpi->grbenv, &(lpi->grbmodel), NULL, ncols, nrows, grbobjsen, 0.0, (SCIP_Real*)obj,
1509  lpi->senarray, lpi->rhsarray, (int*)beg, cnt, (int*)ind, (SCIP_Real*)val, (SCIP_Real*)lb, (SCIP_Real*)ub, NULL, colnames, rownames) );
1510 
1511  CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
1512 
1513  /* free temporary memory */
1514  BMSfreeMemoryArray(&cnt);
1515 
1516  /* update maps for ranged rows */
1517  if ( rngcount > 0 )
1518  {
1519  SCIP_CALL( addRangeInfo(lpi, rngcount, 0) );
1520  }
1521 
1522 #ifndef NDEBUG
1523  {
1524  int temp;
1525 
1526  SCIP_CALL( SCIPlpiGetNCols(lpi, &temp) );
1527  assert(temp == ncols);
1528 
1529  SCIP_CALL( SCIPlpiGetNRows(lpi, &temp) );
1530  assert(temp == nrows);
1531 
1532  SCIP_CALL( SCIPlpiGetNNonz(lpi, &temp) );
1533  assert(temp == nnonz);
1534  }
1535 #endif
1536 
1537  checkRangeInfo(lpi);
1538 
1539  return SCIP_OKAY;
1540 }
1541 
1542 /** adds columns to the LP */
1544  SCIP_LPI* lpi, /**< LP interface structure */
1545  int ncols, /**< number of columns to be added */
1546  const SCIP_Real* obj, /**< objective function values of new columns */
1547  const SCIP_Real* lb, /**< lower bounds of new columns */
1548  const SCIP_Real* ub, /**< upper bounds of new columns */
1549  char** colnames, /**< column names, or NULL */
1550  int nnonz, /**< number of nonzero elements to be added to the constraint matrix */
1551  const int* beg, /**< start index of each column in ind- and val-array, or NULL if nnonz == 0 */
1552  const int* ind, /**< row indices of constraint matrix entries, or NULL if nnonz == 0 */
1553  const SCIP_Real* val /**< values of constraint matrix entries, or NULL if nnonz == 0 */
1554  )
1555 {
1556 
1557  assert(lpi != NULL);
1558  assert(lpi->grbmodel != NULL);
1559  assert(obj != NULL);
1560  assert(lb != NULL);
1561  assert(ub != NULL);
1562  assert(nnonz == 0 || beg != NULL);
1563  assert(nnonz == 0 || ind != NULL);
1564  assert(nnonz == 0 || val != NULL);
1565  assert(nnonz >= 0);
1566  assert(ncols >= 0);
1567 
1568  SCIPdebugMessage("adding %d columns with %d nonzeros to Gurobi\n", ncols, nnonz);
1569 
1570  invalidateSolution(lpi);
1571 
1572 #ifndef NDEBUG
1573  if ( nnonz > 0 )
1574  {
1575  /* perform check that no new rows are added - this is forbidden */
1576  int nrows;
1577  int j;
1578 
1579  SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
1580  for (j = 0; j < nnonz; ++j)
1581  {
1582  assert( 0 <= ind[j] && ind[j] < nrows );
1583  assert( val[j] != 0.0 );
1584  }
1585  }
1586 #endif
1587 
1588  /* delete range variables from Gurobi LP, so that structural variables always come first */
1589  if ( lpi->nrngrows > 0 && lpi->rngvarsadded )
1590  {
1591  /**@todo Save and restore basis - currently, the basis is destroyed if we discard (and later re-add) range variables */
1592  SCIP_CALL( delRangeVars(lpi) );
1593  }
1594 
1595  /* add columns - all new variables are continuous */
1596  CHECK_ZERO( lpi->messagehdlr, GRBaddvars(lpi->grbmodel, ncols, nnonz, (int*)beg, (int*)ind, (SCIP_Real*)val,
1597  (SCIP_Real*)obj, (SCIP_Real*)lb, (SCIP_Real*)ub, NULL, colnames) );
1598  CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
1599 
1600  checkRangeInfo(lpi);
1601 
1602  return SCIP_OKAY;
1603 }
1604 
1605 /** deletes all columns in the given range from LP */
1607  SCIP_LPI* lpi, /**< LP interface structure */
1608  int firstcol, /**< first column to be deleted */
1609  int lastcol /**< last column to be deleted */
1610  )
1611 {
1612  int ndelcols;
1613  int* which;
1614  int j;
1615 
1616  ndelcols = lastcol-firstcol+1;
1617 
1618  assert(lpi != NULL);
1619  assert(lpi->grbmodel != NULL);
1620 #ifndef NDEBUG
1621  {
1622  int temp;
1623 
1624  SCIP_CALL( SCIPlpiGetNCols(lpi, &temp) );
1625  assert(0 <= firstcol && firstcol <= lastcol && lastcol < temp);
1626  }
1627 #endif
1628 
1629  SCIPdebugMessage("deleting %d columns from Gurobi\n", lastcol - firstcol + 1);
1630 
1631  invalidateSolution(lpi);
1632 
1633  /* Gurobi can't delete a range of columns, we have to set up an index array */
1634  SCIP_ALLOC( BMSallocMemoryArray(&which, ndelcols) );
1635  for( j = firstcol; j <= lastcol; ++j )
1636  which[j - firstcol] = j;
1637 
1638  CHECK_ZERO( lpi->messagehdlr, GRBdelvars(lpi->grbmodel, ndelcols, which) );
1639  CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
1640 
1641  BMSfreeMemoryArray( &which );
1642 
1643  checkRangeInfo(lpi);
1644 
1645  return SCIP_OKAY;
1646 }
1647 
1648 /** deletes columns from LP; the new position of a column must not be greater that its old position */
1650  SCIP_LPI* lpi, /**< LP interface structure */
1651  int* dstat /**< deletion status of columns
1652  * input: 1 if column should be deleted, 0 if not
1653  * output: new position of column, -1 if column was deleted */
1654  )
1655 {
1656  int* which;
1657  int ncols;
1658  int num;
1659  int j;
1660 
1661  assert(lpi != NULL);
1662  assert(lpi->grbmodel != NULL);
1663  assert(dstat != NULL);
1664 
1665  SCIPdebugMessage("deleting a column set from Gurobi\n");
1666 
1667  invalidateSolution(lpi);
1668 
1669  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
1670 
1671  /* Gurobi can't delete a set of marked columns, we have to set up an index array */
1672  SCIP_ALLOC( BMSallocMemoryArray(&which, ncols) );
1673  num = 0;
1674  for( j = 0; j < ncols; ++j )
1675  {
1676  if( dstat[j] )
1677  which[num++] = j;
1678  }
1679 
1680  CHECK_ZERO( lpi->messagehdlr, GRBdelvars(lpi->grbmodel, num, which) );
1681  CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
1682 
1683  /* update dstat */
1684  num = 0;
1685  for( j = 0; j < ncols; ++j )
1686  {
1687  if( dstat[j] )
1688  {
1689  dstat[j] = -1;
1690  ++num;
1691  }
1692  else
1693  dstat[j] = j - num;
1694  }
1695 
1696  BMSfreeMemoryArray( &which );
1697 
1698  checkRangeInfo(lpi);
1699 
1700  return SCIP_OKAY;
1701 }
1702 
1703 /** adds rows to the LP */
1705  SCIP_LPI* lpi, /**< LP interface structure */
1706  int nrows, /**< number of rows to be added */
1707  const SCIP_Real* lhs, /**< left hand sides of new rows */
1708  const SCIP_Real* rhs, /**< right hand sides of new rows */
1709  char** rownames, /**< row names, or NULL */
1710  int nnonz, /**< number of nonzero elements to be added to the constraint matrix */
1711  const int* beg, /**< start index of each row in ind- and val-array, or NULL if nnonz == 0 */
1712  const int* ind, /**< column indices of constraint matrix entries, or NULL if nnonz == 0 */
1713  const SCIP_Real* val /**< values of constraint matrix entries, or NULL if nnonz == 0 */
1714  )
1715 {
1716  int rngcount;
1717  int oldnrows = -1;
1718 
1719  assert(lpi != NULL);
1720  assert(lpi->grbmodel != NULL);
1721  assert((lpi->nrngrows > 0) == (lpi->rngrowmap != NULL));
1722  assert(lhs != NULL);
1723  assert(rhs != NULL);
1724  assert(nnonz == 0 || beg != NULL);
1725  assert(nnonz == 0 || ind != NULL);
1726  assert(nnonz == 0 || val != NULL);
1727 
1728  SCIPdebugMessage("adding %d rows with %d nonzeros to Gurobi\n", nrows, nnonz);
1729 
1730  invalidateSolution(lpi);
1731 
1732 #ifndef NDEBUG
1733  if ( nnonz > 0 )
1734  {
1735  /* perform check that no new cols are added - this is forbidden */
1736  int ncols;
1737  int j;
1738 
1739  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
1740  for (j = 0; j < nnonz; ++j) {
1741  assert( 0 <= ind[j] && ind[j] < ncols );
1742  assert( val[j] != 0.0 );
1743  }
1744  }
1745 #endif
1746 
1747  SCIP_CALL( ensureSidechgMem(lpi, nrows) );
1748 
1749  /* convert lhs/rhs into sen/rhs/range tuples */
1750  SCIP_CALL( convertSides(lpi, nrows, lhs, rhs, &rngcount) );
1751  if ( lpi->nrngrows > 0 || rngcount > 0 )
1752  {
1753  SCIP_CALL( SCIPlpiGetNRows(lpi, &oldnrows) );
1754  }
1755 
1756  /* add rows to LP */
1757  CHECK_ZERO( lpi->messagehdlr, GRBaddconstrs(lpi->grbmodel, nrows, nnonz, (int*)beg, (int*)ind, (SCIP_Real*)val, lpi->senarray, lpi->rhsarray, rownames) );
1758  CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
1759 
1760  /* update maps for ranged rows */
1761  if ( rngcount > 0 )
1762  {
1763  SCIP_CALL( addRangeInfo(lpi, rngcount, oldnrows) );
1764  }
1765  else if ( lpi->nrngrows > 0 )
1766  {
1767  int r;
1768 
1769  /* extend existing rngrowmap array */
1770  assert(lpi->rngrowmap != NULL);
1771  assert(lpi->rngrows != NULL);
1772  SCIP_CALL( ensureRngrowmapMem(lpi, oldnrows+nrows) );
1773  for (r = oldnrows; r < oldnrows+nrows; r++)
1774  lpi->rngrowmap[r] = -1;
1775  }
1776 
1777  checkRangeInfo(lpi);
1778 
1779  return SCIP_OKAY;
1780 }
1781 
1782 /** deletes all rows in the given range from LP */
1784  SCIP_LPI* lpi, /**< LP interface structure */
1785  int firstrow, /**< first row to be deleted */
1786  int lastrow /**< last row to be deleted */
1787  )
1788 {
1789  int ndelrows;
1790  int* which;
1791  int i;
1792 
1793  ndelrows = lastrow-firstrow+1;
1794 
1795  assert(lpi != NULL);
1796  assert(lpi->grbmodel != NULL);
1797 #ifndef NDEBUG
1798  {
1799  int nrows;
1800  SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
1801  assert(0 <= firstrow && firstrow <= lastrow && lastrow < nrows);
1802  }
1803 #endif
1804 
1805  SCIPdebugMessage("deleting %d rows from Gurobi\n", ndelrows);
1806 
1807  invalidateSolution(lpi);
1808 
1809  /* Gurobi can't delete a range of rows, we have to set up an index array */
1810  SCIP_ALLOC( BMSallocMemoryArray(&which, ndelrows) );
1811  for( i = firstrow; i <= lastrow; ++i )
1812  which[i - firstrow] = i;
1813 
1814  CHECK_ZERO( lpi->messagehdlr, GRBdelconstrs(lpi->grbmodel, ndelrows, which) );
1815  CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
1816 
1817  BMSfreeMemoryArray( &which );
1818 
1819  /* update ranged row info */
1820  if ( lpi->nrngrows > 0 )
1821  {
1822  int nrngrows;
1823  int nrows;
1824 
1825  assert(lpi->rngrowmap != NULL);
1826  assert(lpi->rngrows != NULL);
1827 
1828  /* find first ranged row that has been deleted */
1829  for (i = 0; i < lpi->nrngrows; i++)
1830  {
1831  if ( lpi->rngrows[i] >= firstrow )
1832  break;
1833  }
1834  nrngrows = i;
1835 
1836  /* skip all deleted ranged rows */
1837  for (; i < lpi->nrngrows; i++)
1838  {
1839  if ( lpi->rngrows[i] > lastrow )
1840  break;
1841  }
1842 
1843  /* move remaining ranged rows to the front */
1844  for (; i < lpi->nrngrows; i++)
1845  {
1846  int oldrow = lpi->rngrows[i];
1847  lpi->rngrowmap[oldrow] = nrngrows; /* store at old place for now */
1848  lpi->rngrows[nrngrows] = oldrow - ndelrows;
1849  lpi->rngvals[nrngrows] = lpi->rngvals[i];
1850  nrngrows++;
1851  }
1852 
1853  if ( nrngrows < lpi->nrngrows && lpi->rngvarsadded )
1854  {
1855  /* For simplicity, just delete all range variables from Gurobi LP - it would suffice to only delete those
1856  * corresponding to deleted ranged rows, but this should not matter much. */
1857  SCIP_CALL( delRangeVars(lpi) );
1858  }
1859 
1860  lpi->nrngrows = nrngrows;
1861 
1862  if ( nrngrows == 0 )
1863  clearRangeInfo(lpi);
1864  else
1865  {
1866  /* move rngrowmap entries */
1867  SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
1868  for (i = firstrow; i < nrows; i++)
1869  {
1870  lpi->rngrowmap[i] = lpi->rngrowmap[i+ndelrows];
1871  assert(-1 <= lpi->rngrowmap[i] && lpi->rngrowmap[i] < lpi->nrngrows);
1872  }
1873  }
1874  }
1875 
1876  checkRangeInfo(lpi);
1877 
1878  return SCIP_OKAY;
1879 }
1880 
1881 /** deletes rows from SCIP_LP; the new position of a row must not be greater that its old position */
1883  SCIP_LPI* lpi, /**< LP interface structure */
1884  int* dstat /**< deletion status of rows
1885  * input: 1 if row should be deleted, 0 if not
1886  * output: new position of row, -1 if row was deleted */
1887  )
1888 {
1889  int i;
1890  int num = 0;
1891  int nrows;
1892  int* which;
1893 
1894  assert(lpi != NULL);
1895  assert(lpi->grbmodel != NULL);
1896 
1897  SCIPdebugMessage("deleting a row set from Gurobi\n");
1898 
1899  invalidateSolution(lpi);
1900 
1901  /* Gurobi can't delete a range of rows, we have to set up an index array */
1902  SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
1903  SCIP_ALLOC( BMSallocMemoryArray(&which, nrows) );
1904  for( i = 0; i < nrows; ++i )
1905  {
1906  if( dstat[i] )
1907  which[num++] = i;
1908  }
1909  CHECK_ZERO( lpi->messagehdlr, GRBdelconstrs(lpi->grbmodel, num, which) );
1910  CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
1911 
1912  /* update dstat */
1913  num = 0;
1914  for( i = 0; i < nrows; ++i )
1915  {
1916  if( dstat[i] )
1917  {
1918  dstat[i] = -1;
1919  ++num;
1920  }
1921  else
1922  dstat[i] = i - num;
1923  }
1924 
1925  /* update ranged row info */
1926  if ( lpi->nrngrows > 0 )
1927  {
1928  int nrngrows = 0;
1929 
1930  assert(lpi->rngrowmap != NULL);
1931  assert(lpi->rngrows != NULL);
1932 
1933  for (i = 0; i < lpi->nrngrows; i++)
1934  {
1935  int oldrow = lpi->rngrows[i];
1936  int newrow = dstat[oldrow];
1937  if ( newrow >= 0 )
1938  {
1939  lpi->rngrowmap[oldrow] = nrngrows; /* store at old place for now */
1940  lpi->rngrows[nrngrows] = newrow;
1941  lpi->rngvals[nrngrows] = lpi->rngvals[i];
1942  nrngrows++;
1943  }
1944  }
1945 
1946  if ( nrngrows < lpi->nrngrows && lpi->rngvarsadded )
1947  {
1948  /* for simplicity, just delete all range variables from
1949  * Gurobi LP - it would suffice to only delete those
1950  * corresponding to deleted ranged rows, but this should
1951  * not matter much
1952  */
1953  SCIP_CALL( delRangeVars(lpi) );
1954  }
1955 
1956  lpi->nrngrows = nrngrows;
1957 
1958  if ( nrngrows == 0 )
1959  clearRangeInfo(lpi);
1960  else
1961  {
1962  /* move rngrowmap entries */
1963  for (i = 0; i < nrows; i++)
1964  {
1965  int newrow = dstat[i];
1966  assert(newrow <= i);
1967  if ( newrow >= 0 )
1968  {
1969  lpi->rngrowmap[newrow] = lpi->rngrowmap[i];
1970  assert(-1 <= lpi->rngrowmap[newrow] && lpi->rngrowmap[newrow] < lpi->nrngrows);
1971  }
1972  }
1973  }
1974  }
1975 
1976  BMSfreeMemoryArray( &which );
1977 
1978  checkRangeInfo(lpi);
1979 
1980  return SCIP_OKAY;
1981 }
1982 
1983 /** clears the whole LP */
1985  SCIP_LPI* lpi /**< LP interface structure */
1986  )
1987 {
1988  int nrows;
1989  int ncols;
1990 
1991  assert( lpi != NULL );
1992  assert( lpi->grbmodel != NULL );
1993  assert( lpi->grbenv != NULL );
1994 
1995  SCIPdebugMessage("clearing Gurobi LP\n");
1996 
1997  invalidateSolution(lpi);
1998 
1999  SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
2000  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
2001 
2002  if ( nrows >= 1 )
2003  {
2004  SCIP_CALL( SCIPlpiDelRows(lpi, 0, nrows-1) );
2005  }
2006  if ( ncols >= 1 )
2007  {
2008  SCIP_CALL( SCIPlpiDelCols(lpi, 0, ncols-1) );
2009  }
2010 
2011 #ifdef SCIP_DISABLED_CODE
2012  /* the following seems to be slower */
2013  CHECK_ZERO( lpi->messagehdlr, GRBfreemodel(lpi->grbmodel) );
2014  CHECK_ZERO( lpi->messagehdlr, GRBnewmodel(lpi->grbenv, &(lpi->grbmodel), "", 0, NULL, NULL, NULL, NULL, NULL) );
2015  CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
2016 #endif
2017 
2018  /* clear ranged row info */
2019  clearRangeInfo(lpi);
2020 
2021  checkRangeInfo(lpi);
2022 
2023  return SCIP_OKAY;
2024 }
2025 
2026 /** changes lower and upper bounds of columns */
2028  SCIP_LPI* lpi, /**< LP interface structure */
2029  int ncols, /**< number of columns to change bounds for */
2030  const int* ind, /**< column indices or NULL if ncols is zero */
2031  const SCIP_Real* lb, /**< values for the new lower bounds or NULL if ncols is zero */
2032  const SCIP_Real* ub /**< values for the new upper bounds or NULL if ncols is zero*/
2033  )
2034 {
2035  int i;
2036 
2037  assert(lpi != NULL);
2038  assert(lpi->grbmodel != NULL);
2039  assert(ncols == 0 || (ind != NULL && lb != NULL && ub != NULL));
2040 
2041  SCIPdebugMessage("changing %d bounds in Gurobi\n", ncols);
2042  if( ncols <= 0 )
2043  return SCIP_OKAY;
2044 
2045  for (i = 0; i < ncols; ++i)
2046  {
2047  SCIPdebugPrintf(" col %d: [%g,%g]\n", ind[i], lb[i], ub[i]);
2048 
2049  if ( SCIPlpiIsInfinity(lpi, lb[i]) )
2050  {
2051  SCIPerrorMessage("LP Error: fixing lower bound for variable %d to infinity.\n", ind[i]);
2052  return SCIP_LPERROR;
2053  }
2054  if ( SCIPlpiIsInfinity(lpi, -ub[i]) )
2055  {
2056  SCIPerrorMessage("LP Error: fixing upper bound for variable %d to -infinity.\n", ind[i]);
2057  return SCIP_LPERROR;
2058  }
2059  }
2060 
2061  invalidateSolution(lpi);
2062 
2063  CHECK_ZERO( lpi->messagehdlr, GRBsetdblattrlist(lpi->grbmodel, GRB_DBL_ATTR_LB, ncols, (int*)ind, (SCIP_Real*)lb) );
2064  CHECK_ZERO( lpi->messagehdlr, GRBsetdblattrlist(lpi->grbmodel, GRB_DBL_ATTR_UB, ncols, (int*)ind, (SCIP_Real*)ub) );
2065 
2066  CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
2067 
2068  checkRangeInfo(lpi);
2069 
2070  return SCIP_OKAY;
2071 }
2072 
2073 /** changes left and right hand sides of rows */
2075  SCIP_LPI* lpi, /**< LP interface structure */
2076  int nrows, /**< number of rows to change sides for */
2077  const int* ind, /**< row indices */
2078  const SCIP_Real* lhs, /**< new values for left hand sides */
2079  const SCIP_Real* rhs /**< new values for right hand sides */
2080  )
2081 {
2082  int rngcount;
2083 
2084  assert(lpi != NULL);
2085  assert(lpi->grbmodel != NULL);
2086  assert(ind != NULL);
2087 
2088  SCIPdebugMessage("changing %d sides in Gurobi\n", nrows);
2089  if( nrows <= 0)
2090  return SCIP_OKAY;
2091 
2092  invalidateSolution(lpi);
2093 
2094  /* convert lhs/rhs into sen/rhs/range tuples */
2095  SCIP_CALL( ensureSidechgMem(lpi, nrows) );
2096  SCIP_CALL( convertSides(lpi, nrows, lhs, rhs, &rngcount) );
2097 
2098  /* change row sides */
2099  CHECK_ZERO( lpi->messagehdlr, GRBsetdblattrlist(lpi->grbmodel, GRB_DBL_ATTR_RHS, nrows, (int*)ind, lpi->rhsarray) );
2100  CHECK_ZERO( lpi->messagehdlr, GRBsetcharattrlist(lpi->grbmodel, GRB_CHAR_ATTR_SENSE, nrows, (int*)ind, lpi->senarray) );
2101 
2102  CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
2103 
2104  /* update ranged row info */
2105  if ( rngcount > 0 || lpi->nrngrows > 0 )
2106  {
2107  int modified = 0;
2108  int nnewrngrows = 0;
2109  int ntotrows;
2110  int ncols;
2111  int i;
2112 
2113  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
2114  SCIP_CALL( SCIPlpiGetNRows(lpi, &ntotrows) );
2115 
2116  SCIP_CALL( ensureRngrowmapMem(lpi, ntotrows) );
2117 
2118  for (i = 0; i < nrows; i++)
2119  {
2120  int rngrowidx;
2121  int row;
2122 
2123  row = ind[i];
2124  rngrowidx = lpi->rngrowmap[row];
2125 
2126  assert(-1 <= rngrowidx && rngrowidx < lpi->nrngrows);
2127 
2128  if ( lpi->senarray[i] == GRB_EQUAL && lpi->rngarray[i] > 0.0 )
2129  {
2130  /* row is (now) a ranged row */
2131  if ( rngrowidx >= 0 )
2132  {
2133  /* row was already a ranged row: just update rngval and ub of associated column */
2134  lpi->rngvals[rngrowidx] = lpi->rngarray[i];
2135  if ( !modified && lpi->rngvarsadded )
2136  {
2137  CHECK_ZERO( lpi->messagehdlr, GRBsetdblattrelement(lpi->grbmodel, GRB_DBL_ATTR_UB, ncols+rngrowidx, lpi->rngvals[rngrowidx]) );
2138  }
2139  }
2140  else
2141  {
2142  /* row was not ranged before: we need to reset range variables */
2143  modified = 1;
2144 
2145  /* for now, add row to end of rngrows/rngvals arrays */
2146  SCIP_CALL( ensureRngrowsMem(lpi, lpi->nrngrows + nnewrngrows + 1) );
2147  lpi->rngrowmap[row] = lpi->nrngrows + nnewrngrows;
2148  lpi->rngrows[lpi->nrngrows + nnewrngrows] = row;
2149  lpi->rngvals[lpi->nrngrows + nnewrngrows] = lpi->rngarray[i];
2150  nnewrngrows++;
2151  }
2152  }
2153  else
2154  {
2155  /* row is not (no longer) a ranged row */
2156  if ( rngrowidx >= 0 )
2157  {
2158  /* row was a ranged row before: we need to reset range variables */
2159  modified = 1;
2160  lpi->rngrowmap[row] = -1;
2161  }
2162  }
2163  }
2164 
2165  if ( modified )
2166  {
2167  int nrngrows = 0;
2168 
2169  /* the range status of at least one row changed: discard range variables */
2170  if ( lpi->rngvarsadded )
2171  {
2172  /**@todo Save and restore basis - currently, the basis is destroyed if we discard (and later re-add) range variables */
2173  SCIP_CALL( delRangeVars(lpi) );
2174  }
2175  assert(!lpi->rngvarsadded);
2176 
2177  if ( nnewrngrows > 0 )
2178  {
2179  /* integrate new ranged rows into arrays */
2180  lpi->nrngrows += nnewrngrows;
2181  SCIPsortIntReal(lpi->rngrows, lpi->rngvals, lpi->nrngrows);
2182  }
2183 
2184  /* update rngrowmap and discard rows that are no longer ranged */
2185  for (i = 0; i < lpi->nrngrows; i++)
2186  {
2187  int row = lpi->rngrows[i];
2188  if ( lpi->rngrowmap[row] >= 0 )
2189  {
2190  lpi->rngrowmap[row] = nrngrows;
2191  lpi->rngrows[nrngrows] = row;
2192  lpi->rngvals[nrngrows] = lpi->rngvals[i];
2193  nrngrows++;
2194  }
2195  }
2196  lpi->nrngrows = nrngrows;
2197 
2198  /* discard ranged row info if no ranged rows remain */
2199  if ( nrngrows == 0 )
2200  clearRangeInfo(lpi);
2201  }
2202  }
2203 
2204  checkRangeInfo(lpi);
2205 
2206  return SCIP_OKAY;
2207 }
2208 
2209 /** changes a single coefficient */
2211  SCIP_LPI* lpi, /**< LP interface structure */
2212  int row, /**< row number of coefficient to change */
2213  int col, /**< column number of coefficient to change */
2214  SCIP_Real newval /**< new value of coefficient */
2215  )
2216 {
2217  assert(lpi != NULL);
2218  assert(lpi->grbmodel != NULL);
2219 
2220  SCIPdebugMessage("changing coefficient row %d, column %d in Gurobi to %g\n", row, col, newval);
2221 
2222  invalidateSolution(lpi);
2223 
2224  CHECK_ZERO( lpi->messagehdlr, GRBchgcoeffs(lpi->grbmodel, 1, &row, &col, &newval) );
2225  CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
2226 
2227  return SCIP_OKAY;
2228 }
2229 
2230 /** changes the objective sense */
2232  SCIP_LPI* lpi, /**< LP interface structure */
2233  SCIP_OBJSEN objsen /**< new objective sense */
2234  )
2235 {
2236  int grbobjsen;
2237 
2238  assert(lpi != NULL);
2239  assert(lpi->grbmodel != NULL);
2240  assert(objsen == SCIP_OBJSEN_MAXIMIZE || objsen == SCIP_OBJSEN_MINIMIZE);
2241 
2242  /* convert objective sense */
2243  grbobjsen = (objsen == SCIP_OBJSEN_MINIMIZE) ? GRB_MINIMIZE : GRB_MAXIMIZE;
2244 
2245  SCIPdebugMessage("changing objective sense in Gurobi to %d\n", grbobjsen);
2246 
2247  invalidateSolution(lpi);
2248 
2249  /* The objective sense of Gurobi and SCIP are equal */
2250  CHECK_ZERO( lpi->messagehdlr, GRBsetintattr(lpi->grbmodel, GRB_INT_ATTR_MODELSENSE, grbobjsen) );
2251  CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
2252 
2253  return SCIP_OKAY;
2254 }
2255 
2256 /** changes objective values of columns in the LP */
2258  SCIP_LPI* lpi, /**< LP interface structure */
2259  int ncols, /**< number of columns to change objective value for */
2260  const int* ind, /**< column indices to change objective value for */
2261  const SCIP_Real* obj /**< new objective values for columns */
2262  )
2263 {
2264  assert(lpi != NULL);
2265  assert(lpi->grbmodel != NULL);
2266  assert(ind != NULL);
2267  assert(obj != NULL);
2268 
2269  SCIPdebugMessage("changing %d objective values in Gurobi\n", ncols);
2270 
2271  invalidateSolution(lpi);
2272 
2273  CHECK_ZERO( lpi->messagehdlr, GRBsetdblattrlist(lpi->grbmodel, GRB_DBL_ATTR_OBJ, ncols, (int*)ind, (SCIP_Real*)obj) );
2274  CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
2275 
2276  return SCIP_OKAY;
2277 }
2278 
2279 /** multiplies a row with a non-zero scalar; for negative scalars, the row's sense is switched accordingly */
2281  SCIP_LPI* lpi, /**< LP interface structure */
2282  int row, /**< row number to scale */
2283  SCIP_Real scaleval /**< scaling multiplier */
2284  )
2285 {
2286  SCIP_Real lhs;
2287  SCIP_Real rhs;
2288  int nnonz;
2289  int ncols;
2290  int beg;
2291  int i;
2292 
2293  assert(lpi != NULL);
2294  assert(lpi->grbmodel != NULL);
2295  assert(scaleval != 0.0);
2296 
2297  SCIPdebugMessage("scaling row %d with factor %g in Gurobi\n", row, scaleval);
2298 
2299  invalidateSolution(lpi);
2300 
2301  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
2302  SCIP_CALL( ensureValMem(lpi, ncols+1) ); /* +1 for range variable */
2303 
2304  /* get the row */
2305  SCIP_CALL( SCIPlpiGetRows(lpi, row, row, &lhs, &rhs, &nnonz, &beg, lpi->indarray, lpi->valarray) );
2306 
2307  /* scale row coefficients */
2308  for ( i = 0; i < nnonz; ++i )
2309  {
2310  SCIP_CALL( SCIPlpiChgCoef(lpi, row, lpi->indarray[i], lpi->valarray[i] * scaleval) );
2311  }
2312 
2313  /* scale row sides */
2314  if( lhs > -GRB_INFBOUND )
2315  lhs *= scaleval;
2316  else if( scaleval < 0.0 )
2317  lhs = GRB_INFBOUND;
2318  if( rhs < GRB_INFBOUND )
2319  rhs *= scaleval;
2320  else if( scaleval < 0.0 )
2321  rhs = -GRB_INFBOUND;
2322  if( scaleval > 0.0 )
2323  {
2324  SCIP_CALL( SCIPlpiChgSides(lpi, 1, &row, &lhs, &rhs) );
2325  }
2326  else
2327  {
2328  SCIP_CALL( SCIPlpiChgSides(lpi, 1, &row, &rhs, &lhs) );
2329  }
2330 
2331  checkRangeInfo(lpi);
2332 
2333  return SCIP_OKAY;
2334 }
2335 
2336 /** multiplies a column with a non-zero scalar; the objective value is multiplied with the scalar, and the bounds
2337  * are divided by the scalar; for negative scalars, the column's bounds are switched
2338  */
2340  SCIP_LPI* lpi, /**< LP interface structure */
2341  int col, /**< column number to scale */
2342  SCIP_Real scaleval /**< scaling multiplier */
2343  )
2344 {
2345  SCIP_Real lb;
2346  SCIP_Real ub;
2347  SCIP_Real obj;
2348  int nnonz;
2349  int nrows;
2350  int beg;
2351  int i;
2352 
2353  assert(lpi != NULL);
2354  assert(lpi->grbmodel != NULL);
2355  assert(scaleval != 0.0);
2356 
2357  SCIPdebugMessage("scaling column %d with factor %g in Gurobi\n", col, scaleval);
2358 
2359  invalidateSolution(lpi);
2360 
2361  SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
2362  SCIP_CALL( ensureValMem(lpi, nrows) );
2363 
2364  /* get the column */
2365  SCIP_CALL( SCIPlpiGetCols(lpi, col, col, &lb, &ub, &nnonz, &beg, lpi->indarray, lpi->valarray) );
2366 
2367  /* get objective coefficient */
2368  SCIP_CALL( SCIPlpiGetObj(lpi, col, col, &obj) );
2369 
2370  /* scale column coefficients */
2371  for( i = 0; i < nnonz; ++i )
2372  {
2373  SCIP_CALL( SCIPlpiChgCoef(lpi, lpi->indarray[i], col, lpi->valarray[i] * scaleval) );
2374  }
2375 
2376  /* scale objective value */
2377  obj *= scaleval;
2378  SCIP_CALL( SCIPlpiChgObj(lpi, 1, &col, &obj) );
2379 
2380  /* scale column bounds */
2381  if( lb > -GRB_INFINITY )
2382  lb /= scaleval;
2383  else if( scaleval < 0.0 )
2384  lb = GRB_INFINITY;
2385  if( ub < GRB_INFINITY )
2386  ub /= scaleval;
2387  else if( scaleval < 0.0 )
2388  ub = -GRB_INFINITY;
2389  if( scaleval > 0.0 )
2390  {
2391  SCIP_CALL( SCIPlpiChgBounds(lpi, 1, &col, &lb, &ub) );
2392  }
2393  else
2394  {
2395  SCIP_CALL( SCIPlpiChgBounds(lpi, 1, &col, &ub, &lb) );
2396  }
2397 
2398  checkRangeInfo(lpi);
2399 
2400  return SCIP_OKAY;
2401 }
2402 
2403 /**@} */
2404 
2405 
2406 
2407 
2408 /*
2409  * Data Accessing Methods
2410  */
2411 
2412 /**@name Data Accessing Methods */
2413 /**@{ */
2414 
2415 /** gets the number of rows in the LP */
2417  SCIP_LPI* lpi, /**< LP interface structure */
2418  int* nrows /**< pointer to store the number of rows */
2419  )
2420 {
2421  assert(lpi != NULL);
2422  assert(lpi->grbmodel != NULL);
2423  assert(nrows != NULL);
2424 
2425  SCIPdebugMessage("getting number of rows\n");
2426 
2427  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_NUMCONSTRS, nrows) );
2428 
2429  return SCIP_OKAY;
2430 }
2431 
2432 /** gets the number of columns in the LP */
2434  SCIP_LPI* lpi, /**< LP interface structure */
2435  int* ncols /**< pointer to store the number of cols */
2436  )
2437 {
2438  assert(lpi != NULL);
2439  assert(lpi->grbmodel != NULL);
2440  assert(ncols != NULL);
2441 
2442  SCIPdebugMessage("getting number of columns\n");
2443 
2444  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_NUMVARS, ncols) );
2445 
2446  /* subtract number of ranged rows, as these are the LPI internal columns */
2447  if ( lpi->rngvarsadded )
2448  (*ncols) -= lpi->nrngrows;
2449 
2450  return SCIP_OKAY;
2451 }
2452 
2453 /** gets the number of nonzero elements in the LP constraint matrix */
2455  SCIP_LPI* lpi, /**< LP interface structure */
2456  int* nnonz /**< pointer to store the number of nonzeros */
2457  )
2458 {
2459  assert(lpi != NULL);
2460  assert(lpi->grbmodel != NULL);
2461  assert(nnonz != NULL);
2462 
2463  SCIPdebugMessage("getting number of non-zeros\n");
2464 
2465  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_NUMNZS, nnonz) );
2466 
2467  /* subtract number of ranged rows, as these are non-zeros for the LPI internal columns */
2468  if ( lpi->rngvarsadded )
2469  (*nnonz) -= lpi->nrngrows;
2470 
2471  return SCIP_OKAY;
2472 }
2473 
2474 /** gets columns from LP problem object; the arrays have to be large enough to store all values;
2475  * Either both, lb and ub, have to be NULL, or both have to be non-NULL,
2476  * either nnonz, beg, ind, and val have to be NULL, or all of them have to be non-NULL.
2477  */
2479  SCIP_LPI* lpi, /**< LP interface structure */
2480  int firstcol, /**< first column to get from LP */
2481  int lastcol, /**< last column to get from LP */
2482  SCIP_Real* lb, /**< buffer to store the lower bound vector, or NULL */
2483  SCIP_Real* ub, /**< buffer to store the upper bound vector, or NULL */
2484  int* nnonz, /**< pointer to store the number of nonzero elements returned, or NULL */
2485  int* beg, /**< buffer to store start index of each column in ind- and val-array, or NULL */
2486  int* ind, /**< buffer to store row indices of constraint matrix entries, or NULL */
2487  SCIP_Real* val /**< buffer to store values of constraint matrix entries, or NULL */
2488  )
2489 {
2490  assert(lpi != NULL);
2491  assert(lpi->grbmodel != NULL);
2492  assert((lb != NULL && ub != NULL) || (lb == NULL && ub == NULL));
2493  assert((nnonz != NULL && beg != NULL && ind != NULL && val != NULL) || (nnonz == NULL && beg == NULL && ind == NULL && val == NULL));
2494 #ifndef NDEBUG
2495  {
2496  int ncols;
2497  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
2498  assert(0 <= firstcol && firstcol <= lastcol && lastcol < ncols);
2499  }
2500 #endif
2501 
2502  SCIPdebugMessage("getting columns %d to %d\n", firstcol, lastcol);
2503 
2504  if( lb != NULL )
2505  {
2506  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_LB, firstcol, lastcol-firstcol+1, lb) );
2507  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_UB, firstcol, lastcol-firstcol+1, ub) );
2508  }
2509 
2510  if( nnonz != NULL )
2511  {
2512  /* get matrix entries */
2513  CHECK_ZERO( lpi->messagehdlr, GRBgetvars(lpi->grbmodel, nnonz, beg, ind, val, firstcol, lastcol-firstcol+1) );
2514  }
2515 
2516  return SCIP_OKAY;
2517 }
2518 
2519 /** gets rows from LP problem object; the arrays have to be large enough to store all values.
2520  * Either both, lhs and rhs, have to be NULL, or both have to be non-NULL,
2521  * either nnonz, beg, ind, and val have to be NULL, or all of them have to be non-NULL.
2522  */
2524  SCIP_LPI* lpi, /**< LP interface structure */
2525  int firstrow, /**< first row to get from LP */
2526  int lastrow, /**< last row to get from LP */
2527  SCIP_Real* lhs, /**< buffer to store left hand side vector, or NULL */
2528  SCIP_Real* rhs, /**< buffer to store right hand side vector, or NULL */
2529  int* nnonz, /**< pointer to store the number of nonzero elements returned, or NULL */
2530  int* beg, /**< buffer to store start index of each row in ind- and val-array, or NULL */
2531  int* ind, /**< buffer to store column indices of constraint matrix entries, or NULL */
2532  SCIP_Real* val /**< buffer to store values of constraint matrix entries, or NULL */
2533  )
2534 {
2535  assert(lpi != NULL);
2536  assert(lpi->grbmodel != NULL);
2537  assert((lhs == NULL && rhs == NULL) || (rhs != NULL && lhs != NULL));
2538  assert((nnonz != NULL && beg != NULL && ind != NULL && val != NULL) || (nnonz == NULL && beg == NULL && ind == NULL && val == NULL));
2539 
2540 #ifndef NDEBUG
2541  {
2542  int nrows;
2543  SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
2544  assert(0 <= firstrow && firstrow <= lastrow && lastrow < nrows);
2545  }
2546 #endif
2547 
2548  SCIPdebugMessage("getting rows %d to %d\n", firstrow, lastrow);
2549 
2550  if( lhs != NULL )
2551  {
2552  /* get row sense and rhs */
2553  SCIP_CALL( ensureSidechgMem(lpi, lastrow - firstrow + 1) );
2554  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_RHS, firstrow, lastrow-firstrow+1, lpi->rhsarray) );
2555  CHECK_ZERO( lpi->messagehdlr, GRBgetcharattrarray(lpi->grbmodel, GRB_CHAR_ATTR_SENSE, firstrow, lastrow-firstrow+1, lpi->senarray) );
2556 
2557  /* convert sen and rhs into lhs/rhs tuples */
2558  SCIP_CALL( reconvertSides(lpi, firstrow, lastrow, lhs, rhs) );
2559  }
2560 
2561  if( nnonz != NULL )
2562  {
2563  assert(beg != NULL && ind != NULL && val != NULL); /* for lint */
2564 
2565  /* get matrix entries */
2566  CHECK_ZERO( lpi->messagehdlr, GRBgetconstrs(lpi->grbmodel, nnonz, beg, ind, val, firstrow, lastrow-firstrow+1) );
2567 
2568  if ( lpi->rngvarsadded )
2569  {
2570  int i;
2571 
2572  assert(lpi->rngrowmap != NULL);
2573  assert(lpi->rngrows != NULL);
2574 
2575  /* remove non-zeros for range variables from rows */
2576  for (i = firstrow; i <= lastrow; i++)
2577  {
2578  assert(-1 <= lpi->rngrowmap[i] && lpi->rngrowmap[i] < lpi->nrngrows);
2579  if ( lpi->rngrowmap[i] >= 0 )
2580  break;
2581  }
2582  if ( i <= lastrow )
2583  {
2584  /* skip last non-zero of this first ranged row */
2585  int newnz = (i < lastrow ? beg[i - firstrow +1]-1 : (*nnonz)-1); /*lint !e661*/
2586 
2587  /* process remaining rows, moving non-zeros to the front */
2588  for (; i <= lastrow; i++)
2589  {
2590  int thebeg;
2591  int theend;
2592 
2593  thebeg = beg[i - firstrow]; /*lint !e661*/
2594  theend = (i < lastrow ? beg[i - firstrow +1] : *nnonz);
2595 
2596  assert(-1 <= lpi->rngrowmap[i] && lpi->rngrowmap[i] < lpi->nrngrows);
2597  if ( lpi->rngrowmap[i] >= 0 )
2598  theend--;
2599 
2600  assert( theend >= thebeg );
2601  memmove(&ind[newnz], &ind[thebeg], ((size_t) (theend - thebeg)) * sizeof(*ind)); /*lint !e776 !e571*/
2602  memmove(&val[newnz], &val[thebeg], ((size_t) (theend - thebeg)) * sizeof(*val)); /*lint !e776 !e571*/
2603  beg[i - firstrow] = newnz; /*lint !e661*/
2604  newnz += theend - thebeg;
2605  }
2606  assert(newnz < *nnonz);
2607  *nnonz = newnz;
2608  }
2609  }
2610  }
2611 
2612  return SCIP_OKAY;
2613 }
2614 
2615 /** gets column names */
2617  SCIP_LPI* lpi, /**< LP interface structure */
2618  int firstcol, /**< first column to get name from LP */
2619  int lastcol, /**< last column to get name from LP */
2620  char** colnames, /**< pointers to column names (of size at least lastcol-firstcol+1) or NULL if namestoragesize is zero */
2621  char* namestorage, /**< storage for col names or NULL if namestoragesize is zero */
2622  int namestoragesize, /**< size of namestorage (if 0, storageleft returns the storage needed) */
2623  int* storageleft /**< amount of storage left (if < 0 the namestorage was not big enough) or NULL if namestoragesize is zero */
2624  )
2625 { /*lint --e{715}*/
2626  assert(lpi != NULL);
2627  assert(lpi->grbmodel != NULL);
2628  assert(colnames != NULL || namestoragesize == 0);
2629  assert(namestorage != NULL || namestoragesize == 0);
2630  assert(namestoragesize >= 0);
2631  assert(storageleft != NULL);
2632  assert(0 <= firstcol && firstcol <= lastcol);
2633  SCIPerrorMessage("SCIPlpiGetColNames() has not been implemented yet.\n");
2634  return SCIP_LPERROR;
2635 }
2636 
2637 /** gets row names */
2639  SCIP_LPI* lpi, /**< LP interface structure */
2640  int firstrow, /**< first row to get name from LP */
2641  int lastrow, /**< last row to get name from LP */
2642  char** rownames, /**< pointers to row names (of size at least lastrow-firstrow+1) or NULL if namestoragesize is zero */
2643  char* namestorage, /**< storage for row names or NULL if namestoragesize is zero */
2644  int namestoragesize, /**< size of namestorage (if 0, -storageleft returns the storage needed) */
2645  int* storageleft /**< amount of storage left (if < 0 the namestorage was not big enough) or NULL if namestoragesize is zero */
2646  )
2647 { /*lint --e{715}*/
2648  assert(lpi != NULL);
2649  assert(lpi->grbmodel != NULL);
2650  assert(rownames != NULL || namestoragesize == 0);
2651  assert(namestorage != NULL || namestoragesize == 0);
2652  assert(namestoragesize >= 0);
2653  assert(storageleft != NULL);
2654  assert(0 <= firstrow && firstrow <= lastrow);
2655  SCIPerrorMessage("SCIPlpiGetRowNames() has not been implemented yet.\n");
2656  return SCIP_LPERROR;
2657 }
2658 
2659 /** gets the objective sense of the LP */
2661  SCIP_LPI* lpi, /**< LP interface structure */
2662  SCIP_OBJSEN* objsen /**< pointer to store objective sense */
2663  )
2664 {
2665  int grbobjsen;
2666 
2667  assert( lpi != NULL );
2668  assert( lpi->grbmodel != NULL );
2669  assert( objsen != NULL );
2670 
2671  SCIPdebugMessage("getting objective sense\n");
2672 
2673  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_MODELSENSE, &grbobjsen) );
2674  assert(grbobjsen == GRB_MINIMIZE || grbobjsen == GRB_MAXIMIZE);
2675 
2676  *objsen = (grbobjsen == GRB_MINIMIZE) ? SCIP_OBJSEN_MINIMIZE : SCIP_OBJSEN_MAXIMIZE;
2677 
2678  return SCIP_OKAY;
2679 }
2680 
2681 /** gets objective coefficients from LP problem object */
2683  SCIP_LPI* lpi, /**< LP interface structure */
2684  int firstcol, /**< first column to get objective coefficient for */
2685  int lastcol, /**< last column to get objective coefficient for */
2686  SCIP_Real* vals /**< array to store objective coefficients */
2687  )
2688 {
2689  assert(lpi != NULL);
2690  assert(lpi->grbmodel != NULL);
2691  assert(firstcol <= lastcol);
2692  assert(vals != NULL);
2693 
2694  SCIPdebugMessage("getting objective values %d to %d\n", firstcol, lastcol);
2695 
2696  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_OBJ, firstcol, lastcol-firstcol+1, vals) );
2697 
2698  return SCIP_OKAY;
2699 }
2700 
2701 /** gets current bounds from LP problem object */
2703  SCIP_LPI* lpi, /**< LP interface structure */
2704  int firstcol, /**< first column to get bounds for */
2705  int lastcol, /**< last column to get bounds for */
2706  SCIP_Real* lbs, /**< array to store lower bound values, or NULL */
2707  SCIP_Real* ubs /**< array to store upper bound values, or NULL */
2708  )
2709 {
2710  assert(lpi != NULL);
2711  assert(lpi->grbmodel != NULL);
2712 #ifndef NDEBUG
2713  {
2714  int ncols;
2715  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
2716  assert(0 <= firstcol && firstcol <= lastcol && lastcol < ncols);
2717  }
2718 #endif
2719 
2720  SCIPdebugMessage("getting bounds %d to %d\n", firstcol, lastcol);
2721 
2722  if( lbs != NULL )
2723  {
2724  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_LB, firstcol, lastcol-firstcol+1, lbs) );
2725  }
2726 
2727  if( ubs != NULL )
2728  {
2729  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_UB, firstcol, lastcol-firstcol+1, ubs) );
2730  }
2731 
2732  return SCIP_OKAY;
2733 }
2734 
2735 /** gets current row sides from LP problem object */
2737  SCIP_LPI* lpi, /**< LP interface structure */
2738  int firstrow, /**< first row to get sides for */
2739  int lastrow, /**< last row to get sides for */
2740  SCIP_Real* lhss, /**< array to store left hand side values, or NULL */
2741  SCIP_Real* rhss /**< array to store right hand side values, or NULL */
2742  )
2743 {
2744  assert(lpi != NULL);
2745  assert(lpi->grbmodel != NULL);
2746  assert(firstrow <= lastrow);
2747 
2748  SCIPdebugMessage("getting row sides %d to %d\n", firstrow, lastrow);
2749 
2750  /* get row sense, rhs, and ranges */
2751  SCIP_CALL( ensureSidechgMem(lpi, lastrow - firstrow + 1) );
2752 
2753  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_RHS, firstrow, lastrow-firstrow+1, lpi->rhsarray) );
2754  CHECK_ZERO( lpi->messagehdlr, GRBgetcharattrarray(lpi->grbmodel, GRB_CHAR_ATTR_SENSE, firstrow, lastrow-firstrow+1, lpi->senarray) );
2755 
2756  /* convert sen and rhs into lhs/rhs tuples */
2757  SCIP_CALL( reconvertSides(lpi, firstrow, lastrow, lhss, rhss) );
2758 
2759  return SCIP_OKAY;
2760 }
2761 
2762 /** gets a single coefficient */
2764  SCIP_LPI* lpi, /**< LP interface structure */
2765  int row, /**< row number of coefficient */
2766  int col, /**< column number of coefficient */
2767  SCIP_Real* val /**< pointer to store the value of the coefficient */
2768  )
2769 {
2770  assert(lpi != NULL);
2771  assert(lpi->grbmodel != NULL);
2772  assert(val != NULL);
2773 
2774  SCIPdebugMessage("getting coefficient of row %d col %d\n", row, col);
2775 
2776  CHECK_ZERO( lpi->messagehdlr, GRBgetcoeff(lpi->grbmodel, row, col, val) );
2777 
2778  return SCIP_OKAY;
2779 }
2780 
2781 /**@} */
2782 
2783 
2784 
2785 
2786 /*
2787  * Solving Methods
2788  */
2789 
2790 /**@name Solving Methods */
2791 /**@{ */
2792 
2793 /** calls primal simplex to solve the LP
2794  *
2795  * @todo Check concurrent (GRB_METHOD_CONCURRENT or GRB_METHOD_DETERMINISTIC_CONCURRENT)
2796  */
2798  SCIP_LPI* lpi /**< LP interface structure */
2799  )
2800 {
2801  double cnt;
2802  int retval;
2803 
2804  assert( lpi != NULL );
2805  assert( lpi->grbmodel != NULL );
2806  assert( lpi->grbenv != NULL );
2807 
2808 #ifdef SCIP_DEBUG
2809  {
2810  int ncols, nrows;
2811  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
2812  SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
2813  SCIPdebugMessage("calling Gurobi primal simplex: %d cols, %d rows\n", ncols, nrows);
2814  }
2815 #endif
2816 
2817  invalidateSolution(lpi);
2818 
2819  if ( lpi->fromscratch )
2820  {
2821  CHECK_ZERO( lpi->messagehdlr, GRBresetmodel(lpi->grbmodel) );
2822  }
2823 
2824  SCIPdebugMessage("calling GRBoptimize() - primal\n");
2825 
2826  /* set primal simplex */
2827  SCIP_CALL( setParameterValues(lpi, &(lpi->grbparam)) );
2828  CHECK_ZERO( lpi->messagehdlr, GRBsetintparam(lpi->grbenv, GRB_INT_PAR_METHOD, GRB_METHOD_PRIMAL) );
2829 
2830  /* add range variables */
2831  if ( lpi->nrngrows > 0 && !lpi->rngvarsadded )
2832  {
2833  SCIP_CALL( addRangeVars(lpi) );
2834  }
2835 
2836  retval = GRBoptimize(lpi->grbmodel);
2837  switch( retval )
2838  {
2839  case 0:
2840  break;
2841  case GRB_ERROR_OUT_OF_MEMORY:
2842  return SCIP_NOMEMORY;
2843  default:
2844  return SCIP_LPERROR;
2845  }
2846 
2847  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_ITERCOUNT, &cnt) );
2848  lpi->iterations = (int) cnt;
2849 
2850  lpi->solisbasic = TRUE;
2851  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_STATUS, &lpi->solstat) );
2852 
2853  SCIPdebugMessage("Gurobi primal simplex needed %d iterations to gain LP status %d\n", (int) cnt, lpi->solstat);
2854 
2855  /* maybe the preprocessor solved the problem; but we need a solution, so solve again without preprocessing */
2856  assert( lpi->solstat != GRB_INF_OR_UNBD );
2857  if( lpi->solstat == GRB_INFEASIBLE )
2858  {
2859  int presolve;
2860 
2861  CHECK_ZERO( lpi->messagehdlr, GRBgetintparam(lpi->grbenv, GRB_INT_PAR_PRESOLVE, &presolve) );
2862 
2863  if( presolve != GRB_PRESOLVE_OFF )
2864  {
2865  SCIPdebugMessage("presolver may have solved the problem -> calling Gurobi primal simplex again without presolve\n");
2866 
2867  /* switch off preprocessing */
2868  CHECK_ZERO( lpi->messagehdlr, GRBsetintparam(lpi->grbenv, GRB_INT_PAR_PRESOLVE, GRB_PRESOLVE_OFF) );
2869 
2870  retval = GRBoptimize(lpi->grbmodel);
2871  switch( retval )
2872  {
2873  case 0:
2874  break;
2875  case GRB_ERROR_OUT_OF_MEMORY:
2876  return SCIP_NOMEMORY;
2877  default:
2878  return SCIP_LPERROR;
2879  }
2880 
2881  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_ITERCOUNT, &cnt) );
2882  lpi->iterations += (int) cnt;
2883  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_STATUS, &lpi->solstat) );
2884  SCIPdebugMessage(" -> Gurobi returned solstat=%d (%d iterations)\n", lpi->solstat, lpi->iterations);
2885 
2886  /* reset parameters */
2887  CHECK_ZERO( lpi->messagehdlr, GRBsetintparam(lpi->grbenv, GRB_INT_PAR_PRESOLVE, presolve) );
2888  }
2889 
2890  if( lpi->solstat == GRB_INF_OR_UNBD )
2891  {
2892  /* preprocessing was not the problem; issue a warning message and treat LP as infeasible */
2893  SCIPerrorMessage("Gurobi primal simplex returned GRB_INF_OR_UNBD after presolving was turned off\n");
2894  return SCIP_LPERROR;
2895  }
2896  }
2897  else if ( lpi->solstat == GRB_UNBOUNDED )
2898  {
2899  /* Unbounded means that there exists an unbounded primal ray. However, this does not state whether the problem is
2900  * feasible. Thus, we temporarily set the objective to 0 and solve again. */
2901  SCIP_Real* zeroobjcoefs;
2902  SCIP_Real* objcoefs;
2903  SCIP_Real oldobjcutoff;
2904  int grbobjsen;
2905  int status;
2906  int ncols;
2907 
2908  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
2909  SCIP_ALLOC( BMSallocMemoryArray(&objcoefs, ncols) );
2910  SCIP_ALLOC( BMSallocClearMemoryArray(&zeroobjcoefs, ncols) );
2911 
2912  /* preserve objective coefficients */
2913  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_OBJ, 0, ncols, objcoefs) );
2914 
2915  /* set objective to 0 */
2916  CHECK_ZERO( lpi->messagehdlr, GRBsetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_OBJ, 0, ncols, zeroobjcoefs) );
2917 
2918  /* disable cutoff */
2919  CHECK_ZERO( lpi->messagehdlr, GRBgetdblparam(lpi->grbenv, GRB_DBL_PAR_CUTOFF, &oldobjcutoff) );
2920 
2921  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_MODELSENSE, &grbobjsen) );
2922  if ( grbobjsen == GRB_MINIMIZE )
2923  {
2924  CHECK_ZERO( lpi->messagehdlr, GRBsetdblparam(lpi->grbenv, GRB_DBL_PAR_CUTOFF, GRB_INFINITY) );
2925  }
2926  else
2927  {
2928  CHECK_ZERO( lpi->messagehdlr, GRBsetdblparam(lpi->grbenv, GRB_DBL_PAR_CUTOFF, -GRB_INFINITY) );
2929  assert( grbobjsen == GRB_MAXIMIZE );
2930  }
2931 
2932  /* solve problem again */
2933  CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
2934  CHECK_ZERO( lpi->messagehdlr, GRBoptimize(lpi->grbmodel) );
2935 
2936  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_ITERCOUNT, &cnt) );
2937  lpi->iterations += (int) cnt;
2938 
2939  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_STATUS, &status) );
2940 
2941  /* restore objective */
2942  CHECK_ZERO( lpi->messagehdlr, GRBsetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_OBJ, 0, ncols, objcoefs) );
2943  CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
2944 
2945  /* restore objective limit */
2946  CHECK_ZERO( lpi->messagehdlr, GRBsetdblparam(lpi->grbenv, GRB_DBL_PAR_CUTOFF, oldobjcutoff) );
2947 
2948  BMSfreeMemoryArray(&zeroobjcoefs);
2949  BMSfreeMemoryArray(&objcoefs);
2950 
2951  /* possibly correct status */
2952  switch ( status )
2953  {
2954  case GRB_INF_OR_UNBD:
2955  case GRB_INFEASIBLE:
2956  lpi->solstat = GRB_INFEASIBLE;
2957  break;
2958 
2959  case GRB_OPTIMAL:
2960  /* We again have to solve the problem to restore possible unbounded rays. */
2961  CHECK_ZERO( lpi->messagehdlr, GRBoptimize(lpi->grbmodel) );
2962  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_ITERCOUNT, &cnt) );
2963  lpi->iterations += (int) cnt;
2964  break;
2965 
2966  case GRB_ITERATION_LIMIT:
2967  case GRB_TIME_LIMIT:
2968  /* do nothing */
2969  break;
2970 
2971  /* GRB_LOADED, GRB_NODE_LIMIT, GRB_CUTOFF, GRB_SOLUTION_LIMIT, GRB_INTERRUPTED, GRB_NUMERIC, GRB_SUBOPTIMAL, GRB_INPROGRESS, GRB_USER_OBJ_LIMIT */
2972  default:
2973  SCIPerrorMessage("Gurobi returned wrong status %d.\n", status);
2974  return SCIP_LPERROR;
2975  }
2976  }
2977 
2978  checkRangeInfo(lpi);
2979 
2980  return SCIP_OKAY;
2981 }
2982 
2983 /** calls dual simplex to solve the LP
2984  *
2985  * @todo Check concurrent (GRB_METHOD_CONCURRENT or GRB_METHOD_DETERMINISTIC_CONCURRENT)
2986  */
2988  SCIP_LPI* lpi /**< LP interface structure */
2989  )
2990 {
2991  int oldprimdual = 0;
2992  int oldpresolve = GRB_PRESOLVE_OFF;
2993  int retval;
2994  double cnt;
2995  double itlim;
2996 
2997  assert( lpi != NULL );
2998  assert( lpi->grbmodel != NULL );
2999  assert( lpi->grbenv != NULL );
3000 
3001 #ifdef SCIP_DEBUG
3002  {
3003  int ncols, nrows;
3004  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
3005  SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
3006  SCIPdebugMessage("calling Gurobi dual simplex: %d cols, %d rows\n", ncols, nrows);
3007  }
3008 #endif
3009 
3010  invalidateSolution(lpi);
3011 
3012  if ( lpi->fromscratch )
3013  {
3014  CHECK_ZERO( lpi->messagehdlr, GRBresetmodel(lpi->grbmodel) );
3015  }
3016 
3017  SCIPdebugMessage("calling GRBoptimize() - dual\n");
3018 
3019  SCIP_CALL( setParameterValues(lpi, &(lpi->grbparam)) );
3020 
3021  /* set dual simplex */
3022  CHECK_ZERO( lpi->messagehdlr, GRBsetintparam(lpi->grbenv, GRB_INT_PAR_METHOD, GRB_METHOD_DUAL) );
3023 
3024  /* add range variables */
3025  if ( lpi->nrngrows > 0 && !lpi->rngvarsadded )
3026  {
3027  SCIP_CALL( addRangeVars(lpi) );
3028  }
3029 
3030  SCIP_CALL( getDblParam(lpi, GRB_DBL_PAR_ITERATIONLIMIT, &itlim) );
3031  if ( itlim < GRB_INFINITY )
3032  {
3033  /* turn off primal-dual switching for an LP solve that might be a strong branching LP solve */
3034  CHECK_ZERO( lpi->messagehdlr, GRBgetintparam(lpi->grbenv, "GURO_PAR_PRIMDUALSWITCH", &oldprimdual) );
3035  if ( oldprimdual != 0 )
3036  {
3037  CHECK_ZERO( lpi->messagehdlr, GRBsetintparam(lpi->grbenv, "GURO_PAR_PRIMDUALSWITCH", 0) );
3038  }
3039 
3040  /* turn off presolve to avoid the case where the iteration limit is reached
3041  * and we do not get a valid dual bound installed for the original model */
3042  CHECK_ZERO( lpi->messagehdlr, GRBgetintparam(lpi->grbenv, GRB_INT_PAR_PRESOLVE, &oldpresolve) );
3043  if ( oldpresolve != GRB_PRESOLVE_OFF )
3044  {
3045  CHECK_ZERO( lpi->messagehdlr, GRBsetintparam(lpi->grbenv, GRB_INT_PAR_PRESOLVE, GRB_PRESOLVE_OFF) );
3046  }
3047  }
3048 
3049  retval = GRBoptimize(lpi->grbmodel);
3050  switch( retval )
3051  {
3052  case 0:
3053  break;
3054  case GRB_ERROR_OUT_OF_MEMORY:
3055  return SCIP_NOMEMORY;
3056  default:
3057  return SCIP_LPERROR;
3058  }
3059 
3060  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_ITERCOUNT, &cnt) );
3061  lpi->iterations = (int) cnt;
3062 
3063  lpi->solisbasic = TRUE;
3064  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_STATUS, &lpi->solstat) );
3065 
3066  SCIPdebugMessage("Gurobi dual simplex needed %d iterations to gain LP status %d\n", (int) cnt, lpi->solstat);
3067 
3068  if( lpi->solstat == GRB_INF_OR_UNBD )
3069  {
3070  int presolve;
3071  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_PAR_PRESOLVE, &presolve) );
3072 
3073  if( presolve != GRB_PRESOLVE_OFF )
3074  {
3075  /* maybe the preprocessor solved the problem; but we need a solution, so solve again without preprocessing */
3076  SCIPdebugMessage("presolver may have solved the problem -> calling Gurobi dual simplex again without presolve\n");
3077 
3078  /* switch off preprocessing */
3079  CHECK_ZERO( lpi->messagehdlr, GRBsetintattr(lpi->grbmodel, GRB_INT_PAR_PRESOLVE, GRB_PRESOLVE_OFF) );
3080  SCIP_CALL( setParameterValues(lpi, &(lpi->grbparam)) );
3081 
3082  retval = GRBoptimize(lpi->grbmodel);
3083  switch( retval )
3084  {
3085  case 0:
3086  break;
3087  case GRB_ERROR_OUT_OF_MEMORY:
3088  return SCIP_NOMEMORY;
3089  default:
3090  return SCIP_LPERROR;
3091  }
3092 
3093  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_ITERCOUNT, &cnt) );
3094  lpi->iterations += (int) cnt;
3095  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_STATUS, &lpi->solstat) );
3096  SCIPdebugMessage(" -> Gurobi returned solstat=%d (%d iterations)\n", lpi->solstat, lpi->iterations);
3097 
3098  /* switch on preprocessing again */
3099  CHECK_ZERO( lpi->messagehdlr, GRBsetintattr(lpi->grbmodel, GRB_INT_PAR_PRESOLVE, GRB_PRESOLVE_AUTO) );
3100  }
3101 
3102  if( lpi->solstat == GRB_INF_OR_UNBD )
3103  {
3104  /* preprocessing was not the problem; issue a warning message and treat LP as infeasible */
3105  SCIPerrorMessage("Gurobi dual simplex returned GRB_INF_OR_UNBD after presolving was turned off.\n");
3106  return SCIP_LPERROR;
3107  }
3108  }
3109 
3110  checkRangeInfo(lpi);
3111 
3112  /* reset parameters to their original values */
3113  if ( oldprimdual != 0 )
3114  {
3115  CHECK_ZERO( lpi->messagehdlr, GRBsetintparam(lpi->grbenv, "GURO_PAR_PRIMDUALSWITCH", oldprimdual) );
3116  }
3117  if ( oldpresolve != GRB_PRESOLVE_OFF )
3118  {
3119  CHECK_ZERO( lpi->messagehdlr, GRBsetintparam(lpi->grbenv, GRB_INT_PAR_PRESOLVE, oldpresolve) );
3120  }
3121 
3122  return SCIP_OKAY;
3123 }
3124 
3125 /** calls barrier or interior point algorithm to solve the LP with crossover to simplex basis */
3127  SCIP_LPI* lpi, /**< LP interface structure */
3128  SCIP_Bool crossover /**< perform crossover */
3129  )
3130 {
3131  int retval;
3132  double cnt;
3133 
3134  assert( lpi != NULL );
3135  assert( lpi->grbmodel != NULL );
3136  assert( lpi->grbenv != NULL );
3137 
3138 #ifdef SCIP_DEBUG
3139  {
3140  int ncols, nrows;
3141  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
3142  SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
3143  SCIPdebugMessage("calling Gurobi barrier: %d cols, %d rows\n", ncols, nrows);
3144  }
3145 #endif
3146 
3147  invalidateSolution(lpi);
3148 
3149  if ( lpi->fromscratch )
3150  {
3151  CHECK_ZERO( lpi->messagehdlr, GRBresetmodel(lpi->grbmodel) );
3152  }
3153 
3154  SCIPdebugMessage("calling GRBoptimize() - barrier\n");
3155 
3156  /* set barrier */
3157  SCIP_CALL( setParameterValues(lpi, &(lpi->grbparam)) );
3158 
3159  if( crossover )
3160  {
3161  /* turn on crossover to automatic setting (-1) */
3162  CHECK_ZERO( lpi->messagehdlr, GRBsetintparam(lpi->grbenv, GRB_INT_PAR_CROSSOVER, -1) );
3163  }
3164  else
3165  {
3166  /* turn off crossover */
3167  CHECK_ZERO( lpi->messagehdlr, GRBsetintparam(lpi->grbenv, GRB_INT_PAR_CROSSOVER, 0) );
3168  }
3169 
3170  CHECK_ZERO( lpi->messagehdlr, GRBsetintparam(lpi->grbenv, GRB_INT_PAR_METHOD, GRB_METHOD_BARRIER) );
3171 
3172  /* add range variables */
3173  if ( lpi->nrngrows > 0 && !lpi->rngvarsadded )
3174  {
3175  SCIP_CALL( addRangeVars(lpi) );
3176  }
3177 
3178  retval = GRBoptimize(lpi->grbmodel);
3179  switch( retval )
3180  {
3181  case 0:
3182  break;
3183  case GRB_ERROR_OUT_OF_MEMORY:
3184  return SCIP_NOMEMORY;
3185  default:
3186  return SCIP_LPERROR;
3187  }
3188 
3189  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_ITERCOUNT, &cnt) );
3190  lpi->iterations = (int) cnt;
3191 
3192  lpi->solisbasic = crossover;
3193  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_STATUS, &lpi->solstat) );
3194 
3195  SCIPdebugMessage("Gurobi barrier needed %d iterations to gain LP status %d\n", (int) cnt, lpi->solstat);
3196 
3197  if( lpi->solstat == GRB_INF_OR_UNBD )
3198  {
3199  int presolve;
3200  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_PAR_PRESOLVE, &presolve) );
3201 
3202  if( presolve != GRB_PRESOLVE_OFF )
3203  {
3204  /* maybe the preprocessor solved the problem; but we need a solution, so solve again without preprocessing */
3205  SCIPdebugMessage("presolver may have solved the problem -> calling Gurobi barrier again without presolve\n");
3206 
3207  /* switch off preprocessing */
3208  CHECK_ZERO( lpi->messagehdlr, GRBsetintattr(lpi->grbmodel, GRB_INT_PAR_PRESOLVE, GRB_PRESOLVE_OFF) );
3209  SCIP_CALL( setParameterValues(lpi, &(lpi->grbparam)) );
3210 
3211  retval = GRBoptimize(lpi->grbmodel);
3212  switch( retval )
3213  {
3214  case 0:
3215  break;
3216  case GRB_ERROR_OUT_OF_MEMORY:
3217  return SCIP_NOMEMORY;
3218  default:
3219  return SCIP_LPERROR;
3220  }
3221 
3222  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_ITERCOUNT, &cnt) );
3223  lpi->iterations += (int) cnt;
3224  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_STATUS, &lpi->solstat) );
3225  SCIPdebugMessage(" -> Gurobi returned solstat=%d (%d iterations)\n", lpi->solstat, lpi->iterations);
3226 
3227  /* switch on preprocessing again */
3228  CHECK_ZERO( lpi->messagehdlr, GRBsetintattr(lpi->grbmodel, GRB_INT_PAR_PRESOLVE, GRB_PRESOLVE_AUTO) );
3229  }
3230 
3231  if( lpi->solstat == GRB_INF_OR_UNBD )
3232  {
3233  /* preprocessing was not the problem; issue a warning message and treat LP as infeasible */
3234  SCIPerrorMessage("Gurobi barrier returned GRB_INF_OR_UNBD after presolving was turned off\n");
3235  return SCIP_LPERROR;
3236  }
3237  }
3238 
3239  checkRangeInfo(lpi);
3240 
3241  return SCIP_OKAY;
3242 }
3243 
3244 /** start strong branching - call before any strong branching */
3246  SCIP_LPI* lpi /**< LP interface structure */
3247  )
3248 { /*lint --e{715}*/
3249  assert( lpi != NULL );
3250  assert( lpi->grbmodel != NULL );
3251  assert( lpi->grbenv != NULL );
3252 
3253  /* currently do nothing */
3254  return SCIP_OKAY;
3255 }
3256 
3257 /** end strong branching - call after any strong branching */
3259  SCIP_LPI* lpi /**< LP interface structure */
3260  )
3261 { /*lint --e{715}*/
3262  assert( lpi != NULL );
3263  assert( lpi->grbmodel != NULL );
3264  assert( lpi->grbenv != NULL );
3265 
3266  /* currently do nothing */
3267  return SCIP_OKAY;
3268 }
3269 
3270 /** performs strong branching iterations on one candidate */
3271 static
3273  SCIP_LPI* lpi, /**< LP interface structure */
3274  int col, /**< column to apply strong branching on */
3275  SCIP_Real psol, /**< current primal solution value of column */
3276  int itlim, /**< iteration limit for strong branchings */
3277  SCIP_Real* down, /**< stores dual bound after branching column down */
3278  SCIP_Real* up, /**< stores dual bound after branching column up */
3279  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
3280  * otherwise, it can only be used as an estimate value */
3281  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
3282  * otherwise, it can only be used as an estimate value */
3283  int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
3284  )
3285 {
3286  SCIP_Real oldlb;
3287  SCIP_Real oldub;
3288  SCIP_Real newlb;
3289  SCIP_Real newub;
3290  SCIP_Real olditlim;
3291  SCIP_Bool error = FALSE;
3292  SCIP_Bool success;
3293  int it;
3294 
3295  assert( lpi != NULL );
3296  assert( lpi->grbmodel != NULL );
3297  assert( lpi->grbenv != NULL );
3298  assert( down != NULL );
3299  assert( up != NULL );
3300  assert( downvalid != NULL );
3301  assert( upvalid != NULL );
3302 
3303  SCIPdebugMessage("performing strong branching on variable %d (%d iterations)\n", col, itlim);
3304 
3305  SCIP_CALL( setParameterValues(lpi, &(lpi->grbparam)) );
3306 
3307  *downvalid = FALSE;
3308  *upvalid = FALSE;
3309  if( iter != NULL )
3310  *iter = 0;
3311 
3312  /* save current LP basis and bounds*/
3313  SCIP_CALL( getBase(lpi, &success) );
3314  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrelement(lpi->grbmodel, GRB_DBL_ATTR_LB, col, &oldlb) );
3315  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrelement(lpi->grbmodel, GRB_DBL_ATTR_UB, col, &oldub) );
3316 
3317  if ( lpi->fromscratch )
3318  {
3319  CHECK_ZERO( lpi->messagehdlr, GRBresetmodel(lpi->grbmodel) );
3320  }
3321 
3322  /* save old iteration limit and set iteration limit to strong branching limit */
3323  if( itlim < 0 )
3324  itlim = INT_MAX;
3325 
3326  SCIP_CALL( getDblParam(lpi, GRB_DBL_PAR_ITERATIONLIMIT, &olditlim) );
3327  SCIP_CALL( setDblParam(lpi, GRB_DBL_PAR_ITERATIONLIMIT, (double) itlim) );
3328 
3329  /* add range variables */
3330  if ( lpi->nrngrows > 0 && !lpi->rngvarsadded )
3331  {
3332  SCIP_CALL( addRangeVars(lpi) );
3333  }
3334 
3335  /* down branch */
3336  newub = EPSCEIL(psol-1.0, 1e-06);
3337  if( newub >= oldlb - 0.5 )
3338  {
3339  SCIPdebugMessage("strong branching down (%g) on x%d (%g) with %d iterations\n", newub, col, psol, itlim);
3340 
3341  CHECK_ZERO( lpi->messagehdlr, GRBsetdblattrelement(lpi->grbmodel, GRB_DBL_ATTR_UB, col, newub) );
3342 
3343  SCIP_CALL( SCIPlpiSolveDual(lpi) );
3344  /* when iteration limit was reached the objective value is not computed */
3345  if( SCIPlpiIsOptimal(lpi) ) /*|| SCIPlpiIsIterlimExc(lpi) ) */
3346  {
3347  SCIP_CALL( SCIPlpiGetObjval(lpi, down) );
3348  *downvalid = TRUE;
3349  }
3350  else if( SCIPlpiIsPrimalInfeasible(lpi) || SCIPlpiIsObjlimExc(lpi) )
3351  {
3352  CHECK_ZERO( lpi->messagehdlr, GRBgetdblparam(lpi->grbenv, GRB_DBL_PAR_CUTOFF, down) );
3353  }
3354  else if( !SCIPlpiIsIterlimExc(lpi) )
3355  error = TRUE;
3356 
3357  if( iter != NULL )
3358  {
3359  SCIP_CALL( SCIPlpiGetIterations(lpi, &it) );
3360  *iter += it;
3361  }
3362  SCIPdebugMessage(" -> down (x%d <= %g): %g\n", col, newub, *down);
3363 
3364  CHECK_ZERO( lpi->messagehdlr, GRBsetdblattrelement(lpi->grbmodel, GRB_DBL_ATTR_UB, col, oldub) );
3365  CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
3366 #ifdef SCIP_DEBUG
3367  {
3368  double b;
3369  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrelement(lpi->grbmodel, GRB_DBL_ATTR_UB, col, &b) );
3370  assert( b == oldub );
3371  }
3372 #endif
3373 
3374  if ( success )
3375  {
3376  SCIP_CALL( setBase(lpi) );
3377  }
3378  }
3379  else
3380  {
3381  CHECK_ZERO( lpi->messagehdlr, GRBgetdblparam(lpi->grbenv, GRB_DBL_PAR_CUTOFF, down) );
3382  *downvalid = TRUE;
3383  }
3384 
3385  /* up branch */
3386  if( !error )
3387  {
3388  newlb = EPSFLOOR(psol+1.0, 1e-06);
3389  if( newlb <= oldub + 0.5 )
3390  {
3391  SCIPdebugMessage("strong branching up (%g) on x%d (%g) with %d iterations\n", newlb, col, psol, itlim);
3392 
3393  CHECK_ZERO( lpi->messagehdlr, GRBsetdblattrelement(lpi->grbmodel, GRB_DBL_ATTR_LB, col, newlb) );
3394 
3395  SCIP_CALL( SCIPlpiSolveDual(lpi) );
3396  /* when iteration limit was reached the objective value is not computed */
3397  if( SCIPlpiIsOptimal(lpi) ) /*|| SCIPlpiIsIterlimExc(lpi) ) */
3398  {
3399  SCIP_CALL( SCIPlpiGetObjval(lpi, up) );
3400  *upvalid = TRUE;
3401  }
3402  else if( SCIPlpiIsPrimalInfeasible(lpi) || SCIPlpiIsObjlimExc(lpi) )
3403  {
3404  CHECK_ZERO( lpi->messagehdlr, GRBgetdblparam(lpi->grbenv, GRB_DBL_PAR_CUTOFF, up) );
3405  }
3406  else if( !SCIPlpiIsIterlimExc(lpi) )
3407  error = TRUE;
3408 
3409  if( iter != NULL )
3410  {
3411  SCIP_CALL( SCIPlpiGetIterations(lpi, &it) );
3412  *iter += it;
3413  }
3414  SCIPdebugMessage(" -> up (x%d >= %g): %g\n", col, newlb, *up);
3415 
3416  CHECK_ZERO( lpi->messagehdlr, GRBsetdblattrelement(lpi->grbmodel, GRB_DBL_ATTR_LB, col, oldlb) );
3417  CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
3418 #ifdef SCIP_DEBUG
3419  {
3420  double b;
3421  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrelement(lpi->grbmodel, GRB_DBL_ATTR_LB, col, &b) );
3422  assert( b == oldlb );
3423  }
3424 #endif
3425 
3426  if ( success )
3427  {
3428  SCIP_CALL( setBase(lpi) );
3429  }
3430  }
3431  else
3432  {
3433  CHECK_ZERO( lpi->messagehdlr, GRBgetdblparam(lpi->grbenv, GRB_DBL_PAR_CUTOFF, up) );
3434  *upvalid = TRUE;
3435  }
3436  }
3437 
3438  /* reset iteration limit */
3439  SCIP_CALL( setDblParam(lpi, GRB_DBL_PAR_ITERATIONLIMIT, olditlim) );
3440  /* CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) ); */
3441 
3442  if( error )
3443  {
3444  SCIPerrorMessage("LP error in strong branching.\n");
3445  return SCIP_LPERROR;
3446  }
3447 
3448  return SCIP_OKAY;
3449 }
3450 
3451 /** performs strong branching iterations on one @b fractional candidate */
3453  SCIP_LPI* lpi, /**< LP interface structure */
3454  int col, /**< column to apply strong branching on */
3455  SCIP_Real psol, /**< fractional current primal solution value of column */
3456  int itlim, /**< iteration limit for strong branchings */
3457  SCIP_Real* down, /**< stores dual bound after branching column down */
3458  SCIP_Real* up, /**< stores dual bound after branching column up */
3459  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
3460  * otherwise, it can only be used as an estimate value */
3461  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
3462  * otherwise, it can only be used as an estimate value */
3463  int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
3464  )
3465 {
3466  /* pass call on to lpiStrongbranch() */
3467  SCIP_CALL( lpiStrongbranch(lpi, col, psol, itlim, down, up, downvalid, upvalid, iter) );
3468 
3469  checkRangeInfo(lpi);
3470 
3471  return SCIP_OKAY;
3472 }
3473 
3474 /** performs strong branching iterations on given @b fractional candidates */
3476  SCIP_LPI* lpi, /**< LP interface structure */
3477  int* cols, /**< columns to apply strong branching on */
3478  int ncols, /**< number of columns */
3479  SCIP_Real* psols, /**< fractional current primal solution values of columns */
3480  int itlim, /**< iteration limit for strong branchings */
3481  SCIP_Real* down, /**< stores dual bounds after branching columns down */
3482  SCIP_Real* up, /**< stores dual bounds after branching columns up */
3483  SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds;
3484  * otherwise, they can only be used as an estimate values */
3485  SCIP_Bool* upvalid, /**< stores whether the returned up values are a valid dual bounds;
3486  * otherwise, they can only be used as an estimate values */
3487  int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
3488  )
3489 {
3490  int j;
3491 
3492  assert( cols != NULL );
3493  assert( psols != NULL );
3494  assert( down != NULL );
3495  assert( up != NULL );
3496  assert( downvalid != NULL );
3497  assert( upvalid != NULL );
3498  assert( down != NULL );
3499 
3500  if( iter != NULL )
3501  *iter = 0;
3502 
3503  for( j = 0; j < ncols; ++j )
3504  {
3505  /* pass call on to lpiStrongbranch() */
3506  SCIP_CALL( lpiStrongbranch(lpi, cols[j], psols[j], itlim, &(down[j]), &(up[j]), &(downvalid[j]), &(upvalid[j]), iter) );
3507  }
3508 
3509  checkRangeInfo(lpi);
3510 
3511  return SCIP_OKAY;
3512 }
3513 
3514 /** performs strong branching iterations on one candidate with @b integral value */
3516  SCIP_LPI* lpi, /**< LP interface structure */
3517  int col, /**< column to apply strong branching on */
3518  SCIP_Real psol, /**< current integral primal solution value of column */
3519  int itlim, /**< iteration limit for strong branchings */
3520  SCIP_Real* down, /**< stores dual bound after branching column down */
3521  SCIP_Real* up, /**< stores dual bound after branching column up */
3522  SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
3523  * otherwise, it can only be used as an estimate value */
3524  SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
3525  * otherwise, it can only be used as an estimate value */
3526  int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
3527  )
3528 {
3529  /* pass call on to lpiStrongbranch() */
3530  SCIP_CALL( lpiStrongbranch(lpi, col, psol, itlim, down, up, downvalid, upvalid, iter) );
3531 
3532  checkRangeInfo(lpi);
3533 
3534  return SCIP_OKAY;
3535 }
3536 
3537 /** performs strong branching iterations on given candidates with @b integral values */
3539  SCIP_LPI* lpi, /**< LP interface structure */
3540  int* cols, /**< columns to apply strong branching on */
3541  int ncols, /**< number of columns */
3542  SCIP_Real* psols, /**< current integral primal solution values of columns */
3543  int itlim, /**< iteration limit for strong branchings */
3544  SCIP_Real* down, /**< stores dual bounds after branching columns down */
3545  SCIP_Real* up, /**< stores dual bounds after branching columns up */
3546  SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds;
3547  * otherwise, they can only be used as an estimate values */
3548  SCIP_Bool* upvalid, /**< stores whether the returned up values are a valid dual bounds;
3549  * otherwise, they can only be used as an estimate values */
3550  int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
3551  )
3552 {
3553  int j;
3554 
3555  assert( cols != NULL );
3556  assert( psols != NULL );
3557  assert( down != NULL );
3558  assert( up != NULL );
3559  assert( downvalid != NULL );
3560  assert( upvalid != NULL );
3561  assert( down != NULL );
3562 
3563  if( iter != NULL )
3564  *iter = 0;
3565 
3566  for( j = 0; j < ncols; ++j )
3567  {
3568  /* pass call on to lpiStrongbranch() */
3569  SCIP_CALL( lpiStrongbranch(lpi, cols[j], psols[j], itlim, &(down[j]), &(up[j]), &(downvalid[j]), &(upvalid[j]), iter) );
3570  }
3571 
3572  checkRangeInfo(lpi);
3573 
3574  return SCIP_OKAY;
3575 }
3576 /**@} */
3577 
3578 
3579 
3580 
3581 /*
3582  * Solution Information Methods
3583  */
3584 
3585 /**@name Solution Information Methods */
3586 /**@{ */
3587 
3588 /** returns whether a solve method was called after the last modification of the LP */
3590  SCIP_LPI* lpi /**< LP interface structure */
3591  )
3592 {
3593  assert(lpi != NULL);
3594 
3595  return (lpi->solstat != -1);
3596 }
3597 
3598 /** gets information about primal and dual feasibility of the current LP solution
3599  *
3600  * The feasibility information is with respect to the last solving call and it is only relevant if SCIPlpiWasSolved()
3601  * returns true. If the LP is changed, this information might be invalidated.
3602  *
3603  * Note that @a primalfeasible and @a dualfeasible should only return true if the solver has proved the respective LP to
3604  * be feasible. Thus, the return values should be equal to the values of SCIPlpiIsPrimalFeasible() and
3605  * SCIPlpiIsDualFeasible(), respectively. Note that if feasibility cannot be proved, they should return false (even if
3606  * the problem might actually be feasible).
3607  */
3609  SCIP_LPI* lpi, /**< LP interface structure */
3610  SCIP_Bool* primalfeasible, /**< pointer to store primal feasibility status */
3611  SCIP_Bool* dualfeasible /**< pointer to store dual feasibility status */
3612  )
3613 {
3614  assert( lpi != NULL );
3615  assert( lpi->grbmodel != NULL );
3616  assert( lpi->grbenv != NULL );
3617  assert( lpi->solstat >= 1 );
3618  assert( primalfeasible != NULL );
3619  assert( dualfeasible != NULL );
3620 
3621  SCIPdebugMessage("getting solution feasibility\n");
3622 
3623  *primalfeasible = SCIPlpiIsPrimalFeasible(lpi);
3624  *dualfeasible = SCIPlpiIsDualFeasible(lpi);
3625 
3626  return SCIP_OKAY;
3627 }
3628 
3629 /** returns TRUE iff LP is proven to have a primal unbounded ray (but not necessary a primal feasible point);
3630  * this does not necessarily mean, that the solver knows and can return the primal ray
3631  */
3633  SCIP_LPI* lpi /**< LP interface structure */
3634  )
3635 {
3636  assert(lpi != NULL);
3637  assert(lpi->grbmodel != NULL);
3638  assert(lpi->solstat >= 0);
3639 
3640  return (lpi->solstat == GRB_UNBOUNDED);
3641 }
3642 
3643 /** returns TRUE iff LP is proven to have a primal unbounded ray (but not necessary a primal feasible point),
3644  * and the solver knows and can return the primal ray
3645  */
3647  SCIP_LPI* lpi /**< LP interface structure */
3648  )
3649 {
3650  int algo;
3651  int res;
3652 
3653  assert( lpi != NULL );
3654  assert( lpi->grbmodel != NULL );
3655  assert( lpi->grbenv != NULL );
3656  assert( lpi->solstat >= 0 );
3657 
3658  res = GRBgetintparam(lpi->grbenv, GRB_INT_PAR_METHOD, &algo);
3659  if ( res != 0 )
3660  {
3661  SCIPABORT();
3662  return FALSE; /*lint !e527*/
3663  }
3664 
3665  return (lpi->solstat == GRB_UNBOUNDED && algo == GRB_METHOD_PRIMAL);
3666 }
3667 
3668 /** returns TRUE iff LP is proven to be primal unbounded */
3670  SCIP_LPI* lpi /**< LP interface structure */
3671  )
3672 {
3673  int algo;
3674  int res;
3675 
3676  assert( lpi != NULL );
3677  assert( lpi->grbmodel != NULL );
3678  assert( lpi->grbenv != NULL );
3679  assert( lpi->solstat >= 0 );
3680 
3681  res = GRBgetintparam(lpi->grbenv, GRB_INT_PAR_METHOD, &algo);
3682  if ( res != 0 )
3683  {
3684  SCIPABORT();
3685  return FALSE; /*lint !e527*/
3686  }
3687 
3688  /* GRB_UNBOUNDED means that there exists a primal ray. SCIPlpiSolvePrimal() will determine whether the problem is
3689  * actually infeasible or (feasible and) unbounded. In the latter case, the status will be GRB_UNBOUNDED.
3690  */
3691  return (lpi->solstat == GRB_UNBOUNDED && algo == GRB_METHOD_PRIMAL);
3692 }
3693 
3694 /** returns TRUE iff LP is proven to be primal infeasible */
3696  SCIP_LPI* lpi /**< LP interface structure */
3697  )
3698 {
3699  assert(lpi != NULL);
3700  assert(lpi->grbmodel != NULL);
3701  assert(lpi->solstat >= 0);
3702 
3703  SCIPdebugMessage("checking for primal infeasibility\n");
3704 
3705  assert( lpi->solstat != GRB_INF_OR_UNBD );
3706  return (lpi->solstat == GRB_INFEASIBLE);
3707 }
3708 
3709 /** returns TRUE iff LP is proven to be primal feasible */
3711  SCIP_LPI* lpi /**< LP interface structure */
3712  )
3713 {
3714  int algo;
3715  int res;
3716 
3717  assert( lpi != NULL );
3718  assert( lpi->grbmodel != NULL );
3719  assert( lpi->grbenv != NULL );
3720  assert( lpi->solstat >= 0 );
3721 
3722  SCIPdebugMessage("checking for primal feasibility\n");
3723 
3724  if ( lpi->solstat == GRB_OPTIMAL )
3725  return TRUE;
3726 
3727  res = GRBgetintparam(lpi->grbenv, GRB_INT_PAR_METHOD, &algo);
3728  if ( res != 0 )
3729  {
3730  SCIPABORT();
3731  return FALSE; /*lint !e527*/
3732  }
3733  if ( algo != GRB_METHOD_PRIMAL )
3734  return FALSE;
3735 
3736  if( lpi->solstat == GRB_ITERATION_LIMIT )
3737  {
3738  double consviol;
3739  double boundviol;
3740  double eps;
3741 
3742  /* get feasibility tolerance */
3743  res = GRBgetdblparam(lpi->grbenv, GRB_DBL_PAR_FEASIBILITYTOL, &eps);
3744  if ( res != 0 )
3745  {
3746  SCIPABORT();
3747  return FALSE; /*lint !e527*/
3748  }
3749  res = GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_CONSTR_VIO, &consviol);
3750  if ( res != 0 )
3751  {
3752  /* If Gurobi cannot return the constraint violation, there is no feasible solution available. */
3753  return FALSE;
3754  }
3755  res = GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_BOUND_VIO, &boundviol);
3756  if ( res != 0 )
3757  {
3758  /* If Gurobi cannot return the bound violation, there is no feasible solution available. */
3759  return FALSE;
3760  }
3761 
3762  if ( consviol <= eps && boundviol <= eps )
3763  return TRUE;
3764  }
3765 
3766  return FALSE;
3767 }
3768 
3769 /** returns TRUE iff LP is proven to have a dual unbounded ray (but not necessary a dual feasible point);
3770  * this does not necessarily mean, that the solver knows and can return the dual ray
3771  */
3773  SCIP_LPI* lpi /**< LP interface structure */
3774  )
3775 {
3776  assert(lpi != NULL);
3777  assert(lpi->grbmodel != NULL);
3778  assert(lpi->solstat >= 0);
3779 
3780  return (lpi->solstat == GRB_INFEASIBLE);
3781 }
3782 
3783 /** returns TRUE iff LP is proven to have a dual unbounded ray (but not necessary a dual feasible point),
3784  * and the solver knows and can return the dual ray
3785  */
3787  SCIP_LPI* lpi /**< LP interface structure */
3788  )
3789 {
3790  int algo;
3791  int res;
3792 
3793  assert( lpi != NULL );
3794  assert( lpi->grbmodel != NULL );
3795  assert( lpi->grbenv != NULL );
3796  assert( lpi->solstat >= 0 );
3797 
3798  res = GRBgetintparam(lpi->grbenv, GRB_INT_PAR_METHOD, &algo);
3799  if ( res != 0 )
3800  {
3801  SCIPABORT();
3802  return FALSE; /*lint !e527*/
3803  }
3804 
3805  return (lpi->solstat == GRB_INFEASIBLE && algo == GRB_METHOD_DUAL);
3806 }
3807 
3808 /** returns TRUE iff LP is proven to be dual unbounded */
3810  SCIP_LPI* lpi /**< LP interface structure */
3811  )
3812 {
3813  int algo;
3814  int res;
3815 
3816  assert( lpi != NULL );
3817  assert( lpi->grbmodel != NULL );
3818  assert( lpi->grbenv != NULL );
3819  assert( lpi->solstat >= 0 );
3820 
3821  SCIPdebugMessage("checking for dual unboundedness\n");
3822 
3823  res = GRBgetintparam(lpi->grbenv, GRB_INT_PAR_METHOD, &algo);
3824  if ( res != 0 )
3825  {
3826  SCIPABORT();
3827  return FALSE; /*lint !e527*/
3828  }
3829 
3830  return (lpi->solstat == GRB_INFEASIBLE && algo == GRB_METHOD_DUAL);
3831 }
3832 
3833 /** returns TRUE iff LP is proven to be dual infeasible */
3835  SCIP_LPI* lpi /**< LP interface structure */
3836  )
3837 {
3838  assert( lpi != NULL );
3839  assert( lpi->grbmodel != NULL );
3840  assert( lpi->solstat >= 0 );
3841 
3842  SCIPdebugMessage("checking for dual infeasibility\n");
3843 
3844  return (lpi->solstat == GRB_UNBOUNDED);
3845 }
3846 
3847 /** returns TRUE iff LP is proven to be dual feasible */
3849  SCIP_LPI* lpi /**< LP interface structure */
3850  )
3851 {
3852  int algo;
3853  int res;
3854 
3855  assert( lpi != NULL );
3856  assert( lpi->grbmodel != NULL );
3857  assert( lpi->grbenv != NULL );
3858  assert( lpi->solstat >= 0 );
3859 
3860  SCIPdebugMessage("checking for dual feasibility\n");
3861 
3862  res = GRBgetintparam(lpi->grbenv, GRB_INT_PAR_METHOD, &algo);
3863  if ( res != 0 )
3864  {
3865  SCIPABORT();
3866  return FALSE; /*lint !e527*/
3867  }
3868 
3869  return (lpi->solstat == GRB_OPTIMAL ||
3870  (lpi->solstat == GRB_INFEASIBLE && algo == GRB_METHOD_DUAL) ||
3871  (lpi->solstat == GRB_ITERATION_LIMIT && algo == GRB_METHOD_DUAL) );
3872 }
3873 
3874 /** returns TRUE iff LP was solved to optimality */
3876  SCIP_LPI* lpi /**< LP interface structure */
3877  )
3878 {
3879  assert(lpi != NULL);
3880  assert(lpi->grbmodel != NULL);
3881  assert(lpi->solstat >= 0);
3882 
3883  return (lpi->solstat == GRB_OPTIMAL);
3884 }
3885 
3886 /** returns TRUE iff current LP solution is stable
3887  *
3888  * This function should return true if the solution is reliable, i.e., feasible and optimal (or proven
3889  * infeasible/unbounded) with respect to the original problem. The optimality status might be with respect to a scaled
3890  * version of the problem, but the solution might not be feasible to the unscaled original problem; in this case,
3891  * SCIPlpiIsStable() should return false.
3892  */
3894  SCIP_LPI* lpi /**< LP interface structure */
3895  )
3896 {
3897  double consviol;
3898  double boundviol;
3899  double dualviol;
3900  double feastol;
3901  double optimalitytol;
3902  int res;
3903 
3904  assert(lpi != NULL);
3905  assert(lpi->grbmodel != NULL);
3906  assert(lpi->solstat >= 0);
3907 
3908  SCIPdebugMessage("checking for stability: Gurobi solstat = %d\n", lpi->solstat);
3909 
3910  /* If the condition number of the basis should be checked, everything above the specified threshold is counted as
3911  * instable. */
3912  if ( lpi->checkcondition && (SCIPlpiIsOptimal(lpi) || SCIPlpiIsObjlimExc(lpi)) )
3913  {
3914  SCIP_Real kappa;
3915  SCIP_RETCODE retcode;
3916 
3918  if ( retcode != SCIP_OKAY ) /*lint !e774*/
3919  {
3920  SCIPABORT();
3921  return FALSE; /*lint !e527*/
3922  }
3923 
3924  /* if the kappa could not be computed (e.g., because we do not have a basis), we cannot check the condition */
3925  if ( kappa != SCIP_INVALID || kappa > lpi->conditionlimit ) /*lint !e777*/
3926  return FALSE;
3927  }
3928 
3929  /* test whether we have unscaled infeasibilities */
3930  if ( SCIPlpiIsOptimal(lpi) )
3931  {
3932  /* first get tolerances */
3933  res = GRBgetdblparam(lpi->grbenv, GRB_DBL_PAR_FEASIBILITYTOL, &feastol);
3934  if ( res != 0 )
3935  {
3936  SCIPABORT();
3937  return FALSE; /*lint !e527*/
3938  }
3939  res = GRBgetdblparam(lpi->grbenv, GRB_DBL_PAR_OPTIMALITYTOL, &optimalitytol);
3940  if ( res != 0 )
3941  {
3942  SCIPABORT();
3943  return FALSE; /*lint !e527*/
3944  }
3945 
3946  /* next get constraint, bound, and reduced cost violations */
3947  res = GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_CONSTR_VIO, &consviol);
3948  if ( res != 0 )
3949  {
3950  SCIPABORT();
3951  return FALSE; /*lint !e527*/
3952  }
3953  res = GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_BOUND_VIO, &boundviol);
3954  if ( res != 0 )
3955  {
3956  SCIPABORT();
3957  return FALSE; /*lint !e527*/
3958  }
3959  res = GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_DUAL_VIO, &dualviol);
3960  if ( res != 0 )
3961  {
3962  SCIPABORT();
3963  return FALSE; /*lint !e527*/
3964  }
3965 
3966  return ( consviol <= feastol && boundviol <= feastol && dualviol <= optimalitytol );
3967  }
3968 
3969  return (lpi->solstat != GRB_NUMERIC);
3970 }
3971 
3972 /** returns TRUE iff the objective limit was reached */
3974  SCIP_LPI* lpi /**< LP interface structure */
3975  )
3976 {
3977  assert(lpi != NULL);
3978  assert(lpi->grbmodel != NULL);
3979  assert(lpi->solstat >= 0);
3980 
3981  return (lpi->solstat == GRB_CUTOFF);
3982 }
3983 
3984 /** returns TRUE iff the iteration limit was reached */
3986  SCIP_LPI* lpi /**< LP interface structure */
3987  )
3988 {
3989  assert(lpi != NULL);
3990  assert(lpi->grbmodel != NULL);
3991  assert(lpi->solstat >= 0);
3992 
3993  return (lpi->solstat == GRB_ITERATION_LIMIT);
3994 }
3995 
3996 /** returns TRUE iff the time limit was reached */
3998  SCIP_LPI* lpi /**< LP interface structure */
3999  )
4000 {
4001  assert(lpi != NULL);
4002  assert(lpi->grbmodel != NULL);
4003  assert(lpi->solstat >= 0);
4004 
4005  return (lpi->solstat == GRB_TIME_LIMIT);
4006 }
4007 
4008 /** returns the internal solution status of the solver */
4010  SCIP_LPI* lpi /**< LP interface structure */
4011  )
4012 {
4013  assert(lpi != NULL);
4014  assert(lpi->grbmodel != NULL);
4015 
4016  return lpi->solstat;
4017 }
4018 
4019 /** tries to reset the internal status of the LP solver in order to ignore an instability of the last solving call */
4021  SCIP_LPI* lpi, /**< LP interface structure */
4022  SCIP_Bool* success /**< pointer to store, whether the instability could be ignored */
4023  )
4024 {
4025  assert(lpi != NULL);
4026  assert(lpi->grbmodel != NULL);
4027  assert(success != NULL);
4028 
4029  *success = FALSE;
4030 
4031  return SCIP_OKAY;
4032 }
4033 
4034 /** gets objective value of solution
4035  *
4036  * @note if the solution status is iteration limit reached (GRB_ITERATION_LIMIT), the objective value was not computed
4037  */
4039  SCIP_LPI* lpi, /**< LP interface structure */
4040  SCIP_Real* objval /**< stores the objective value */
4041  )
4042 {
4043  int ret;
4044 
4045 #ifndef NDEBUG
4046  double oval = GRB_INFINITY;
4047  double obnd = -GRB_INFINITY;
4048 #endif
4049 
4050  assert(lpi != NULL);
4051  assert(lpi->grbmodel != NULL);
4052  assert(objval != NULL);
4053 
4054  SCIPdebugMessage("getting solution's objective value\n");
4055 
4056 #ifndef NDEBUG
4057  (void)GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_OBJVAL, &oval);
4058  (void)GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_OBJBOUND, &obnd);
4059 
4060  assert(lpi->solstat != GRB_OPTIMAL || oval == obnd); /*lint !e777*/
4061 #endif
4062 
4063  ret = GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_OBJBOUND, objval);
4064 
4065  if( ret == GRB_ERROR_DATA_NOT_AVAILABLE )
4066  {
4067  /* return minus infinity if value not available and we reached an iteration limit (see lpi_cpx) */
4068  if( lpi->solstat == GRB_ITERATION_LIMIT )
4069  *objval = -SCIPlpiInfinity(lpi);
4070  /**@todo The following is some kind of hack which works with the current SCIP implementation and should be fixed. In
4071  * the case that the LP status is GRB_CUTOFF it might be that certain attributes cannot be queries (e.g., objval,
4072  * primal and dual solution), in this case we just return the installed cutoff value minus some epsilon. This is some
4073  * kind of hack for the code in conflict.c:7595 were some extra code handles CPLEX' FASTMIP case that is similar to
4074  * this case.
4075  */
4076  else if( lpi->solstat == GRB_CUTOFF )
4077  {
4078  SCIP_Real dval;
4079  SCIP_OBJSEN objsense;
4080 
4081  SCIP_CALL( SCIPlpiGetObjsen(lpi, &objsense) );
4082  SCIP_CALL( getDblParam(lpi, GRB_DBL_PAR_CUTOFF, &dval) );
4083 
4084  if( objsense == SCIP_OBJSEN_MINIMIZE )
4085  *objval = dval - 1e-06;
4086  else
4087  *objval = dval + 1e-06;
4088  }
4089  }
4090  else
4091  {
4092  CHECK_ZERO( lpi->messagehdlr, ret );
4093  }
4094 
4095  return SCIP_OKAY;
4096 }
4097 
4098 /** gets primal and dual solution vectors for feasible LPs
4099  *
4100  * Before calling this function, the caller must ensure that the LP has been solved to optimality, i.e., that
4101  * SCIPlpiIsOptimal() returns true.
4102  */
4104  SCIP_LPI* lpi, /**< LP interface structure */
4105  SCIP_Real* objval, /**< stores the objective value, may be NULL if not needed */
4106  SCIP_Real* primsol, /**< primal solution vector, may be NULL if not needed */
4107  SCIP_Real* dualsol, /**< dual solution vector, may be NULL if not needed */
4108  SCIP_Real* activity, /**< row activity vector, may be NULL if not needed */
4109  SCIP_Real* redcost /**< reduced cost vector, may be NULL if not needed */
4110  )
4111 {
4112  int ncols;
4113  int nrows;
4114 
4115  assert(lpi != NULL);
4116  assert(lpi->grbmodel != NULL);
4117  assert(lpi->solstat >= 0);
4118 
4119  SCIPdebugMessage("getting solution\n");
4120 
4121  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
4122  SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
4123  assert( ncols >= 0 && nrows >= 0 );
4124 
4125  if( objval != NULL )
4126  {
4127  SCIP_CALL( SCIPlpiGetObjval(lpi, objval) );
4128  }
4129 
4130  if( primsol != NULL )
4131  {
4132  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_X, 0, ncols, primsol) );
4133  }
4134 
4135  if( dualsol != NULL )
4136  {
4137  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_PI, 0, nrows, dualsol) );
4138  }
4139 
4140  if( activity != NULL )
4141  {
4142  int i;
4143 
4144  /* first get the values of the slack variables */
4145  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_SLACK, 0, nrows, activity) );
4146 
4147  SCIP_CALL( ensureSidechgMem(lpi, nrows) );
4148 
4149  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_RHS, 0, nrows, lpi->rhsarray) );
4150  CHECK_ZERO( lpi->messagehdlr, GRBgetcharattrarray(lpi->grbmodel, GRB_CHAR_ATTR_SENSE, 0, nrows, lpi->senarray) );
4151 
4152  for( i = 0; i < nrows; ++i )
4153  {
4154  switch(lpi->senarray[i])
4155  {
4156  case GRB_EQUAL:
4157  if ( lpi->rngrowmap != NULL && lpi->rngrowmap[i] >= 0 )
4158  {
4159  /* get solution value of range variable */
4160  SCIP_Real solval;
4161  assert(lpi->rngrowmap[i] < lpi->nrngrows);
4162  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrelement(lpi->grbmodel, GRB_DBL_ATTR_X, ncols + lpi->rngrowmap[i], &solval) );
4163  activity[i] = lpi->rhsarray[i] + solval;
4164  }
4165  else
4166  {
4167  activity[i] = lpi->rhsarray[i] - activity[i];
4168  }
4169  break;
4170  case GRB_LESS_EQUAL:
4171  activity[i] = lpi->rhsarray[i] - activity[i];
4172  break;
4173  case GRB_GREATER_EQUAL:
4174  activity[i] = lpi->rhsarray[i] - activity[i];
4175  break;
4176  default:
4177  SCIPerrorMessage("Unkown sense %c.\n", lpi->senarray[i]);
4178  SCIPABORT();
4179  return SCIP_INVALIDDATA; /*lint !e527*/
4180  }
4181  }
4182  }
4183 
4184  if( redcost != NULL )
4185  {
4186  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_RC, 0, ncols, redcost) );
4187  }
4188 
4189  return SCIP_OKAY;
4190 }
4191 
4192 /** gets primal ray for unbounded LPs */
4194  SCIP_LPI* lpi, /**< LP interface structure */
4195  SCIP_Real* ray /**< primal ray */
4196  )
4197 {
4198  int ncols;
4199 
4200  assert(lpi != NULL);
4201  assert(lpi->grbmodel != NULL);
4202  assert(lpi->solstat >= 0);
4203  assert(ray != NULL);
4204 
4205  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
4206  assert( ncols >= 0 );
4207 
4208  SCIPdebugMessage("calling Gurobi get primal ray: %d cols\n", ncols);
4209 
4210  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_UNBDRAY, 0, ncols, ray) );
4211 
4212  return SCIP_OKAY;
4213 }
4214 
4215 /** gets dual Farkas proof for infeasibility */
4217  SCIP_LPI* lpi, /**< LP interface structure */
4218  SCIP_Real* dualfarkas /**< dual Farkas row multipliers */
4219  )
4220 {
4221  int nrows;
4222  int i;
4223 
4224  assert(lpi != NULL);
4225  assert(lpi->grbmodel != NULL);
4226  assert(lpi->solstat >= 0);
4227  assert(dualfarkas != NULL);
4228 
4229  SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
4230  assert( nrows >= 0 );
4231 
4232  SCIPdebugMessage("calling Gurobi dual Farkas: %d rows\n", nrows);
4233 
4234  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_FARKASDUAL, 0, nrows, dualfarkas) );
4235 
4236  /* correct sign of ray */
4237  for (i = 0; i < nrows; ++i)
4238  dualfarkas[i] *= -1.0;
4239 
4240  return SCIP_OKAY;
4241 }
4242 
4243 /** gets the number of LP iterations of the last solve call */
4245  SCIP_LPI* lpi, /**< LP interface structure */
4246  int* iterations /**< pointer to store the number of iterations of the last solve call */
4247  )
4248 {
4249  assert(lpi != NULL);
4250  assert(lpi->grbmodel != NULL);
4251  assert(iterations != NULL);
4252 
4253  *iterations = lpi->iterations;
4254 
4255  return SCIP_OKAY;
4256 }
4257 
4258 /** gets information about the quality of an LP solution
4259  *
4260  * Such information is usually only available, if also a (maybe not optimal) solution is available.
4261  * The LPI should return SCIP_INVALID for @p quality, if the requested quantity is not available.
4262  */
4264  SCIP_LPI* lpi, /**< LP interface structure */
4265  SCIP_LPSOLQUALITY qualityindicator, /**< indicates which quality should be returned */
4266  SCIP_Real* quality /**< pointer to store quality number */
4267  )
4268 { /*lint --e{715}*/
4269  const char* what;
4270  int ret;
4271 
4272  assert(lpi != NULL);
4273  assert(lpi->grbmodel != NULL);
4274  assert(quality != NULL);
4275 
4276  SCIPdebugMessage("requesting solution quality from Gurobi: quality %d\n", qualityindicator);
4277 
4278  switch( qualityindicator )
4279  {
4281  what = GRB_DBL_ATTR_KAPPA;
4282  break;
4283 
4285  what = GRB_DBL_ATTR_KAPPA_EXACT;
4286  break;
4287 
4288  default:
4289  SCIPerrorMessage("Solution quality %d unknown.\n", qualityindicator);
4290  return SCIP_INVALIDDATA;
4291  }
4292 
4293  ret = GRBgetdblattr(lpi->grbmodel, what, quality);
4294  if( ret != 0 )
4295  *quality = SCIP_INVALID;
4296 
4297  return SCIP_OKAY;
4298 }
4299 
4300 /**@} */
4301 
4302 
4303 
4304 
4305 /*
4306  * LP Basis Methods
4307  */
4308 
4309 /**@name LP Basis Methods */
4310 /**@{ */
4311 
4312 /** gets current basis status for columns and rows; arrays must be large enough to store the basis status */
4314  SCIP_LPI* lpi, /**< LP interface structure */
4315  int* cstat, /**< array to store column basis status, or NULL */
4316  int* rstat /**< array to store row basis status, or NULL */
4317  )
4318 {
4319  int nrows;
4320  int ncols;
4321 
4322  assert(lpi != NULL);
4323  assert(lpi->grbmodel != NULL);
4324 
4325  SCIPdebugMessage("saving Gurobi basis into %p/%p\n", (void*) cstat, (void*) rstat);
4326 
4327  SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
4328  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
4329 
4330  if( rstat != NULL )
4331  {
4332  int i;
4333 
4334  SCIP_CALL( ensureSidechgMem(lpi, nrows) );
4335 
4336  CHECK_ZERO( lpi->messagehdlr, GRBgetintattrarray(lpi->grbmodel, GRB_INT_ATTR_CBASIS, 0, nrows, rstat) );
4337  CHECK_ZERO( lpi->messagehdlr, GRBgetcharattrarray(lpi->grbmodel, GRB_CHAR_ATTR_SENSE, 0, nrows, lpi->senarray) );
4338 
4339  for( i = 0; i < nrows; ++i )
4340  {
4341  if ( lpi->rngrowmap != NULL && lpi->rngrowmap[i] >= 0 && rstat[i] != GRB_BASIC )
4342  {
4343  int idx;
4344 
4345  /* get range row basis status from corresponding range variable */
4346  idx = ncols + lpi->rngrowmap[i];
4347  assert(lpi->rngrowmap[i] < lpi->nrngrows);
4348  CHECK_ZERO( lpi->messagehdlr, GRBgetintattrelement(lpi->grbmodel, GRB_INT_ATTR_VBASIS, idx, &rstat[i]) );
4349 
4350  switch( rstat[i] )
4351  {
4352  case GRB_BASIC:
4353  rstat[i] = (int) SCIP_BASESTAT_BASIC;
4354  break;
4355 
4356  case GRB_NONBASIC_LOWER:
4357  rstat[i] = (int) SCIP_BASESTAT_LOWER;
4358  break;
4359 
4360  case GRB_NONBASIC_UPPER:
4361  rstat[i] = (int) SCIP_BASESTAT_UPPER;
4362  break;
4363 
4364  /*lint -fallthrough*/
4365  case GRB_SUPERBASIC:
4366  default:
4367  SCIPerrorMessage("invalid basis status %d for ranged row.\n", rstat[i]);
4368  SCIPABORT();
4369  return SCIP_INVALIDDATA; /*lint !e527*/
4370  }
4371  }
4372  else
4373  {
4374  /* Slack variables can only be basic or at their lower bounds in Gurobi. */
4375  switch( rstat[i] )
4376  {
4377  case GRB_BASIC:
4378  rstat[i] = (int) SCIP_BASESTAT_BASIC;
4379  break;
4380 
4381  case GRB_NONBASIC_LOWER:
4382  if ( lpi->senarray[i] == '>' || lpi->senarray[i] == '=' )
4383  rstat[i] = (int) SCIP_BASESTAT_LOWER;
4384  else
4385  {
4386  assert( lpi->senarray[i] == '<' );
4387  rstat[i] = (int) SCIP_BASESTAT_UPPER;
4388  }
4389  break;
4390 
4391  /*lint -fallthrough*/
4392  case GRB_NONBASIC_UPPER:
4393  case GRB_SUPERBASIC:
4394  default:
4395  SCIPerrorMessage("invalid basis status %d for row.\n", rstat[i]);
4396  SCIPABORT();
4397  return SCIP_INVALIDDATA; /*lint !e527*/
4398  }
4399  }
4400  }
4401  }
4402 
4403  if( cstat != 0 )
4404  {
4405  int j;
4406 
4407  CHECK_ZERO( lpi->messagehdlr, GRBgetintattrarray(lpi->grbmodel, GRB_INT_ATTR_VBASIS, 0, ncols, cstat) );
4408 
4409  for( j = 0; j < ncols; ++j )
4410  {
4411  switch( cstat[j] )
4412  {
4413  case GRB_BASIC:
4414  cstat[j] = (int) SCIP_BASESTAT_BASIC;
4415  break;
4416 
4417  case GRB_NONBASIC_LOWER:
4418  cstat[j] = (int) SCIP_BASESTAT_LOWER;
4419  break;
4420 
4421  case GRB_NONBASIC_UPPER:
4422  cstat[j] = (int) SCIP_BASESTAT_UPPER;
4423  break;
4424 
4425  case GRB_SUPERBASIC:
4426  cstat[j] = (int) SCIP_BASESTAT_ZERO;
4427  break;
4428 
4429  default:
4430  SCIPerrorMessage("invalid basis status %d for column.\n", cstat[j]);
4431  SCIPABORT();
4432  return SCIP_INVALIDDATA; /*lint !e527*/
4433  }
4434  }
4435  }
4436 
4437  return SCIP_OKAY;
4438 }
4439 
4440 /** sets current basis status for columns and rows */
4442  SCIP_LPI* lpi, /**< LP interface structure */
4443  const int* cstat, /**< array with column basis status */
4444  const int* rstat /**< array with row basis status */
4445  )
4446 {
4447  int i, j;
4448  int nrows, ncols;
4449 #ifndef NDEBUG
4450  int nrngsfound = 0;
4451 #endif
4452 
4453  assert(lpi != NULL);
4454  assert(lpi->grbmodel != NULL);
4455 
4456  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
4457  SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
4458 
4459  assert(cstat != NULL || ncols == 0);
4460  assert(rstat != NULL || nrows == 0);
4461 
4462  SCIPdebugMessage("loading basis %p/%p into Gurobi\n", (void*) cstat, (void*) rstat);
4463 
4464  invalidateSolution(lpi);
4465 
4466  SCIP_CALL( ensureCstatMem(lpi, ncols+lpi->nrngrows) );
4467  SCIP_CALL( ensureRstatMem(lpi, nrows) );
4468 
4469  for( i = 0; i < nrows; ++i )
4470  {
4471  if ( lpi->rngrowmap != NULL && lpi->rngrowmap[i] >= 0 )
4472  {
4473  int idx;
4474 
4475  /* set basis status of corresponding range variable; ranged row is always non-basic */
4476  idx = ncols + lpi->rngrowmap[i];
4477  assert(lpi->rngrowmap[i] < lpi->nrngrows);
4478  lpi->cstat[idx] = lpi->rstat[i];
4479  lpi->rstat[i] = GRB_NONBASIC_LOWER;
4480 #ifndef NDEBUG
4481  nrngsfound++;
4482 #endif
4483  }
4484  else
4485  {
4486  switch( rstat[i] ) /*lint !e613*/
4487  {
4488  case SCIP_BASESTAT_BASIC:
4489  lpi->rstat[i] = GRB_BASIC;
4490  break;
4491 
4492  case SCIP_BASESTAT_UPPER:
4493  {
4494 #ifndef NDEBUG
4495  char sense;
4496  CHECK_ZERO( lpi->messagehdlr, GRBgetcharattrarray(lpi->grbmodel, GRB_CHAR_ATTR_SENSE, i, 1, &sense) );
4497  assert( sense == '<' );
4498 #endif
4499  /* Slack variables can only be basic or at their lower bounds in Gurobi. */
4500  lpi->rstat[i] = GRB_NONBASIC_LOWER;
4501  break;
4502  }
4503 
4504  case SCIP_BASESTAT_LOWER:
4505  {
4506 #ifndef NDEBUG
4507  char sense;
4508  CHECK_ZERO( lpi->messagehdlr, GRBgetcharattrarray(lpi->grbmodel, GRB_CHAR_ATTR_SENSE, i, 1, &sense) );
4509  assert( sense == '>' || sense == '=' );
4510 #endif
4511  lpi->rstat[i] = GRB_NONBASIC_LOWER;
4512  break;
4513  }
4514 
4515  case SCIP_BASESTAT_ZERO:
4516  default:
4517  SCIPerrorMessage("invalid basis status %d for row.\n", rstat[i]); /*lint !e613*/
4518  SCIPABORT();
4519  return SCIP_INVALIDDATA; /*lint !e527*/
4520  }
4521  }
4522  }
4523 
4524  for( j = 0; j < ncols; ++j )
4525  {
4526  switch( cstat[j] ) /*lint !e613*/
4527  {
4528  case SCIP_BASESTAT_BASIC:
4529  lpi->cstat[j] = GRB_BASIC;
4530  break;
4531 
4532  case SCIP_BASESTAT_LOWER:
4533  lpi->cstat[j] = GRB_NONBASIC_LOWER;
4534  break;
4535 
4536  case SCIP_BASESTAT_UPPER:
4537  lpi->cstat[j] = GRB_NONBASIC_UPPER;
4538  break;
4539 
4540  case SCIP_BASESTAT_ZERO:
4541  lpi->cstat[j] = GRB_SUPERBASIC;
4542  break;
4543 
4544  default:
4545  SCIPerrorMessage("invalid basis status %d\n", cstat[j]); /*lint !e613*/
4546  SCIPABORT();
4547  return SCIP_INVALIDDATA; /*lint !e527*/
4548  }
4549  }
4550 
4551 #ifndef NDEBUG
4552  assert(nrngsfound == lpi->nrngrows);
4553 #endif
4554 
4555  CHECK_ZERO( lpi->messagehdlr, GRBsetintattrarray(lpi->grbmodel, GRB_INT_ATTR_CBASIS, 0, nrows, lpi->rstat) );
4556  CHECK_ZERO( lpi->messagehdlr, GRBsetintattrarray(lpi->grbmodel, GRB_INT_ATTR_VBASIS, 0, ncols+lpi->nrngrows, lpi->cstat) );
4557 
4558  return SCIP_OKAY;
4559 }
4560 
4561 /** returns the indices of the basic columns and rows; basic column n gives value n, basic row m gives value -1-m */
4563  SCIP_LPI* lpi, /**< LP interface structure */
4564  int* bind /**< pointer to store basis indices ready to keep number of rows entries */
4565  )
4566 {
4567  int i;
4568  int nrows;
4569  int ncols;
4570  int ngrbcols;
4571  int* bhead;
4572  int status;
4573 
4574  assert(lpi != NULL);
4575  assert(lpi->grbmodel != NULL);
4576  assert(bind != NULL);
4577 
4578  SCIPdebugMessage("getting basis information\n");
4579 
4580  /* check whether we have to reoptimize */
4581  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_STATUS, &status) );
4582  if ( status == GRB_LOADED || status == GRB_INTERRUPTED || status == GRB_INPROGRESS )
4583  {
4585  }
4586 
4587  SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
4588  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
4589  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_NUMVARS, &ngrbcols) );
4590 
4591  /**@todo avoid memory allocation by using bind directly */
4592  /* get space for bhead */
4593  SCIP_ALLOC( BMSallocMemoryArray(&bhead, nrows) );
4594 
4595  /* get basis indices */
4596  CHECK_ZERO( lpi->messagehdlr, GRBgetBasisHead(lpi->grbmodel, bhead) );
4597 
4598  for (i = 0; i < nrows; ++i)
4599  {
4600  /* entries >= ncols refer to slack variables */
4601  if ( bhead[i] < ncols )
4602  bind[i] = bhead[i];
4603  else if ( bhead[i] < ngrbcols )
4604  {
4605  /* a range variable: use corresponding ranged row */
4606  int rngrow = bhead[i]-ncols;
4607  assert(rngrow < lpi->nrngrows);
4608  assert(lpi->rngrowmap != NULL);
4609  assert(lpi->rngrows != NULL);
4610  assert(lpi->rngrowmap[lpi->rngrows[rngrow]] == rngrow);
4611  bind[i] = -1 - lpi->rngrows[rngrow];
4612  }
4613  else
4614  {
4615  /* a regular slack variable */
4616  bind[i] = -1 - (bhead[i] - ngrbcols);
4617  }
4618  }
4619  BMSfreeMemoryArray(&bhead);
4620 
4621  return SCIP_OKAY;
4622 }
4623 
4624 /** get row of inverse basis matrix B^-1
4625  *
4626  * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
4627  * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
4628  * see also the explanation in lpi.h.
4629  *
4630  * @todo check that the result is in terms of the LP interface definition
4631  */
4633  SCIP_LPI* lpi, /**< LP interface structure */
4634  int r, /**< row number */
4635  SCIP_Real* coef, /**< pointer to store the coefficients of the row */
4636  int* inds, /**< array to store the non-zero indices, or NULL */
4637  int* ninds /**< pointer to store the number of non-zero indices, or NULL
4638  * (-1: if we do not store sparsity information) */
4639  )
4640 {
4641  SVECTOR x;
4642  SVECTOR b;
4643  int nrows;
4644  double val;
4645  int ind;
4646  int status;
4647 
4648  assert(lpi != NULL);
4649  assert(lpi->grbmodel != NULL);
4650  assert(coef != NULL);
4651 
4652  SCIPdebugMessage("getting binv-row %d\n", r);
4653 
4654  /* check whether we have to reoptimize */
4655  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_STATUS, &status) );
4656  if ( status == GRB_LOADED || status == GRB_INTERRUPTED || status == GRB_INPROGRESS )
4657  {
4659  }
4660 
4661  SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
4662 
4663  /* set up solution vector */
4664  x.len = 0;
4665  SCIP_ALLOC( BMSallocMemoryArray(&(x.ind), nrows) );
4666  SCIP_ALLOC( BMSallocMemoryArray(&(x.val), nrows) );
4667 
4668  /* get basis indices, temporarily using memory of x.ind */
4669  SCIP_CALL( SCIPlpiGetBasisInd(lpi, x.ind) );
4670 
4671  /* set up rhs */
4672  b.len = 1;
4673  ind = r;
4674  val = (x.ind)[r] >= 0 ? 1.0 : -1.0;
4675  b.ind = &ind;
4676  b.val = &val;
4677 
4678  /* solve B^T x = e_r, which results in the r-th row of the basis inverse */
4679  CHECK_ZERO( lpi->messagehdlr, GRBBSolve(lpi->grbmodel, &b, &x) );
4680 
4681  /* size should be at most the number of rows */
4682  assert( x.len <= nrows );
4683 
4684  /* check whether we require a dense or sparse result vector */
4685  if ( ninds != NULL && inds != NULL )
4686  {
4687  int idx;
4688  int i;
4689 
4690  /* copy sparse solution */
4691  for (i = 0; i < x.len; ++i)
4692  {
4693  idx = (x.ind)[i];
4694  assert( idx >= 0 && idx < nrows );
4695  inds[i] = idx;
4696  coef[idx] = (x.val)[i];
4697  }
4698  *ninds = x.len;
4699  }
4700  else
4701  {
4702  int idx;
4703  int i;
4704 
4705  /* copy solution to dense vector */
4706  BMSclearMemoryArray(coef, nrows);
4707  for (i = 0; i < x.len; ++i)
4708  {
4709  idx = (x.ind)[i];
4710  assert( idx >= 0 && idx < nrows );
4711  coef[idx] = (x.val)[i];
4712  }
4713  }
4714 
4715  /* free solution space */
4716  BMSfreeMemoryArray(&(x.val));
4717  BMSfreeMemoryArray(&(x.ind));
4718 
4719  return SCIP_OKAY;
4720 }
4721 
4722 /** get column of inverse basis matrix B^-1
4723  *
4724  * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
4725  * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
4726  * see also the explanation in lpi.h.
4727  *
4728  * @todo check that the result is in terms of the LP interface definition
4729  */
4731  SCIP_LPI* lpi, /**< LP interface structure */
4732  int c, /**< column number of B^-1; this is NOT the number of the column in the LP;
4733  * you have to call SCIPlpiGetBasisInd() to get the array which links the
4734  * B^-1 column numbers to the row and column numbers of the LP!
4735  * c must be between 0 and nrows-1, since the basis has the size
4736  * nrows * nrows */
4737  SCIP_Real* coef, /**< pointer to store the coefficients of the column */
4738  int* inds, /**< array to store the non-zero indices, or NULL */
4739  int* ninds /**< pointer to store the number of non-zero indices, or NULL
4740  * (-1: if we do not store sparsity information) */
4741  )
4742 {
4743  SVECTOR x;
4744  SVECTOR b;
4745  int* bind;
4746  int nrows;
4747  double val;
4748  int ind;
4749  int status;
4750 
4751  assert(lpi != NULL);
4752  assert(lpi->grbmodel != NULL);
4753  assert(coef != NULL);
4754 
4755  SCIPdebugMessage("getting binv-col %d\n", c);
4756 
4757  /* check whether we have to reoptimize */
4758  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_STATUS, &status) );
4759  if ( status == GRB_LOADED || status == GRB_INTERRUPTED || status == GRB_INPROGRESS )
4760  {
4762  }
4763 
4764  SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
4765 
4766  /* set up solution vector */
4767  x.len = 0;
4768  SCIP_ALLOC( BMSallocMemoryArray(&(x.ind), nrows) );
4769  SCIP_ALLOC( BMSallocMemoryArray(&(x.val), nrows) );
4770 
4771  /* set up rhs */
4772  b.len = 1;
4773  ind = c;
4774  val = 1.0;
4775  b.ind = &ind;
4776  b.val = &val;
4777 
4778  /* solve B x = e_c, which results in the c-th columns of the basis inverse */
4779  CHECK_ZERO( lpi->messagehdlr, GRBFSolve(lpi->grbmodel, &b, &x) );
4780 
4781  /* size should be at most the number of rows */
4782  assert( x.len <= nrows );
4783 
4784  /* get basis indices: entries that correspond to slack variables with coefficient -1 must be negated */
4785  SCIP_ALLOC( BMSallocMemoryArray(&bind, nrows) );
4786  SCIP_CALL( SCIPlpiGetBasisInd(lpi, bind) );
4787 
4788  /* check whether we require a dense or sparse result vector */
4789  if ( ninds != NULL && inds != NULL )
4790  {
4791  int idx;
4792  int i;
4793 
4794  /* copy sparse solution */
4795  for (i = 0; i < x.len; ++i)
4796  {
4797  idx = (x.ind)[i];
4798  assert( idx >= 0 && idx < nrows );
4799  inds[i] = idx;
4800  coef[idx] = (x.val)[i];
4801  if( bind[idx] < 0 )
4802  coef[idx] *= -1.0;
4803  }
4804  *ninds = x.len;
4805  }
4806  else
4807  {
4808  int idx;
4809  int i;
4810 
4811  /* copy solution to dense vector */
4812  BMSclearMemoryArray(coef, nrows);
4813  for (i = 0; i < x.len; ++i)
4814  {
4815  idx = (x.ind)[i];
4816  assert( idx >= 0 && idx < nrows );
4817  coef[idx] = (x.val)[i];
4818  if( bind[idx] < 0 )
4819  coef[idx] *= -1.0;
4820  }
4821  }
4822 
4823  /* free solution space and basis index array */
4824  BMSfreeMemoryArray(&bind);
4825  BMSfreeMemoryArray(&(x.val));
4826  BMSfreeMemoryArray(&(x.ind));
4827 
4828  return SCIP_OKAY;
4829 }
4830 
4831 /** get row of inverse basis matrix times constraint matrix B^-1 * A
4832  *
4833  * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
4834  * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
4835  * see also the explanation in lpi.h.
4836  *
4837  * @todo check that the result is in terms of the LP interface definition
4838  */
4840  SCIP_LPI* lpi, /**< LP interface structure */
4841  int r, /**< row number */
4842  const SCIP_Real* binvrow, /**< row in (A_B)^-1 from prior call to SCIPlpiGetBInvRow(), or NULL */
4843  SCIP_Real* coef, /**< vector to return coefficients of the row */
4844  int* inds, /**< array to store the non-zero indices, or NULL */
4845  int* ninds /**< pointer to store the number of non-zero indices, or NULL
4846  * (-1: if we do not store sparsity information) */
4847  )
4848 { /*lint --e{715}*/
4849  SVECTOR x;
4850  int nrows;
4851  int ncols;
4852  int ngrbcols;
4853  int status;
4854  SCIP_Bool isslackvar;
4855 
4856  assert(lpi != NULL);
4857  assert(lpi->grbmodel != NULL);
4858  assert(coef != NULL);
4859  SCIP_UNUSED( binvrow );
4860 
4861  SCIPdebugMessage("getting binv-row %d\n", r);
4862 
4863  /* check whether we have to reoptimize */
4864  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_STATUS, &status) );
4865  if ( status == GRB_LOADED || status == GRB_INTERRUPTED || status == GRB_INPROGRESS )
4866  {
4868  }
4869 
4870  SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
4871  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
4872  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_NUMVARS, &ngrbcols) );
4873  assert( r >= 0 && r < nrows );
4874 
4875  x.len = 0;
4876  SCIP_ALLOC( BMSallocMemoryArray(&(x.ind), ngrbcols + nrows) );
4877  SCIP_ALLOC( BMSallocMemoryArray(&(x.val), ngrbcols + nrows) );
4878 
4879  /* get basis indices, temporarily using memory of x.ind: if r corresponds to a slack variable with coefficient -1 we
4880  * have to negate all values
4881  */
4882  SCIP_CALL( SCIPlpiGetBasisInd(lpi, x.ind) );
4883  isslackvar = ((x.ind)[r] < 0);
4884 
4885  /* retrieve row */
4886  CHECK_ZERO( lpi->messagehdlr, GRBBinvRowi(lpi->grbmodel, r, &x) );
4887 
4888  /* size should be at most the number of columns plus rows for slack variables */
4889  assert( x.len <= ngrbcols + nrows );
4890 
4891  /* check whether we require a dense or sparse result vector */
4892  if ( ninds != NULL && inds != NULL )
4893  {
4894  int idx;
4895  int k;
4896  int j;
4897 
4898  /* Copy sparse solution: Column indices ngrbcols and larger correspond to slack variables artificially introduced
4899  * by Gurobi; column indices ncols, ncols+1, ..., ngrbcols-1 correspond to slack variables introduced by the LPI
4900  * implementation. Both must simply be ignored.
4901  */
4902  k = 0;
4903  for (j = 0; j < x.len; ++j)
4904  {
4905  idx = (x.ind)[j];
4906  assert( idx >= 0 && idx < ngrbcols+nrows );
4907  if ( idx < ncols )
4908  {
4909  inds[k++] = idx;
4910  coef[idx] = (x.val)[j];
4911  if( isslackvar )
4912  coef[idx] *= -1.0;
4913  }
4914  }
4915  *ninds = k;
4916  }
4917  else
4918  {
4919  int idx;
4920  int j;
4921 
4922  /* Copy dense solution (see comment above). */
4923  BMSclearMemoryArray(coef, ncols);
4924  for (j = 0; j < x.len; ++j)
4925  {
4926  idx = (x.ind)[j];
4927  assert( idx >= 0 && idx < ngrbcols+nrows );
4928  if ( idx < ncols )
4929  {
4930  coef[idx] = (x.val)[j];
4931  if( isslackvar )
4932  coef[idx] *= -1.0;
4933  }
4934  }
4935  }
4936 
4937  /* free solution space */
4938  BMSfreeMemoryArray(&(x.val));
4939  BMSfreeMemoryArray(&(x.ind));
4940 
4941  return SCIP_OKAY;
4942 }
4943 
4944 /** get column of inverse basis matrix times constraint matrix B^-1 * A
4945  *
4946  * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
4947  * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
4948  * see also the explanation in lpi.h.
4949  *
4950  * @todo check that the result is in terms of the LP interface definition
4951  */
4953  SCIP_LPI* lpi, /**< LP interface structure */
4954  int c, /**< column number */
4955  SCIP_Real* coef, /**< vector to return coefficients of the column */
4956  int* inds, /**< array to store the non-zero indices, or NULL */
4957  int* ninds /**< pointer to store the number of non-zero indices, or NULL
4958  * (-1: if we do not store sparsity information) */
4959  )
4960 { /*lint --e{715}*/
4961  SVECTOR x;
4962  int* bind;
4963  int nrows;
4964  int status;
4965 
4966  assert(lpi != NULL);
4967  assert(lpi->grbmodel != NULL);
4968  assert(coef != NULL);
4969 
4970  SCIPdebugMessage("getting binv-col %d\n", c);
4971 
4972  /* check whether we have to reoptimize */
4973  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_STATUS, &status) );
4974  if ( status == GRB_LOADED || status == GRB_INTERRUPTED || status == GRB_INPROGRESS )
4975  {
4977  }
4978 
4979  SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
4980 
4981  x.len = 0;
4982  SCIP_ALLOC( BMSallocMemoryArray(&(x.ind), nrows) );
4983  SCIP_ALLOC( BMSallocMemoryArray(&(x.val), nrows) );
4984 
4985  CHECK_ZERO( lpi->messagehdlr, GRBBinvColj(lpi->grbmodel, c, &x) );
4986 
4987  /* size should be at most the number of rows */
4988  assert( x.len <= nrows );
4989 
4990  /* get basis indices: entries that correspond to slack variables with coefficient -1 must be negated */
4991  SCIP_ALLOC( BMSallocMemoryArray(&bind, nrows) );
4992  SCIP_CALL( SCIPlpiGetBasisInd(lpi, bind) );
4993 
4994  /* check whether we require a dense or sparse result vector */
4995  if ( ninds != NULL && inds != NULL )
4996  {
4997  int idx;
4998  int j;
4999 
5000  /* copy sparse solution */
5001  for (j = 0; j < x.len; ++j)
5002  {
5003  idx = (x.ind)[j];
5004  assert( idx >= 0 && idx < nrows );
5005  inds[j] = idx;
5006  coef[idx] = (x.val)[j];
5007  if( bind[idx] < 0 )
5008  coef[idx] *= -1.0;
5009  }
5010  *ninds = x.len;
5011  }
5012  else
5013  {
5014  int idx;
5015  int j;
5016 
5017  /* copy dense solution */
5018  BMSclearMemoryArray(coef, nrows);
5019  for (j = 0; j < x.len; ++j)
5020  {
5021  idx = (x.ind)[j];
5022  assert( idx >= 0 && idx < nrows );
5023  coef[idx] = (x.val)[j];
5024  if( bind[idx] < 0 )
5025  coef[idx] *= -1.0;
5026  }
5027  }
5028 
5029  /* free solution space and basis index array */
5030  BMSfreeMemoryArray(&bind);
5031  BMSfreeMemoryArray(&(x.val));
5032  BMSfreeMemoryArray(&(x.ind));
5033 
5034  return SCIP_OKAY;
5035 }
5036 
5037 /**@} */
5038 
5039 
5040 
5041 
5042 /*
5043  * LP State Methods
5044  */
5045 
5046 /**@name LP State Methods */
5047 /**@{ */
5048 
5049 /** stores LPi state (like basis information) into lpistate object */
5051  SCIP_LPI* lpi, /**< LP interface structure */
5052  BMS_BLKMEM* blkmem, /**< block memory */
5053  SCIP_LPISTATE** lpistate /**< pointer to LPi state information (like basis information) */
5054  )
5055 {
5056  SCIP_Bool success;
5057  int ncols;
5058  int nrows;
5059 
5060  assert(blkmem != NULL);
5061  assert(lpi != NULL);
5062  assert(lpi->grbmodel != NULL);
5063  assert(lpistate != NULL);
5064 
5065  /* if there is no basis information available, no state can be saved */
5066  if( !lpi->solisbasic )
5067  {
5068  *lpistate = NULL;
5069  return SCIP_OKAY;
5070  }
5071 
5072  SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
5073  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
5074  assert(ncols >= 0);
5075  assert(nrows >= 0);
5076 
5077  /* get unpacked basis information from Gurobi */
5078  SCIP_CALL( getBase(lpi, &success) );
5079 
5080  if ( success )
5081  {
5082  /* allocate lpistate data */
5083  SCIP_CALL( lpistateCreate(lpistate, blkmem, ncols, nrows, lpi->nrngrows) );
5084  (*lpistate)->ncols = ncols;
5085  (*lpistate)->nrows = nrows;
5086  (*lpistate)->nrngrows = lpi->nrngrows;
5087 
5088  SCIPdebugMessage("stored Gurobi LPI state in %p (%d cols, %d rows, %d ranged rows)\n",
5089  (void*) *lpistate, ncols, nrows, lpi->nrngrows);
5090 
5091  /* pack LPi state data */
5092  lpistatePack(*lpistate, lpi->cstat, lpi->rstat);
5093  }
5094  else
5095  {
5096  /* In this case no basis information is available. Since SCIP expects the information to work in any case, we
5097  * allocate the lpistate, but do not use the packed information. This might happen if the model is infeasible,
5098  * since Gurobi currently does not return basis information in this case. */
5099  SCIP_ALLOC( BMSallocBlockMemory(blkmem, lpistate) );
5100  (*lpistate)->ncols = ncols;
5101  (*lpistate)->nrows = nrows;
5102  (*lpistate)->nrngrows = lpi->nrngrows;
5103  (*lpistate)->packrstat = NULL;
5104  (*lpistate)->packcstat = NULL;
5105  }
5106 
5107  return SCIP_OKAY;
5108 }
5109 
5110 /** loads LPi state (like basis information) into solver; note that the LP might have been extended with additional
5111  * columns and rows since the state was stored with SCIPlpiGetState()
5112  */
5114  SCIP_LPI* lpi, /**< LP interface structure */
5115  BMS_BLKMEM* blkmem, /**< block memory */
5116  const SCIP_LPISTATE* lpistate /**< LPi state information (like basis information), or NULL */
5117  )
5118 {
5119  int ncols;
5120  int nrows;
5121  int i;
5122 
5123  assert(blkmem != NULL);
5124  assert(lpi != NULL);
5125  assert(lpi->grbmodel != NULL);
5126 
5127  /* if there was no basis information available, the LPI state was not stored */
5128  if( lpistate == NULL || lpistate->packrstat == NULL || lpistate->packcstat == NULL )
5129  return SCIP_OKAY;
5130 
5131  SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
5132  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
5133  assert(lpistate->ncols <= ncols);
5134  assert(lpistate->nrows <= nrows);
5135  assert(lpistate->nrngrows <= lpi->nrngrows);
5136 
5137  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",
5138  (void*) lpistate, lpistate->ncols, lpistate->nrows, lpistate->nrngrows, ncols, nrows, lpi->nrngrows);
5139 
5140  if( lpistate->ncols == 0 || lpistate->nrows == 0 )
5141  return SCIP_OKAY;
5142 
5143  /* allocate enough memory for storing uncompressed basis information */
5144  SCIP_CALL( ensureCstatMem(lpi, ncols + lpi->nrngrows) );
5145  SCIP_CALL( ensureRstatMem(lpi, nrows) );
5146 
5147  /* unpack LPi state data */
5148  lpistateUnpack(lpistate, lpi->cstat, lpi->rstat);
5149 
5150  if ( lpistate->nrngrows > 0 && lpistate->ncols < ncols )
5151  {
5152  /* New columns have been added: need to move range variable information */
5153  memmove(&lpi->cstat[ncols], &lpi->cstat[lpistate->ncols], (size_t) lpistate->nrngrows * sizeof(*lpi->cstat)); /*lint !e571*/
5154  }
5155 
5156  /* extend the basis to the current LP beyond the previously existing columns */
5157  for( i = lpistate->ncols; i < ncols; ++i )
5158  {
5159  SCIP_Real bnd;
5160  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrelement(lpi->grbmodel, GRB_DBL_ATTR_LB, i, &bnd) );
5161  if ( SCIPlpiIsInfinity(lpi, REALABS(bnd)) )
5162  {
5163  /* if lower bound is +/- infinity -> try upper bound */
5164  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrelement(lpi->grbmodel, GRB_DBL_ATTR_UB, i, &bnd) );
5165  if ( SCIPlpiIsInfinity(lpi, REALABS(bnd)) )
5166  lpi->cstat[i] = (int) SCIP_BASESTAT_ZERO; /* variable is free */
5167  else
5168  lpi->cstat[i] = (int) SCIP_BASESTAT_UPPER; /* use finite upper bound */
5169  }
5170  else
5171  lpi->cstat[i] = (int) SCIP_BASESTAT_LOWER; /* use finite lower bound */
5172  }
5173  for( i = lpistate->nrngrows; i < lpi->nrngrows; ++i )
5174  lpi->cstat[ncols + i] = (int) SCIP_BASESTAT_LOWER;
5175  for( i = lpistate->nrows; i < nrows; ++i )
5176  lpi->rstat[i] = (int) SCIP_BASESTAT_BASIC;
5177 
5178  /* load basis information into Gurobi */
5179  SCIP_CALL( setBase(lpi) );
5180 
5181  return SCIP_OKAY;
5182 }
5183 
5184 /** clears current LPi state (like basis information) of the solver */
5186  SCIP_LPI* lpi /**< LP interface structure */
5187  )
5188 {
5189  assert(lpi != NULL);
5190  assert(lpi->grbmodel != NULL);
5191 
5192  CHECK_ZERO( lpi->messagehdlr, GRBresetmodel(lpi->grbmodel) );
5193 
5194  return SCIP_OKAY;
5195 }
5196 
5197 /** frees LPi state information */
5199  SCIP_LPI* lpi, /**< LP interface structure */
5200  BMS_BLKMEM* blkmem, /**< block memory */
5201  SCIP_LPISTATE** lpistate /**< pointer to LPi state information (like basis information) */
5202  )
5203 {
5204  assert(lpi != NULL);
5205  assert(lpistate != NULL);
5206  assert(blkmem != NULL);
5207 
5208  if( *lpistate != NULL )
5209  lpistateFree(lpistate, blkmem);
5210 
5211  return SCIP_OKAY;
5212 }
5213 
5214 /** checks, whether the given LP state contains simplex basis information */
5216  SCIP_LPI* lpi, /**< LP interface structure */
5217  SCIP_LPISTATE* lpistate /**< LP state information (like basis information), or NULL */
5218  )
5219 { /*lint --e{715}*/
5220  assert(lpi != NULL);
5221  return (lpistate != NULL && lpistate->packcstat != NULL);
5222 }
5223 
5224 /** reads LP state (like basis information from a file */
5226  SCIP_LPI* lpi, /**< LP interface structure */
5227  const char* fname /**< file name */
5228  )
5229 {
5230  size_t l;
5231 
5232  assert(lpi != NULL);
5233  assert(lpi->grbmodel != NULL);
5234  assert(fname != NULL);
5235 
5236  SCIPdebugMessage("reading LP state from file <%s>\n", fname);
5237 
5238  /* gurobi reads a basis if the extension is ".bas" */
5239  l = strlen(fname);
5240  if ( l > 4 && fname[l-4] == '.' && fname[l-3] == 'b' && fname[l-2] == 'a' && fname[l-1] == 's' )
5241  {
5242  CHECK_ZERO( lpi->messagehdlr, GRBread(lpi->grbmodel, fname) );
5243  }
5244  else
5245  {
5246  SCIPerrorMessage("To read a basis with gurobi, the extension has to be '.bas'.\n");
5247  return SCIP_LPERROR;
5248  }
5249 
5250  return SCIP_OKAY;
5251 }
5252 
5253 /** writes LPi state (i.e. basis information) to a file */
5255  SCIP_LPI* lpi, /**< LP interface structure */
5256  const char* fname /**< file name */
5257  )
5258 {
5259  size_t l;
5260 
5261  assert(lpi != NULL);
5262  assert(lpi->grbmodel != NULL);
5263  assert(fname != NULL);
5264 
5265  SCIPdebugMessage("writing basis state to file <%s>\n", fname);
5266 
5267  /* gurobi writes the basis if the extension is ".bas" */
5268  l = strlen(fname);
5269  if ( l > 4 && fname[l-4] == '.' && fname[l-3] == 'b' && fname[l-2] == 'a' && fname[l-1] == 's' )
5270  {
5271  CHECK_ZERO( lpi->messagehdlr, GRBwrite(lpi->grbmodel, fname) );
5272  }
5273  else
5274  {
5275  char name[SCIP_MAXSTRLEN];
5276 
5277  /* force extension to be ".bas" */
5278  if ( strlen(fname) > SCIP_MAXSTRLEN-4)
5279  {
5280  SCIPerrorMessage("Basis file name too long.\n");
5281  return SCIP_LPERROR;
5282  }
5283  (void) snprintf(name, SCIP_MAXSTRLEN, "%s.bas", fname);
5284  CHECK_ZERO( lpi->messagehdlr, GRBwrite(lpi->grbmodel, fname) );
5285  }
5286 
5287  return SCIP_OKAY;
5288 }
5289 
5290 /**@} */
5291 
5292 
5293 
5294 
5295 /*
5296  * LP Pricing Norms Methods
5297  */
5298 
5299 /**@name LP Pricing Norms Methods */
5300 /**@{ */
5301 
5302 /** stores LPi pricing norms information */
5304  SCIP_LPI* lpi, /**< LP interface structure */
5305  BMS_BLKMEM* blkmem, /**< block memory */
5306  SCIP_LPINORMS** lpinorms /**< pointer to LPi pricing norms information */
5307  )
5308 { /*lint --e{715}*/
5309  int hasnorm;
5310  int ncols;
5311  int nrows;
5312 
5313  assert(blkmem != NULL);
5314  assert(lpi != NULL);
5315  assert(lpi->grbmodel != NULL);
5316  assert(lpinorms != NULL);
5317 
5318  *lpinorms = NULL;
5319 
5320  /* if there is no basis information available (e.g. after barrier without crossover), norms cannot be saved */
5321  if( !lpi->solisbasic )
5322  return SCIP_OKAY;
5323 
5324  /* check if dual norms are available:
5325  * value 0: no basis, so no norms available
5326  * value 1: basis exists, so norms can be computed
5327  * value 2: norms are available
5328  */
5329  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_HASDUALNORM, &hasnorm) );
5330  if( hasnorm <= 1 )
5331  return SCIP_OKAY;
5332 
5333  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_NUMVARS, &ncols) );
5334  CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_NUMCONSTRS, &nrows) );
5335 
5336  /* allocate lpinorms data */
5337  SCIP_ALLOC( BMSallocBlockMemory(blkmem, lpinorms) );
5338  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpinorms)->colnorm, ncols) );
5339  SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpinorms)->rownorm, nrows) );
5340  (*lpinorms)->ncols = ncols;
5341  (*lpinorms)->nrows = nrows;
5342 
5343  /* query dual norms from Gurobi */
5344  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_VDUALNORM, 0, ncols, (*lpinorms)->colnorm) );
5345  CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_CDUALNORM, 0, nrows, (*lpinorms)->rownorm) );
5346 
5347  return SCIP_OKAY;
5348 }
5349 
5350 /** loads LPi pricing norms into solver; note that the LP might have been extended with additional
5351  * columns and rows since the state was stored with SCIPlpiGetNorms()
5352  */
5354  SCIP_LPI* lpi, /**< LP interface structure */
5355  BMS_BLKMEM* blkmem, /**< block memory */
5356  const SCIP_LPINORMS* lpinorms /**< LPi pricing norms information, or NULL */
5357  )
5358 { /*lint --e{715}*/
5359  int error;
5360 
5361  assert(blkmem != NULL);
5362  assert(lpi != NULL);
5363 
5364  /* if there was no pricing norms information available, the LPI norms were not stored */
5365  if( lpinorms == NULL )
5366  return SCIP_OKAY;
5367 
5368  /* store dual norms in Gurobi */
5369  error = GRBsetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_VDUALNORM, 0, lpinorms->ncols, lpinorms->colnorm);
5370  /* it can fail to set the norms if no basis was previously set, e.g.,
5371  * this can happen if flushing an LP did not change anything and
5372  * therefore no basis was set, as a result Gurobi has no extra user
5373  * warmstart information and cannot set norms */
5374 #ifdef SCIP_DEBUG
5375  if( error )
5376  SCIPmessagePrintWarning(lpi->messagehdlr, "Warning: setting dual variable norms failed with Gurobi error %d\n", error);
5377 #else
5378  (void)error;
5379 #endif
5380 
5381  error = GRBsetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_CDUALNORM, 0, lpinorms->nrows, lpinorms->rownorm);
5382  /* it can fail to set the norms if no basis was previously set, e.g.,
5383  * this can happen if flushing an LP did not change anything and
5384  * therefore no basis was set, as a result Gurobi has no extra user
5385  * warmstart information and cannot set norms */
5386 #ifdef SCIP_DEBUG
5387  if( error )
5388  SCIPmessagePrintWarning(lpi->messagehdlr, "Warning: setting dual constraint norms failed with Gurobi error %d\n", error);
5389 #else
5390  (void)error;
5391 #endif
5392 
5393  return SCIP_OKAY;
5394 }
5395 
5396 /** frees pricing norms information */
5398  SCIP_LPI* lpi, /**< LP interface structure */
5399  BMS_BLKMEM* blkmem, /**< block memory */
5400  SCIP_LPINORMS** lpinorms /**< pointer to LPi pricing norms information, or NULL */
5401  )
5402 { /*lint --e{715}*/
5403  assert(lpi != NULL);
5404  assert(lpinorms != NULL);
5405 
5406  if ( *lpinorms != NULL )
5407  {
5408  BMSfreeBlockMemoryArray(blkmem, &(*lpinorms)->colnorm, (*lpinorms)->ncols);
5409  BMSfreeBlockMemoryArray(blkmem, &(*lpinorms)->rownorm, (*lpinorms)->nrows);
5410  BMSfreeBlockMemory(blkmem, lpinorms);
5411  }
5412 
5413  return SCIP_OKAY;
5414 }
5415 
5416 /**@} */
5417 
5418 
5419 
5420 
5421 /*
5422  * Parameter Methods
5423  */
5424 
5425 /**@name Parameter Methods */
5426 /**@{ */
5427 
5428 /** gets integer parameter of LP */
5430  SCIP_LPI* lpi, /**< LP interface structure */
5431  SCIP_LPPARAM type, /**< parameter number */
5432  int* ival /**< buffer to store the parameter value */
5433  )
5434 {
5435  int temp;
5436  SCIP_Real dtemp;
5437 
5438  assert(lpi != NULL);
5439  assert(lpi->grbmodel != NULL);
5440  assert(ival != NULL);
5441 
5442  SCIPdebugMessage("getting int parameter %d\n", type);
5443 
5444  switch( type )
5445  {
5447  *ival = (int) lpi->fromscratch;
5448  break;
5449  case SCIP_LPPAR_FASTMIP:
5450  /* maybe set perturbation */
5451  return SCIP_PARAMETERUNKNOWN;
5452  case SCIP_LPPAR_SCALING:
5453  SCIP_CALL( getIntParam(lpi, GRB_INT_PAR_SCALEFLAG, &temp) );
5454  assert(temp >= -1 && temp <= 3);
5455  if( temp == -1 )
5456  *ival = 1;
5457  else
5458  *ival = temp;
5459  break;
5460  case SCIP_LPPAR_PRESOLVING:
5461  SCIP_CALL( getIntParam(lpi, GRB_INT_PAR_PRESOLVE, &temp) );
5462  assert( temp == GRB_PRESOLVE_AUTO || temp == GRB_PRESOLVE_OFF || temp == GRB_PRESOLVE_CONSERVATIVE || temp == GRB_PRESOLVE_AGGRESSIVE );
5463  *ival = (temp == GRB_PRESOLVE_OFF) ? FALSE : TRUE;
5464  break;
5465  case SCIP_LPPAR_PRICING:
5466  *ival = (int) lpi->pricing;
5467  break;
5468  case SCIP_LPPAR_LPINFO:
5469  SCIP_CALL( getIntParam(lpi, GRB_INT_PAR_OUTPUTFLAG, &temp) );
5470  assert( temp == 0 || temp == 1 );
5471  *ival = (temp == 1) ? TRUE : FALSE;
5472  break;
5473  case SCIP_LPPAR_LPITLIM:
5474  SCIP_CALL( getDblParam(lpi, GRB_DBL_PAR_ITERATIONLIMIT, &dtemp) );
5475  assert( dtemp >= 0.0 );
5476  if( dtemp >= INT_MAX )
5477  *ival = INT_MAX;
5478  else
5479  *ival = (int) dtemp;
5480  break;
5481  case SCIP_LPPAR_THREADS:
5482  SCIP_CALL( getIntParam(lpi, GRB_INT_PAR_THREADS, ival) );
5483  break;
5484  case SCIP_LPPAR_RANDOMSEED:
5485  SCIP_CALL( getIntParam(lpi, GRB_INT_PAR_SEED, ival) );
5486  break;
5487  default:
5488  return SCIP_PARAMETERUNKNOWN;
5489  } /*lint !e788*/
5490 
5491  return SCIP_OKAY;
5492 }
5493 
5494 /** sets integer parameter of LP */
5496  SCIP_LPI* lpi, /**< LP interface structure */
5497  SCIP_LPPARAM type, /**< parameter number */
5498  int ival /**< parameter value */
5499  )
5500 {
5501  assert(lpi != NULL);
5502  assert(lpi->grbmodel != NULL);
5503 
5504  SCIPdebugMessage("setting int parameter %d to %d\n", type, ival);
5505 
5506  switch( type )
5507  {
5509  assert(ival == TRUE || ival == FALSE);
5510  lpi->fromscratch = (SCIP_Bool) ival;
5511  break;
5512  case SCIP_LPPAR_FASTMIP:
5513  assert(ival == TRUE || ival == FALSE);
5514  return SCIP_PARAMETERUNKNOWN;
5515  case SCIP_LPPAR_SCALING:
5516  if( ival == 1 )
5517  SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_SCALEFLAG, -1) );
5518  else
5519  SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_SCALEFLAG, ival) );
5520  break;
5521  case SCIP_LPPAR_PRESOLVING:
5522  assert(ival == TRUE || ival == FALSE);
5523  if( ival )
5524  SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_PRESOLVE, GRB_PRESOLVE_AUTO) );
5525  else
5526  SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_PRESOLVE, GRB_PRESOLVE_OFF) );
5527  break;
5528  case SCIP_LPPAR_PRICING:
5529  lpi->pricing = (SCIP_PRICING)ival;
5530  switch( (SCIP_PRICING)ival )
5531  {
5533  case SCIP_PRICING_AUTO:
5534  SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_SIMPLEXPRICING, GRB_SIMPLEXPRICING_AUTO) );
5535  break;
5536  case SCIP_PRICING_FULL:
5537  /* full does not seem to exist -> use auto */
5538  SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_SIMPLEXPRICING, GRB_SIMPLEXPRICING_AUTO) );
5539  break;
5540  case SCIP_PRICING_PARTIAL:
5541  SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_SIMPLEXPRICING, GRB_SIMPLEXPRICING_PARTIAL) );
5542  break;
5543  case SCIP_PRICING_STEEP:
5544  SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_SIMPLEXPRICING, GRB_SIMPLEXPRICING_STEEPEST_EDGE) );
5545  break;
5547  SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_SIMPLEXPRICING, GRB_SIMPLEXPRICING_STEEPEST_QUICK) );
5548  break;
5549  case SCIP_PRICING_DEVEX:
5550  SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_SIMPLEXPRICING, GRB_SIMPLEXPRICING_DEVEX) );
5551  break;
5552  default:
5553  return SCIP_PARAMETERUNKNOWN;
5554  }
5555  break;
5556  case SCIP_LPPAR_LPINFO:
5557  assert(ival == TRUE || ival == FALSE);
5558  if( ival )
5559  SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_OUTPUTFLAG, 1) );
5560  else
5561  SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_OUTPUTFLAG, 0) );
5562  break;
5563  case SCIP_LPPAR_LPITLIM:
5564  assert( ival >= 0 );
5565  /* 0 <= ival, 0 stopping immediately */
5566  {
5567  double itlim;
5568  itlim = (ival >= INT_MAX ? GRB_INFINITY : ival);
5569  SCIP_CALL( setDblParam(lpi, GRB_DBL_PAR_ITERATIONLIMIT, itlim) );
5570  }
5571  break;
5572  case SCIP_LPPAR_THREADS:
5573  assert( ival >= 0 );
5574  SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_THREADS, ival) );
5575  break;
5576  case SCIP_LPPAR_RANDOMSEED:
5577  assert( ival >= 0 );
5578  SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_SEED, ival) );
5579  break;
5580  default:
5581  return SCIP_PARAMETERUNKNOWN;
5582  } /*lint !e788*/
5583 
5584  return SCIP_OKAY;
5585 }
5586 
5587 /** gets floating point parameter of LP */
5589  SCIP_LPI* lpi, /**< LP interface structure */
5590  SCIP_LPPARAM type, /**< parameter number */
5591  SCIP_Real* dval /**< buffer to store the parameter value */
5592  )
5593 {
5594  assert(lpi != NULL);
5595  assert(lpi->grbmodel != NULL);
5596  assert(dval != NULL);
5597 
5598  SCIPdebugMessage("getting real parameter %d\n", type);
5599 
5600  switch( type )
5601  {
5602  case SCIP_LPPAR_FEASTOL:
5603  SCIP_CALL( getDblParam(lpi, GRB_DBL_PAR_FEASIBILITYTOL, dval) );
5604  break;
5606  SCIP_CALL( getDblParam(lpi, GRB_DBL_PAR_OPTIMALITYTOL, dval) );
5607  break;
5609  SCIP_CALL( getDblParam(lpi, GRB_DBL_PAR_BARCONVTOL, dval) );
5610  break;
5611  case SCIP_LPPAR_OBJLIM:
5612  SCIP_CALL( getDblParam(lpi, GRB_DBL_PAR_CUTOFF, dval) );
5613  break;
5614  case SCIP_LPPAR_LPTILIM:
5615  SCIP_CALL( getDblParam(lpi, GRB_DBL_PAR_TIMELIMIT, dval) );
5616  break;
5617  case SCIP_LPPAR_MARKOWITZ:
5618  SCIP_CALL( getDblParam(lpi, GRB_DBL_PAR_MARKOWITZTOL, dval) );
5619  break;
5621  *dval = lpi->conditionlimit;
5622  break;
5623  default:
5624  return SCIP_PARAMETERUNKNOWN;
5625  } /*lint !e788*/
5626 
5627  return SCIP_OKAY;
5628 }
5629 
5630 /** sets floating point parameter of LP */
5632  SCIP_LPI* lpi, /**< LP interface structure */
5633  SCIP_LPPARAM type, /**< parameter number */
5634  SCIP_Real dval /**< parameter value */
5635  )
5636 {
5637  assert(lpi != NULL);
5638  assert(lpi->grbmodel != NULL);
5639 
5640  SCIPdebugMessage("setting real parameter %d to %g\n", type, dval);
5641 
5642  switch( type )
5643  {
5644  case SCIP_LPPAR_FEASTOL:
5645  assert( dval > 0.0 );
5646  /* 1e-9 <= dval <= 1e-2 */
5647  if( dval < 1e-9 )
5648  dval = 1e-9;
5649  else if( dval > 1e-2 )
5650  dval = 1e-2;
5651 
5652  SCIP_CALL( setDblParam(lpi, GRB_DBL_PAR_FEASIBILITYTOL, dval) );
5653  break;
5655  assert( dval > 0.0 );
5656  /* 1e-9 <= dval <= 1e-2 */
5657  if (dval < 1e-9)
5658  dval = 1e-9;
5659  else if( dval > 1e-2 )
5660  dval = 1e-2;
5661 
5662  SCIP_CALL( setDblParam(lpi, GRB_DBL_PAR_OPTIMALITYTOL, dval) );
5663  break;
5665  /* 0 <= dval <= 1 */
5666  assert( dval >= 0.0 );
5667  if( dval > 1.0 )
5668  dval = 1.0;
5669 
5670  SCIP_CALL( setDblParam(lpi, GRB_DBL_PAR_BARCONVTOL, dval) );
5671  break;
5672  case SCIP_LPPAR_OBJLIM:
5673  /* no restriction on dval */
5674 
5675  SCIP_CALL( setDblParam(lpi, GRB_DBL_PAR_CUTOFF, dval) );
5676  break;
5677  case SCIP_LPPAR_LPTILIM:
5678  assert( dval > 0.0 );
5679  /* gurobi requires 0 <= dval
5680  *
5681  * However for consistency we assert the timelimit to be strictly positive.
5682  */
5683 
5684  SCIP_CALL( setDblParam(lpi, GRB_DBL_PAR_TIMELIMIT, dval) );
5685  break;
5686  case SCIP_LPPAR_MARKOWITZ:
5687  /* 1e-4 <= dval <= 0.999 */
5688  if( dval < 1e-4 )
5689  dval = 1e-4;
5690  else if( dval > 0.999 )
5691  dval = 0.999;
5692 
5693  SCIP_CALL( setDblParam(lpi, GRB_DBL_PAR_MARKOWITZTOL, dval) );
5694  break;
5696  lpi->conditionlimit = dval;
5697  lpi->checkcondition = (dval >= 0.0) ? TRUE : FALSE;
5698  break;
5699  default:
5700  return SCIP_PARAMETERUNKNOWN;
5701  } /*lint !e788*/
5702 
5703  return SCIP_OKAY;
5704 }
5705 
5706 /**@} */
5707 
5708 
5709 
5710 
5711 /*
5712  * Numerical Methods
5713  */
5714 
5715 /**@name Numerical Methods */
5716 /**@{ */
5717 
5718 /** returns value treated as infinity in the LP solver */
5720  SCIP_LPI* lpi /**< LP interface structure */
5721  )
5722 { /*lint --e{715}*/
5723  assert(lpi != NULL);
5724  return GRB_INFINITY;
5725 }
5726 
5727 /** checks if given value is treated as infinity in the LP solver */
5729  SCIP_LPI* lpi, /**< LP interface structure */
5730  SCIP_Real val /**< value to be checked for infinity */
5731  )
5732 { /*lint --e{715}*/
5733  assert(lpi != NULL);
5734  return (val >= GRB_INFINITY);
5735 }
5736 
5737 /**@} */
5738 
5739 
5740 
5741 
5742 /*
5743  * File Interface Methods
5744  */
5745 
5746 /**@name File Interface Methods */
5747 /**@{ */
5748 
5749 /** reads LP from a file */
5751  SCIP_LPI* lpi, /**< LP interface structure */
5752  const char* fname /**< file name */
5753  )
5754 {
5755  assert(lpi != NULL);
5756  assert(lpi->grbmodel != NULL);
5757  assert(fname != NULL);
5758 
5759  SCIPdebugMessage("reading LP from file <%s>\n", fname);
5760 
5761  CHECK_ZERO( lpi->messagehdlr, GRBreadmodel(lpi->grbenv, fname, &lpi->grbmodel) );
5762 
5763  /* the model name seems to be empty, use filename */
5764  CHECK_ZERO( lpi->messagehdlr, GRBsetstrattr(lpi->grbmodel, GRB_STR_ATTR_MODELNAME, fname) );
5765 
5766  return SCIP_OKAY;
5767 }
5768 
5769 /** writes LP to a file */
5771  SCIP_LPI* lpi, /**< LP interface structure */
5772  const char* fname /**< file name */
5773  )
5774 {
5775  assert(lpi != NULL);
5776  assert(lpi->grbmodel != NULL);
5777  assert(fname != NULL);
5778 
5779  SCIPdebugMessage("writing LP to file <%s>\n", fname);
5780 
5781  /* if range rows were not added, add, print and remove them; otherwise, just print */
5782  if ( lpi->nrngrows > 0 && !lpi->rngvarsadded )
5783  {
5784  SCIP_CALL( addRangeVars(lpi) );
5785  CHECK_ZERO( lpi->messagehdlr, GRBwrite(lpi->grbmodel, fname) );
5786  SCIP_CALL( delRangeVars(lpi) );
5787  }
5788  else
5789  {
5790  CHECK_ZERO( lpi->messagehdlr, GRBwrite(lpi->grbmodel, fname) );
5791  }
5792 
5793  return SCIP_OKAY;
5794 }
5795 
5796 /**@} */
SCIP_RETCODE SCIPlpiCreate(SCIP_LPI **lpi, SCIP_MESSAGEHDLR *messagehdlr, const char *name, SCIP_OBJSEN objsen)
Definition: lpi_grb.c:1307
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:5495
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:3475
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:5719
#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:5429
SCIP_RETCODE SCIPlpiSetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, const SCIP_LPINORMS *lpinorms)
Definition: lpi_grb.c:5353
SCIP_RETCODE SCIPlpiGetDualfarkas(SCIP_LPI *lpi, SCIP_Real *dualfarkas)
Definition: lpi_grb.c:4216
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:2210
ROWPACKET * packrstat
Definition: lpi_clp.cpp:128
struct GRBParam GRBPARAM
Definition: lpi_grb.c:123
int * rngrowmap
Definition: lpi_grb.c:154
SCIP_PRICING pricing
Definition: lpi_clp.cpp:103
double dblparval[NUMDBLPARAM]
Definition: lpi_cpx.c:129
double * colnorm
Definition: lpi_grb.c:179
#define SCIP_MAXSTRLEN
Definition: def.h:279
SCIP_RETCODE SCIPlpiGetBase(SCIP_LPI *lpi, int *cstat, int *rstat)
Definition: lpi_grb.c:4313
SCIP_RETCODE SCIPlpiGetObj(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *vals)
Definition: lpi_grb.c:2682
int sidechgsize
Definition: lpi_cpx.c:153
static const char * dblparam[NUMDBLPARAM]
Definition: lpi_grb.c:94
static SCIP_RETCODE getBase(SCIP_LPI *lpi, SCIP_Bool *success)
Definition: lpi_grb.c:335
enum SCIP_ObjSen SCIP_OBJSEN
Definition: type_lpi.h:36
void * SCIPlpiGetSolverPointer(SCIP_LPI *lpi)
Definition: lpi_grb.c:1248
SCIP_Bool SCIPlpiHasStateBasis(SCIP_LPI *lpi, SCIP_LPISTATE *lpistate)
Definition: lpi_grb.c:5215
SCIP_Bool SCIPlpiHasPrimalRay(SCIP_LPI *lpi)
Definition: lpi_grb.c:3646
static SCIP_RETCODE ensureRngrowmapMem(SCIP_LPI *lpi, int num)
Definition: lpi_grb.c:287
interface methods for specific LP solvers
SCIP_RETCODE SCIPlpiSolveBarrier(SCIP_LPI *lpi, SCIP_Bool crossover)
Definition: lpi_grb.c:3126
SCIP_RETCODE SCIPlpiAddRows(SCIP_LPI *lpi, int nrows, const SCIP_Real *lhs, const SCIP_Real *rhs, char **rownames, int nnonz, const int *beg, const int *ind, const SCIP_Real *val)
Definition: lpi_grb.c:1704
SCIP_Bool SCIPlpiIsInfinity(SCIP_LPI *lpi, SCIP_Real val)
Definition: lpi_grb.c:5728
#define FALSE
Definition: def.h:73
SCIP_Bool SCIPlpiHasPrimalSolve(void)
Definition: lpi_grb.c:1271
static void lpistateFree(SCIP_LPISTATE **lpistate, BMS_BLKMEM *blkmem)
Definition: lpi_grb.c:648
SCIP_Bool SCIPlpiIsPrimalInfeasible(SCIP_LPI *lpi)
Definition: lpi_grb.c:3695
#define TRUE
Definition: def.h:72
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:54
SCIP_RETCODE SCIPlpiGetBInvACol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_grb.c:4952
SCIP_RETCODE SCIPlpiStartStrongbranch(SCIP_LPI *lpi)
Definition: lpi_grb.c:3245
int rstatsize
Definition: lpi_clp.cpp:101
int nrngrows
Definition: lpi_grb.c:169
SCIP_Bool checkcondition
Definition: lpi_cpx.c:165
int valsize
Definition: lpi_cpx.c:154
SCIP_RETCODE SCIPlpiGetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition: lpi_grb.c:5303
static void lpistatePack(SCIP_LPISTATE *lpistate, const int *cstat, const int *rstat)
Definition: lpi_grb.c:594
SCIP_Real * rhsarray
Definition: lpi_cpx.c:145
#define SCIP_UNUSED(x)
Definition: def.h:424
enum SCIP_LPParam SCIP_LPPARAM
Definition: type_lpi.h:64
int * rngidxarray
Definition: lpi_grb.c:138
static SCIP_RETCODE setDblParam(SCIP_LPI *lpi, const char *param, double parval)
Definition: lpi_grb.c:848
#define BMSallocMemoryArray(ptr, num)
Definition: memory.h:115
SCIP_Bool SCIPlpiIsObjlimExc(SCIP_LPI *lpi)
Definition: lpi_grb.c:3973
SCIP_RETCODE SCIPlpiDelRows(SCIP_LPI *lpi, int firstrow, int lastrow)
Definition: lpi_grb.c:1783
#define SCIPdebugMessage
Definition: pub_message.h:87
static GRBenv * grbenv
Definition: lpi_grb.c:184
GRBmodel * grbmodel
Definition: lpi_grb.c:129
SCIP_RETCODE SCIPlpiGetCoef(SCIP_LPI *lpi, int row, int col, SCIP_Real *val)
Definition: lpi_grb.c:2763
#define BMSfreeMemory(ptr)
Definition: memory.h:137
enum SCIP_Pricing SCIP_PRICING
Definition: type_lpi.h:77
#define GRB_REFACTORMAXITERS
Definition: lpi_grb.c:75
SCIP_VAR ** x
Definition: circlepacking.c:54
static SCIP_RETCODE delRangeVars(SCIP_LPI *lpi)
Definition: lpi_grb.c:1109
real eps
SCIP_RETCODE SCIPlpiGetBInvCol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_grb.c:4730
SCIP_Bool SCIPlpiIsIterlimExc(SCIP_LPI *lpi)
Definition: lpi_grb.c:3985
static SCIP_RETCODE setIntParam(SCIP_LPI *lpi, const char *param, int parval)
Definition: lpi_grb.c:798
static const char * intparam[NUMINTPARAM]
Definition: lpi_grb.c:81
SCIP_DUALPACKET COLPACKET
Definition: lpi_clp.cpp:117
#define GRB_INFBOUND
Definition: lpi_grb.c:49
SCIP_RETCODE SCIPlpiLoadColLP(SCIP_LPI *lpi, SCIP_OBJSEN objsen, int ncols, const SCIP_Real *obj, const SCIP_Real *lb, const SCIP_Real *ub, char **colnames, int nrows, const SCIP_Real *lhs, const SCIP_Real *rhs, char **rownames, int nnonz, const int *beg, const int *ind, const SCIP_Real *val)
Definition: lpi_grb.c:1442
#define SVECTOR
Definition: lpi_grb.c:60
#define SCIP_DUALPACKETSIZE
Definition: lpi_grb.c:64
SCIP_Bool SCIPlpiIsDualUnbounded(SCIP_LPI *lpi)
Definition: lpi_grb.c:3809
SCIP_RETCODE SCIPlpiScaleCol(SCIP_LPI *lpi, int col, SCIP_Real scaleval)
Definition: lpi_grb.c:2339
int rngrowmapsize
Definition: lpi_grb.c:158
SCIP_RETCODE SCIPlpiReadState(SCIP_LPI *lpi, const char *fname)
Definition: lpi_grb.c:5225
SCIP_RETCODE SCIPlpiStrongbranchFrac(SCIP_LPI *lpi, int col, SCIP_Real psol, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, int *iter)
Definition: lpi_grb.c:3452
SCIP_RETCODE SCIPlpiGetNRows(SCIP_LPI *lpi, int *nrows)
Definition: lpi_grb.c:2416
static SCIP_RETCODE getIntParam(SCIP_LPI *lpi, const char *param, int *p)
Definition: lpi_grb.c:773
#define BMSfreeMemoryArray(ptr)
Definition: memory.h:139
SCIP_RETCODE SCIPlpiGetSolFeasibility(SCIP_LPI *lpi, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
Definition: lpi_grb.c:3608
#define SCIPerrorMessage
Definition: pub_message.h:55
static SCIP_RETCODE ensureCstatMem(SCIP_LPI *lpi, int num)
Definition: lpi_grb.c:243
#define SCIPdebugPrintf
Definition: pub_message.h:90
char * senarray
Definition: lpi_cpx.c:144
SCIP_RETCODE SCIPlpiEndStrongbranch(SCIP_LPI *lpi)
Definition: lpi_grb.c:3258
SCIP_Bool SCIPlpiIsTimelimExc(SCIP_LPI *lpi)
Definition: lpi_grb.c:3997
SCIP_RETCODE SCIPlpiSetBase(SCIP_LPI *lpi, const int *cstat, const int *rstat)
Definition: lpi_grb.c:4441
SCIP_RETCODE SCIPlpiWriteLP(SCIP_LPI *lpi, const char *fname)
Definition: lpi_grb.c:5770
SCIP_RETCODE SCIPlpiDelColset(SCIP_LPI *lpi, int *dstat)
Definition: lpi_grb.c:1649
SCIP_RETCODE SCIPlpiGetRowNames(SCIP_LPI *lpi, int firstrow, int lastrow, char **rownames, char *namestorage, int namestoragesize, int *storageleft)
Definition: lpi_grb.c:2638
SCIP_RETCODE SCIPlpiSetIntegralityInformation(SCIP_LPI *lpi, int ncols, int *intInfo)
Definition: lpi_grb.c:1256
SCIP_Bool SCIPlpiExistsDualRay(SCIP_LPI *lpi)
Definition: lpi_grb.c:3772
static void checkRangeInfo(SCIP_LPI *lpi)
Definition: lpi_grb.c:1036
static SCIP_RETCODE pricing(SCIP *scip, SCIP_PRICER *pricer, SCIP_Real *lowerbound, SCIP_Bool farkas)
Definition: pricer_stp.c:176
SCIP_RETCODE SCIPlpiChgObjsen(SCIP_LPI *lpi, SCIP_OBJSEN objsen)
Definition: lpi_grb.c:2231
SCIP_RETCODE SCIPlpiGetObjval(SCIP_LPI *lpi, SCIP_Real *objval)
Definition: lpi_grb.c:4038
SCIP_DUALPACKET ROWPACKET
Definition: lpi_clp.cpp:119
static SCIP_RETCODE reconvertSides(SCIP_LPI *lpi, int firstrow, int lastrow, SCIP_Real *lhs, SCIP_Real *rhs)
Definition: lpi_grb.c:941
static SCIP_RETCODE presolve(SCIP *scip, SCIP_Bool *unbounded, SCIP_Bool *infeasible, SCIP_Bool *vanished)
Definition: scip_solve.c:1248
static SCIP_RETCODE convertSides(SCIP_LPI *lpi, int nrows, const SCIP_Real *lhs, const SCIP_Real *rhs, int *rngcount)
Definition: lpi_grb.c:883
SCIP_Bool SCIPlpiHasDualSolve(void)
Definition: lpi_grb.c:1279
SCIP_RETCODE SCIPlpiIgnoreInstability(SCIP_LPI *lpi, SCIP_Bool *success)
Definition: lpi_grb.c:4020
void SCIPmessagePrintWarning(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
Definition: message.c:418
SCIP_RETCODE SCIPlpiDelCols(SCIP_LPI *lpi, int firstcol, int lastcol)
Definition: lpi_grb.c:1606
SCIP_RETCODE SCIPlpiClearState(SCIP_LPI *lpi)
Definition: lpi_grb.c:5185
#define NULL
Definition: lpi_spx1.cpp:155
double * rownorm
Definition: lpi_grb.c:180
int * rstat
Definition: lpi_clp.cpp:99
#define REALABS(x)
Definition: def.h:187
SCIP_RETCODE SCIPlpiGetSides(SCIP_LPI *lpi, int firstrow, int lastrow, SCIP_Real *lhss, SCIP_Real *rhss)
Definition: lpi_grb.c:2736
int cstatsize
Definition: lpi_clp.cpp:100
#define SCIP_CALL(x)
Definition: def.h:370
SCIP_Bool fromscratch
Definition: lpi_cpx.c:161
SCIP_RETCODE SCIPlpiChgSides(SCIP_LPI *lpi, int nrows, const int *ind, const SCIP_Real *lhs, const SCIP_Real *rhs)
Definition: lpi_grb.c:2074
GRBPARAM defparam
Definition: lpi_grb.c:132
SCIP_RETCODE SCIPlpiStrongbranchesInt(SCIP_LPI *lpi, int *cols, int ncols, SCIP_Real *psols, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, int *iter)
Definition: lpi_grb.c:3538
SCIP_RETCODE SCIPlpiAddCols(SCIP_LPI *lpi, int ncols, const SCIP_Real *obj, const SCIP_Real *lb, const SCIP_Real *ub, char **colnames, int nnonz, const int *beg, const int *ind, const SCIP_Real *val)
Definition: lpi_grb.c:1543
SCIP_RETCODE SCIPlpiFreeNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition: lpi_grb.c:5397
SCIP_Bool SCIPlpiIsDualFeasible(SCIP_LPI *lpi)
Definition: lpi_grb.c:3848
#define COLS_PER_PACKET
Definition: lpi_grb.c:67
SCIP_RETCODE SCIPlpiChgBounds(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *lb, const SCIP_Real *ub)
Definition: lpi_grb.c:2027
#define EPSCEIL(x, eps)
Definition: def.h:197
int * indarray
Definition: lpi_cpx.c:151
static SCIP_RETCODE ensureRstatMem(SCIP_LPI *lpi, int num)
Definition: lpi_grb.c:265
COLPACKET * packcstat
Definition: lpi_clp.cpp:127
#define BMSfreeBlockMemory(mem, ptr)
Definition: memory.h:456
static void SCIPencodeDualBitNeg(const int *inp, SCIP_DUALPACKET *out, int count)
Definition: lpi_grb.c:447
unsigned int SCIP_DUALPACKET
Definition: bitencode.h:33
SCIP_RETCODE SCIPlpiGetBInvARow(SCIP_LPI *lpi, int r, const SCIP_Real *binvrow, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_grb.c:4839
SCIP_RETCODE SCIPlpiScaleRow(SCIP_LPI *lpi, int row, SCIP_Real scaleval)
Definition: lpi_grb.c:2280
static SCIP_RETCODE checkParameterValues(SCIP_LPI *lpi)
Definition: lpi_grb.c:697
int solstat
Definition: lpi_cpx.c:140
#define SCIP_Bool
Definition: def.h:70
SCIP_RETCODE SCIPlpiSolvePrimal(SCIP_LPI *lpi)
Definition: lpi_grb.c:2797
static SCIP_RETCODE setBase(SCIP_LPI *lpi)
Definition: lpi_grb.c:393
#define BMSallocBlockMemoryArray(mem, ptr, num)
Definition: memory.h:445
const char * SCIPlpiGetSolverDesc(void)
Definition: lpi_grb.c:1237
GRBPARAM curparam
Definition: lpi_grb.c:133
#define BMSfreeBlockMemoryArray(mem, ptr, num)
Definition: memory.h:458
SCIP_RETCODE SCIPlpiSetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real dval)
Definition: lpi_grb.c:5631
#define MAX(x, y)
Definition: tclique_def.h:83
static SCIP_RETCODE addRangeInfo(SCIP_LPI *lpi, int rngcount, int firstrow)
Definition: lpi_grb.c:1156
SCIP_EXPORT void SCIPsortIntReal(int *intarray, SCIP_Real *realarray, int len)
SCIP_RETCODE SCIPlpiGetNCols(SCIP_LPI *lpi, int *ncols)
Definition: lpi_grb.c:2433
SCIP_RETCODE SCIPlpiGetBounds(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *lbs, SCIP_Real *ubs)
Definition: lpi_grb.c:2702
static SCIP_RETCODE ensureValMem(SCIP_LPI *lpi, int num)
Definition: lpi_grb.c:220
SCIP_RETCODE SCIPlpiGetCols(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *lb, SCIP_Real *ub, int *nnonz, int *beg, int *ind, SCIP_Real *val)
Definition: lpi_grb.c:2478
SCIP_RETCODE SCIPlpiGetRows(SCIP_LPI *lpi, int firstrow, int lastrow, SCIP_Real *lhs, SCIP_Real *rhs, int *nnonz, int *beg, int *ind, SCIP_Real *val)
Definition: lpi_grb.c:2523
SCIP_RETCODE SCIPlpiChgObj(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *obj)
Definition: lpi_grb.c:2257
SCIP_Bool SCIPlpiIsStable(SCIP_LPI *lpi)
Definition: lpi_grb.c:3893
SCIP_RETCODE SCIPlpiGetBasisInd(SCIP_LPI *lpi, int *bind)
Definition: lpi_grb.c:4562
int iterations
Definition: lpi_cpx.c:157
SCIP_RETCODE SCIPlpiGetColNames(SCIP_LPI *lpi, int firstcol, int lastcol, char **colnames, char *namestorage, int namestoragesize, int *storageleft)
Definition: lpi_grb.c:2616
SCIP_Real * rngarray
Definition: lpi_cpx.c:146
#define NUMDBLPARAM
Definition: lpi_grb.c:92
int SCIPlpiGetInternalStatus(SCIP_LPI *lpi)
Definition: lpi_grb.c:4009
#define BMSallocClearMemoryArray(ptr, num)
Definition: memory.h:117
static SCIP_RETCODE lpiStrongbranch(SCIP_LPI *lpi, int col, SCIP_Real psol, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, int *iter)
Definition: lpi_grb.c:3272
#define SCIP_CALL_QUIET(x)
Definition: def.h:345
SCIP_Real * r
Definition: circlepacking.c:50
methods for sorting joint arrays of various types
SCIP_Bool SCIPlpiHasDualRay(SCIP_LPI *lpi)
Definition: lpi_grb.c:3786
SCIP_VAR ** b
Definition: circlepacking.c:56
SCIP_DUALPACKET ROWPACKET
Definition: lpi_grb.c:68
SCIP_Bool SCIPlpiIsPrimalUnbounded(SCIP_LPI *lpi)
Definition: lpi_grb.c:3669
SCIP_RETCODE SCIPlpiGetSol(SCIP_LPI *lpi, SCIP_Real *objval, SCIP_Real *primsol, SCIP_Real *dualsol, SCIP_Real *activity, SCIP_Real *redcost)
Definition: lpi_grb.c:4103
SCIP_RETCODE SCIPlpiGetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lpi_grb.c:5050
SCIP_Real * valarray
Definition: lpi_cpx.c:147
SCIP_Bool SCIPlpiIsPrimalFeasible(SCIP_LPI *lpi)
Definition: lpi_grb.c:3710
int nrngrows
Definition: lpi_grb.c:159
static SCIP_RETCODE getParameterValues(SCIP_LPI *lpi, GRBPARAM *grbparam)
Definition: lpi_grb.c:670
SCIP_Bool SCIPlpiIsOptimal(SCIP_LPI *lpi)
Definition: lpi_grb.c:3875
int * rngrows
Definition: lpi_grb.c:156
static int colpacketNum(int ncols)
Definition: lpi_grb.c:426
static const double dblparammin[NUMDBLPARAM]
Definition: lpi_grb.c:106
SCIP_RETCODE SCIPlpiFree(SCIP_LPI **lpi)
Definition: lpi_grb.c:1391
SCIP_RETCODE SCIPlpiSetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, const SCIP_LPISTATE *lpistate)
Definition: lpi_grb.c:5113
static void copyParameterValues(GRBPARAM *dest, const GRBPARAM *source)
Definition: lpi_grb.c:758
static SCIP_RETCODE lpistateCreate(SCIP_LPISTATE **lpistate, BMS_BLKMEM *blkmem, int ncols, int nrows, int nrngrows)
Definition: lpi_grb.c:626
public methods for message output
SCIP_RETCODE SCIPlpiGetNNonz(SCIP_LPI *lpi, int *nnonz)
Definition: lpi_grb.c:2454
static int rowpacketNum(int nrows)
Definition: lpi_grb.c:435
static void clearRangeInfo(SCIP_LPI *lpi)
Definition: lpi_grb.c:1139
#define SCIP_Real
Definition: def.h:163
SCIP_Bool SCIPlpiWasSolved(SCIP_LPI *lpi)
Definition: lpi_grb.c:3589
#define BMSallocMemory(ptr)
Definition: memory.h:111
#define SCIP_INVALID
Definition: def.h:183
#define BMSreallocMemoryArray(ptr, num)
Definition: memory.h:119
SCIP_RETCODE SCIPlpiClear(SCIP_LPI *lpi)
Definition: lpi_grb.c:1984
SCIP_RETCODE SCIPlpiStrongbranchInt(SCIP_LPI *lpi, int col, SCIP_Real psol, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, int *iter)
Definition: lpi_grb.c:3515
static int numlp
Definition: lpi_grb.c:185
SCIP_Bool SCIPlpiExistsPrimalRay(SCIP_LPI *lpi)
Definition: lpi_grb.c:3632
int intparval[NUMINTPARAM]
Definition: lpi_cpx.c:128
SCIP_MESSAGEHDLR * messagehdlr
Definition: lpi_cpx.c:175
SCIP_RETCODE SCIPlpiGetBInvRow(SCIP_LPI *lpi, int r, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_grb.c:4632
SCIP_RETCODE SCIPlpiSolveDual(SCIP_LPI *lpi)
Definition: lpi_grb.c:2987
SCIP_RETCODE SCIPlpiFreeState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lpi_grb.c:5198
static SCIP_RETCODE ensureSidechgMem(SCIP_LPI *lpi, int num)
Definition: lpi_grb.c:195
static SCIP_RETCODE ensureRngrowsMem(SCIP_LPI *lpi, int num)
Definition: lpi_grb.c:312
SCIP_RETCODE SCIPlpiGetIterations(SCIP_LPI *lpi, int *iterations)
Definition: lpi_grb.c:4244
SCIP_Bool SCIPlpiIsDualInfeasible(SCIP_LPI *lpi)
Definition: lpi_grb.c:3834
#define BMSallocBlockMemory(mem, ptr)
Definition: memory.h:443
SCIP_RETCODE SCIPlpiGetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real *dval)
Definition: lpi_grb.c:5588
#define EPSFLOOR(x, eps)
Definition: def.h:196
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:122
#define ROWS_PER_PACKET
Definition: lpi_grb.c:69
struct BMS_BlkMem BMS_BLKMEM
Definition: memory.h:429
#define CHECK_ZERO(messagehdlr, x)
Definition: lpi_grb.c:51
#define SCIP_CALL_ABORT(x)
Definition: def.h:349
SCIP_RETCODE SCIPlpiDelRowset(SCIP_LPI *lpi, int *dstat)
Definition: lpi_grb.c:1882
#define SCIP_ALLOC(x)
Definition: def.h:381
SCIP_CPXPARAM curparam
Definition: lpi_cpx.c:138
#define SCIPABORT()
Definition: def.h:342
SCIP_RETCODE SCIPlpiGetPrimalRay(SCIP_LPI *lpi, SCIP_Real *ray)
Definition: lpi_grb.c:4193
SCIP_RETCODE SCIPlpiReadLP(SCIP_LPI *lpi, const char *fname)
Definition: lpi_grb.c:5750
static void SCIPdecodeDualBitNeg(const SCIP_DUALPACKET *inp, int *out, int count)
Definition: lpi_grb.c:518
int * cstat
Definition: lpi_clp.cpp:98
SCIP_RETCODE SCIPlpiGetRealSolQuality(SCIP_LPI *lpi, SCIP_LPSOLQUALITY qualityindicator, SCIP_Real *quality)
Definition: lpi_grb.c:4263
SCIP_Real * rngvals
Definition: lpi_grb.c:157
SCIP_Bool rngvarsadded
Definition: lpi_grb.c:161
static void invalidateSolution(SCIP_LPI *lpi)
Definition: lpi_grb.c:873
SCIP_RETCODE SCIPlpiWriteState(SCIP_LPI *lpi, const char *fname)
Definition: lpi_grb.c:5254
SCIP_Bool SCIPlpiHasBarrierSolve(void)
Definition: lpi_grb.c:1287
SCIP_RETCODE SCIPlpiGetObjsen(SCIP_LPI *lpi, SCIP_OBJSEN *objsen)
Definition: lpi_grb.c:2660