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