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