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
92typedef 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
95typedef SCIP_DUALPACKET COLPACKET; /**< each column needs two bits of information (basic/on_lower/on_upper) */
96#define COLS_PER_PACKET SCIP_DUALPACKETSIZE
97typedef 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
110static 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
123static 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 */
135static 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 */
147struct GRBParam
148{
149 int intparval[NUMINTPARAM]; /**< integer parameter values */
150 double dblparval[NUMDBLPARAM]; /**< double parameter values */
151};
152typedef struct GRBParam GRBPARAM;
153
154
155/** LP interface */
156struct 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 */
198struct 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 */
208struct 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 */
223static
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) );
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 */
248static
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 */
271static
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 */
293static
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 */
315static
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 */
340static
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 */
363static
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 */
421static
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 */
454static
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 */
463static
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 */
475static
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 */
546static
548 const SCIP_DUALPACKET* inp, /**< packed input vector */
549 int* out, /**< buffer to store unpacked vector */
550 int count /**< number of elements */
551 )
552{
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 */
622static
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 */
638static
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 */
654static
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 */
676static
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 */
698static
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 */
725static
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 */
745static
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 */
786static
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 */
801static
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 */
826static
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 */
851static
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 */
876static
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 */
901static
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 */
911static
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 */
969static
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 */
1032static
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 */
1064static
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 */
1106static
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 */
1137static
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 */
1167static
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 */
1184static
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
1246static 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', '\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#if GRB_VERSION_MAJOR < 8
2920 CHECK_ZERO( lpi->messagehdlr, GRBresetmodel(lpi->grbmodel) );
2921#else
2922 CHECK_ZERO( lpi->messagehdlr, GRBreset(lpi->grbmodel, 1) );
2923#endif
2924 }
2925
2926 SCIPdebugMessage("calling GRBoptimize() - primal\n");
2927
2928 /* set primal simplex */
2929 SCIP_CALL( setParameterValues(lpi, &(lpi->grbparam)) );
2930 CHECK_ZERO( lpi->messagehdlr, GRBsetintparam(lpi->grbenv, GRB_INT_PAR_METHOD, GRB_METHOD_PRIMAL) );
2931
2932 /* add range variables */
2933 if ( lpi->nrngrows > 0 && !lpi->rngvarsadded )
2934 {
2935 SCIP_CALL( addRangeVars(lpi) );
2936 }
2937
2938 retval = GRBoptimize(lpi->grbmodel);
2939 switch( retval )
2940 {
2941 case 0:
2942 break;
2943 case GRB_ERROR_OUT_OF_MEMORY:
2944 return SCIP_NOMEMORY;
2945 default:
2946 return SCIP_LPERROR;
2947 }
2948
2949 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_ITERCOUNT, &cnt) );
2950 lpi->iterations = (int) cnt;
2951
2952 lpi->solisbasic = TRUE;
2953 CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_STATUS, &lpi->solstat) );
2954
2955 SCIPdebugMessage("Gurobi primal simplex needed %d iterations to gain LP status %d\n", (int) cnt, lpi->solstat);
2956
2957 /* maybe the preprocessor solved the problem; but we need a solution, so solve again without preprocessing */
2958 assert( lpi->solstat != GRB_INF_OR_UNBD );
2959 if( lpi->solstat == GRB_INFEASIBLE )
2960 {
2961 int presolve;
2962
2963 CHECK_ZERO( lpi->messagehdlr, GRBgetintparam(lpi->grbenv, GRB_INT_PAR_PRESOLVE, &presolve) );
2964
2965 if( presolve != GRB_PRESOLVE_OFF )
2966 {
2967 SCIPdebugMessage("presolver may have solved the problem -> calling Gurobi primal simplex again without presolve\n");
2968
2969 /* switch off preprocessing */
2970 CHECK_ZERO( lpi->messagehdlr, GRBsetintparam(lpi->grbenv, GRB_INT_PAR_PRESOLVE, GRB_PRESOLVE_OFF) );
2971
2972 retval = GRBoptimize(lpi->grbmodel);
2973 switch( retval )
2974 {
2975 case 0:
2976 break;
2977 case GRB_ERROR_OUT_OF_MEMORY:
2978 return SCIP_NOMEMORY;
2979 default:
2980 return SCIP_LPERROR;
2981 }
2982
2983 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_ITERCOUNT, &cnt) );
2984 lpi->iterations += (int) cnt;
2985 CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_STATUS, &lpi->solstat) );
2986 SCIPdebugMessage(" -> Gurobi returned solstat=%d (%d iterations)\n", lpi->solstat, lpi->iterations);
2987
2988 /* reset parameters */
2989 CHECK_ZERO( lpi->messagehdlr, GRBsetintparam(lpi->grbenv, GRB_INT_PAR_PRESOLVE, presolve) );
2990 }
2991
2992 if( lpi->solstat == GRB_INF_OR_UNBD )
2993 {
2994 /* preprocessing was not the problem; issue a warning message and treat LP as infeasible */
2995 SCIPerrorMessage("Gurobi primal simplex returned GRB_INF_OR_UNBD after presolving was turned off\n");
2996 return SCIP_LPERROR;
2997 }
2998 }
2999 else if ( lpi->solstat == GRB_UNBOUNDED )
3000 {
3001 /* Unbounded means that there exists an unbounded primal ray. However, this does not state whether the problem is
3002 * feasible. Thus, we temporarily set the objective to 0 and solve again. */
3003 SCIP_Real* zeroobjcoefs;
3004 SCIP_Real* objcoefs;
3005 SCIP_Real oldobjcutoff;
3006 int grbobjsen;
3007 int status;
3008 int ncols;
3009
3010 SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
3011 SCIP_ALLOC( BMSallocMemoryArray(&objcoefs, ncols) );
3012 SCIP_ALLOC( BMSallocClearMemoryArray(&zeroobjcoefs, ncols) );
3013
3014 /* preserve objective coefficients */
3015 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_OBJ, 0, ncols, objcoefs) );
3016
3017 /* set objective to 0 */
3018 CHECK_ZERO( lpi->messagehdlr, GRBsetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_OBJ, 0, ncols, zeroobjcoefs) );
3019
3020 /* disable cutoff */
3021 CHECK_ZERO( lpi->messagehdlr, GRBgetdblparam(lpi->grbenv, GRB_DBL_PAR_CUTOFF, &oldobjcutoff) );
3022
3023 CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_MODELSENSE, &grbobjsen) );
3024 if ( grbobjsen == GRB_MINIMIZE )
3025 {
3026 CHECK_ZERO( lpi->messagehdlr, GRBsetdblparam(lpi->grbenv, GRB_DBL_PAR_CUTOFF, GRB_INFINITY) );
3027 }
3028 else
3029 {
3030 CHECK_ZERO( lpi->messagehdlr, GRBsetdblparam(lpi->grbenv, GRB_DBL_PAR_CUTOFF, -GRB_INFINITY) );
3031 assert( grbobjsen == GRB_MAXIMIZE );
3032 }
3033
3034 /* solve problem again */
3035 CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
3036 CHECK_ZERO( lpi->messagehdlr, GRBoptimize(lpi->grbmodel) );
3037
3038 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_ITERCOUNT, &cnt) );
3039 lpi->iterations += (int) cnt;
3040
3041 CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_STATUS, &status) );
3042
3043 /* restore objective */
3044 CHECK_ZERO( lpi->messagehdlr, GRBsetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_OBJ, 0, ncols, objcoefs) );
3045 CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
3046
3047 /* restore objective limit */
3048 CHECK_ZERO( lpi->messagehdlr, GRBsetdblparam(lpi->grbenv, GRB_DBL_PAR_CUTOFF, oldobjcutoff) );
3049
3050 BMSfreeMemoryArray(&zeroobjcoefs);
3051 BMSfreeMemoryArray(&objcoefs);
3052
3053 /* possibly correct status */
3054 switch ( status )
3055 {
3056 case GRB_INF_OR_UNBD:
3057 case GRB_INFEASIBLE:
3058 lpi->solstat = GRB_INFEASIBLE;
3059 break;
3060
3061 case GRB_OPTIMAL:
3062 /* We again have to solve the problem to restore possible unbounded rays. */
3063 CHECK_ZERO( lpi->messagehdlr, GRBoptimize(lpi->grbmodel) );
3064 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_ITERCOUNT, &cnt) );
3065 lpi->iterations += (int) cnt;
3066 break;
3067
3068 case GRB_ITERATION_LIMIT:
3069 case GRB_TIME_LIMIT:
3070 /* do nothing */
3071 break;
3072
3073 /* GRB_LOADED, GRB_NODE_LIMIT, GRB_CUTOFF, GRB_SOLUTION_LIMIT, GRB_INTERRUPTED, GRB_NUMERIC, GRB_SUBOPTIMAL, GRB_INPROGRESS, GRB_USER_OBJ_LIMIT */
3074 default:
3075 SCIPerrorMessage("Gurobi returned wrong status %d.\n", status);
3076 return SCIP_LPERROR;
3077 }
3078 }
3079
3080 checkRangeInfo(lpi);
3081
3082 return SCIP_OKAY;
3083}
3084
3085/** calls dual simplex to solve the LP
3086 *
3087 * @todo Check concurrent (GRB_METHOD_CONCURRENT or GRB_METHOD_DETERMINISTIC_CONCURRENT)
3088 */
3090 SCIP_LPI* lpi /**< LP interface structure */
3091 )
3092{
3093 int oldprimdual = 0;
3094 int oldpresolve = GRB_PRESOLVE_OFF;
3095 int retval;
3096 double cnt;
3097 double itlim;
3098
3099 assert( lpi != NULL );
3100 assert( lpi->grbmodel != NULL );
3101 assert( lpi->grbenv != NULL );
3102
3103#ifdef SCIP_DEBUG
3104 {
3105 int ncols, nrows;
3106 SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
3107 SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
3108 SCIPdebugMessage("calling Gurobi dual simplex: %d cols, %d rows\n", ncols, nrows);
3109 }
3110#endif
3111
3112 invalidateSolution(lpi);
3113
3114 if ( lpi->fromscratch )
3115 {
3116#if GRB_VERSION_MAJOR < 8
3117 CHECK_ZERO( lpi->messagehdlr, GRBresetmodel(lpi->grbmodel) );
3118#else
3119 CHECK_ZERO( lpi->messagehdlr, GRBreset(lpi->grbmodel, 1) );
3120#endif
3121 }
3122
3123 SCIPdebugMessage("calling GRBoptimize() - dual\n");
3124
3125 SCIP_CALL( setParameterValues(lpi, &(lpi->grbparam)) );
3126
3127 /* set dual simplex */
3128 CHECK_ZERO( lpi->messagehdlr, GRBsetintparam(lpi->grbenv, GRB_INT_PAR_METHOD, GRB_METHOD_DUAL) );
3129
3130 /* add range variables */
3131 if ( lpi->nrngrows > 0 && !lpi->rngvarsadded )
3132 {
3133 SCIP_CALL( addRangeVars(lpi) );
3134 }
3135
3136 SCIP_CALL( getDblParam(lpi, GRB_DBL_PAR_ITERATIONLIMIT, &itlim) );
3137 if ( itlim < GRB_INFINITY )
3138 {
3139 /* turn off primal-dual switching for an LP solve that might be a strong branching LP solve */
3140 CHECK_ZERO( lpi->messagehdlr, GRBgetintparam(lpi->grbenv, "GURO_PAR_PRIMDUALSWITCH", &oldprimdual) );
3141 if ( oldprimdual != 0 )
3142 {
3143 CHECK_ZERO( lpi->messagehdlr, GRBsetintparam(lpi->grbenv, "GURO_PAR_PRIMDUALSWITCH", 0) );
3144 }
3145
3146 /* turn off presolve to avoid the case where the iteration limit is reached
3147 * and we do not get a valid dual bound installed for the original model */
3148 CHECK_ZERO( lpi->messagehdlr, GRBgetintparam(lpi->grbenv, GRB_INT_PAR_PRESOLVE, &oldpresolve) );
3149 if ( oldpresolve != GRB_PRESOLVE_OFF )
3150 {
3151 CHECK_ZERO( lpi->messagehdlr, GRBsetintparam(lpi->grbenv, GRB_INT_PAR_PRESOLVE, GRB_PRESOLVE_OFF) );
3152 }
3153 }
3154
3155 retval = GRBoptimize(lpi->grbmodel);
3156 switch( retval )
3157 {
3158 case 0:
3159 break;
3160 case GRB_ERROR_OUT_OF_MEMORY:
3161 return SCIP_NOMEMORY;
3162 default:
3163 return SCIP_LPERROR;
3164 }
3165
3166 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_ITERCOUNT, &cnt) );
3167 lpi->iterations = (int) cnt;
3168
3169 lpi->solisbasic = TRUE;
3170 CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_STATUS, &lpi->solstat) );
3171
3172 SCIPdebugMessage("Gurobi dual simplex needed %d iterations to gain LP status %d\n", (int) cnt, lpi->solstat);
3173
3174 if( lpi->solstat == GRB_INF_OR_UNBD )
3175 {
3176 int presolve;
3177 CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_PAR_PRESOLVE, &presolve) );
3178
3179 if( presolve != GRB_PRESOLVE_OFF )
3180 {
3181 /* maybe the preprocessor solved the problem; but we need a solution, so solve again without preprocessing */
3182 SCIPdebugMessage("presolver may have solved the problem -> calling Gurobi dual simplex again without presolve\n");
3183
3184 /* switch off preprocessing */
3185 CHECK_ZERO( lpi->messagehdlr, GRBsetintattr(lpi->grbmodel, GRB_INT_PAR_PRESOLVE, GRB_PRESOLVE_OFF) );
3186 SCIP_CALL( setParameterValues(lpi, &(lpi->grbparam)) );
3187
3188 retval = GRBoptimize(lpi->grbmodel);
3189 switch( retval )
3190 {
3191 case 0:
3192 break;
3193 case GRB_ERROR_OUT_OF_MEMORY:
3194 return SCIP_NOMEMORY;
3195 default:
3196 return SCIP_LPERROR;
3197 }
3198
3199 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_ITERCOUNT, &cnt) );
3200 lpi->iterations += (int) cnt;
3201 CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_STATUS, &lpi->solstat) );
3202 SCIPdebugMessage(" -> Gurobi returned solstat=%d (%d iterations)\n", lpi->solstat, lpi->iterations);
3203
3204 /* switch on preprocessing again */
3205 CHECK_ZERO( lpi->messagehdlr, GRBsetintattr(lpi->grbmodel, GRB_INT_PAR_PRESOLVE, GRB_PRESOLVE_AUTO) );
3206 }
3207
3208 if( lpi->solstat == GRB_INF_OR_UNBD )
3209 {
3210 /* preprocessing was not the problem; issue a warning message and treat LP as infeasible */
3211 SCIPerrorMessage("Gurobi dual simplex returned GRB_INF_OR_UNBD after presolving was turned off.\n");
3212 return SCIP_LPERROR;
3213 }
3214 }
3215
3216 checkRangeInfo(lpi);
3217
3218 /* reset parameters to their original values */
3219 if ( oldprimdual != 0 )
3220 {
3221 CHECK_ZERO( lpi->messagehdlr, GRBsetintparam(lpi->grbenv, "GURO_PAR_PRIMDUALSWITCH", oldprimdual) );
3222 }
3223 if ( oldpresolve != GRB_PRESOLVE_OFF )
3224 {
3225 CHECK_ZERO( lpi->messagehdlr, GRBsetintparam(lpi->grbenv, GRB_INT_PAR_PRESOLVE, oldpresolve) );
3226 }
3227
3228 return SCIP_OKAY;
3229}
3230
3231/** calls barrier or interior point algorithm to solve the LP with crossover to simplex basis */
3233 SCIP_LPI* lpi, /**< LP interface structure */
3234 SCIP_Bool crossover /**< perform crossover */
3235 )
3236{
3237 int retval;
3238 double cnt;
3239
3240 assert( lpi != NULL );
3241 assert( lpi->grbmodel != NULL );
3242 assert( lpi->grbenv != NULL );
3243
3244#ifdef SCIP_DEBUG
3245 {
3246 int ncols, nrows;
3247 SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
3248 SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
3249 SCIPdebugMessage("calling Gurobi barrier: %d cols, %d rows\n", ncols, nrows);
3250 }
3251#endif
3252
3253 invalidateSolution(lpi);
3254
3255 if ( lpi->fromscratch )
3256 {
3257#if GRB_VERSION_MAJOR < 8
3258 CHECK_ZERO( lpi->messagehdlr, GRBresetmodel(lpi->grbmodel) );
3259#else
3260 CHECK_ZERO( lpi->messagehdlr, GRBreset(lpi->grbmodel, 1) );
3261#endif
3262 }
3263
3264 SCIPdebugMessage("calling GRBoptimize() - barrier\n");
3265
3266 /* set barrier */
3267 SCIP_CALL( setParameterValues(lpi, &(lpi->grbparam)) );
3268
3269 if( crossover )
3270 {
3271 /* turn on crossover to automatic setting (-1) */
3272 CHECK_ZERO( lpi->messagehdlr, GRBsetintparam(lpi->grbenv, GRB_INT_PAR_CROSSOVER, -1) );
3273 }
3274 else
3275 {
3276 /* turn off crossover */
3277 CHECK_ZERO( lpi->messagehdlr, GRBsetintparam(lpi->grbenv, GRB_INT_PAR_CROSSOVER, 0) );
3278 }
3279
3280 CHECK_ZERO( lpi->messagehdlr, GRBsetintparam(lpi->grbenv, GRB_INT_PAR_METHOD, GRB_METHOD_BARRIER) );
3281
3282 /* add range variables */
3283 if ( lpi->nrngrows > 0 && !lpi->rngvarsadded )
3284 {
3285 SCIP_CALL( addRangeVars(lpi) );
3286 }
3287
3288 retval = GRBoptimize(lpi->grbmodel);
3289 switch( retval )
3290 {
3291 case 0:
3292 break;
3293 case GRB_ERROR_OUT_OF_MEMORY:
3294 return SCIP_NOMEMORY;
3295 default:
3296 return SCIP_LPERROR;
3297 }
3298
3299 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_ITERCOUNT, &cnt) );
3300 lpi->iterations = (int) cnt;
3301
3302 lpi->solisbasic = crossover;
3303 CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_STATUS, &lpi->solstat) );
3304
3305 SCIPdebugMessage("Gurobi barrier needed %d iterations to gain LP status %d\n", (int) cnt, lpi->solstat);
3306
3307 if( lpi->solstat == GRB_INF_OR_UNBD )
3308 {
3309 int presolve;
3310 CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_PAR_PRESOLVE, &presolve) );
3311
3312 if( presolve != GRB_PRESOLVE_OFF )
3313 {
3314 /* maybe the preprocessor solved the problem; but we need a solution, so solve again without preprocessing */
3315 SCIPdebugMessage("presolver may have solved the problem -> calling Gurobi barrier again without presolve\n");
3316
3317 /* switch off preprocessing */
3318 CHECK_ZERO( lpi->messagehdlr, GRBsetintattr(lpi->grbmodel, GRB_INT_PAR_PRESOLVE, GRB_PRESOLVE_OFF) );
3319 SCIP_CALL( setParameterValues(lpi, &(lpi->grbparam)) );
3320
3321 retval = GRBoptimize(lpi->grbmodel);
3322 switch( retval )
3323 {
3324 case 0:
3325 break;
3326 case GRB_ERROR_OUT_OF_MEMORY:
3327 return SCIP_NOMEMORY;
3328 default:
3329 return SCIP_LPERROR;
3330 }
3331
3332 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_ITERCOUNT, &cnt) );
3333 lpi->iterations += (int) cnt;
3334 CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_STATUS, &lpi->solstat) );
3335 SCIPdebugMessage(" -> Gurobi returned solstat=%d (%d iterations)\n", lpi->solstat, lpi->iterations);
3336
3337 /* switch on preprocessing again */
3338 CHECK_ZERO( lpi->messagehdlr, GRBsetintattr(lpi->grbmodel, GRB_INT_PAR_PRESOLVE, GRB_PRESOLVE_AUTO) );
3339 }
3340
3341 if( lpi->solstat == GRB_INF_OR_UNBD )
3342 {
3343 /* preprocessing was not the problem; issue a warning message and treat LP as infeasible */
3344 SCIPerrorMessage("Gurobi barrier returned GRB_INF_OR_UNBD after presolving was turned off\n");
3345 return SCIP_LPERROR;
3346 }
3347 }
3348
3349 checkRangeInfo(lpi);
3350
3351 return SCIP_OKAY;
3352}
3353
3354/** start strong branching - call before any strong branching */
3356 SCIP_LPI* lpi /**< LP interface structure */
3357 )
3358{ /*lint --e{715}*/
3359 assert( lpi != NULL );
3360 assert( lpi->grbmodel != NULL );
3361 assert( lpi->grbenv != NULL );
3362
3363 /* currently do nothing */
3364 return SCIP_OKAY;
3365}
3366
3367/** end strong branching - call after any strong branching */
3369 SCIP_LPI* lpi /**< LP interface structure */
3370 )
3371{ /*lint --e{715}*/
3372 assert( lpi != NULL );
3373 assert( lpi->grbmodel != NULL );
3374 assert( lpi->grbenv != NULL );
3375
3376 /* currently do nothing */
3377 return SCIP_OKAY;
3378}
3379
3380/** performs strong branching iterations on one candidate */
3381static
3383 SCIP_LPI* lpi, /**< LP interface structure */
3384 int col, /**< column to apply strong branching on */
3385 SCIP_Real psol, /**< current primal solution value of column */
3386 int itlim, /**< iteration limit for strong branchings */
3387 SCIP_Real* down, /**< stores dual bound after branching column down */
3388 SCIP_Real* up, /**< stores dual bound after branching column up */
3389 SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
3390 * otherwise, it can only be used as an estimate value */
3391 SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
3392 * otherwise, it can only be used as an estimate value */
3393 int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
3394 )
3395{
3396 SCIP_Real oldlb;
3397 SCIP_Real oldub;
3398 SCIP_Real newlb;
3399 SCIP_Real newub;
3400 SCIP_Real olditlim;
3401 SCIP_Bool error = FALSE;
3402 SCIP_Bool success;
3403 int it;
3404
3405 assert( lpi != NULL );
3406 assert( lpi->grbmodel != NULL );
3407 assert( lpi->grbenv != NULL );
3408 assert( down != NULL );
3409 assert( up != NULL );
3410 assert( downvalid != NULL );
3411 assert( upvalid != NULL );
3412
3413 SCIPdebugMessage("performing strong branching on variable %d (%d iterations)\n", col, itlim);
3414
3415 SCIP_CALL( setParameterValues(lpi, &(lpi->grbparam)) );
3416
3417 *downvalid = FALSE;
3418 *upvalid = FALSE;
3419 if( iter != NULL )
3420 *iter = 0;
3421
3422 /* save current LP basis and bounds*/
3423 SCIP_CALL( getBase(lpi, &success) );
3424 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrelement(lpi->grbmodel, GRB_DBL_ATTR_LB, col, &oldlb) );
3425 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrelement(lpi->grbmodel, GRB_DBL_ATTR_UB, col, &oldub) );
3426
3427 if ( lpi->fromscratch )
3428 {
3429#if GRB_VERSION_MAJOR < 8
3430 CHECK_ZERO( lpi->messagehdlr, GRBresetmodel(lpi->grbmodel) );
3431#else
3432 CHECK_ZERO( lpi->messagehdlr, GRBreset(lpi->grbmodel, 1) );
3433#endif
3434 }
3435
3436 /* save old iteration limit and set iteration limit to strong branching limit */
3437 if( itlim < 0 )
3438 itlim = INT_MAX;
3439
3440 SCIP_CALL( getDblParam(lpi, GRB_DBL_PAR_ITERATIONLIMIT, &olditlim) );
3441 SCIP_CALL( setDblParam(lpi, GRB_DBL_PAR_ITERATIONLIMIT, (double) itlim) );
3442
3443 /* add range variables */
3444 if ( lpi->nrngrows > 0 && !lpi->rngvarsadded )
3445 {
3446 SCIP_CALL( addRangeVars(lpi) );
3447 }
3448
3449 /* down branch */
3450 newub = EPSCEIL(psol-1.0, 1e-06);
3451 if( newub >= oldlb - 0.5 )
3452 {
3453 SCIPdebugMessage("strong branching down (%g) on x%d (%g) with %d iterations\n", newub, col, psol, itlim);
3454
3455 CHECK_ZERO( lpi->messagehdlr, GRBsetdblattrelement(lpi->grbmodel, GRB_DBL_ATTR_UB, col, newub) );
3456
3458 /* when iteration limit was reached the objective value is not computed */
3459 if( SCIPlpiIsOptimal(lpi) ) /*|| SCIPlpiIsIterlimExc(lpi) ) */
3460 {
3461 SCIP_CALL( SCIPlpiGetObjval(lpi, down) );
3462 *downvalid = TRUE;
3463 }
3464 else if( SCIPlpiIsPrimalInfeasible(lpi) || SCIPlpiIsObjlimExc(lpi) )
3465 {
3466 CHECK_ZERO( lpi->messagehdlr, GRBgetdblparam(lpi->grbenv, GRB_DBL_PAR_CUTOFF, down) );
3467 }
3468 else if( !SCIPlpiIsIterlimExc(lpi) )
3469 error = TRUE;
3470
3471 if( iter != NULL )
3472 {
3473 SCIP_CALL( SCIPlpiGetIterations(lpi, &it) );
3474 *iter += it;
3475 }
3476 SCIPdebugMessage(" -> down (x%d <= %g): %g\n", col, newub, *down);
3477
3478 CHECK_ZERO( lpi->messagehdlr, GRBsetdblattrelement(lpi->grbmodel, GRB_DBL_ATTR_UB, col, oldub) );
3479 CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
3480#ifdef SCIP_DEBUG
3481 {
3482 double b;
3483 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrelement(lpi->grbmodel, GRB_DBL_ATTR_UB, col, &b) );
3484 assert( b == oldub );
3485 }
3486#endif
3487
3488 if ( success )
3489 {
3490 SCIP_CALL( setBase(lpi) );
3491 }
3492 }
3493 else
3494 {
3495 CHECK_ZERO( lpi->messagehdlr, GRBgetdblparam(lpi->grbenv, GRB_DBL_PAR_CUTOFF, down) );
3496 *downvalid = TRUE;
3497 }
3498
3499 /* up branch */
3500 if( !error )
3501 {
3502 newlb = EPSFLOOR(psol+1.0, 1e-06);
3503 if( newlb <= oldub + 0.5 )
3504 {
3505 SCIPdebugMessage("strong branching up (%g) on x%d (%g) with %d iterations\n", newlb, col, psol, itlim);
3506
3507 CHECK_ZERO( lpi->messagehdlr, GRBsetdblattrelement(lpi->grbmodel, GRB_DBL_ATTR_LB, col, newlb) );
3508
3510 /* when iteration limit was reached the objective value is not computed */
3511 if( SCIPlpiIsOptimal(lpi) ) /*|| SCIPlpiIsIterlimExc(lpi) ) */
3512 {
3513 SCIP_CALL( SCIPlpiGetObjval(lpi, up) );
3514 *upvalid = TRUE;
3515 }
3516 else if( SCIPlpiIsPrimalInfeasible(lpi) || SCIPlpiIsObjlimExc(lpi) )
3517 {
3518 CHECK_ZERO( lpi->messagehdlr, GRBgetdblparam(lpi->grbenv, GRB_DBL_PAR_CUTOFF, up) );
3519 }
3520 else if( !SCIPlpiIsIterlimExc(lpi) )
3521 error = TRUE;
3522
3523 if( iter != NULL )
3524 {
3525 SCIP_CALL( SCIPlpiGetIterations(lpi, &it) );
3526 *iter += it;
3527 }
3528 SCIPdebugMessage(" -> up (x%d >= %g): %g\n", col, newlb, *up);
3529
3530 CHECK_ZERO( lpi->messagehdlr, GRBsetdblattrelement(lpi->grbmodel, GRB_DBL_ATTR_LB, col, oldlb) );
3531 CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
3532#ifdef SCIP_DEBUG
3533 {
3534 double b;
3535 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrelement(lpi->grbmodel, GRB_DBL_ATTR_LB, col, &b) );
3536 assert( b == oldlb );
3537 }
3538#endif
3539
3540 if ( success )
3541 {
3542 SCIP_CALL( setBase(lpi) );
3543 }
3544 }
3545 else
3546 {
3547 CHECK_ZERO( lpi->messagehdlr, GRBgetdblparam(lpi->grbenv, GRB_DBL_PAR_CUTOFF, up) );
3548 *upvalid = TRUE;
3549 }
3550 }
3551
3552 /* reset iteration limit */
3553 SCIP_CALL( setDblParam(lpi, GRB_DBL_PAR_ITERATIONLIMIT, olditlim) );
3554 /* CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) ); */
3555
3556 if( error )
3557 {
3558 SCIPerrorMessage("LP error in strong branching.\n");
3559 return SCIP_LPERROR;
3560 }
3561
3562 return SCIP_OKAY;
3563}
3564
3565/** performs strong branching iterations on one @b fractional candidate */
3567 SCIP_LPI* lpi, /**< LP interface structure */
3568 int col, /**< column to apply strong branching on */
3569 SCIP_Real psol, /**< fractional current primal solution value of column */
3570 int itlim, /**< iteration limit for strong branchings */
3571 SCIP_Real* down, /**< stores dual bound after branching column down */
3572 SCIP_Real* up, /**< stores dual bound after branching column up */
3573 SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
3574 * otherwise, it can only be used as an estimate value */
3575 SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
3576 * otherwise, it can only be used as an estimate value */
3577 int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
3578 )
3579{
3580 /* pass call on to lpiStrongbranch() */
3581 SCIP_CALL( lpiStrongbranch(lpi, col, psol, itlim, down, up, downvalid, upvalid, iter) );
3582
3583 checkRangeInfo(lpi);
3584
3585 return SCIP_OKAY;
3586}
3587
3588/** performs strong branching iterations on given @b fractional candidates */
3590 SCIP_LPI* lpi, /**< LP interface structure */
3591 int* cols, /**< columns to apply strong branching on */
3592 int ncols, /**< number of columns */
3593 SCIP_Real* psols, /**< fractional current primal solution values of columns */
3594 int itlim, /**< iteration limit for strong branchings */
3595 SCIP_Real* down, /**< stores dual bounds after branching columns down */
3596 SCIP_Real* up, /**< stores dual bounds after branching columns up */
3597 SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds;
3598 * otherwise, they can only be used as an estimate values */
3599 SCIP_Bool* upvalid, /**< stores whether the returned up values are a valid dual bounds;
3600 * otherwise, they can only be used as an estimate values */
3601 int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
3602 )
3603{
3604 int j;
3605
3606 assert( cols != NULL );
3607 assert( psols != NULL );
3608 assert( down != NULL );
3609 assert( up != NULL );
3610 assert( downvalid != NULL );
3611 assert( upvalid != NULL );
3612 assert( down != NULL );
3613
3614 if( iter != NULL )
3615 *iter = 0;
3616
3617 for( j = 0; j < ncols; ++j )
3618 {
3619 /* pass call on to lpiStrongbranch() */
3620 SCIP_CALL( lpiStrongbranch(lpi, cols[j], psols[j], itlim, &(down[j]), &(up[j]), &(downvalid[j]), &(upvalid[j]), iter) );
3621 }
3622
3623 checkRangeInfo(lpi);
3624
3625 return SCIP_OKAY;
3626}
3627
3628/** performs strong branching iterations on one candidate with @b integral value */
3630 SCIP_LPI* lpi, /**< LP interface structure */
3631 int col, /**< column to apply strong branching on */
3632 SCIP_Real psol, /**< current integral primal solution value of column */
3633 int itlim, /**< iteration limit for strong branchings */
3634 SCIP_Real* down, /**< stores dual bound after branching column down */
3635 SCIP_Real* up, /**< stores dual bound after branching column up */
3636 SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
3637 * otherwise, it can only be used as an estimate value */
3638 SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
3639 * otherwise, it can only be used as an estimate value */
3640 int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
3641 )
3642{
3643 /* pass call on to lpiStrongbranch() */
3644 SCIP_CALL( lpiStrongbranch(lpi, col, psol, itlim, down, up, downvalid, upvalid, iter) );
3645
3646 checkRangeInfo(lpi);
3647
3648 return SCIP_OKAY;
3649}
3650
3651/** performs strong branching iterations on given candidates with @b integral values */
3653 SCIP_LPI* lpi, /**< LP interface structure */
3654 int* cols, /**< columns to apply strong branching on */
3655 int ncols, /**< number of columns */
3656 SCIP_Real* psols, /**< current integral primal solution values of columns */
3657 int itlim, /**< iteration limit for strong branchings */
3658 SCIP_Real* down, /**< stores dual bounds after branching columns down */
3659 SCIP_Real* up, /**< stores dual bounds after branching columns up */
3660 SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds;
3661 * otherwise, they can only be used as an estimate values */
3662 SCIP_Bool* upvalid, /**< stores whether the returned up values are a valid dual bounds;
3663 * otherwise, they can only be used as an estimate values */
3664 int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
3665 )
3666{
3667 int j;
3668
3669 assert( cols != NULL );
3670 assert( psols != NULL );
3671 assert( down != NULL );
3672 assert( up != NULL );
3673 assert( downvalid != NULL );
3674 assert( upvalid != NULL );
3675 assert( down != NULL );
3676
3677 if( iter != NULL )
3678 *iter = 0;
3679
3680 for( j = 0; j < ncols; ++j )
3681 {
3682 /* pass call on to lpiStrongbranch() */
3683 SCIP_CALL( lpiStrongbranch(lpi, cols[j], psols[j], itlim, &(down[j]), &(up[j]), &(downvalid[j]), &(upvalid[j]), iter) );
3684 }
3685
3686 checkRangeInfo(lpi);
3687
3688 return SCIP_OKAY;
3689}
3690/**@} */
3691
3692
3693
3694
3695/*
3696 * Solution Information Methods
3697 */
3698
3699/**@name Solution Information Methods */
3700/**@{ */
3701
3702/** returns whether a solve method was called after the last modification of the LP */
3704 SCIP_LPI* lpi /**< LP interface structure */
3705 )
3706{
3707 assert(lpi != NULL);
3708
3709 return (lpi->solstat != -1);
3710}
3711
3712/** gets information about primal and dual feasibility of the current LP solution
3713 *
3714 * The feasibility information is with respect to the last solving call and it is only relevant if SCIPlpiWasSolved()
3715 * returns true. If the LP is changed, this information might be invalidated.
3716 *
3717 * Note that @a primalfeasible and @a dualfeasible should only return true if the solver has proved the respective LP to
3718 * be feasible. Thus, the return values should be equal to the values of SCIPlpiIsPrimalFeasible() and
3719 * SCIPlpiIsDualFeasible(), respectively. Note that if feasibility cannot be proved, they should return false (even if
3720 * the problem might actually be feasible).
3721 */
3723 SCIP_LPI* lpi, /**< LP interface structure */
3724 SCIP_Bool* primalfeasible, /**< pointer to store primal feasibility status */
3725 SCIP_Bool* dualfeasible /**< pointer to store dual feasibility status */
3726 )
3727{
3728 assert( lpi != NULL );
3729 assert( lpi->grbmodel != NULL );
3730 assert( lpi->grbenv != NULL );
3731 assert( lpi->solstat >= 1 );
3732 assert( primalfeasible != NULL );
3733 assert( dualfeasible != NULL );
3734
3735 SCIPdebugMessage("getting solution feasibility\n");
3736
3737 *primalfeasible = SCIPlpiIsPrimalFeasible(lpi);
3738 *dualfeasible = SCIPlpiIsDualFeasible(lpi);
3739
3740 return SCIP_OKAY;
3741}
3742
3743/** returns TRUE iff LP is proven to have a primal unbounded ray (but not necessary a primal feasible point);
3744 * this does not necessarily mean, that the solver knows and can return the primal ray
3745 */
3747 SCIP_LPI* lpi /**< LP interface structure */
3748 )
3749{
3750 assert(lpi != NULL);
3751 assert(lpi->grbmodel != NULL);
3752 assert(lpi->solstat >= 0);
3753
3754 return (lpi->solstat == GRB_UNBOUNDED);
3755}
3756
3757/** returns TRUE iff LP is proven to have a primal unbounded ray (but not necessary a primal feasible point),
3758 * and the solver knows and can return the primal ray
3759 */
3761 SCIP_LPI* lpi /**< LP interface structure */
3762 )
3763{
3764 int algo;
3765 int res;
3766
3767 assert( lpi != NULL );
3768 assert( lpi->grbmodel != NULL );
3769 assert( lpi->grbenv != NULL );
3770 assert( lpi->solstat >= 0 );
3771
3772 res = GRBgetintparam(lpi->grbenv, GRB_INT_PAR_METHOD, &algo);
3773 if ( res != 0 )
3774 {
3775 SCIPABORT();
3776 return FALSE; /*lint !e527*/
3777 }
3778
3779 return (lpi->solstat == GRB_UNBOUNDED && algo == GRB_METHOD_PRIMAL);
3780}
3781
3782/** returns TRUE iff LP is proven to be primal unbounded */
3784 SCIP_LPI* lpi /**< LP interface structure */
3785 )
3786{
3787 int algo;
3788 int res;
3789
3790 assert( lpi != NULL );
3791 assert( lpi->grbmodel != NULL );
3792 assert( lpi->grbenv != NULL );
3793 assert( lpi->solstat >= 0 );
3794
3795 res = GRBgetintparam(lpi->grbenv, GRB_INT_PAR_METHOD, &algo);
3796 if ( res != 0 )
3797 {
3798 SCIPABORT();
3799 return FALSE; /*lint !e527*/
3800 }
3801
3802 /* GRB_UNBOUNDED means that there exists a primal ray. SCIPlpiSolvePrimal() will determine whether the problem is
3803 * actually infeasible or (feasible and) unbounded. In the latter case, the status will be GRB_UNBOUNDED.
3804 */
3805 return (lpi->solstat == GRB_UNBOUNDED && algo == GRB_METHOD_PRIMAL);
3806}
3807
3808/** returns TRUE iff LP is proven to be primal infeasible */
3810 SCIP_LPI* lpi /**< LP interface structure */
3811 )
3812{
3813 assert(lpi != NULL);
3814 assert(lpi->grbmodel != NULL);
3815 assert(lpi->solstat >= 0);
3816
3817 SCIPdebugMessage("checking for primal infeasibility\n");
3818
3819 assert( lpi->solstat != GRB_INF_OR_UNBD );
3820 return (lpi->solstat == GRB_INFEASIBLE);
3821}
3822
3823/** returns TRUE iff LP is proven to be primal feasible */
3825 SCIP_LPI* lpi /**< LP interface structure */
3826 )
3827{
3828 int algo;
3829 int res;
3830
3831 assert( lpi != NULL );
3832 assert( lpi->grbmodel != NULL );
3833 assert( lpi->grbenv != NULL );
3834 assert( lpi->solstat >= 0 );
3835
3836 SCIPdebugMessage("checking for primal feasibility\n");
3837
3838 if ( lpi->solstat == GRB_OPTIMAL )
3839 return TRUE;
3840
3841 res = GRBgetintparam(lpi->grbenv, GRB_INT_PAR_METHOD, &algo);
3842 if ( res != 0 )
3843 {
3844 SCIPABORT();
3845 return FALSE; /*lint !e527*/
3846 }
3847 if ( algo != GRB_METHOD_PRIMAL )
3848 return FALSE;
3849
3850 if( lpi->solstat == GRB_ITERATION_LIMIT )
3851 {
3852 double consviol;
3853 double boundviol;
3854 double eps;
3855
3856 /* get feasibility tolerance */
3857 res = GRBgetdblparam(lpi->grbenv, GRB_DBL_PAR_FEASIBILITYTOL, &eps);
3858 if ( res != 0 )
3859 {
3860 SCIPABORT();
3861 return FALSE; /*lint !e527*/
3862 }
3863 res = GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_CONSTR_VIO, &consviol);
3864 if ( res != 0 )
3865 {
3866 /* If Gurobi cannot return the constraint violation, there is no feasible solution available. */
3867 return FALSE;
3868 }
3869 res = GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_BOUND_VIO, &boundviol);
3870 if ( res != 0 )
3871 {
3872 /* If Gurobi cannot return the bound violation, there is no feasible solution available. */
3873 return FALSE;
3874 }
3875
3876 if ( consviol <= eps && boundviol <= eps )
3877 return TRUE;
3878 }
3879
3880 return FALSE;
3881}
3882
3883/** returns TRUE iff LP is proven to have a dual unbounded ray (but not necessary a dual feasible point);
3884 * this does not necessarily mean, that the solver knows and can return the dual ray
3885 */
3887 SCIP_LPI* lpi /**< LP interface structure */
3888 )
3889{
3890 assert(lpi != NULL);
3891 assert(lpi->grbmodel != NULL);
3892 assert(lpi->solstat >= 0);
3893
3894 return (lpi->solstat == GRB_INFEASIBLE);
3895}
3896
3897/** returns TRUE iff LP is proven to have a dual unbounded ray (but not necessary a dual feasible point),
3898 * and the solver knows and can return the dual ray
3899 */
3901 SCIP_LPI* lpi /**< LP interface structure */
3902 )
3903{
3904 int algo;
3905 int res;
3906
3907 assert( lpi != NULL );
3908 assert( lpi->grbmodel != NULL );
3909 assert( lpi->grbenv != NULL );
3910 assert( lpi->solstat >= 0 );
3911
3912 res = GRBgetintparam(lpi->grbenv, GRB_INT_PAR_METHOD, &algo);
3913 if ( res != 0 )
3914 {
3915 SCIPABORT();
3916 return FALSE; /*lint !e527*/
3917 }
3918
3919 return (lpi->solstat == GRB_INFEASIBLE && algo == GRB_METHOD_DUAL);
3920}
3921
3922/** returns TRUE iff LP is proven to be dual unbounded */
3924 SCIP_LPI* lpi /**< LP interface structure */
3925 )
3926{
3927 int algo;
3928 int res;
3929
3930 assert( lpi != NULL );
3931 assert( lpi->grbmodel != NULL );
3932 assert( lpi->grbenv != NULL );
3933 assert( lpi->solstat >= 0 );
3934
3935 SCIPdebugMessage("checking for dual unboundedness\n");
3936
3937 res = GRBgetintparam(lpi->grbenv, GRB_INT_PAR_METHOD, &algo);
3938 if ( res != 0 )
3939 {
3940 SCIPABORT();
3941 return FALSE; /*lint !e527*/
3942 }
3943
3944 return (lpi->solstat == GRB_INFEASIBLE && algo == GRB_METHOD_DUAL);
3945}
3946
3947/** returns TRUE iff LP is proven to be dual infeasible */
3949 SCIP_LPI* lpi /**< LP interface structure */
3950 )
3951{
3952 assert( lpi != NULL );
3953 assert( lpi->grbmodel != NULL );
3954 assert( lpi->solstat >= 0 );
3955
3956 SCIPdebugMessage("checking for dual infeasibility\n");
3957
3958 return (lpi->solstat == GRB_UNBOUNDED);
3959}
3960
3961/** returns TRUE iff LP is proven to be dual feasible */
3963 SCIP_LPI* lpi /**< LP interface structure */
3964 )
3965{
3966 int algo;
3967 int res;
3968
3969 assert( lpi != NULL );
3970 assert( lpi->grbmodel != NULL );
3971 assert( lpi->grbenv != NULL );
3972 assert( lpi->solstat >= 0 );
3973
3974 SCIPdebugMessage("checking for dual feasibility\n");
3975
3976 res = GRBgetintparam(lpi->grbenv, GRB_INT_PAR_METHOD, &algo);
3977 if ( res != 0 )
3978 {
3979 SCIPABORT();
3980 return FALSE; /*lint !e527*/
3981 }
3982
3983 return (lpi->solstat == GRB_OPTIMAL ||
3984 (lpi->solstat == GRB_INFEASIBLE && algo == GRB_METHOD_DUAL) ||
3985 (lpi->solstat == GRB_ITERATION_LIMIT && algo == GRB_METHOD_DUAL) );
3986}
3987
3988/** returns TRUE iff LP was solved to optimality */
3990 SCIP_LPI* lpi /**< LP interface structure */
3991 )
3992{
3993 assert(lpi != NULL);
3994 assert(lpi->grbmodel != NULL);
3995 assert(lpi->solstat >= 0);
3996
3997 return (lpi->solstat == GRB_OPTIMAL);
3998}
3999
4000/** returns TRUE iff current LP solution is stable
4001 *
4002 * This function should return true if the solution is reliable, i.e., feasible and optimal (or proven
4003 * infeasible/unbounded) with respect to the original problem. The optimality status might be with respect to a scaled
4004 * version of the problem, but the solution might not be feasible to the unscaled original problem; in this case,
4005 * SCIPlpiIsStable() should return false.
4006 */
4008 SCIP_LPI* lpi /**< LP interface structure */
4009 )
4010{
4011 double consviol;
4012 double boundviol;
4013 double dualviol;
4014 double feastol;
4015 double optimalitytol;
4016 int res;
4017
4018 assert(lpi != NULL);
4019 assert(lpi->grbmodel != NULL);
4020 assert(lpi->solstat >= 0);
4021
4022 SCIPdebugMessage("checking for stability: Gurobi solstat = %d\n", lpi->solstat);
4023
4024 /* If the condition number of the basis should be checked, everything above the specified threshold is counted as
4025 * instable. */
4026 if ( lpi->checkcondition && (SCIPlpiIsOptimal(lpi) || SCIPlpiIsObjlimExc(lpi)) )
4027 {
4028 SCIP_Real kappa;
4029 SCIP_RETCODE retcode;
4030
4032 if ( retcode != SCIP_OKAY ) /*lint !e774*/
4033 {
4034 SCIPABORT();
4035 return FALSE; /*lint !e527*/
4036 }
4037
4038 /* if the kappa could not be computed (e.g., because we do not have a basis), we cannot check the condition */
4039 if ( kappa != SCIP_INVALID || kappa > lpi->conditionlimit ) /*lint !e777*/
4040 return FALSE;
4041 }
4042
4043 /* test whether we have unscaled infeasibilities */
4044 if ( SCIPlpiIsOptimal(lpi) )
4045 {
4046 /* first get tolerances */
4047 res = GRBgetdblparam(lpi->grbenv, GRB_DBL_PAR_FEASIBILITYTOL, &feastol);
4048 if ( res != 0 )
4049 {
4050 SCIPABORT();
4051 return FALSE; /*lint !e527*/
4052 }
4053 res = GRBgetdblparam(lpi->grbenv, GRB_DBL_PAR_OPTIMALITYTOL, &optimalitytol);
4054 if ( res != 0 )
4055 {
4056 SCIPABORT();
4057 return FALSE; /*lint !e527*/
4058 }
4059
4060 /* next get constraint, bound, and reduced cost violations */
4061 res = GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_CONSTR_VIO, &consviol);
4062 if ( res != 0 )
4063 {
4064 SCIPABORT();
4065 return FALSE; /*lint !e527*/
4066 }
4067 res = GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_BOUND_VIO, &boundviol);
4068 if ( res != 0 )
4069 {
4070 SCIPABORT();
4071 return FALSE; /*lint !e527*/
4072 }
4073 res = GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_DUAL_VIO, &dualviol);
4074 if ( res != 0 )
4075 {
4076 SCIPABORT();
4077 return FALSE; /*lint !e527*/
4078 }
4079
4080 return ( consviol <= feastol && boundviol <= feastol && dualviol <= optimalitytol );
4081 }
4082
4083 return (lpi->solstat != GRB_NUMERIC);
4084}
4085
4086/** returns TRUE iff the objective limit was reached */
4088 SCIP_LPI* lpi /**< LP interface structure */
4089 )
4090{
4091 assert(lpi != NULL);
4092 assert(lpi->grbmodel != NULL);
4093 assert(lpi->solstat >= 0);
4094
4095 return (lpi->solstat == GRB_CUTOFF);
4096}
4097
4098/** returns TRUE iff the iteration limit was reached */
4100 SCIP_LPI* lpi /**< LP interface structure */
4101 )
4102{
4103 assert(lpi != NULL);
4104 assert(lpi->grbmodel != NULL);
4105 assert(lpi->solstat >= 0);
4106
4107 return (lpi->solstat == GRB_ITERATION_LIMIT);
4108}
4109
4110/** returns TRUE iff the time limit was reached */
4112 SCIP_LPI* lpi /**< LP interface structure */
4113 )
4114{
4115 assert(lpi != NULL);
4116 assert(lpi->grbmodel != NULL);
4117 assert(lpi->solstat >= 0);
4118
4119 return (lpi->solstat == GRB_TIME_LIMIT);
4120}
4121
4122/** returns the internal solution status of the solver */
4124 SCIP_LPI* lpi /**< LP interface structure */
4125 )
4126{
4127 assert(lpi != NULL);
4128 assert(lpi->grbmodel != NULL);
4129
4130 return lpi->solstat;
4131}
4132
4133/** tries to reset the internal status of the LP solver in order to ignore an instability of the last solving call */
4135 SCIP_LPI* lpi, /**< LP interface structure */
4136 SCIP_Bool* success /**< pointer to store, whether the instability could be ignored */
4137 )
4138{
4139 assert(lpi != NULL);
4140 assert(lpi->grbmodel != NULL);
4141 assert(success != NULL);
4142
4143 *success = FALSE;
4144
4145 return SCIP_OKAY;
4146}
4147
4148/** gets objective value of solution */
4150 SCIP_LPI* lpi, /**< LP interface structure */
4151 SCIP_Real* objval /**< stores the objective value */
4152 )
4153{
4154 int ret;
4155
4156#ifndef NDEBUG
4157 double oval = GRB_INFINITY;
4158 double obnd = -GRB_INFINITY;
4159#endif
4160
4161 assert(lpi != NULL);
4162 assert(lpi->grbmodel != NULL);
4163 assert(objval != NULL);
4164
4165 SCIPdebugMessage("getting solution's objective value\n");
4166
4167#ifndef NDEBUG
4168 (void)GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_OBJVAL, &oval);
4169 (void)GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_OBJBOUND, &obnd);
4170
4171 assert(lpi->solstat != GRB_OPTIMAL || oval == obnd); /*lint !e777*/
4172#endif
4173
4174 /* obtain objective value */
4175 ret = GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_OBJVAL, objval);
4176 assert( ret == 0 || ret == GRB_ERROR_DATA_NOT_AVAILABLE );
4177 SCIP_UNUSED(ret);
4178
4179 /* return minus infinity if value not available and we reached the iteration limit (see lpi_cpx) */
4180 if( lpi->solstat == GRB_ITERATION_LIMIT )
4181 {
4182 (void)GRBgetdblattr(lpi->grbmodel, GRB_DBL_ATTR_OBJBOUND, objval);
4183 }
4184 else if( lpi->solstat == GRB_CUTOFF )
4185 {
4186 SCIP_Real cutoff;
4187
4188 /* if we reached the cutoff, then OBJBOUND seems to be -infinity; we set the value to the cutoff in this case */
4189 SCIP_CALL( getDblParam(lpi, GRB_DBL_PAR_CUTOFF, &cutoff) );
4190 *objval = cutoff;
4191
4192#ifdef SCIP_DISABLED_CODE
4193 /**@todo The following is some kind of hack which works with the current SCIP implementation and should be fixed. In
4194 * the case that the LP status is GRB_CUTOFF it might be that certain attributes cannot be queried (e.g., objval,
4195 * primal and dual solution), in this case we just return the installed cutoff value minus some epsilon. This is some
4196 * kind of hack for the code in conflict.c:7595 were some extra code handles CPLEX' FASTMIP case that is similar to
4197 * this case.
4198 */
4199 SCIP_Real dval;
4200 SCIP_OBJSEN objsense;
4201
4202 SCIP_CALL( SCIPlpiGetObjsen(lpi, &objsense) );
4203 SCIP_CALL( getDblParam(lpi, GRB_DBL_PAR_CUTOFF, &dval) );
4204
4205 if( objsense == SCIP_OBJSEN_MINIMIZE )
4206 *objval = dval - 1e-06;
4207 else
4208 *objval = dval + 1e-06;
4209#endif
4210 }
4211
4212 return SCIP_OKAY;
4213}
4214
4215/** gets primal and dual solution vectors for feasible LPs
4216 *
4217 * Before calling this function, the caller must ensure that the LP has been solved to optimality, i.e., that
4218 * SCIPlpiIsOptimal() returns true.
4219 */
4221 SCIP_LPI* lpi, /**< LP interface structure */
4222 SCIP_Real* objval, /**< stores the objective value, may be NULL if not needed */
4223 SCIP_Real* primsol, /**< primal solution vector, may be NULL if not needed */
4224 SCIP_Real* dualsol, /**< dual solution vector, may be NULL if not needed */
4225 SCIP_Real* activity, /**< row activity vector, may be NULL if not needed */
4226 SCIP_Real* redcost /**< reduced cost vector, may be NULL if not needed */
4227 )
4228{
4229 int ncols;
4230 int nrows;
4231
4232 assert(lpi != NULL);
4233 assert(lpi->grbmodel != NULL);
4234 assert(lpi->solstat >= 0);
4235
4236 SCIPdebugMessage("getting solution\n");
4237
4238 SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
4239 SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
4240 assert( ncols >= 0 && nrows >= 0 );
4241
4242 if( objval != NULL )
4243 {
4244 SCIP_CALL( SCIPlpiGetObjval(lpi, objval) );
4245 }
4246
4247 if( primsol != NULL )
4248 {
4249 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_X, 0, ncols, primsol) );
4250 }
4251
4252 if( dualsol != NULL )
4253 {
4254 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_PI, 0, nrows, dualsol) );
4255 }
4256
4257 if( activity != NULL )
4258 {
4259 int i;
4260
4261 /* first get the values of the slack variables */
4262 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_SLACK, 0, nrows, activity) );
4263
4264 SCIP_CALL( ensureSidechgMem(lpi, nrows) );
4265
4266 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_RHS, 0, nrows, lpi->rhsarray) );
4267 CHECK_ZERO( lpi->messagehdlr, GRBgetcharattrarray(lpi->grbmodel, GRB_CHAR_ATTR_SENSE, 0, nrows, lpi->senarray) );
4268
4269 for( i = 0; i < nrows; ++i )
4270 {
4271 switch(lpi->senarray[i])
4272 {
4273 case GRB_EQUAL:
4274 if ( lpi->rngrowmap != NULL && lpi->rngrowmap[i] >= 0 )
4275 {
4276 /* get solution value of range variable */
4277 SCIP_Real solval;
4278 assert(lpi->rngrowmap[i] < lpi->nrngrows);
4279 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrelement(lpi->grbmodel, GRB_DBL_ATTR_X, ncols + lpi->rngrowmap[i], &solval) );
4280 activity[i] = lpi->rhsarray[i] + solval;
4281 }
4282 else
4283 {
4284 activity[i] = lpi->rhsarray[i] - activity[i];
4285 }
4286 break;
4287 case GRB_LESS_EQUAL:
4288 activity[i] = lpi->rhsarray[i] - activity[i];
4289 break;
4290 case GRB_GREATER_EQUAL:
4291 activity[i] = lpi->rhsarray[i] - activity[i];
4292 break;
4293 default:
4294 SCIPerrorMessage("Unkown sense %c.\n", lpi->senarray[i]);
4295 SCIPABORT();
4296 return SCIP_INVALIDDATA; /*lint !e527*/
4297 }
4298 }
4299 }
4300
4301 if( redcost != NULL )
4302 {
4303 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_RC, 0, ncols, redcost) );
4304 }
4305
4306 return SCIP_OKAY;
4307}
4308
4309/** gets primal ray for unbounded LPs */
4311 SCIP_LPI* lpi, /**< LP interface structure */
4312 SCIP_Real* ray /**< primal ray */
4313 )
4314{
4315 int ncols;
4316
4317 assert(lpi != NULL);
4318 assert(lpi->grbmodel != NULL);
4319 assert(lpi->solstat >= 0);
4320 assert(ray != NULL);
4321
4322 SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
4323 assert( ncols >= 0 );
4324
4325 SCIPdebugMessage("calling Gurobi get primal ray: %d cols\n", ncols);
4326
4327 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_UNBDRAY, 0, ncols, ray) );
4328
4329 return SCIP_OKAY;
4330}
4331
4332/** gets dual Farkas proof for infeasibility */
4334 SCIP_LPI* lpi, /**< LP interface structure */
4335 SCIP_Real* dualfarkas /**< dual Farkas row multipliers */
4336 )
4337{
4338 int nrows;
4339 int i;
4340
4341 assert(lpi != NULL);
4342 assert(lpi->grbmodel != NULL);
4343 assert(lpi->solstat >= 0);
4344 assert(dualfarkas != NULL);
4345
4346 SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
4347 assert( nrows >= 0 );
4348
4349 SCIPdebugMessage("calling Gurobi dual Farkas: %d rows\n", nrows);
4350
4351 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_FARKASDUAL, 0, nrows, dualfarkas) );
4352
4353 /* correct sign of ray */
4354 for (i = 0; i < nrows; ++i)
4355 dualfarkas[i] *= -1.0;
4356
4357 return SCIP_OKAY;
4358}
4359
4360/** gets the number of LP iterations of the last solve call */
4362 SCIP_LPI* lpi, /**< LP interface structure */
4363 int* iterations /**< pointer to store the number of iterations of the last solve call */
4364 )
4365{
4366 assert(lpi != NULL);
4367 assert(lpi->grbmodel != NULL);
4368 assert(iterations != NULL);
4369
4370 *iterations = lpi->iterations;
4371
4372 return SCIP_OKAY;
4373}
4374
4375/** gets information about the quality of an LP solution
4376 *
4377 * Such information is usually only available, if also a (maybe not optimal) solution is available.
4378 * The LPI should return SCIP_INVALID for @p quality, if the requested quantity is not available.
4379 */
4381 SCIP_LPI* lpi, /**< LP interface structure */
4382 SCIP_LPSOLQUALITY qualityindicator, /**< indicates which quality should be returned */
4383 SCIP_Real* quality /**< pointer to store quality number */
4384 )
4385{ /*lint --e{715}*/
4386 const char* what;
4387 int ret;
4388
4389 assert(lpi != NULL);
4390 assert(lpi->grbmodel != NULL);
4391 assert(quality != NULL);
4392
4393 SCIPdebugMessage("requesting solution quality from Gurobi: quality %d\n", qualityindicator);
4394
4395 switch( qualityindicator )
4396 {
4398 what = GRB_DBL_ATTR_KAPPA;
4399 break;
4400
4402 what = GRB_DBL_ATTR_KAPPA_EXACT;
4403 break;
4404
4405 default:
4406 SCIPerrorMessage("Solution quality %d unknown.\n", qualityindicator);
4407 return SCIP_INVALIDDATA;
4408 }
4409
4410 ret = GRBgetdblattr(lpi->grbmodel, what, quality);
4411 if( ret != 0 )
4412 *quality = SCIP_INVALID;
4413
4414 return SCIP_OKAY;
4415}
4416
4417/**@} */
4418
4419
4420
4421
4422/*
4423 * LP Basis Methods
4424 */
4425
4426/**@name LP Basis Methods */
4427/**@{ */
4428
4429/** gets current basis status for columns and rows; arrays must be large enough to store the basis status */
4431 SCIP_LPI* lpi, /**< LP interface structure */
4432 int* cstat, /**< array to store column basis status, or NULL */
4433 int* rstat /**< array to store row basis status, or NULL */
4434 )
4435{
4436 int nrows;
4437 int ncols;
4438
4439 assert(lpi != NULL);
4440 assert(lpi->grbmodel != NULL);
4441
4442 SCIPdebugMessage("saving Gurobi basis into %p/%p\n", (void*) cstat, (void*) rstat);
4443
4444 SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
4445 SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
4446
4447 if( rstat != NULL )
4448 {
4449 int i;
4450
4451 SCIP_CALL( ensureSidechgMem(lpi, nrows) );
4452
4453 CHECK_ZERO( lpi->messagehdlr, GRBgetintattrarray(lpi->grbmodel, GRB_INT_ATTR_CBASIS, 0, nrows, rstat) );
4454 CHECK_ZERO( lpi->messagehdlr, GRBgetcharattrarray(lpi->grbmodel, GRB_CHAR_ATTR_SENSE, 0, nrows, lpi->senarray) );
4455
4456 for( i = 0; i < nrows; ++i )
4457 {
4458 if ( lpi->rngrowmap != NULL && lpi->rngrowmap[i] >= 0 && rstat[i] != GRB_BASIC )
4459 {
4460 int idx;
4461
4462 /* get range row basis status from corresponding range variable */
4463 idx = ncols + lpi->rngrowmap[i];
4464 assert(lpi->rngrowmap[i] < lpi->nrngrows);
4465 CHECK_ZERO( lpi->messagehdlr, GRBgetintattrelement(lpi->grbmodel, GRB_INT_ATTR_VBASIS, idx, &rstat[i]) );
4466
4467 switch( rstat[i] )
4468 {
4469 case GRB_BASIC:
4470 rstat[i] = (int) SCIP_BASESTAT_BASIC;
4471 break;
4472
4473 case GRB_NONBASIC_LOWER:
4474 rstat[i] = (int) SCIP_BASESTAT_LOWER;
4475 break;
4476
4477 case GRB_NONBASIC_UPPER:
4478 rstat[i] = (int) SCIP_BASESTAT_UPPER;
4479 break;
4480
4481 /*lint -fallthrough*/
4482 case GRB_SUPERBASIC:
4483 default:
4484 SCIPerrorMessage("invalid basis status %d for ranged row.\n", rstat[i]);
4485 SCIPABORT();
4486 return SCIP_INVALIDDATA; /*lint !e527*/
4487 }
4488 }
4489 else
4490 {
4491 /* Slack variables can only be basic or at their lower bounds in Gurobi. */
4492 switch( rstat[i] )
4493 {
4494 case GRB_BASIC:
4495 rstat[i] = (int) SCIP_BASESTAT_BASIC;
4496 break;
4497
4498 case GRB_NONBASIC_LOWER:
4499 if ( lpi->senarray[i] == '>' || lpi->senarray[i] == '=' )
4500 rstat[i] = (int) SCIP_BASESTAT_LOWER;
4501 else
4502 {
4503 assert( lpi->senarray[i] == '<' );
4504 rstat[i] = (int) SCIP_BASESTAT_UPPER;
4505 }
4506 break;
4507
4508 /*lint -fallthrough*/
4509 case GRB_NONBASIC_UPPER:
4510 case GRB_SUPERBASIC:
4511 default:
4512 SCIPerrorMessage("invalid basis status %d for row.\n", rstat[i]);
4513 SCIPABORT();
4514 return SCIP_INVALIDDATA; /*lint !e527*/
4515 }
4516 }
4517 }
4518 }
4519
4520 if( cstat != 0 )
4521 {
4522 int j;
4523
4524 CHECK_ZERO( lpi->messagehdlr, GRBgetintattrarray(lpi->grbmodel, GRB_INT_ATTR_VBASIS, 0, ncols, cstat) );
4525
4526 for( j = 0; j < ncols; ++j )
4527 {
4528 switch( cstat[j] )
4529 {
4530 case GRB_BASIC:
4531 cstat[j] = (int) SCIP_BASESTAT_BASIC;
4532 break;
4533
4534 case GRB_NONBASIC_LOWER:
4535 cstat[j] = (int) SCIP_BASESTAT_LOWER;
4536 break;
4537
4538 case GRB_NONBASIC_UPPER:
4539 cstat[j] = (int) SCIP_BASESTAT_UPPER;
4540 break;
4541
4542 case GRB_SUPERBASIC:
4543 cstat[j] = (int) SCIP_BASESTAT_ZERO;
4544 break;
4545
4546 default:
4547 SCIPerrorMessage("invalid basis status %d for column.\n", cstat[j]);
4548 SCIPABORT();
4549 return SCIP_INVALIDDATA; /*lint !e527*/
4550 }
4551 }
4552 }
4553
4554 return SCIP_OKAY;
4555}
4556
4557/** sets current basis status for columns and rows */
4559 SCIP_LPI* lpi, /**< LP interface structure */
4560 const int* cstat, /**< array with column basis status */
4561 const int* rstat /**< array with row basis status */
4562 )
4563{
4564 int i, j;
4565 int nrows, ncols;
4566#ifndef NDEBUG
4567 int nrngsfound = 0;
4568#endif
4569
4570 assert(lpi != NULL);
4571 assert(lpi->grbmodel != NULL);
4572
4573 SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
4574 SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
4575
4576 assert(cstat != NULL || ncols == 0);
4577 assert(rstat != NULL || nrows == 0);
4578
4579 SCIPdebugMessage("loading basis %p/%p into Gurobi\n", (void*) cstat, (void*) rstat);
4580
4581 invalidateSolution(lpi);
4582
4583 SCIP_CALL( ensureCstatMem(lpi, ncols+lpi->nrngrows) );
4584 SCIP_CALL( ensureRstatMem(lpi, nrows) );
4585
4586 for( i = 0; i < nrows; ++i )
4587 {
4588 if ( lpi->rngrowmap != NULL && lpi->rngrowmap[i] >= 0 )
4589 {
4590 int idx;
4591
4592 /* set basis status of corresponding range variable; ranged row is always non-basic */
4593 idx = ncols + lpi->rngrowmap[i];
4594 assert(lpi->rngrowmap[i] < lpi->nrngrows);
4595 lpi->cstat[idx] = lpi->rstat[i];
4596 lpi->rstat[i] = GRB_NONBASIC_LOWER;
4597#ifndef NDEBUG
4598 nrngsfound++;
4599#endif
4600 }
4601 else
4602 {
4603 switch( rstat[i] ) /*lint !e613*/
4604 {
4606 lpi->rstat[i] = GRB_BASIC;
4607 break;
4608
4610 {
4611#ifndef NDEBUG
4612 char sense;
4613 CHECK_ZERO( lpi->messagehdlr, GRBgetcharattrarray(lpi->grbmodel, GRB_CHAR_ATTR_SENSE, i, 1, &sense) );
4614 assert( sense == '<' );
4615#endif
4616 /* Slack variables can only be basic or at their lower bounds in Gurobi. */
4617 lpi->rstat[i] = GRB_NONBASIC_LOWER;
4618 break;
4619 }
4620
4622 {
4623#ifndef NDEBUG
4624 char sense;
4625 CHECK_ZERO( lpi->messagehdlr, GRBgetcharattrarray(lpi->grbmodel, GRB_CHAR_ATTR_SENSE, i, 1, &sense) );
4626 assert( sense == '>' || sense == '=' );
4627#endif
4628 lpi->rstat[i] = GRB_NONBASIC_LOWER;
4629 break;
4630 }
4631
4632 case SCIP_BASESTAT_ZERO:
4633 default:
4634 SCIPerrorMessage("invalid basis status %d for row.\n", rstat[i]); /*lint !e613*/
4635 SCIPABORT();
4636 return SCIP_INVALIDDATA; /*lint !e527*/
4637 }
4638 }
4639 }
4640
4641 for( j = 0; j < ncols; ++j )
4642 {
4643 switch( cstat[j] ) /*lint !e613*/
4644 {
4646 lpi->cstat[j] = GRB_BASIC;
4647 break;
4648
4650 lpi->cstat[j] = GRB_NONBASIC_LOWER;
4651 break;
4652
4654 lpi->cstat[j] = GRB_NONBASIC_UPPER;
4655 break;
4656
4657 case SCIP_BASESTAT_ZERO:
4658 lpi->cstat[j] = GRB_SUPERBASIC;
4659 break;
4660
4661 default:
4662 SCIPerrorMessage("invalid basis status %d\n", cstat[j]); /*lint !e613*/
4663 SCIPABORT();
4664 return SCIP_INVALIDDATA; /*lint !e527*/
4665 }
4666 }
4667
4668#ifndef NDEBUG
4669 assert(nrngsfound == lpi->nrngrows);
4670#endif
4671
4672 CHECK_ZERO( lpi->messagehdlr, GRBsetintattrarray(lpi->grbmodel, GRB_INT_ATTR_CBASIS, 0, nrows, lpi->rstat) );
4673 CHECK_ZERO( lpi->messagehdlr, GRBsetintattrarray(lpi->grbmodel, GRB_INT_ATTR_VBASIS, 0, ncols+lpi->nrngrows, lpi->cstat) );
4674
4675 /* flush model changes */
4676 CHECK_ZERO( lpi->messagehdlr, GRBupdatemodel(lpi->grbmodel) );
4677
4678 return SCIP_OKAY;
4679}
4680
4681/** returns the indices of the basic columns and rows; basic column n gives value n, basic row m gives value -1-m */
4683 SCIP_LPI* lpi, /**< LP interface structure */
4684 int* bind /**< pointer to store basis indices ready to keep number of rows entries */
4685 )
4686{
4687 int i;
4688 int nrows;
4689 int ncols;
4690 int ngrbcols;
4691 int* bhead;
4692 int status;
4693
4694 assert(lpi != NULL);
4695 assert(lpi->grbmodel != NULL);
4696 assert(bind != NULL);
4697
4698 SCIPdebugMessage("getting basis information\n");
4699
4700 /* check whether we have to reoptimize */
4701 CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_STATUS, &status) );
4702 if ( status == GRB_LOADED || status == GRB_INTERRUPTED || status == GRB_INPROGRESS )
4703 {
4705 }
4706
4707 SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
4708 SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
4709 CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_NUMVARS, &ngrbcols) );
4710
4711 /**@todo avoid memory allocation by using bind directly */
4712 /* get space for bhead */
4713 SCIP_ALLOC( BMSallocMemoryArray(&bhead, nrows) );
4714
4715 /* get basis indices */
4716 CHECK_ZERO( lpi->messagehdlr, GRBgetBasisHead(lpi->grbmodel, bhead) );
4717
4718 for (i = 0; i < nrows; ++i)
4719 {
4720 /* entries >= ncols refer to slack variables */
4721 if ( bhead[i] < ncols )
4722 bind[i] = bhead[i];
4723 else if ( bhead[i] < ngrbcols )
4724 {
4725 /* a range variable: use corresponding ranged row */
4726 int rngrow = bhead[i]-ncols;
4727 assert(rngrow < lpi->nrngrows);
4728 assert(lpi->rngrowmap != NULL);
4729 assert(lpi->rngrows != NULL);
4730 assert(lpi->rngrowmap[lpi->rngrows[rngrow]] == rngrow);
4731 bind[i] = -1 - lpi->rngrows[rngrow];
4732 }
4733 else
4734 {
4735 /* a regular slack variable */
4736 bind[i] = -1 - (bhead[i] - ngrbcols);
4737 }
4738 }
4739 BMSfreeMemoryArray(&bhead);
4740
4741 return SCIP_OKAY;
4742}
4743
4744/** get row of inverse basis matrix B^-1
4745 *
4746 * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
4747 * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
4748 * see also the explanation in lpi.h.
4749 *
4750 * @todo check that the result is in terms of the LP interface definition
4751 */
4753 SCIP_LPI* lpi, /**< LP interface structure */
4754 int r, /**< row number */
4755 SCIP_Real* coef, /**< pointer to store the coefficients of the row */
4756 int* inds, /**< array to store the non-zero indices, or NULL */
4757 int* ninds /**< pointer to store the number of non-zero indices, or NULL
4758 * (-1: if we do not store sparsity information) */
4759 )
4760{
4761 SVECTOR x;
4762 SVECTOR b;
4763 int nrows;
4764 double val;
4765 int ind;
4766 int status;
4767
4768 assert(lpi != NULL);
4769 assert(lpi->grbmodel != NULL);
4770 assert(coef != NULL);
4771
4772 SCIPdebugMessage("getting binv-row %d\n", r);
4773
4774 /* check whether we have to reoptimize */
4775 CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_STATUS, &status) );
4776 if ( status == GRB_LOADED || status == GRB_INTERRUPTED || status == GRB_INPROGRESS )
4777 {
4779 }
4780
4781 SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
4782
4783 /* set up solution vector */
4784 x.len = 0;
4785 SCIP_ALLOC( BMSallocMemoryArray(&(x.ind), nrows) );
4786 SCIP_ALLOC( BMSallocMemoryArray(&(x.val), nrows) );
4787
4788 /* get basis indices, temporarily using memory of x.ind */
4789 SCIP_CALL( SCIPlpiGetBasisInd(lpi, x.ind) );
4790
4791 /* set up rhs */
4792 b.len = 1;
4793 ind = r;
4794 val = (x.ind)[r] >= 0 ? 1.0 : -1.0;
4795 b.ind = &ind;
4796 b.val = &val;
4797
4798 /* solve B^T x = e_r, which results in the r-th row of the basis inverse */
4799 CHECK_ZERO( lpi->messagehdlr, GRBBSolve(lpi->grbmodel, &b, &x) );
4800
4801 /* size should be at most the number of rows */
4802 assert( x.len <= nrows );
4803
4804 /* check whether we require a dense or sparse result vector */
4805 if ( ninds != NULL && inds != NULL )
4806 {
4807 int idx;
4808 int i;
4809
4810 /* copy sparse solution */
4811 for (i = 0; i < x.len; ++i)
4812 {
4813 idx = (x.ind)[i];
4814 assert( idx >= 0 && idx < nrows );
4815 inds[i] = idx;
4816 coef[idx] = (x.val)[i];
4817 }
4818 *ninds = x.len;
4819 }
4820 else
4821 {
4822 int idx;
4823 int i;
4824
4825 /* copy solution to dense vector */
4826 BMSclearMemoryArray(coef, nrows);
4827 for (i = 0; i < x.len; ++i)
4828 {
4829 idx = (x.ind)[i];
4830 assert( idx >= 0 && idx < nrows );
4831 coef[idx] = (x.val)[i];
4832 }
4833 }
4834
4835 /* free solution space */
4836 BMSfreeMemoryArray(&(x.val));
4837 BMSfreeMemoryArray(&(x.ind));
4838
4839 return SCIP_OKAY;
4840}
4841
4842/** get column of inverse basis matrix B^-1
4843 *
4844 * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
4845 * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
4846 * see also the explanation in lpi.h.
4847 *
4848 * @todo check that the result is in terms of the LP interface definition
4849 */
4851 SCIP_LPI* lpi, /**< LP interface structure */
4852 int c, /**< column number of B^-1; this is NOT the number of the column in the LP;
4853 * you have to call SCIPlpiGetBasisInd() to get the array which links the
4854 * B^-1 column numbers to the row and column numbers of the LP!
4855 * c must be between 0 and nrows-1, since the basis has the size
4856 * nrows * nrows */
4857 SCIP_Real* coef, /**< pointer to store the coefficients of the column */
4858 int* inds, /**< array to store the non-zero indices, or NULL */
4859 int* ninds /**< pointer to store the number of non-zero indices, or NULL
4860 * (-1: if we do not store sparsity information) */
4861 )
4862{
4863 SVECTOR x;
4864 SVECTOR b;
4865 int* bind;
4866 int nrows;
4867 double val;
4868 int ind;
4869 int status;
4870
4871 assert(lpi != NULL);
4872 assert(lpi->grbmodel != NULL);
4873 assert(coef != NULL);
4874
4875 SCIPdebugMessage("getting binv-col %d\n", c);
4876
4877 /* check whether we have to reoptimize */
4878 CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_STATUS, &status) );
4879 if ( status == GRB_LOADED || status == GRB_INTERRUPTED || status == GRB_INPROGRESS )
4880 {
4882 }
4883
4884 SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
4885
4886 /* set up solution vector */
4887 x.len = 0;
4888 SCIP_ALLOC( BMSallocMemoryArray(&(x.ind), nrows) );
4889 SCIP_ALLOC( BMSallocMemoryArray(&(x.val), nrows) );
4890
4891 /* set up rhs */
4892 b.len = 1;
4893 ind = c;
4894 val = 1.0;
4895 b.ind = &ind;
4896 b.val = &val;
4897
4898 /* solve B x = e_c, which results in the c-th columns of the basis inverse */
4899 CHECK_ZERO( lpi->messagehdlr, GRBFSolve(lpi->grbmodel, &b, &x) );
4900
4901 /* size should be at most the number of rows */
4902 assert( x.len <= nrows );
4903
4904 /* get basis indices: entries that correspond to slack variables with coefficient -1 must be negated */
4905 SCIP_ALLOC( BMSallocMemoryArray(&bind, nrows) );
4906 SCIP_CALL( SCIPlpiGetBasisInd(lpi, bind) );
4907
4908 /* check whether we require a dense or sparse result vector */
4909 if ( ninds != NULL && inds != NULL )
4910 {
4911 int idx;
4912 int i;
4913
4914 /* copy sparse solution */
4915 for (i = 0; i < x.len; ++i)
4916 {
4917 idx = (x.ind)[i];
4918 assert( idx >= 0 && idx < nrows );
4919 inds[i] = idx;
4920 coef[idx] = (x.val)[i];
4921 if( bind[idx] < 0 )
4922 coef[idx] *= -1.0;
4923 }
4924 *ninds = x.len;
4925 }
4926 else
4927 {
4928 int idx;
4929 int i;
4930
4931 /* copy solution to dense vector */
4932 BMSclearMemoryArray(coef, nrows);
4933 for (i = 0; i < x.len; ++i)
4934 {
4935 idx = (x.ind)[i];
4936 assert( idx >= 0 && idx < nrows );
4937 coef[idx] = (x.val)[i];
4938 if( bind[idx] < 0 )
4939 coef[idx] *= -1.0;
4940 }
4941 }
4942
4943 /* free solution space and basis index array */
4944 BMSfreeMemoryArray(&bind);
4945 BMSfreeMemoryArray(&(x.val));
4946 BMSfreeMemoryArray(&(x.ind));
4947
4948 return SCIP_OKAY;
4949}
4950
4951/** get row of inverse basis matrix times constraint matrix B^-1 * A
4952 *
4953 * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
4954 * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
4955 * see also the explanation in lpi.h.
4956 *
4957 * @todo check that the result is in terms of the LP interface definition
4958 */
4960 SCIP_LPI* lpi, /**< LP interface structure */
4961 int r, /**< row number */
4962 const SCIP_Real* binvrow, /**< row in (A_B)^-1 from prior call to SCIPlpiGetBInvRow(), or NULL */
4963 SCIP_Real* coef, /**< vector to return coefficients of the row */
4964 int* inds, /**< array to store the non-zero indices, or NULL */
4965 int* ninds /**< pointer to store the number of non-zero indices, or NULL
4966 * (-1: if we do not store sparsity information) */
4967 )
4968{ /*lint --e{715}*/
4969 SVECTOR x;
4970 int nrows;
4971 int ncols;
4972 int ngrbcols;
4973 int status;
4974 SCIP_Bool isslackvar;
4975
4976 assert(lpi != NULL);
4977 assert(lpi->grbmodel != NULL);
4978 assert(coef != NULL);
4979 SCIP_UNUSED( binvrow );
4980
4981 SCIPdebugMessage("getting binv-row %d\n", r);
4982
4983 /* check whether we have to reoptimize */
4984 CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_STATUS, &status) );
4985 if ( status == GRB_LOADED || status == GRB_INTERRUPTED || status == GRB_INPROGRESS )
4986 {
4988 }
4989
4990 SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
4991 SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
4992 CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_NUMVARS, &ngrbcols) );
4993 assert( r >= 0 && r < nrows );
4994
4995 x.len = 0;
4996 SCIP_ALLOC( BMSallocMemoryArray(&(x.ind), ngrbcols + nrows) );
4997 SCIP_ALLOC( BMSallocMemoryArray(&(x.val), ngrbcols + nrows) );
4998
4999 /* get basis indices, temporarily using memory of x.ind: if r corresponds to a slack variable with coefficient -1 we
5000 * have to negate all values
5001 */
5002 SCIP_CALL( SCIPlpiGetBasisInd(lpi, x.ind) );
5003 isslackvar = ((x.ind)[r] < 0);
5004
5005 /* retrieve row */
5006 CHECK_ZERO( lpi->messagehdlr, GRBBinvRowi(lpi->grbmodel, r, &x) );
5007
5008 /* size should be at most the number of columns plus rows for slack variables */
5009 assert( x.len <= ngrbcols + nrows );
5010
5011 /* check whether we require a dense or sparse result vector */
5012 if ( ninds != NULL && inds != NULL )
5013 {
5014 int idx;
5015 int k;
5016 int j;
5017
5018 /* Copy sparse solution: Column indices ngrbcols and larger correspond to slack variables artificially introduced
5019 * by Gurobi; column indices ncols, ncols+1, ..., ngrbcols-1 correspond to slack variables introduced by the LPI
5020 * implementation. Both must simply be ignored.
5021 */
5022 k = 0;
5023 for (j = 0; j < x.len; ++j)
5024 {
5025 idx = (x.ind)[j];
5026 assert( idx >= 0 && idx < ngrbcols+nrows );
5027 if ( idx < ncols )
5028 {
5029 inds[k++] = idx;
5030 coef[idx] = (x.val)[j];
5031 if( isslackvar )
5032 coef[idx] *= -1.0;
5033 }
5034 }
5035 *ninds = k;
5036 }
5037 else
5038 {
5039 int idx;
5040 int j;
5041
5042 /* Copy dense solution (see comment above). */
5043 BMSclearMemoryArray(coef, ncols);
5044 for (j = 0; j < x.len; ++j)
5045 {
5046 idx = (x.ind)[j];
5047 assert( idx >= 0 && idx < ngrbcols+nrows );
5048 if ( idx < ncols )
5049 {
5050 coef[idx] = (x.val)[j];
5051 if( isslackvar )
5052 coef[idx] *= -1.0;
5053 }
5054 }
5055 }
5056
5057 /* free solution space */
5058 BMSfreeMemoryArray(&(x.val));
5059 BMSfreeMemoryArray(&(x.ind));
5060
5061 return SCIP_OKAY;
5062}
5063
5064/** get column of inverse basis matrix times constraint matrix B^-1 * A
5065 *
5066 * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
5067 * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
5068 * see also the explanation in lpi.h.
5069 *
5070 * @todo check that the result is in terms of the LP interface definition
5071 */
5073 SCIP_LPI* lpi, /**< LP interface structure */
5074 int c, /**< column number */
5075 SCIP_Real* coef, /**< vector to return coefficients of the column */
5076 int* inds, /**< array to store the non-zero indices, or NULL */
5077 int* ninds /**< pointer to store the number of non-zero indices, or NULL
5078 * (-1: if we do not store sparsity information) */
5079 )
5080{ /*lint --e{715}*/
5081 SVECTOR x;
5082 int* bind;
5083 int nrows;
5084 int status;
5085
5086 assert(lpi != NULL);
5087 assert(lpi->grbmodel != NULL);
5088 assert(coef != NULL);
5089
5090 SCIPdebugMessage("getting binv-col %d\n", c);
5091
5092 /* check whether we have to reoptimize */
5093 CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_STATUS, &status) );
5094 if ( status == GRB_LOADED || status == GRB_INTERRUPTED || status == GRB_INPROGRESS )
5095 {
5097 }
5098
5099 SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
5100
5101 x.len = 0;
5102 SCIP_ALLOC( BMSallocMemoryArray(&(x.ind), nrows) );
5103 SCIP_ALLOC( BMSallocMemoryArray(&(x.val), nrows) );
5104
5105 CHECK_ZERO( lpi->messagehdlr, GRBBinvColj(lpi->grbmodel, c, &x) );
5106
5107 /* size should be at most the number of rows */
5108 assert( x.len <= nrows );
5109
5110 /* get basis indices: entries that correspond to slack variables with coefficient -1 must be negated */
5111 SCIP_ALLOC( BMSallocMemoryArray(&bind, nrows) );
5112 SCIP_CALL( SCIPlpiGetBasisInd(lpi, bind) );
5113
5114 /* check whether we require a dense or sparse result vector */
5115 if ( ninds != NULL && inds != NULL )
5116 {
5117 int idx;
5118 int j;
5119
5120 /* copy sparse solution */
5121 for (j = 0; j < x.len; ++j)
5122 {
5123 idx = (x.ind)[j];
5124 assert( idx >= 0 && idx < nrows );
5125 inds[j] = idx;
5126 coef[idx] = (x.val)[j];
5127 if( bind[idx] < 0 )
5128 coef[idx] *= -1.0;
5129 }
5130 *ninds = x.len;
5131 }
5132 else
5133 {
5134 int idx;
5135 int j;
5136
5137 /* copy dense solution */
5138 BMSclearMemoryArray(coef, nrows);
5139 for (j = 0; j < x.len; ++j)
5140 {
5141 idx = (x.ind)[j];
5142 assert( idx >= 0 && idx < nrows );
5143 coef[idx] = (x.val)[j];
5144 if( bind[idx] < 0 )
5145 coef[idx] *= -1.0;
5146 }
5147 }
5148
5149 /* free solution space and basis index array */
5150 BMSfreeMemoryArray(&bind);
5151 BMSfreeMemoryArray(&(x.val));
5152 BMSfreeMemoryArray(&(x.ind));
5153
5154 return SCIP_OKAY;
5155}
5156
5157/**@} */
5158
5159
5160
5161
5162/*
5163 * LP State Methods
5164 */
5165
5166/**@name LP State Methods */
5167/**@{ */
5168
5169/** stores LPi state (like basis information) into lpistate object */
5171 SCIP_LPI* lpi, /**< LP interface structure */
5172 BMS_BLKMEM* blkmem, /**< block memory */
5173 SCIP_LPISTATE** lpistate /**< pointer to LPi state information (like basis information) */
5174 )
5175{
5176 SCIP_Bool success;
5177 int ncols;
5178 int nrows;
5179
5180 assert(blkmem != NULL);
5181 assert(lpi != NULL);
5182 assert(lpi->grbmodel != NULL);
5183 assert(lpistate != NULL);
5184
5185 /* if there is no basis information available, no state can be saved */
5186 if( !lpi->solisbasic )
5187 {
5188 *lpistate = NULL;
5189 return SCIP_OKAY;
5190 }
5191
5192 SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
5193 SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
5194 assert(ncols >= 0);
5195 assert(nrows >= 0);
5196
5197 /* get unpacked basis information from Gurobi */
5198 SCIP_CALL( getBase(lpi, &success) );
5199
5200 if ( success )
5201 {
5202 /* allocate lpistate data */
5203 SCIP_CALL( lpistateCreate(lpistate, blkmem, ncols, nrows, lpi->nrngrows) );
5204 (*lpistate)->ncols = ncols;
5205 (*lpistate)->nrows = nrows;
5206 (*lpistate)->nrngrows = lpi->nrngrows;
5207
5208 SCIPdebugMessage("stored Gurobi LPI state in %p (%d cols, %d rows, %d ranged rows)\n",
5209 (void*) *lpistate, ncols, nrows, lpi->nrngrows);
5210
5211 /* pack LPi state data */
5212 lpistatePack(*lpistate, lpi->cstat, lpi->rstat);
5213 }
5214 else
5215 {
5216 /* In this case no basis information is available. Since SCIP expects the information to work in any case, we
5217 * allocate the lpistate, but do not use the packed information. This might happen if the model is infeasible,
5218 * since Gurobi currently does not return basis information in this case. */
5219 SCIP_ALLOC( BMSallocBlockMemory(blkmem, lpistate) );
5220 (*lpistate)->ncols = ncols;
5221 (*lpistate)->nrows = nrows;
5222 (*lpistate)->nrngrows = lpi->nrngrows;
5223 (*lpistate)->packrstat = NULL;
5224 (*lpistate)->packcstat = NULL;
5225 }
5226
5227 return SCIP_OKAY;
5228}
5229
5230/** loads LPi state (like basis information) into solver; note that the LP might have been extended with additional
5231 * columns and rows since the state was stored with SCIPlpiGetState()
5232 */
5234 SCIP_LPI* lpi, /**< LP interface structure */
5235 BMS_BLKMEM* blkmem, /**< block memory */
5236 const SCIP_LPISTATE* lpistate /**< LPi state information (like basis information), or NULL */
5237 )
5238{
5239 int ncols;
5240 int nrows;
5241 int i;
5242
5243 assert(blkmem != NULL);
5244 assert(lpi != NULL);
5245 assert(lpi->grbmodel != NULL);
5246
5247 /* if there was no basis information available, the LPI state was not stored */
5248 if( lpistate == NULL || lpistate->packrstat == NULL || lpistate->packcstat == NULL )
5249 return SCIP_OKAY;
5250
5251 SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
5252 SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
5253 assert(lpistate->ncols <= ncols);
5254 assert(lpistate->nrows <= nrows);
5255 assert(lpistate->nrngrows <= lpi->nrngrows);
5256
5257 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",
5258 (void*) lpistate, lpistate->ncols, lpistate->nrows, lpistate->nrngrows, ncols, nrows, lpi->nrngrows);
5259
5260 if( lpistate->ncols == 0 || lpistate->nrows == 0 )
5261 return SCIP_OKAY;
5262
5263 /* allocate enough memory for storing uncompressed basis information */
5264 SCIP_CALL( ensureCstatMem(lpi, ncols + lpi->nrngrows) );
5265 SCIP_CALL( ensureRstatMem(lpi, nrows) );
5266
5267 /* unpack LPi state data */
5268 lpistateUnpack(lpistate, lpi->cstat, lpi->rstat);
5269
5270 if ( lpistate->nrngrows > 0 && lpistate->ncols < ncols )
5271 {
5272 /* New columns have been added: need to move range variable information */
5273 memmove(&lpi->cstat[ncols], &lpi->cstat[lpistate->ncols], (size_t) lpistate->nrngrows * sizeof(*lpi->cstat)); /*lint !e571*/
5274 }
5275
5276 /* extend the basis to the current LP beyond the previously existing columns */
5277 for( i = lpistate->ncols; i < ncols; ++i )
5278 {
5279 SCIP_Real bnd;
5280 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrelement(lpi->grbmodel, GRB_DBL_ATTR_LB, i, &bnd) );
5281 if ( SCIPlpiIsInfinity(lpi, REALABS(bnd)) )
5282 {
5283 /* if lower bound is +/- infinity -> try upper bound */
5284 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrelement(lpi->grbmodel, GRB_DBL_ATTR_UB, i, &bnd) );
5285 if ( SCIPlpiIsInfinity(lpi, REALABS(bnd)) )
5286 lpi->cstat[i] = (int) SCIP_BASESTAT_ZERO; /* variable is free */
5287 else
5288 lpi->cstat[i] = (int) SCIP_BASESTAT_UPPER; /* use finite upper bound */
5289 }
5290 else
5291 lpi->cstat[i] = (int) SCIP_BASESTAT_LOWER; /* use finite lower bound */
5292 }
5293 for( i = lpistate->nrngrows; i < lpi->nrngrows; ++i )
5294 lpi->cstat[ncols + i] = (int) SCIP_BASESTAT_LOWER;
5295 for( i = lpistate->nrows; i < nrows; ++i )
5296 lpi->rstat[i] = (int) SCIP_BASESTAT_BASIC;
5297
5298 /* load basis information into Gurobi */
5299 SCIP_CALL( setBase(lpi) );
5300
5301 return SCIP_OKAY;
5302}
5303
5304/** clears current LPi state (like basis information) of the solver */
5306 SCIP_LPI* lpi /**< LP interface structure */
5307 )
5308{
5309 assert(lpi != NULL);
5310 assert(lpi->grbmodel != NULL);
5311
5312#if GRB_VERSION_MAJOR < 8
5313 CHECK_ZERO( lpi->messagehdlr, GRBresetmodel(lpi->grbmodel) );
5314#else
5315 CHECK_ZERO( lpi->messagehdlr, GRBreset(lpi->grbmodel, 1) );
5316#endif
5317
5318 return SCIP_OKAY;
5319}
5320
5321/** frees LPi state information */
5323 SCIP_LPI* lpi, /**< LP interface structure */
5324 BMS_BLKMEM* blkmem, /**< block memory */
5325 SCIP_LPISTATE** lpistate /**< pointer to LPi state information (like basis information) */
5326 )
5327{
5328 assert(lpi != NULL);
5329 assert(lpistate != NULL);
5330 assert(blkmem != NULL);
5331
5332 if( *lpistate != NULL )
5333 lpistateFree(lpistate, blkmem);
5334
5335 return SCIP_OKAY;
5336}
5337
5338/** checks, whether the given LP state contains simplex basis information */
5340 SCIP_LPI* lpi, /**< LP interface structure */
5341 SCIP_LPISTATE* lpistate /**< LP state information (like basis information), or NULL */
5342 )
5343{ /*lint --e{715}*/
5344 assert(lpi != NULL);
5345 return (lpistate != NULL && lpistate->packcstat != NULL);
5346}
5347
5348/** reads LP state (like basis information from a file */
5350 SCIP_LPI* lpi, /**< LP interface structure */
5351 const char* fname /**< file name */
5352 )
5353{
5354 size_t l;
5355
5356 assert(lpi != NULL);
5357 assert(lpi->grbmodel != NULL);
5358 assert(fname != NULL);
5359
5360 SCIPdebugMessage("reading LP state from file <%s>\n", fname);
5361
5362 /* gurobi reads a basis if the extension is ".bas" */
5363 l = strlen(fname);
5364 if ( l > 4 && fname[l-4] == '.' && fname[l-3] == 'b' && fname[l-2] == 'a' && fname[l-1] == 's' )
5365 {
5366 CHECK_ZERO( lpi->messagehdlr, GRBread(lpi->grbmodel, fname) );
5367 }
5368 else
5369 {
5370 SCIPerrorMessage("To read a basis with gurobi, the extension has to be '.bas'.\n");
5371 return SCIP_LPERROR;
5372 }
5373
5374 return SCIP_OKAY;
5375}
5376
5377/** writes LPi state (i.e. basis information) to a file */
5379 SCIP_LPI* lpi, /**< LP interface structure */
5380 const char* fname /**< file name */
5381 )
5382{
5383 size_t l;
5384
5385 assert(lpi != NULL);
5386 assert(lpi->grbmodel != NULL);
5387 assert(fname != NULL);
5388
5389 SCIPdebugMessage("writing basis state to file <%s>\n", fname);
5390
5391 /* gurobi writes the basis if the extension is ".bas" */
5392 l = strlen(fname);
5393 if ( l > 4 && fname[l-4] == '.' && fname[l-3] == 'b' && fname[l-2] == 'a' && fname[l-1] == 's' )
5394 {
5395 CHECK_ZERO( lpi->messagehdlr, GRBwrite(lpi->grbmodel, fname) );
5396 }
5397 else
5398 {
5399 char name[SCIP_MAXSTRLEN];
5400
5401 /* force extension to be ".bas" */
5402 if ( strlen(fname) > SCIP_MAXSTRLEN-4)
5403 {
5404 SCIPerrorMessage("Basis file name too long.\n");
5405 return SCIP_LPERROR;
5406 }
5407 (void) snprintf(name, SCIP_MAXSTRLEN, "%s.bas", fname);
5408 CHECK_ZERO( lpi->messagehdlr, GRBwrite(lpi->grbmodel, fname) );
5409 }
5410
5411 return SCIP_OKAY;
5412}
5413
5414/**@} */
5415
5416
5417
5418
5419/*
5420 * LP Pricing Norms Methods
5421 */
5422
5423/**@name LP Pricing Norms Methods */
5424/**@{ */
5425
5426/** stores LPi pricing norms information */
5428 SCIP_LPI* lpi, /**< LP interface structure */
5429 BMS_BLKMEM* blkmem, /**< block memory */
5430 SCIP_LPINORMS** lpinorms /**< pointer to LPi pricing norms information */
5431 )
5432{ /*lint --e{715}*/
5433 int hasnorm;
5434 int ncols;
5435 int nrows;
5436
5437 assert(blkmem != NULL);
5438 assert(lpi != NULL);
5439 assert(lpi->grbmodel != NULL);
5440 assert(lpinorms != NULL);
5441
5442 *lpinorms = NULL;
5443
5444 /* if there is no basis information available (e.g. after barrier without crossover), norms cannot be saved */
5445 if( !lpi->solisbasic )
5446 return SCIP_OKAY;
5447
5448 /* check if dual norms are available:
5449 * value 0: no basis, so no norms available
5450 * value 1: basis exists, so norms can be computed
5451 * value 2: norms are available
5452 */
5453 CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_HASDUALNORM, &hasnorm) );
5454 if( hasnorm <= 1 )
5455 return SCIP_OKAY;
5456
5457 CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_NUMVARS, &ncols) );
5458 CHECK_ZERO( lpi->messagehdlr, GRBgetintattr(lpi->grbmodel, GRB_INT_ATTR_NUMCONSTRS, &nrows) );
5459
5460 /* allocate lpinorms data */
5461 SCIP_ALLOC( BMSallocBlockMemory(blkmem, lpinorms) );
5462 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpinorms)->colnorm, ncols) );
5463 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpinorms)->rownorm, nrows) );
5464 (*lpinorms)->ncols = ncols;
5465 (*lpinorms)->nrows = nrows;
5466
5467 /* query dual norms from Gurobi */
5468 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_VDUALNORM, 0, ncols, (*lpinorms)->colnorm) );
5469 CHECK_ZERO( lpi->messagehdlr, GRBgetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_CDUALNORM, 0, nrows, (*lpinorms)->rownorm) );
5470
5471 return SCIP_OKAY;
5472}
5473
5474/** loads LPi pricing norms into solver; note that the LP might have been extended with additional
5475 * columns and rows since the state was stored with SCIPlpiGetNorms()
5476 */
5478 SCIP_LPI* lpi, /**< LP interface structure */
5479 BMS_BLKMEM* blkmem, /**< block memory */
5480 const SCIP_LPINORMS* lpinorms /**< LPi pricing norms information, or NULL */
5481 )
5482{ /*lint --e{715}*/
5483 int error;
5484
5485 assert(blkmem != NULL);
5486 assert(lpi != NULL);
5487
5488 /* if there was no pricing norms information available, the LPI norms were not stored */
5489 if( lpinorms == NULL )
5490 return SCIP_OKAY;
5491
5492 /* store dual norms in Gurobi */
5493 error = GRBsetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_VDUALNORM, 0, lpinorms->ncols, lpinorms->colnorm);
5494 /* it can fail to set the norms if no basis was previously set, e.g.,
5495 * this can happen if flushing an LP did not change anything and
5496 * therefore no basis was set, as a result Gurobi has no extra user
5497 * warmstart information and cannot set norms */
5498#ifdef SCIP_DEBUG
5499 if( error )
5500 SCIPmessagePrintWarning(lpi->messagehdlr, "Warning: setting dual variable norms failed with Gurobi error %d\n", error);
5501#else
5502 (void)error;
5503#endif
5504
5505 error = GRBsetdblattrarray(lpi->grbmodel, GRB_DBL_ATTR_CDUALNORM, 0, lpinorms->nrows, lpinorms->rownorm);
5506 /* it can fail to set the norms if no basis was previously set, e.g.,
5507 * this can happen if flushing an LP did not change anything and
5508 * therefore no basis was set, as a result Gurobi has no extra user
5509 * warmstart information and cannot set norms */
5510#ifdef SCIP_DEBUG
5511 if( error )
5512 SCIPmessagePrintWarning(lpi->messagehdlr, "Warning: setting dual constraint norms failed with Gurobi error %d\n", error);
5513#else
5514 (void)error;
5515#endif
5516
5517 return SCIP_OKAY;
5518}
5519
5520/** frees pricing norms information */
5522 SCIP_LPI* lpi, /**< LP interface structure */
5523 BMS_BLKMEM* blkmem, /**< block memory */
5524 SCIP_LPINORMS** lpinorms /**< pointer to LPi pricing norms information, or NULL */
5525 )
5526{ /*lint --e{715}*/
5527 assert(lpi != NULL);
5528 assert(lpinorms != NULL);
5529
5530 if ( *lpinorms != NULL )
5531 {
5532 BMSfreeBlockMemoryArray(blkmem, &(*lpinorms)->colnorm, (*lpinorms)->ncols);
5533 BMSfreeBlockMemoryArray(blkmem, &(*lpinorms)->rownorm, (*lpinorms)->nrows);
5534 BMSfreeBlockMemory(blkmem, lpinorms);
5535 }
5536
5537 return SCIP_OKAY;
5538}
5539
5540/**@} */
5541
5542
5543
5544
5545/*
5546 * Parameter Methods
5547 */
5548
5549/**@name Parameter Methods */
5550/**@{ */
5551
5552/** gets integer parameter of LP */
5554 SCIP_LPI* lpi, /**< LP interface structure */
5555 SCIP_LPPARAM type, /**< parameter number */
5556 int* ival /**< buffer to store the parameter value */
5557 )
5558{
5559 int temp;
5560 SCIP_Real dtemp;
5561
5562 assert(lpi != NULL);
5563 assert(lpi->grbmodel != NULL);
5564 assert(ival != NULL);
5565
5566 SCIPdebugMessage("getting int parameter %d\n", type);
5567
5568 switch( type )
5569 {
5571 *ival = (int) lpi->fromscratch;
5572 break;
5573 case SCIP_LPPAR_FASTMIP:
5574 /* maybe set perturbation */
5575 return SCIP_PARAMETERUNKNOWN;
5576 case SCIP_LPPAR_SCALING:
5577 SCIP_CALL( getIntParam(lpi, GRB_INT_PAR_SCALEFLAG, &temp) );
5578 assert(temp >= -1 && temp <= 3);
5579 if( temp == -1 )
5580 *ival = 1;
5581 else
5582 *ival = temp;
5583 break;
5585 SCIP_CALL( getIntParam(lpi, GRB_INT_PAR_PRESOLVE, &temp) );
5586 assert( temp == GRB_PRESOLVE_AUTO || temp == GRB_PRESOLVE_OFF || temp == GRB_PRESOLVE_CONSERVATIVE || temp == GRB_PRESOLVE_AGGRESSIVE );
5587 *ival = (temp == GRB_PRESOLVE_OFF) ? FALSE : TRUE;
5588 break;
5589 case SCIP_LPPAR_PRICING:
5590 *ival = (int) lpi->pricing;
5591 break;
5592 case SCIP_LPPAR_LPINFO:
5593 SCIP_CALL( getIntParam(lpi, GRB_INT_PAR_OUTPUTFLAG, &temp) );
5594 assert( temp == 0 || temp == 1 );
5595 *ival = (temp == 1) ? TRUE : FALSE;
5596 break;
5597 case SCIP_LPPAR_LPITLIM:
5598 SCIP_CALL( getDblParam(lpi, GRB_DBL_PAR_ITERATIONLIMIT, &dtemp) );
5599 assert( dtemp >= 0.0 );
5600 if( dtemp >= INT_MAX )
5601 *ival = INT_MAX;
5602 else
5603 *ival = (int) dtemp;
5604 break;
5605 case SCIP_LPPAR_THREADS:
5606 SCIP_CALL( getIntParam(lpi, GRB_INT_PAR_THREADS, ival) );
5607 break;
5609 SCIP_CALL( getIntParam(lpi, GRB_INT_PAR_SEED, ival) );
5610 break;
5611 default:
5612 return SCIP_PARAMETERUNKNOWN;
5613 } /*lint !e788*/
5614
5615 return SCIP_OKAY;
5616}
5617
5618/** sets integer parameter of LP */
5620 SCIP_LPI* lpi, /**< LP interface structure */
5621 SCIP_LPPARAM type, /**< parameter number */
5622 int ival /**< parameter value */
5623 )
5624{
5625 assert(lpi != NULL);
5626 assert(lpi->grbmodel != NULL);
5627
5628 SCIPdebugMessage("setting int parameter %d to %d\n", type, ival);
5629
5630 switch( type )
5631 {
5633 assert(ival == TRUE || ival == FALSE);
5634 lpi->fromscratch = (SCIP_Bool) ival;
5635 break;
5636 case SCIP_LPPAR_FASTMIP:
5637 assert(ival == TRUE || ival == FALSE);
5638 return SCIP_PARAMETERUNKNOWN;
5639 case SCIP_LPPAR_SCALING:
5640 if( ival == 1 )
5641 SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_SCALEFLAG, -1) );
5642 else
5643 SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_SCALEFLAG, ival) );
5644 break;
5646 assert(ival == TRUE || ival == FALSE);
5647 if( ival )
5648 SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_PRESOLVE, GRB_PRESOLVE_AUTO) );
5649 else
5650 SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_PRESOLVE, GRB_PRESOLVE_OFF) );
5651 break;
5652 case SCIP_LPPAR_PRICING:
5653 lpi->pricing = (SCIP_PRICING)ival;
5654 switch( (SCIP_PRICING)ival )
5655 {
5657 case SCIP_PRICING_AUTO:
5658 SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_SIMPLEXPRICING, GRB_SIMPLEXPRICING_AUTO) );
5659 break;
5660 case SCIP_PRICING_FULL:
5661 /* full does not seem to exist -> use auto */
5662 SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_SIMPLEXPRICING, GRB_SIMPLEXPRICING_AUTO) );
5663 break;
5665 SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_SIMPLEXPRICING, GRB_SIMPLEXPRICING_PARTIAL) );
5666 break;
5667 case SCIP_PRICING_STEEP:
5668 SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_SIMPLEXPRICING, GRB_SIMPLEXPRICING_STEEPEST_EDGE) );
5669 break;
5671 SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_SIMPLEXPRICING, GRB_SIMPLEXPRICING_STEEPEST_QUICK) );
5672 break;
5673 case SCIP_PRICING_DEVEX:
5674 SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_SIMPLEXPRICING, GRB_SIMPLEXPRICING_DEVEX) );
5675 break;
5676 default:
5677 return SCIP_PARAMETERUNKNOWN;
5678 }
5679 break;
5680 case SCIP_LPPAR_LPINFO:
5681 assert(ival == TRUE || ival == FALSE);
5682 if( ival )
5683 SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_OUTPUTFLAG, 1) );
5684 else
5685 SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_OUTPUTFLAG, 0) );
5686 break;
5687 case SCIP_LPPAR_LPITLIM:
5688 assert( ival >= 0 );
5689 /* 0 <= ival, 0 stopping immediately */
5690 {
5691 double itlim;
5692 itlim = (ival >= INT_MAX ? GRB_INFINITY : ival);
5693 SCIP_CALL( setDblParam(lpi, GRB_DBL_PAR_ITERATIONLIMIT, itlim) );
5694 }
5695 break;
5696 case SCIP_LPPAR_THREADS:
5697 assert( ival >= 0 );
5698 SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_THREADS, ival) );
5699 break;
5701 assert( ival >= 0 );
5702 SCIP_CALL( setIntParam(lpi, GRB_INT_PAR_SEED, ival) );
5703 break;
5704 default:
5705 return SCIP_PARAMETERUNKNOWN;
5706 } /*lint !e788*/
5707
5708 return SCIP_OKAY;
5709}
5710
5711/** gets floating point parameter of LP */
5713 SCIP_LPI* lpi, /**< LP interface structure */
5714 SCIP_LPPARAM type, /**< parameter number */
5715 SCIP_Real* dval /**< buffer to store the parameter value */
5716 )
5717{
5718 assert(lpi != NULL);
5719 assert(lpi->grbmodel != NULL);
5720 assert(dval != NULL);
5721
5722 SCIPdebugMessage("getting real parameter %d\n", type);
5723
5724 switch( type )
5725 {
5726 case SCIP_LPPAR_FEASTOL:
5727 SCIP_CALL( getDblParam(lpi, GRB_DBL_PAR_FEASIBILITYTOL, dval) );
5728 break;
5730 SCIP_CALL( getDblParam(lpi, GRB_DBL_PAR_OPTIMALITYTOL, dval) );
5731 break;
5733 SCIP_CALL( getDblParam(lpi, GRB_DBL_PAR_BARCONVTOL, dval) );
5734 break;
5735 case SCIP_LPPAR_OBJLIM:
5736 SCIP_CALL( getDblParam(lpi, GRB_DBL_PAR_CUTOFF, dval) );
5737 break;
5738 case SCIP_LPPAR_LPTILIM:
5739 SCIP_CALL( getDblParam(lpi, GRB_DBL_PAR_TIMELIMIT, dval) );
5740 break;
5742 SCIP_CALL( getDblParam(lpi, GRB_DBL_PAR_MARKOWITZTOL, dval) );
5743 break;
5745 *dval = lpi->conditionlimit;
5746 break;
5747 default:
5748 return SCIP_PARAMETERUNKNOWN;
5749 } /*lint !e788*/
5750
5751 return SCIP_OKAY;
5752}
5753
5754/** sets floating point parameter of LP */
5756 SCIP_LPI* lpi, /**< LP interface structure */
5757 SCIP_LPPARAM type, /**< parameter number */
5758 SCIP_Real dval /**< parameter value */
5759 )
5760{
5761 assert(lpi != NULL);
5762 assert(lpi->grbmodel != NULL);
5763
5764 SCIPdebugMessage("setting real parameter %d to %g\n", type, dval);
5765
5766 switch( type )
5767 {
5768 case SCIP_LPPAR_FEASTOL:
5769 assert( dval > 0.0 );
5770 /* 1e-9 <= dval <= 1e-2 */
5771 if( dval < 1e-9 )
5772 dval = 1e-9;
5773 else if( dval > 1e-2 )
5774 dval = 1e-2;
5775
5776 SCIP_CALL( setDblParam(lpi, GRB_DBL_PAR_FEASIBILITYTOL, dval) );
5777 break;
5779 assert( dval > 0.0 );
5780 /* 1e-9 <= dval <= 1e-2 */
5781 if (dval < 1e-9)
5782 dval = 1e-9;
5783 else if( dval > 1e-2 )
5784 dval = 1e-2;
5785
5786 SCIP_CALL( setDblParam(lpi, GRB_DBL_PAR_OPTIMALITYTOL, dval) );
5787 break;
5789 /* 0 <= dval <= 1 */
5790 assert( dval >= 0.0 );
5791 if( dval > 1.0 )
5792 dval = 1.0;
5793
5794 SCIP_CALL( setDblParam(lpi, GRB_DBL_PAR_BARCONVTOL, dval) );
5795 break;
5796 case SCIP_LPPAR_OBJLIM:
5797 /* no restriction on dval */
5798
5799 SCIP_CALL( setDblParam(lpi, GRB_DBL_PAR_CUTOFF, dval) );
5800 break;
5801 case SCIP_LPPAR_LPTILIM:
5802 assert( dval > 0.0 );
5803 /* gurobi requires 0 <= dval
5804 *
5805 * However for consistency we assert the timelimit to be strictly positive.
5806 */
5807
5808 SCIP_CALL( setDblParam(lpi, GRB_DBL_PAR_TIMELIMIT, dval) );
5809 break;
5811 /* 1e-4 <= dval <= 0.999 */
5812 if( dval < 1e-4 )
5813 dval = 1e-4;
5814 else if( dval > 0.999 )
5815 dval = 0.999;
5816
5817 SCIP_CALL( setDblParam(lpi, GRB_DBL_PAR_MARKOWITZTOL, dval) );
5818 break;
5820 lpi->conditionlimit = dval;
5821 lpi->checkcondition = (dval >= 0.0) ? TRUE : FALSE;
5822 break;
5823 default:
5824 return SCIP_PARAMETERUNKNOWN;
5825 } /*lint !e788*/
5826
5827 return SCIP_OKAY;
5828}
5829
5830/** interrupts the currently ongoing lp solve or disables the interrupt */ /*lint -e{715}*/
5832 SCIP_LPI* lpi, /**< LP interface structure */
5833 SCIP_Bool interrupt /**< TRUE if interrupt should be set, FALSE if it should be disabled */
5834 )
5835{ /*lint --e{715}*/
5836 assert(lpi != NULL);
5837
5838 return SCIP_OKAY;
5839}
5840
5841/**@} */
5842
5843
5844
5845
5846/*
5847 * Numerical Methods
5848 */
5849
5850/**@name Numerical Methods */
5851/**@{ */
5852
5853/** returns value treated as infinity in the LP solver */
5855 SCIP_LPI* lpi /**< LP interface structure */
5856 )
5857{ /*lint --e{715}*/
5858 assert(lpi != NULL);
5859 return GRB_INFINITY;
5860}
5861
5862/** checks if given value is treated as infinity in the LP solver */
5864 SCIP_LPI* lpi, /**< LP interface structure */
5865 SCIP_Real val /**< value to be checked for infinity */
5866 )
5867{ /*lint --e{715}*/
5868 assert(lpi != NULL);
5869 return (val >= GRB_INFINITY);
5870}
5871
5872/**@} */
5873
5874
5875
5876
5877/*
5878 * File Interface Methods
5879 */
5880
5881/**@name File Interface Methods */
5882/**@{ */
5883
5884/** reads LP from 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("reading LP from file <%s>\n", fname);
5895
5896 CHECK_ZERO( lpi->messagehdlr, GRBreadmodel(lpi->grbenv, fname, &lpi->grbmodel) );
5897
5898 /* the model name seems to be empty, use filename */
5899 CHECK_ZERO( lpi->messagehdlr, GRBsetstrattr(lpi->grbmodel, GRB_STR_ATTR_MODELNAME, fname) );
5900
5901 return SCIP_OKAY;
5902}
5903
5904/** writes LP to a file */
5906 SCIP_LPI* lpi, /**< LP interface structure */
5907 const char* fname /**< file name */
5908 )
5909{
5910 assert(lpi != NULL);
5911 assert(lpi->grbmodel != NULL);
5912 assert(fname != NULL);
5913
5914 SCIPdebugMessage("writing LP to file <%s>\n", fname);
5915
5916 /* if range rows were not added, add, print and remove them; otherwise, just print */
5917 if ( lpi->nrngrows > 0 && !lpi->rngvarsadded )
5918 {
5919 SCIP_CALL( addRangeVars(lpi) );
5920 CHECK_ZERO( lpi->messagehdlr, GRBwrite(lpi->grbmodel, fname) );
5921 SCIP_CALL( delRangeVars(lpi) );
5922 }
5923 else
5924 {
5925 CHECK_ZERO( lpi->messagehdlr, GRBwrite(lpi->grbmodel, fname) );
5926 }
5927
5928 return SCIP_OKAY;
5929}
5930
5931/**@} */
unsigned int SCIP_DUALPACKET
Definition: bitencode.h:42
SCIP_VAR ** b
Definition: circlepacking.c:65
SCIP_Real * r
Definition: circlepacking.c:59
SCIP_VAR ** x
Definition: circlepacking.c:63
#define NULL
Definition: def.h:266
#define SCIP_MAXSTRLEN
Definition: def.h:287
#define SCIP_UNUSED(x)
Definition: def.h:427
#define SCIP_INVALID
Definition: def.h:192
#define SCIP_Bool
Definition: def.h:91
#define SCIP_CALL_QUIET(x)
Definition: def.h:348
#define SCIP_ALLOC(x)
Definition: def.h:384
#define SCIP_Real
Definition: def.h:172
#define TRUE
Definition: def.h:93
#define FALSE
Definition: def.h:94
#define MAX(x, y)
Definition: def.h:238
#define SCIP_CALL_ABORT(x)
Definition: def.h:352
#define EPSCEIL(x, eps)
Definition: def.h:206
#define SCIPABORT()
Definition: def.h:345
#define EPSFLOOR(x, eps)
Definition: def.h:205
#define REALABS(x)
Definition: def.h:196
#define SCIP_CALL(x)
Definition: def.h:373
SCIP_RETCODE SCIPlpiChgSides(SCIP_LPI *lpi, int nrows, const int *ind, const SCIP_Real *lhs, const SCIP_Real *rhs)
Definition: lpi_grb.c:2172
SCIP_RETCODE SCIPlpiSetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, const SCIP_LPISTATE *lpistate)
Definition: lpi_grb.c:5233
SCIP_RETCODE SCIPlpiGetBInvACol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_grb.c:5072
SCIP_RETCODE SCIPlpiGetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real *dval)
Definition: lpi_grb.c:5712
SCIP_Real SCIPlpiInfinity(SCIP_LPI *lpi)
Definition: lpi_grb.c:5854
SCIP_Bool SCIPlpiIsObjlimExc(SCIP_LPI *lpi)
Definition: lpi_grb.c:4087
SCIP_RETCODE SCIPlpiChgObjsen(SCIP_LPI *lpi, SCIP_OBJSEN objsen)
Definition: lpi_grb.c:2329
SCIP_Bool SCIPlpiIsInfinity(SCIP_LPI *lpi, SCIP_Real val)
Definition: lpi_grb.c:5863
SCIP_RETCODE SCIPlpiClear(SCIP_LPI *lpi)
Definition: lpi_grb.c:2082
SCIP_RETCODE SCIPlpiClearState(SCIP_LPI *lpi)
Definition: lpi_grb.c:5305
SCIP_Bool SCIPlpiExistsDualRay(SCIP_LPI *lpi)
Definition: lpi_grb.c:3886
SCIP_Bool SCIPlpiExistsPrimalRay(SCIP_LPI *lpi)
Definition: lpi_grb.c:3746
SCIP_RETCODE SCIPlpiGetBase(SCIP_LPI *lpi, int *cstat, int *rstat)
Definition: lpi_grb.c:4430
SCIP_RETCODE SCIPlpiReadState(SCIP_LPI *lpi, const char *fname)
Definition: lpi_grb.c:5349
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 SCIPlpiGetPrimalRay(SCIP_LPI *lpi, SCIP_Real *ray)
Definition: lpi_grb.c:4310
SCIP_RETCODE SCIPlpiGetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int *ival)
Definition: lpi_grb.c:5553
SCIP_RETCODE SCIPlpiWriteLP(SCIP_LPI *lpi, const char *fname)
Definition: lpi_grb.c:5905
SCIP_RETCODE SCIPlpiSetIntegralityInformation(SCIP_LPI *lpi, int ncols, int *intInfo)
Definition: lpi_grb.c:1285
SCIP_Bool SCIPlpiIsDualInfeasible(SCIP_LPI *lpi)
Definition: lpi_grb.c:3948
SCIP_RETCODE SCIPlpiSetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real dval)
Definition: lpi_grb.c:5755
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:3566
SCIP_RETCODE SCIPlpiSetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, const SCIP_LPINORMS *lpinorms)
Definition: lpi_grb.c:5477
SCIP_RETCODE SCIPlpiGetNNonz(SCIP_LPI *lpi, int *nnonz)
Definition: lpi_grb.c:2552
SCIP_Bool SCIPlpiHasPrimalSolve(void)
Definition: lpi_grb.c:1300
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:3629
SCIP_RETCODE SCIPlpiGetBounds(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *lbs, SCIP_Real *ubs)
Definition: lpi_grb.c:2800
SCIP_Bool SCIPlpiHasBarrierSolve(void)
Definition: lpi_grb.c:1316
SCIP_RETCODE SCIPlpiGetDualfarkas(SCIP_LPI *lpi, SCIP_Real *dualfarkas)
Definition: lpi_grb.c:4333
SCIP_RETCODE SCIPlpiGetObjval(SCIP_LPI *lpi, SCIP_Real *objval)
Definition: lpi_grb.c:4149
SCIP_RETCODE SCIPlpiScaleCol(SCIP_LPI *lpi, int col, SCIP_Real scaleval)
Definition: lpi_grb.c:2437
int SCIPlpiGetInternalStatus(SCIP_LPI *lpi)
Definition: lpi_grb.c:4123
SCIP_RETCODE SCIPlpiStartStrongbranch(SCIP_LPI *lpi)
Definition: lpi_grb.c:3355
SCIP_RETCODE SCIPlpiGetSolFeasibility(SCIP_LPI *lpi, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
Definition: lpi_grb.c:3722
SCIP_RETCODE SCIPlpiFreeNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition: lpi_grb.c:5521
SCIP_Bool SCIPlpiIsIterlimExc(SCIP_LPI *lpi)
Definition: lpi_grb.c:4099
SCIP_RETCODE SCIPlpiChgBounds(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *lb, const SCIP_Real *ub)
Definition: lpi_grb.c:2125
SCIP_Bool SCIPlpiIsPrimalUnbounded(SCIP_LPI *lpi)
Definition: lpi_grb.c:3783
SCIP_RETCODE SCIPlpiIgnoreInstability(SCIP_LPI *lpi, SCIP_Bool *success)
Definition: lpi_grb.c:4134
SCIP_RETCODE SCIPlpiWriteState(SCIP_LPI *lpi, const char *fname)
Definition: lpi_grb.c:5378
SCIP_RETCODE SCIPlpiFree(SCIP_LPI **lpi)
Definition: lpi_grb.c:1480
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:3589
SCIP_RETCODE SCIPlpiGetCoef(SCIP_LPI *lpi, int row, int col, SCIP_Real *val)
Definition: lpi_grb.c:2861
SCIP_Bool SCIPlpiIsPrimalFeasible(SCIP_LPI *lpi)
Definition: lpi_grb.c:3824
SCIP_RETCODE SCIPlpiReadLP(SCIP_LPI *lpi, const char *fname)
Definition: lpi_grb.c:5885
SCIP_RETCODE SCIPlpiGetRealSolQuality(SCIP_LPI *lpi, SCIP_LPSOLQUALITY qualityindicator, SCIP_Real *quality)
Definition: lpi_grb.c:4380
SCIP_Bool SCIPlpiIsDualFeasible(SCIP_LPI *lpi)
Definition: lpi_grb.c:3962
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:3382
SCIP_RETCODE SCIPlpiGetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition: lpi_grb.c:5427
SCIP_Bool SCIPlpiIsTimelimExc(SCIP_LPI *lpi)
Definition: lpi_grb.c:4111
SCIP_Bool SCIPlpiHasStateBasis(SCIP_LPI *lpi, SCIP_LPISTATE *lpistate)
Definition: lpi_grb.c:5339
SCIP_RETCODE SCIPlpiSetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int ival)
Definition: lpi_grb.c:5619
const char * SCIPlpiGetSolverName(void)
Definition: lpi_grb.c:1258
SCIP_RETCODE SCIPlpiSetBase(SCIP_LPI *lpi, const int *cstat, const int *rstat)
Definition: lpi_grb.c:4558
SCIP_Bool SCIPlpiHasPrimalRay(SCIP_LPI *lpi)
Definition: lpi_grb.c:3760
SCIP_RETCODE SCIPlpiGetBInvRow(SCIP_LPI *lpi, int r, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_grb.c:4752
SCIP_RETCODE SCIPlpiDelRows(SCIP_LPI *lpi, int firstrow, int lastrow)
Definition: lpi_grb.c:1881
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_RETCODE SCIPlpiGetBInvCol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_grb.c:4850
SCIP_RETCODE SCIPlpiGetColNames(SCIP_LPI *lpi, int firstcol, int lastcol, char **colnames, char *namestorage, int namestoragesize, int *storageleft)
Definition: lpi_grb.c:2714
SCIP_RETCODE SCIPlpiGetBInvARow(SCIP_LPI *lpi, int r, const SCIP_Real *binvrow, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_grb.c:4959
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_Bool SCIPlpiWasSolved(SCIP_LPI *lpi)
Definition: lpi_grb.c:3703
const char * SCIPlpiGetSolverDesc(void)
Definition: lpi_grb.c:1266
SCIP_RETCODE SCIPlpiSolveBarrier(SCIP_LPI *lpi, SCIP_Bool crossover)
Definition: lpi_grb.c:3232
SCIP_Bool SCIPlpiIsOptimal(SCIP_LPI *lpi)
Definition: lpi_grb.c:3989
SCIP_RETCODE SCIPlpiGetRowNames(SCIP_LPI *lpi, int firstrow, int lastrow, char **rownames, char *namestorage, int namestoragesize, int *storageleft)
Definition: lpi_grb.c:2736
SCIP_Bool SCIPlpiHasDualSolve(void)
Definition: lpi_grb.c:1308
SCIP_RETCODE SCIPlpiEndStrongbranch(SCIP_LPI *lpi)
Definition: lpi_grb.c:3368
SCIP_RETCODE SCIPlpiGetSides(SCIP_LPI *lpi, int firstrow, int lastrow, SCIP_Real *lhss, SCIP_Real *rhss)
Definition: lpi_grb.c:2834
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:3652
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:4220
SCIP_Bool SCIPlpiHasDualRay(SCIP_LPI *lpi)
Definition: lpi_grb.c:3900
SCIP_RETCODE SCIPlpiDelColset(SCIP_LPI *lpi, int *dstat)
Definition: lpi_grb.c:1747
SCIP_RETCODE SCIPlpiGetObj(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *vals)
Definition: lpi_grb.c:2780
SCIP_RETCODE SCIPlpiFreeState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lpi_grb.c:5322
SCIP_Bool SCIPlpiIsPrimalInfeasible(SCIP_LPI *lpi)
Definition: lpi_grb.c:3809
SCIP_RETCODE SCIPlpiSolveDual(SCIP_LPI *lpi)
Definition: lpi_grb.c:3089
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
SCIP_RETCODE SCIPlpiSolvePrimal(SCIP_LPI *lpi)
Definition: lpi_grb.c:2895
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
SCIP_Bool SCIPlpiIsDualUnbounded(SCIP_LPI *lpi)
Definition: lpi_grb.c:3923
SCIP_RETCODE SCIPlpiGetIterations(SCIP_LPI *lpi, int *iterations)
Definition: lpi_grb.c:4361
SCIP_RETCODE SCIPlpiGetBasisInd(SCIP_LPI *lpi, int *bind)
Definition: lpi_grb.c:4682
SCIP_RETCODE SCIPlpiCreate(SCIP_LPI **lpi, SCIP_MESSAGEHDLR *messagehdlr, const char *name, SCIP_OBJSEN objsen)
Definition: lpi_grb.c:1336
void * SCIPlpiGetSolverPointer(SCIP_LPI *lpi)
Definition: lpi_grb.c:1277
SCIP_RETCODE SCIPlpiChgObj(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *obj)
Definition: lpi_grb.c:2355
SCIP_RETCODE SCIPlpiGetObjsen(SCIP_LPI *lpi, SCIP_OBJSEN *objsen)
Definition: lpi_grb.c:2758
SCIP_Bool SCIPlpiIsStable(SCIP_LPI *lpi)
Definition: lpi_grb.c:4007
SCIP_RETCODE SCIPlpiGetNCols(SCIP_LPI *lpi, int *ncols)
Definition: lpi_grb.c:2531
SCIP_RETCODE SCIPlpiInterrupt(SCIP_LPI *lpi, SCIP_Bool interrupt)
Definition: lpi_grb.c:5831
SCIP_RETCODE SCIPlpiDelCols(SCIP_LPI *lpi, int firstcol, int lastcol)
Definition: lpi_grb.c:1704
SCIP_RETCODE SCIPlpiDelRowset(SCIP_LPI *lpi, int *dstat)
Definition: lpi_grb.c:1980
SCIP_RETCODE SCIPlpiScaleRow(SCIP_LPI *lpi, int row, SCIP_Real scaleval)
Definition: lpi_grb.c:2378
SCIP_RETCODE SCIPlpiGetNRows(SCIP_LPI *lpi, int *nrows)
Definition: lpi_grb.c:2514
SCIP_RETCODE SCIPlpiGetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lpi_grb.c:5170
SCIP_RETCODE SCIPlpiChgCoef(SCIP_LPI *lpi, int row, int col, SCIP_Real newval)
Definition: lpi_grb.c:2308
void SCIPsortIntReal(int *intarray, SCIP_Real *realarray, int len)
interface methods for specific LP solvers
SCIP_DUALPACKET ROWPACKET
Definition: lpi_clp.cpp:128
SCIP_DUALPACKET COLPACKET
Definition: lpi_clp.cpp:126
static void SCIPdecodeDualBitNeg(const SCIP_DUALPACKET *inp, int *out, int count)
Definition: lpi_grb.c:547
static SCIP_RETCODE setBase(SCIP_LPI *lpi)
Definition: lpi_grb.c:422
static void lpistatePack(SCIP_LPISTATE *lpistate, const int *cstat, const int *rstat)
Definition: lpi_grb.c:623
static SCIP_RETCODE getDblParam(SCIP_LPI *lpi, const char *param, double *p)
Definition: lpi_grb.c:852
static SCIP_RETCODE getBase(SCIP_LPI *lpi, SCIP_Bool *success)
Definition: lpi_grb.c:364
static void lpistateUnpack(const SCIP_LPISTATE *lpistate, int *cstat, int *rstat)
Definition: lpi_grb.c:639
static int rowpacketNum(int nrows)
Definition: lpi_grb.c:464
static SCIP_RETCODE reconvertSides(SCIP_LPI *lpi, int firstrow, int lastrow, SCIP_Real *lhs, SCIP_Real *rhs)
Definition: lpi_grb.c:970
struct GRBParam GRBPARAM
Definition: lpi_grb.c:152
static SCIP_RETCODE addRangeVars(SCIP_LPI *lpi)
Definition: lpi_grb.c:1107
static void copyParameterValues(GRBPARAM *dest, const GRBPARAM *source)
Definition: lpi_grb.c:787
SCIP_DUALPACKET ROWPACKET
Definition: lpi_grb.c:97
static SCIP_RETCODE ensureCstatMem(SCIP_LPI *lpi, int num)
Definition: lpi_grb.c:272
static GRBenv * reusegrbenv
Definition: lpi_grb.c:65
static SCIP_RETCODE getIntParam(SCIP_LPI *lpi, const char *param, int *p)
Definition: lpi_grb.c:802
#define COLS_PER_PACKET
Definition: lpi_grb.c:96
static void checkRangeInfo(SCIP_LPI *lpi)
Definition: lpi_grb.c:1065
static SCIP_RETCODE ensureRngrowmapMem(SCIP_LPI *lpi, int num)
Definition: lpi_grb.c:316
static int numlp
Definition: lpi_grb.c:66
static SCIP_RETCODE convertSides(SCIP_LPI *lpi, int nrows, const SCIP_Real *lhs, const SCIP_Real *rhs, int *rngcount)
Definition: lpi_grb.c:912
static SCIP_RETCODE delRangeVars(SCIP_LPI *lpi)
Definition: lpi_grb.c:1138
static void lpistateFree(SCIP_LPISTATE **lpistate, BMS_BLKMEM *blkmem)
Definition: lpi_grb.c:677
SCIP_DUALPACKET COLPACKET
Definition: lpi_grb.c:95
static SCIP_RETCODE restoreLPData(SCIP_LPI *lpi)
Definition: lpi_grb.c:1033
static void SCIPencodeDualBitNeg(const int *inp, SCIP_DUALPACKET *out, int count)
Definition: lpi_grb.c:476
#define CHECK_ZERO(messagehdlr, x)
Definition: lpi_grb.c:71
static const double dblparammin[NUMDBLPARAM]
Definition: lpi_grb.c:135
#define NUMINTPARAM
Definition: lpi_grb.c:108
#define SCIP_DUALPACKETSIZE
Definition: lpi_grb.c:93
static SCIP_RETCODE ensureRstatMem(SCIP_LPI *lpi, int num)
Definition: lpi_grb.c:294
static int colpacketNum(int ncols)
Definition: lpi_grb.c:455
static SCIP_RETCODE ensureRngrowsMem(SCIP_LPI *lpi, int num)
Definition: lpi_grb.c:341
static SCIP_RETCODE setParameterValues(SCIP_LPI *lpi, GRBPARAM *grbparam)
Definition: lpi_grb.c:746
static SCIP_RETCODE ensureSidechgMem(SCIP_LPI *lpi, int num)
Definition: lpi_grb.c:224
static const char * dblparam[NUMDBLPARAM]
Definition: lpi_grb.c:123
static SCIP_RETCODE getParameterValues(SCIP_LPI *lpi, GRBPARAM *grbparam)
Definition: lpi_grb.c:699
#define NUMDBLPARAM
Definition: lpi_grb.c:121
static void clearRangeInfo(SCIP_LPI *lpi)
Definition: lpi_grb.c:1168
static const char grbname[]
Definition: lpi_grb.c:1246
static SCIP_RETCODE addRangeInfo(SCIP_LPI *lpi, int rngcount, int firstrow)
Definition: lpi_grb.c:1185
static const char * intparam[NUMINTPARAM]
Definition: lpi_grb.c:110
#define CHECK_ZERO_STAR(messagehdlr, x)
Definition: lpi_grb.c:80
static SCIP_RETCODE setIntParam(SCIP_LPI *lpi, const char *param, int parval)
Definition: lpi_grb.c:827
#define ROWS_PER_PACKET
Definition: lpi_grb.c:98
static SCIP_RETCODE checkParameterValues(SCIP_LPI *lpi)
Definition: lpi_grb.c:726
static SCIP_RETCODE lpistateCreate(SCIP_LPISTATE **lpistate, BMS_BLKMEM *blkmem, int ncols, int nrows, int nrngrows)
Definition: lpi_grb.c:655
static SCIP_RETCODE setDblParam(SCIP_LPI *lpi, const char *param, double parval)
Definition: lpi_grb.c:877
static void invalidateSolution(SCIP_LPI *lpi)
Definition: lpi_grb.c:902
#define GRB_REFACTORMAXITERS
Definition: lpi_grb.c:104
#define SVECTOR
Definition: lpi_grb.c:89
unsigned int SCIP_DUALPACKET
Definition: lpi_grb.c:92
static SCIP_RETCODE ensureValMem(SCIP_LPI *lpi, int num)
Definition: lpi_grb.c:249
#define BMSfreeMemory(ptr)
Definition: memory.h:145
#define BMSfreeBlockMemory(mem, ptr)
Definition: memory.h:465
#define BMSallocBlockMemory(mem, ptr)
Definition: memory.h:451
#define BMSreallocMemoryArray(ptr, num)
Definition: memory.h:127
#define BMSfreeBlockMemoryArrayNull(mem, ptr, num)
Definition: memory.h:468
#define BMSallocMemoryArray(ptr, num)
Definition: memory.h:123
#define BMSfreeMemoryArray(ptr)
Definition: memory.h:147
#define BMSallocBlockMemoryArray(mem, ptr, num)
Definition: memory.h:454
#define BMSfreeBlockMemoryArray(mem, ptr, num)
Definition: memory.h:467
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:130
#define BMSallocClearMemoryArray(ptr, num)
Definition: memory.h:125
struct BMS_BlkMem BMS_BLKMEM
Definition: memory.h:437
#define BMSfreeMemoryArrayNull(ptr)
Definition: memory.h:148
#define BMSallocMemory(ptr)
Definition: memory.h:118
void SCIPmessagePrintWarning(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr,...)
Definition: message.c:427
real eps
public methods for message output
#define SCIPerrorMessage
Definition: pub_message.h:64
#define SCIPdebugMessage
Definition: pub_message.h:96
#define SCIPdebugPrintf
Definition: pub_message.h:99
methods for sorting joint arrays of various types
static SCIP_RETCODE presolve(SCIP *scip, SCIP_Bool *unbounded, SCIP_Bool *infeasible, SCIP_Bool *vanished)
Definition: scip_solve.c:1114
double dblparval[NUMDBLPARAM]
Definition: lpi_cpx.c:138
int intparval[NUMINTPARAM]
Definition: lpi_cpx.c:137
double * rownorm
Definition: lpi_grb.c:213
double * colnorm
Definition: lpi_grb.c:212
COLPACKET * packcstat
Definition: lpi_clp.cpp:136
ROWPACKET * packrstat
Definition: lpi_clp.cpp:137
int nrngrows
Definition: lpi_grb.c:202
GRBPARAM grbparam
Definition: lpi_grb.c:167
int rngrowmapsize
Definition: lpi_grb.c:191
GRBPARAM curparam
Definition: lpi_grb.c:166
int * rngrows
Definition: lpi_grb.c:189
int rngrowssize
Definition: lpi_grb.c:193
int iterations
Definition: lpi_cpx.c:167
GRBenv * grbenv
Definition: lpi_grb.c:158
SCIP_Real * valarray
Definition: lpi_cpx.c:157
GRBPARAM defparam
Definition: lpi_grb.c:165
int valsize
Definition: lpi_cpx.c:164
int * rngrowmap
Definition: lpi_grb.c:187
GRBmodel * grbmodel
Definition: lpi_grb.c:163
SCIP_Bool rngvarsadded
Definition: lpi_grb.c:194
GRBenv ** reusegrbenv
Definition: lpi_grb.c:161
SCIP_CPXPARAM curparam
Definition: lpi_cpx.c:147
int * indarray
Definition: lpi_cpx.c:161
SCIP_Real conditionlimit
Definition: lpi_cpx.c:174
int * numlp
Definition: lpi_grb.c:160
int * cstat
Definition: lpi_clp.cpp:107
SCIP_Real * rngvals
Definition: lpi_grb.c:190
SCIP_Bool solisbasic
Definition: lpi_cpx.c:169
int solstat
Definition: lpi_cpx.c:149
SCIP_Bool fromscratch
Definition: lpi_cpx.c:171
int rstatsize
Definition: lpi_clp.cpp:110
SCIP_Real * rhsarray
Definition: lpi_cpx.c:155
int * rstat
Definition: lpi_clp.cpp:108
int sidechgsize
Definition: lpi_cpx.c:163
SCIP_PRICING pricing
Definition: lpi_clp.cpp:112
int cstatsize
Definition: lpi_clp.cpp:109
char * senarray
Definition: lpi_cpx.c:154
SCIP_MESSAGEHDLR * messagehdlr
Definition: lpi_cpx.c:185
SCIP_Real * rngarray
Definition: lpi_cpx.c:156
int * rngidxarray
Definition: lpi_grb.c:171
SCIP_Bool checkcondition
Definition: lpi_cpx.c:175
int nrngrows
Definition: lpi_grb.c:192
@ SCIP_PRICING_STEEPQSTART
Definition: type_lpi.h:83
@ SCIP_PRICING_AUTO
Definition: type_lpi.h:79
@ SCIP_PRICING_DEVEX
Definition: type_lpi.h:84
@ SCIP_PRICING_STEEP
Definition: type_lpi.h:82
@ SCIP_PRICING_FULL
Definition: type_lpi.h:80
@ SCIP_PRICING_LPIDEFAULT
Definition: type_lpi.h:78
@ SCIP_PRICING_PARTIAL
Definition: type_lpi.h:81
enum SCIP_Pricing SCIP_PRICING
Definition: type_lpi.h:86
enum SCIP_LPParam SCIP_LPPARAM
Definition: type_lpi.h:73
@ SCIP_LPSOLQUALITY_EXACTCONDITION
Definition: type_lpi.h:102
@ SCIP_LPSOLQUALITY_ESTIMCONDITION
Definition: type_lpi.h:101
@ SCIP_LPPAR_PRICING
Definition: type_lpi.h:54
@ SCIP_LPPAR_THREADS
Definition: type_lpi.h:66
@ SCIP_LPPAR_LPINFO
Definition: type_lpi.h:55
@ SCIP_LPPAR_SCALING
Definition: type_lpi.h:52
@ SCIP_LPPAR_LPTILIM
Definition: type_lpi.h:61
@ SCIP_LPPAR_BARRIERCONVTOL
Definition: type_lpi.h:58
@ SCIP_LPPAR_PRESOLVING
Definition: type_lpi.h:53
@ SCIP_LPPAR_CONDITIONLIMIT
Definition: type_lpi.h:67
@ SCIP_LPPAR_RANDOMSEED
Definition: type_lpi.h:69
@ SCIP_LPPAR_FASTMIP
Definition: type_lpi.h:51
@ SCIP_LPPAR_DUALFEASTOL
Definition: type_lpi.h:57
@ SCIP_LPPAR_FROMSCRATCH
Definition: type_lpi.h:50
@ SCIP_LPPAR_MARKOWITZ
Definition: type_lpi.h:62
@ SCIP_LPPAR_FEASTOL
Definition: type_lpi.h:56
@ SCIP_LPPAR_LPITLIM
Definition: type_lpi.h:60
@ SCIP_LPPAR_OBJLIM
Definition: type_lpi.h:59
@ SCIP_BASESTAT_BASIC
Definition: type_lpi.h:92
@ SCIP_BASESTAT_UPPER
Definition: type_lpi.h:93
@ SCIP_BASESTAT_LOWER
Definition: type_lpi.h:91
@ SCIP_BASESTAT_ZERO
Definition: type_lpi.h:94
enum SCIP_LPSolQuality SCIP_LPSOLQUALITY
Definition: type_lpi.h:104
@ SCIP_OBJSEN_MAXIMIZE
Definition: type_lpi.h:42
@ SCIP_OBJSEN_MINIMIZE
Definition: type_lpi.h:43
enum SCIP_ObjSen SCIP_OBJSEN
Definition: type_lpi.h:45
@ SCIP_LPERROR
Definition: type_retcode.h:49
@ SCIP_INVALIDDATA
Definition: type_retcode.h:52
@ SCIP_PARAMETERUNKNOWN
Definition: type_retcode.h:55
@ SCIP_NOMEMORY
Definition: type_retcode.h:44
@ SCIP_OKAY
Definition: type_retcode.h:42
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63