Scippy

SCIP

Solving Constraint Integer Programs

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