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