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