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