Scippy

SCIP

Solving Constraint Integer Programs

lpi_cpx.c
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the program and library */
4/* SCIP --- Solving Constraint Integer Programs */
5/* */
6/* Copyright (c) 2002-2024 Zuse Institute Berlin (ZIB) */
7/* */
8/* Licensed under the Apache License, Version 2.0 (the "License"); */
9/* you may not use this file except in compliance with the License. */
10/* You may obtain a copy of the License at */
11/* */
12/* http://www.apache.org/licenses/LICENSE-2.0 */
13/* */
14/* Unless required by applicable law or agreed to in writing, software */
15/* distributed under the License is distributed on an "AS IS" BASIS, */
16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17/* See the License for the specific language governing permissions and */
18/* limitations under the License. */
19/* */
20/* You should have received a copy of the Apache-2.0 license */
21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
22/* */
23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24
25/**@file lpi_cpx.c
26 * @ingroup LPIS
27 * @brief LP interface for CPLEX >= 8.0
28 * @author Tobias Achterberg
29 * @author Timo Berthold
30 * @author Stefan Heinz
31 * @author Gerald Gamrath
32 * @author Ambros Gleixner
33 * @author Marc Pfetsch
34 * @author Stefan Vigerske
35 * @author Michael Winkler
36 * @author Kati Wolter
37 * @author Felipe Serrano
38 */
39
40/*--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
41
42#include <assert.h>
43
44#include "cplex.h"
45#ifndef CPX_SUBVERSION
46#define CPX_SUBVERSION 0
47#endif
48#include "scip/bitencode.h"
49#include "lpi/lpi.h"
50#include "scip/pub_message.h"
51
52
53
54#define CHECK_ZERO(messagehdlr, x) { int _restat_; \
55 if( (_restat_ = (x)) != 0 ) \
56 { \
57 SCIPmessagePrintWarning((messagehdlr), "LP Error: CPLEX returned %d\n", _restat_); \
58 return SCIP_LPERROR; \
59 } \
60 }
61
62/* this macro is only called in functions returning SCIP_Bool; thus, we return FALSE if there is an error in optimized mode */
63#define ABORT_ZERO(x) { /*lint --e{527}*/ int _restat_; \
64 if( (_restat_ = (x)) != 0 ) \
65 { \
66 SCIPerrorMessage("LP Error: CPLEX returned %d\n", _restat_); \
67 SCIPABORT(); \
68 return FALSE; \
69 } \
70 }
71
72#define CPX_INT_MAX 2100000000 /* CPLEX doesn't accept larger values in integer parameters */
73
74/* At several places we need to guarantee to have a factorization of an optimal basis and call the simplex to produce
75 * it. In a numerical perfect world, this should need no iterations. However, due to numerical inaccuracies after
76 * refactorization, it might be necessary to do a few extra pivot steps. */
77#define CPX_REFACTORMAXITERS 50 /* maximal number of iterations allowed for producing a refactorization of the basis */
78
79/* CPLEX seems to ignore bounds with absolute value less than 1e-10. There is no interface define for this constant yet,
80 * so we define it here. */
81#define CPX_MAGICZEROCONSTANT 1e-10
82
83typedef SCIP_DUALPACKET COLPACKET; /* each column needs two bits of information (basic/on_lower/on_upper) */
84#define COLS_PER_PACKET SCIP_DUALPACKETSIZE
85typedef SCIP_DUALPACKET ROWPACKET; /* each row needs two bit of information (basic/on_lower/on_upper) */
86#define ROWS_PER_PACKET SCIP_DUALPACKETSIZE
87
88/* CPLEX parameter lists which can be changed */
89#if (CPX_VERSION < 12060100)
90#define NUMINTPARAM 11
91#else
92#define NUMINTPARAM 10
93#endif
94static const int intparam[NUMINTPARAM] =
95{
96 CPX_PARAM_ADVIND,
97 CPX_PARAM_ITLIM,
98#if (CPX_VERSION < 12060100)
99 CPX_PARAM_FASTMIP,
100#endif
101 CPX_PARAM_SCAIND,
102 CPX_PARAM_PREIND,
103 CPX_PARAM_PPRIIND,
104 CPX_PARAM_DPRIIND,
105 CPX_PARAM_SIMDISPLAY,
106 CPX_PARAM_SCRIND,
107 CPX_PARAM_THREADS,
108 CPX_PARAM_RANDOMSEED
109};
110
111#define NUMDBLPARAM 7
112static const int dblparam[NUMDBLPARAM] =
113{
114 CPX_PARAM_EPRHS,
115 CPX_PARAM_EPOPT,
116 CPX_PARAM_BAREPCOMP,
117 CPX_PARAM_OBJLLIM,
118 CPX_PARAM_OBJULIM,
119 CPX_PARAM_TILIM,
120 CPX_PARAM_EPMRK
121};
122
123static const double dblparammin[NUMDBLPARAM] =
124{
125 +1e-09, /*CPX_PARAM_EPRHS*/
126 +1e-09, /*CPX_PARAM_EPOPT*/
127 +1e-12, /*CPX_PARAM_BAREPCOMP*/
128 -1e+99, /*CPX_PARAM_OBJLLIM*/
129 -1e+99, /*CPX_PARAM_OBJULIM*/
130 -1e+99, /*CPX_PARAM_TILIM*/
131 0.0001 /*CPX_PARAM_EPMRK*/
132};
133
134/** CPLEX parameter settings */
136{
137 int intparval[NUMINTPARAM]; /**< integer parameter values */
138 double dblparval[NUMDBLPARAM]; /**< double parameter values */
139};
141
142/** LP interface */
143struct SCIP_LPi
144{
145 CPXENVptr cpxenv; /**< CPLEX environment */
146 SCIP_CPXPARAM defparam; /**< default CPLEX parameters */
147 SCIP_CPXPARAM curparam; /**< current CPLEX parameters in the environment */
148 CPXLPptr cpxlp; /**< CPLEX LP pointer */
149 int solstat; /**< solution status of last optimization call */
150 int method; /**< solution method of last optimization call */
151 SCIP_CPXPARAM cpxparam; /**< current parameter values for this LP */
152 char* larray; /**< array with 'L' entries for changing lower bounds */
153 char* uarray; /**< array with 'U' entries for changing upper bounds */
154 char* senarray; /**< array for storing row senses */
155 SCIP_Real* rhsarray; /**< array for storing rhs values */
156 SCIP_Real* rngarray; /**< array for storing range values */
157 SCIP_Real* valarray; /**< array for storing coefficient values */
158 int* rngindarray; /**< array for storing row indices with range values */
159 int* cstat; /**< array for storing column basis status */
160 int* rstat; /**< array for storing row basis status */
161 int* indarray; /**< array for storing coefficient indices */
162 int boundchgsize; /**< size of larray and uarray */
163 int sidechgsize; /**< size of senarray, rngarray, and rngindarray */
164 int valsize; /**< size of valarray and indarray */
165 int cstatsize; /**< size of cstat array */
166 int rstatsize; /**< size of rstat array */
167 int iterations; /**< number of iterations used in the last solving call */
168 SCIP_PRICING pricing; /**< SCIP pricing setting */
169 SCIP_Bool solisbasic; /**< is current LP solution a basic solution? */
170 SCIP_Bool instabilityignored; /**< was the instability of the last LP ignored? */
171 SCIP_Bool fromscratch; /**< shall solves be performed with CPX_PARAM_ADVIND turned off? */
172 SCIP_Bool clearstate; /**< shall next solve be performed with CPX_PARAM_ADVIND turned off? */
173 SCIP_Real feastol; /**< feasibility tolerance for integrality */
174 SCIP_Real conditionlimit; /**< maximum condition number of LP basis counted as stable (-1.0: no limit) */
175 SCIP_Bool checkcondition; /**< should condition number of LP basis be checked for stability? */
176#if (CPX_VERSION <= 1100)
177 SCIP_Bool rngfound; /**< was ranged row found; scaling is disabled, because there is a bug
178 * in the scaling algorithm for ranged rows in CPLEX up to version 11.0 */
179#endif
180#if (CPX_VERSION == 1100 || (CPX_VERSION == 1220 && (CPX_SUBVERSION == 0 || CPX_SUBVERSION == 2)))
181 int pseudonthreads; /**< number of threads that SCIP set for the LP solver, but due to CPLEX bug,
182 * we set the thread count to 1. In order to fulfill assert in lp.c,
183 * we have to return the value set by SCIP and not the real thread count */
184#endif
185 SCIP_MESSAGEHDLR* messagehdlr; /**< messagehdlr handler to printing messages, or NULL */
186};
187
188/** LPi state stores basis information */
189struct SCIP_LPiState
190{
191 int ncols; /**< number of LP columns */
192 int nrows; /**< number of LP rows */
193 COLPACKET* packcstat; /**< column basis status in compressed form */
194 ROWPACKET* packrstat; /**< row basis status in compressed form */
195};
196
197/** LPi norms stores pricing norms */
199{
200 int normlen; /**< number of rows for which dual norm is stored */
201 double* norm; /**< dual norms */
202 int* head; /**< row/column indices corresponding to norms */
203};
204
205
206/*
207 * dynamic memory arrays
208 */
209
210/** resizes larray and uarray to have at least num entries */
211static
213 SCIP_LPI* lpi, /**< LP interface structure */
214 int num /**< minimal number of entries in array */
215 )
216{
217 assert(lpi != NULL);
218
219 if( num > lpi->boundchgsize )
220 {
221 int newsize;
222 int i;
223
224 newsize = MAX(2*lpi->boundchgsize, num);
225 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->larray, newsize) );
226 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->uarray, newsize) );
227 for( i = lpi->boundchgsize; i < newsize; ++i )
228 {
229 lpi->larray[i] = 'L';
230 lpi->uarray[i] = 'U';
231 }
232 lpi->boundchgsize = newsize;
233 }
234 assert(num <= lpi->boundchgsize);
235
236 return SCIP_OKAY;
237}
238
239/** resizes senarray, rngarray, and rngindarray to have at least num entries */
240static
242 SCIP_LPI* lpi, /**< LP interface structure */
243 int num /**< minimal number of entries in array */
244 )
245{
246 assert(lpi != NULL);
247
248 if( num > lpi->sidechgsize )
249 {
250 int newsize;
251
252 newsize = MAX(2*lpi->sidechgsize, num);
253 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->senarray, newsize) );
254 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->rhsarray, newsize) );
255 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->rngarray, newsize) );
257 lpi->sidechgsize = newsize;
258 }
259 assert(num <= lpi->sidechgsize);
260
261 return SCIP_OKAY;
262}
263
264/** resizes valarray and indarray to have at least num entries */
265static
267 SCIP_LPI* lpi, /**< LP interface structure */
268 int num /**< minimal number of entries in array */
269 )
270{
271 assert(lpi != NULL);
272
273 if( num > lpi->valsize )
274 {
275 int newsize;
276
277 newsize = MAX(2*lpi->valsize, num);
278 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->valarray, newsize) );
279 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->indarray, newsize) );
280 lpi->valsize = newsize;
281 }
282 assert(num <= lpi->valsize);
283
284 return SCIP_OKAY;
285}
286
287/** resizes cstat array to have at least num entries */
288static
290 SCIP_LPI* lpi, /**< LP interface structure */
291 int num /**< minimal number of entries in array */
292 )
293{
294 assert(lpi != NULL);
295
296 if( num > lpi->cstatsize )
297 {
298 int newsize;
299
300 newsize = MAX(2*lpi->cstatsize, num);
301 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->cstat, newsize) );
302 lpi->cstatsize = newsize;
303 }
304 assert(num <= lpi->cstatsize);
305
306 return SCIP_OKAY;
307}
308
309/** resizes rstat array to have at least num entries */
310static
312 SCIP_LPI* lpi, /**< LP interface structure */
313 int num /**< minimal number of entries in array */
314 )
315{
316 assert(lpi != NULL);
317
318 if( num > lpi->rstatsize )
319 {
320 int newsize;
321
322 newsize = MAX(2*lpi->rstatsize, num);
323 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->rstat, newsize) );
324 lpi->rstatsize = newsize;
325 }
326 assert(num <= lpi->rstatsize);
327
328 return SCIP_OKAY;
329}
330
331/** stores current basis in internal arrays of LPI data structure */
332static
334 SCIP_LPI* lpi /**< LP interface structure */
335 )
336{
337 int ncols;
338 int nrows;
339
340 assert(lpi != NULL);
341 assert(lpi->cpxenv != NULL);
342
343 SCIPdebugMessage("getBase()\n");
344
345 ncols = CPXgetnumcols(lpi->cpxenv, lpi->cpxlp);
346 nrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
347
348 /* allocate enough memory for storing uncompressed basis information */
349 SCIP_CALL( ensureCstatMem(lpi, ncols) );
350 SCIP_CALL( ensureRstatMem(lpi, nrows) );
351
352 /* get unpacked basis information from CPLEX */
353 CHECK_ZERO( lpi->messagehdlr, CPXgetbase(lpi->cpxenv, lpi->cpxlp, lpi->cstat, lpi->rstat) );
354
355 return SCIP_OKAY;
356}
357
358/** loads basis stored in internal arrays of LPI data structure into CPLEX */
359static
361 SCIP_LPI* lpi /**< LP interface structure */
362 )
363{
364 assert(lpi != NULL);
365 assert(lpi->cpxenv != NULL);
366
367 SCIPdebugMessage("setBase()\n");
368
369 /* load basis information into CPLEX */
370 CHECK_ZERO( lpi->messagehdlr, CPXcopybase(lpi->cpxenv, lpi->cpxlp, lpi->cstat, lpi->rstat) );
371
372 /* because the basis status values are equally defined in SCIP and CPLEX, they don't need to be transformed */
373 assert((int)SCIP_BASESTAT_LOWER == CPX_AT_LOWER); /*lint !e506*/
374 assert((int)SCIP_BASESTAT_BASIC == CPX_BASIC); /*lint !e506*/
375 assert((int)SCIP_BASESTAT_UPPER == CPX_AT_UPPER); /*lint !e506*/
376 assert((int)SCIP_BASESTAT_ZERO == CPX_FREE_SUPER); /*lint !e506*/
377
378 return SCIP_OKAY;
379}
380
381
382
383
384/*
385 * LPi state methods
386 */
387
388/** returns the number of packets needed to store column packet information */
389static
391 int ncols /**< number of columns to store */
392 )
393{
394 return (ncols+(int)COLS_PER_PACKET-1)/(int)COLS_PER_PACKET;
395}
396
397/** returns the number of packets needed to store row packet information */
398static
400 int nrows /**< number of rows to store */
401 )
402{
403 return (nrows+(int)ROWS_PER_PACKET-1)/(int)ROWS_PER_PACKET;
404}
405
406/** store row and column basis status in a packed LPi state object */
407static
409 SCIP_LPISTATE* lpistate, /**< pointer to LPi state data */
410 const int* cstat, /**< basis status of columns in unpacked format */
411 const int* rstat /**< basis status of rows in unpacked format */
412 )
413{
414 assert(lpistate != NULL);
415 assert(lpistate->packcstat != NULL);
416 assert(lpistate->packrstat != NULL);
417
418 SCIPencodeDualBit(cstat, lpistate->packcstat, lpistate->ncols);
419 SCIPencodeDualBit(rstat, lpistate->packrstat, lpistate->nrows);
420}
421
422/** unpacks row and column basis status from a packed LPi state object */
423static
425 const SCIP_LPISTATE* lpistate, /**< pointer to LPi state data */
426 int* cstat, /**< buffer for storing basis status of columns in unpacked format */
427 int* rstat /**< buffer for storing basis status of rows in unpacked format */
428 )
429{
430 assert(lpistate != NULL);
431 assert(lpistate->packcstat != NULL);
432 assert(lpistate->packrstat != NULL);
433
434 SCIPdecodeDualBit(lpistate->packcstat, cstat, lpistate->ncols);
435 SCIPdecodeDualBit(lpistate->packrstat, rstat, lpistate->nrows);
436}
437
438/** creates LPi state information object */
439static
441 SCIP_LPISTATE** lpistate, /**< pointer to LPi state */
442 BMS_BLKMEM* blkmem, /**< block memory */
443 int ncols, /**< number of columns to store */
444 int nrows /**< number of rows to store */
445 )
446{
447 assert(lpistate != NULL);
448 assert(blkmem != NULL);
449 assert(ncols >= 0);
450 assert(nrows >= 0);
451
452 SCIP_ALLOC( BMSallocBlockMemory(blkmem, lpistate) );
453 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpistate)->packcstat, colpacketNum(ncols)) );
454 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpistate)->packrstat, rowpacketNum(nrows)) );
455
456 return SCIP_OKAY;
457}
458
459/** frees LPi state information */
460static
462 SCIP_LPISTATE** lpistate, /**< pointer to LPi state information (like basis information) */
463 BMS_BLKMEM* blkmem /**< block memory */
464 )
465{
466 assert(blkmem != NULL);
467 assert(lpistate != NULL);
468 assert(*lpistate != NULL);
469
470 BMSfreeBlockMemoryArray(blkmem, &(*lpistate)->packcstat, colpacketNum((*lpistate)->ncols));
471 BMSfreeBlockMemoryArray(blkmem, &(*lpistate)->packrstat, rowpacketNum((*lpistate)->nrows));
472 BMSfreeBlockMemory(blkmem, lpistate);
473}
474
475
476
477/*
478 * local methods
479 */
480
481/** gets all CPLEX parameters used in LPI */
482static
484 SCIP_LPI* lpi, /**< LP interface structure */
485 SCIP_CPXPARAM* cpxparam /**< current parameter values for this LP */
486 )
487{
488 int i;
489
490 assert(lpi != NULL);
491 assert(cpxparam != NULL);
492
493 SCIPdebugMessage("getParameterValues()\n");
494
495 for( i = 0; i < NUMINTPARAM; ++i )
496 {
497 CHECK_ZERO( lpi->messagehdlr, CPXgetintparam(lpi->cpxenv, intparam[i], &(cpxparam->intparval[i])) );
498 }
499 for( i = 0; i < NUMDBLPARAM; ++i )
500 {
501 CHECK_ZERO( lpi->messagehdlr, CPXgetdblparam(lpi->cpxenv, dblparam[i], &(cpxparam->dblparval[i])) );
502 }
503
504 return SCIP_OKAY;
505}
506
507/** in debug mode, checks validity of CPLEX parameters */
508static
510 SCIP_LPI*const lpi /**< LP interface structure */
511 )
512{
513#ifndef NDEBUG
514 SCIP_CPXPARAM par;
515 int i;
516
517 assert(lpi != NULL);
518 assert(lpi->cpxenv != NULL);
519
520 SCIP_CALL( getParameterValues(lpi, &par) );
521 for( i = 0; i < NUMINTPARAM; ++i )
522 {
523#if (CPX_VERSION == 12070100 || CPX_VERSION == 12070000)
524 /* due to a bug in CPLEX 12.7.0 and CPLEX 12.7.1, we need to disable scaling for these versions */
525 if ( intparam[i] != CPX_PARAM_SCAIND )
526#endif
527 assert(lpi->curparam.intparval[i] == par.intparval[i]
528 || (lpi->curparam.intparval[i] == CPX_INT_MAX && par.intparval[i] >= CPX_INT_MAX));
529 }
530 for( i = 0; i < NUMDBLPARAM; ++i )
531 assert(MAX(lpi->curparam.dblparval[i], dblparammin[i]) == par.dblparval[i]); /*lint !e777*/
532#endif
533
534 return SCIP_OKAY;
535}
536
537/** sets all CPLEX parameters used in LPI */
538static
540 SCIP_LPI*const lpi, /**< LP interface structure */
541 SCIP_CPXPARAM*const cpxparam /**< current parameter values for this LP */
542 )
543{
544 int i;
545
546 assert(lpi != NULL);
547 assert(lpi->cpxenv != NULL);
548 assert(cpxparam != NULL);
549
550 SCIPdebugMessage("setParameterValues()\n");
551
552 for( i = 0; i < NUMINTPARAM; ++i )
553 {
554 if( lpi->curparam.intparval[i] != cpxparam->intparval[i] )
555 {
556 SCIPdebugMessage("setting CPLEX int parameter %d from %d to %d\n",
557 intparam[i], lpi->curparam.intparval[i], cpxparam->intparval[i]);
558 lpi->curparam.intparval[i] = cpxparam->intparval[i];
559#if (CPX_VERSION == 12070000)
560 /* due to a bug in CPLEX 12.7.0, we need to disable scaling for this version */
561 if ( intparam[i] != CPX_PARAM_SCAIND )
562#endif
563 {
564 CHECK_ZERO( lpi->messagehdlr, CPXsetintparam(lpi->cpxenv, intparam[i], lpi->curparam.intparval[i]) );
565 }
566 }
567 }
568 for( i = 0; i < NUMDBLPARAM; ++i )
569 {
570 if( lpi->curparam.dblparval[i] != cpxparam->dblparval[i] ) /*lint !e777*/
571 {
572 SCIPdebugMessage("setting CPLEX dbl parameter %d from %g to %g\n",
573 dblparam[i], lpi->curparam.dblparval[i], MAX(cpxparam->dblparval[i], dblparammin[i]));
574 lpi->curparam.dblparval[i] = MAX(cpxparam->dblparval[i], dblparammin[i]);
575 CHECK_ZERO( lpi->messagehdlr, CPXsetdblparam(lpi->cpxenv, dblparam[i], lpi->curparam.dblparval[i]) );
576 }
577 }
578
580
581 return SCIP_OKAY;
582}
583
584/** copies CPLEX parameters from source to dest */
585static
587 SCIP_CPXPARAM* dest, /**< CPLEX parameters to copy to */
588 SCIP_CPXPARAM*const source /**< CPLEX parameters which will be copied */
589 )
590{
591 int i;
592
593 for( i = 0; i < NUMINTPARAM; ++i )
594 dest->intparval[i] = source->intparval[i];
595 for( i = 0; i < NUMDBLPARAM; ++i )
596 dest->dblparval[i] = source->dblparval[i];
597}
598
599/** gets a single integer parameter value */
600static
602 SCIP_LPI* lpi, /**< LP interface structure */
603 int const param /**< parameter to get value for */
604 )
605{
606 int i;
607
608 assert(lpi != NULL);
609
610 for( i = 0; i < NUMINTPARAM; ++i )
611 {
612 if( intparam[i] == param )
613 return lpi->cpxparam.intparval[i];
614 }
615
616 SCIPerrorMessage("unknown CPLEX integer parameter\n");
617 SCIPABORT();
618 return 0; /*lint !e527*/
619}
620
621/** gets a single double parameter value */
622static
624 SCIP_LPI* lpi, /**< LP interface structure */
625 int const param /**< parameter to get value for */
626 )
627{
628 SCIP_Real val;
629 int i;
630
631 assert(lpi != NULL);
632
633 for( i = 0; i < NUMDBLPARAM; ++i )
634 {
635 if( dblparam[i] == param )
636 {
637 val = lpi->cpxparam.dblparval[i];
638 if( val >= CPX_INFBOUND )
639 return CPX_INFBOUND;
640 else if( val <= -CPX_INFBOUND )
641 return -CPX_INFBOUND;
642 else
643 return val;
644 }
645 }
646
647 SCIPerrorMessage("unknown CPLEX double parameter\n");
648 SCIPABORT();
649 return 0.0; /*lint !e527*/
650}
651
652/** sets a single integer parameter value */
653static
655 SCIP_LPI* lpi, /**< LP interface structure */
656 int const param, /**< parameter to set value */
657 int const parval /**< new value for parameter */
658 )
659{
660 int i;
661
662 assert(lpi != NULL);
663
664 for( i = 0; i < NUMINTPARAM; ++i )
665 {
666 if( intparam[i] == param )
667 {
668 lpi->cpxparam.intparval[i] = parval;
669 return;
670 }
671 }
672
673 SCIPerrorMessage("unknown CPLEX integer parameter\n");
674 SCIPABORT();
675}
676
677/** sets a single double parameter value */
678static
680 SCIP_LPI* lpi, /**< LP interface structure */
681 int const param, /**< parameter to set value */
682 double parval /**< new value for parameter */
683 )
684{
685 int i;
686
687 assert(lpi != NULL);
688
689 if( parval >= CPX_INFBOUND )
690 parval = 1e+75;
691 else if( parval <= -CPX_INFBOUND )
692 parval = -1e+75;
693
694 for( i = 0; i < NUMDBLPARAM; ++i )
695 {
696 if( dblparam[i] == param )
697 {
698 lpi->cpxparam.dblparval[i] = parval;
699 return;
700 }
701 }
702
703 SCIPerrorMessage("unknown CPLEX double parameter\n");
704 SCIPABORT();
705}
706
707/** marks the current LP to be unsolved */
708static
710 SCIP_LPI* const lpi /**< LP interface structure */
711 )
712{
713 assert(lpi != NULL);
714 lpi->solstat = -1;
715 lpi->method = CPX_ALG_NONE;
717}
718
719/** converts SCIP's objective sense into CPLEX's objective sense */
720static
722 SCIP_OBJSEN const objsen /**< objective sense */
723 )
724{
725 switch( objsen )
726 {
728 return CPX_MAX;
730 return CPX_MIN;
731 default:
732 SCIPerrorMessage("invalid objective sense\n");
733 SCIPABORT();
734 return 0; /*lint !e527*/
735 }
736}
737
738/** converts SCIP's lhs/rhs pairs into CPLEX's sen/rhs/rng */
739static
741 SCIP_LPI* lpi, /**< LP interface structure */
742 int nrows, /**< number of rows */
743 const SCIP_Real* lhs, /**< left hand side vector */
744 const SCIP_Real* rhs, /**< right hand side vector */
745 int indoffset, /**< index of first row in LP */
746 int* rngcount /**< pointer to store the number of range rows */
747 )
748{
749 int i;
750
751 assert(lpi != NULL);
752 assert(nrows >= 0);
753 assert(lhs != NULL);
754 assert(rhs != NULL);
755 assert(rngcount != NULL);
756
757 /* convert lhs/rhs into sen/rhs/rng */
758 *rngcount = 0;
759 for( i = 0; i < nrows; ++i )
760 {
761 assert(lhs[i] <= rhs[i]);
762 if( lhs[i] == rhs[i] ) /*lint !e777*/
763 {
764 assert(-CPX_INFBOUND < rhs[i] && rhs[i] < CPX_INFBOUND);
765 lpi->senarray[i] = 'E';
766 lpi->rhsarray[i] = rhs[i];
767 }
768 else if( lhs[i] <= -CPX_INFBOUND )
769 {
770 lpi->senarray[i] = 'L';
771 lpi->rhsarray[i] = rhs[i];
772 }
773 else if( rhs[i] >= CPX_INFBOUND )
774 {
775 lpi->senarray[i] = 'G';
776 lpi->rhsarray[i] = lhs[i];
777 }
778 else
779 {
780 /* CPLEX defines a ranged row to be within rhs and rhs+rng.
781 * -> To keep SCIP's meaning of the rhs value, we would like to use negative range values: rng := lhs - rhs,
782 * but there seems to be a bug in CPLEX's presolve with negative range values:
783 * the ranged row
784 * 0 <= -x <= 100000 with x >= 0 (rhs=0, rng=-100000)
785 * would lead to the CPLEX row
786 * -x -Rg = 100000
787 * Rg = 0
788 * instead of the correct presolving implication Rg = -100000.
789 * -> Because of this bug, we have to use an additional rhsarray[] for the converted right hand sides and
790 * use rhsarray[i] = lhs[i] and rngarray[i] = rhs[i] - lhs[i] for ranged rows to keep the range values
791 * non-negative.
792 */
793 lpi->senarray[i] = 'R';
794 lpi->rhsarray[i] = lhs[i];
795 lpi->rngarray[*rngcount] = rhs[i] - lhs[i];
796 lpi->rngindarray[*rngcount] = i + indoffset;
797 (*rngcount)++;
798 }
799 }
800}
801
802/** converts CPLEX's sen/rhs/rng triplets into SCIP's lhs/rhs pairs */
803static
805 SCIP_LPI* lpi, /**< LP interface structure */
806 int nrows, /**< number of rows */
807 SCIP_Real* lhs, /**< buffer to store the left hand side vector */
808 SCIP_Real* rhs /**< buffer to store the right hand side vector */
809 )
810{
811 int i;
812
813 assert(lpi != NULL);
814 assert(nrows >= 0);
815 assert(lhs != NULL);
816 assert(rhs != NULL);
817
818 for( i = 0; i < nrows; ++i )
819 {
820 switch( lpi->senarray[i] )
821 {
822 case 'E':
823 lhs[i] = lpi->rhsarray[i];
824 rhs[i] = lpi->rhsarray[i];
825 break;
826
827 case 'L':
828 lhs[i] = -CPX_INFBOUND;
829 rhs[i] = lpi->rhsarray[i];
830 break;
831
832 case 'G':
833 lhs[i] = lpi->rhsarray[i];
834 rhs[i] = CPX_INFBOUND;
835 break;
836
837 case 'R':
838 assert(lpi->rngarray[i] != 0.0);
839 if( lpi->rngarray[i] > 0.0 )
840 {
841 lhs[i] = lpi->rhsarray[i];
842 rhs[i] = lpi->rhsarray[i] + lpi->rngarray[i];
843 }
844 else
845 {
846 lhs[i] = lpi->rhsarray[i] + lpi->rngarray[i];
847 rhs[i] = lpi->rhsarray[i];
848 }
849 break;
850
851 default:
852 SCIPerrorMessage("invalid row sense\n");
853 SCIPABORT();
854 }
855 assert(lhs[i] <= rhs[i]);
856 }
857}
858
859/** converts CPLEX's sen/rhs/rng triplets into SCIP's lhs/rhs pairs, only storing the left hand side */
860static
862 SCIP_LPI* lpi, /**< LP interface structure */
863 int nrows, /**< number of rows */
864 SCIP_Real* lhs /**< buffer to store the left hand side vector */
865 )
866{
867 int i;
868
869 assert(lpi != NULL);
870 assert(nrows >= 0);
871 assert(lhs != NULL);
872
873 for( i = 0; i < nrows; ++i )
874 {
875 switch( lpi->senarray[i] )
876 {
877 case 'E':
878 assert(lpi->rngarray[i] == 0.0);
879 lhs[i] = lpi->rhsarray[i];
880 break;
881
882 case 'L':
883 assert(lpi->rngarray[i] == 0.0);
884 lhs[i] = -CPX_INFBOUND;
885 break;
886
887 case 'G':
888 assert(lpi->rngarray[i] == 0.0);
889 lhs[i] = lpi->rhsarray[i];
890 break;
891
892 case 'R':
893 assert(lpi->rngarray[i] != 0.0);
894 if( lpi->rngarray[i] > 0.0 )
895 lhs[i] = lpi->rhsarray[i];
896 else
897 lhs[i] = lpi->rhsarray[i] + lpi->rngarray[i];
898 break;
899
900 default:
901 SCIPerrorMessage("invalid row sense\n");
902 SCIPABORT();
903 }
904 }
905}
906
907/** converts CPLEX's sen/rhs/rng triplets into SCIP's lhs/rhs pairs, only storing the right hand side */
908static
910 SCIP_LPI* lpi, /**< LP interface structure */
911 int nrows, /**< number of rows */
912 SCIP_Real* rhs /**< buffer to store the right hand side vector */
913 )
914{
915 int i;
916
917 assert(lpi != NULL);
918 assert(nrows >= 0);
919 assert(rhs != NULL);
920
921 for( i = 0; i < nrows; ++i )
922 {
923 switch( lpi->senarray[i] )
924 {
925 case 'E':
926 assert(lpi->rngarray[i] == 0.0);
927 rhs[i] = lpi->rhsarray[i];
928 break;
929
930 case 'L':
931 assert(lpi->rngarray[i] == 0.0);
932 rhs[i] = lpi->rhsarray[i];
933 break;
934
935 case 'G':
936 assert(lpi->rngarray[i] == 0.0);
937 rhs[i] = CPX_INFBOUND;
938 break;
939
940 case 'R':
941 assert(lpi->rngarray[i] != 0.0);
942 if( lpi->rngarray[i] > 0.0 )
943 rhs[i] = lpi->rhsarray[i] + lpi->rngarray[i];
944 else
945 rhs[i] = lpi->rhsarray[i];
946 break;
947
948 default:
949 SCIPerrorMessage("invalid row sense\n");
950 SCIPABORT();
951 }
952 }
953}
954
955/** converts CPLEX's sen/rhs/rng triplets into SCIP's lhs/rhs pairs */
956static
958 SCIP_LPI* lpi, /**< LP interface structure */
959 int nrows, /**< number of rows */
960 SCIP_Real* lhs, /**< buffer to store the left hand side vector, or NULL */
961 SCIP_Real* rhs /**< buffer to store the right hand side vector, or NULL */
962 )
963{
964 if( lhs != NULL && rhs != NULL )
965 reconvertBothSides(lpi, nrows, lhs, rhs);
966 else if( lhs != NULL )
967 reconvertLhs(lpi, nrows, lhs);
968 else if( rhs != NULL )
969 reconvertRhs(lpi, nrows, rhs);
970}
971
972
973/** after restoring the old lp data in CPLEX we need to resolve the lp to be able to retrieve correct information */
974static
976 SCIP_LPI* lpi /**< LP interface structure */
977 )
978{
979 assert(lpi != NULL);
980
981 /* modifying the LP, restoring the old LP, and loading the old basis is not enough for CPLEX to be able to return the
982 * basis -> we have to resolve the LP;
983 *
984 * this may happen after manual strong branching on an integral variable, or after conflict analysis on a strong
985 * branching conflict created a constraint that is not able to modify the LP but trigger the additional call of the
986 * separators, in particular, the Gomory separator
987 *
988 * In a numerical perfect world, CPX_REFACTORMAXITERS below should be zero. However, due to numerical inaccuracies
989 * after refactorization, it might be necessary to do a few extra pivot steps.
990 */
991 CHECK_ZERO( lpi->messagehdlr, CPXdualopt(lpi->cpxenv, lpi->cpxlp) );
992#ifndef NDEBUG
993 if ( CPXgetphase1cnt(lpi->cpxenv, lpi->cpxlp) > CPX_REFACTORMAXITERS )
994 SCIPmessagePrintWarning(lpi->messagehdlr, "CPLEX needed %d phase 1 iterations to restore optimal basis.\n", CPXgetphase1cnt(lpi->cpxenv, lpi->cpxlp));
995 if ( CPXgetitcnt(lpi->cpxenv, lpi->cpxlp) > CPX_REFACTORMAXITERS )
996 SCIPmessagePrintWarning(lpi->messagehdlr, "CPLEX needed %d iterations to restore optimal basis.\n", CPXgetitcnt(lpi->cpxenv, lpi->cpxlp));
997#endif
998
999 return SCIP_OKAY;
1000}
1001
1002
1003/*
1004 * LP Interface Methods
1005 */
1006
1007
1008/*
1009 * Miscellaneous Methods
1010 */
1011/*lint --e{778}*/
1012/*lint --e{835}*/
1013static const char cpxname[]= {'C', 'P', 'L', 'E', 'X', ' ',
1014#if (defined CPX_VERSION_VERSION) && (CPX_VERSION_VERSION >= 10) && (CPX_VERSION_RELEASE >= 10)
1015 (CPX_VERSION_VERSION/10) + '0', (CPX_VERSION_VERSION%10) + '0', '.', (CPX_VERSION_RELEASE/10) + '0', (CPX_VERSION_RELEASE%10) + '0', '.', CPX_VERSION_MODIFICATION + '0', '.', CPX_VERSION_FIX + '0'
1016#elif (defined CPX_VERSION_VERSION) && (CPX_VERSION_VERSION <= 9) && (CPX_VERSION_RELEASE <= 9)
1017 CPX_VERSION_VERSION + '0', '.',CPX_VERSION_RELEASE + '0', '.', CPX_VERSION_MODIFICATION + '0', '.', CPX_VERSION_FIX + '0'
1018#elif (defined CPX_VERSION_VERSION) && (CPX_VERSION_VERSION >= 10) && (CPX_VERSION_RELEASE <= 9)
1019 (CPX_VERSION_VERSION/10) + '0', (CPX_VERSION_VERSION%10) + '0', '.', CPX_VERSION_RELEASE + '0', '.', CPX_VERSION_MODIFICATION + '0', '.', CPX_VERSION_FIX + '0'
1020#elif (defined CPX_VERSION_VERSION) && (CPX_VERSION_VERSION <= 9) && (CPX_VERSION_RELEASE >= 10)
1021 CPX_VERSION_VERSION + '0', '.', (CPX_VERSION_RELEASE/10) + '0', (CPX_VERSION_RELEASE%10) + '0', '.', CPX_VERSION_MODIFICATION + '0', '.', CPX_VERSION_FIX + '0'
1022#else
1023 (CPX_VERSION / 100) + '0', '.', ((CPX_VERSION % 100) / 10) + '0', '.', (CPX_VERSION % 10) + '0', '.', CPX_SUBVERSION + '0'
1024#endif
1025 , '\0'
1026};
1027
1028
1029/**@name Miscellaneous Methods */
1030/**@{ */
1031
1032/** gets name and version of LP solver */
1034 void
1035 )
1036{
1037 return cpxname;
1038}
1039
1040/** gets description of LP solver (developer, webpage, ...) */
1042 void
1043 )
1044{
1045 return "Linear Programming Solver developed by IBM (www.cplex.com)";
1046}
1047
1048/** gets pointer for LP solver - use only with great care
1049 *
1050 * Here we return the pointer to the LP environment.
1051 */
1053 SCIP_LPI* lpi /**< pointer to an LP interface structure */
1054 )
1055{
1056 return (void*) lpi->cpxlp;
1057}
1058
1059/** pass integrality information to LP solver */
1061 SCIP_LPI* lpi, /**< pointer to an LP interface structure */
1062 int ncols, /**< length of integrality array */
1063 int* intInfo /**< integrality array (0: continuous, 1: integer). May be NULL iff ncols is 0. */
1064 )
1065{ /*lint --e{715}*/
1066 assert( lpi != NULL );
1067 assert( ncols >= 0 );
1068 assert( ncols == 0 || intInfo != NULL );
1069
1070 SCIPerrorMessage("SCIPlpiSetIntegralityInformation() has not been implemented yet.\n");
1071 return SCIP_LPERROR;
1072}
1073
1074/** informs about availability of a primal simplex solving method */
1076 void
1077 )
1078{
1079 return TRUE;
1080}
1081
1082/** informs about availability of a dual simplex solving method */
1084 void
1085 )
1086{
1087 return TRUE;
1088}
1089
1090/** informs about availability of a barrier solving method */
1092 void
1093 )
1094{
1095 return TRUE;
1096}
1097
1098/**@} */
1099
1100
1101
1102
1103/*
1104 * LPI Creation and Destruction Methods
1105 */
1106
1107/**@name LPI Creation and Destruction Methods */
1108/**@{ */
1109
1110/** creates an LP problem object */
1112 SCIP_LPI** lpi, /**< pointer to an LP interface structure */
1113 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler to use for printing messages, or NULL */
1114 const char* name, /**< problem name */
1115 SCIP_OBJSEN objsen /**< objective sense */
1116 )
1117{
1118 int restat;
1119
1120 assert(sizeof(SCIP_Real) == sizeof(double)); /* CPLEX only works with doubles as floating points */ /*lint !e506*/
1121 assert(lpi != NULL);
1122 assert(name != NULL);
1123
1124 SCIPdebugMessage("SCIPlpiCreate()\n");
1125
1126 SCIP_ALLOC( BMSallocMemory(lpi) );
1127
1128 /* create environment */
1129 (*lpi)->cpxenv = CPXopenCPLEX(&restat);
1130 CHECK_ZERO( messagehdlr, restat );
1131
1132#if (CPX_VERSION == 1100 || (CPX_VERSION == 1220 && (CPX_SUBVERSION == 0 || CPX_SUBVERSION == 2)))
1133 /* manually set number of threads to 1 to avoid huge system load due to CPLEX bug (version 1100) or segmentation fault (version 1220) */
1134 CHECK_ZERO( messagehdlr, CPXsetintparam((*lpi)->cpxenv, CPX_PARAM_THREADS, 1) );
1135#endif
1136
1137#ifdef SCIP_DISABLED_CODE /* turning presolve off seems to be faster than turning it off on demand (if presolve detects infeasibility) */
1138 /* turn presolve off, s.t. for an infeasible problem, a ray is always available */
1139 CHECK_ZERO( messagehdlr, CPXsetintparam((*lpi)->cpxenv, CPX_PARAM_PREIND, CPX_OFF) );
1140#endif
1141
1142#if (CPX_VERSION == 12070000)
1143 /* due to a bug in CPLEX 12.7.0, we need to disable scaling for this version */
1144 CHECK_ZERO( messagehdlr, CPXsetintparam((*lpi)->cpxenv, CPX_PARAM_SCAIND, -1) );
1145#endif
1146
1147 /* get default parameter values */
1148 SCIP_CALL( getParameterValues((*lpi), &((*lpi)->defparam)) );
1149 copyParameterValues(&((*lpi)->curparam), &((*lpi)->defparam));
1150
1151 /* create LP */
1152 (*lpi)->larray = NULL;
1153 (*lpi)->uarray = NULL;
1154 (*lpi)->senarray = NULL;
1155 (*lpi)->rhsarray = NULL;
1156 (*lpi)->rngarray = NULL;
1157 (*lpi)->valarray = NULL;
1158 (*lpi)->rngindarray = NULL;
1159 (*lpi)->cstat = NULL;
1160 (*lpi)->rstat = NULL;
1161 (*lpi)->indarray = NULL;
1162 (*lpi)->boundchgsize = 0;
1163 (*lpi)->sidechgsize = 0;
1164 (*lpi)->valsize = 0;
1165 (*lpi)->cstatsize = 0;
1166 (*lpi)->rstatsize = 0;
1167 (*lpi)->iterations = 0;
1168 (*lpi)->pricing = SCIP_PRICING_LPIDEFAULT;
1169 (*lpi)->solisbasic = FALSE;
1170 (*lpi)->cpxlp = CPXcreateprob((*lpi)->cpxenv, &restat, name);
1171 (*lpi)->instabilityignored = FALSE;
1172 (*lpi)->fromscratch = FALSE;
1173 (*lpi)->clearstate = FALSE;
1174 (*lpi)->feastol = 1e-06;
1175 (*lpi)->conditionlimit = -1.0;
1176 (*lpi)->checkcondition = FALSE;
1177#if (CPX_VERSION <= 1100)
1178 (*lpi)->rngfound = FALSE;
1179#endif
1180 (*lpi)->messagehdlr = messagehdlr;
1181
1182 CHECK_ZERO( messagehdlr, restat );
1183 invalidateSolution(*lpi);
1184 copyParameterValues(&((*lpi)->cpxparam), &((*lpi)->defparam));
1185
1186 /* set objective sense */
1187 SCIP_CALL( SCIPlpiChgObjsen(*lpi, objsen) );
1188
1189 /* set default pricing */
1190 SCIP_CALL( SCIPlpiSetIntpar(*lpi, SCIP_LPPAR_PRICING, (int)(*lpi)->pricing) );
1191
1192 return SCIP_OKAY;
1193}
1194
1195/** deletes an LP problem object */
1197 SCIP_LPI** lpi /**< pointer to an LP interface structure */
1198 )
1199{
1200 assert(lpi != NULL);
1201 assert(*lpi != NULL);
1202 assert((*lpi)->cpxenv != NULL);
1203
1204 SCIPdebugMessage("SCIPlpiFree()\n");
1205
1206 /* free LP */
1207 CHECK_ZERO( (*lpi)->messagehdlr, CPXfreeprob((*lpi)->cpxenv, &((*lpi)->cpxlp)) );
1208
1209 /* free memory */
1210 BMSfreeMemoryArrayNull(&(*lpi)->larray);
1211 BMSfreeMemoryArrayNull(&(*lpi)->uarray);
1212 BMSfreeMemoryArrayNull(&(*lpi)->senarray);
1213 BMSfreeMemoryArrayNull(&(*lpi)->rhsarray);
1214 BMSfreeMemoryArrayNull(&(*lpi)->rngarray);
1215 BMSfreeMemoryArrayNull(&(*lpi)->valarray);
1216 BMSfreeMemoryArrayNull(&(*lpi)->rngindarray);
1217 BMSfreeMemoryArrayNull(&(*lpi)->cstat);
1218 BMSfreeMemoryArrayNull(&(*lpi)->rstat);
1219 BMSfreeMemoryArrayNull(&(*lpi)->indarray);
1220
1221 /* free environment */
1222 CHECK_ZERO( (*lpi)->messagehdlr, CPXcloseCPLEX(&((*lpi)->cpxenv)) );
1223
1224 BMSfreeMemory(lpi);
1225
1226 return SCIP_OKAY;
1227}
1228
1229/**@} */
1230
1231
1232
1233
1234/*
1235 * Modification Methods
1236 */
1237
1238/**@name Modification Methods */
1239/**@{ */
1240
1241/** copies LP data with column matrix into LP solver */
1243 SCIP_LPI* lpi, /**< LP interface structure */
1244 SCIP_OBJSEN objsen, /**< objective sense */
1245 int ncols, /**< number of columns */
1246 const SCIP_Real* obj, /**< objective function values of columns */
1247 const SCIP_Real* lb, /**< lower bounds of columns */
1248 const SCIP_Real* ub, /**< upper bounds of columns */
1249 char** colnames, /**< column names, or NULL */
1250 int nrows, /**< number of rows */
1251 const SCIP_Real* lhs, /**< left hand sides of rows */
1252 const SCIP_Real* rhs, /**< right hand sides of rows */
1253 char** rownames, /**< row names, or NULL */
1254 int nnonz, /**< number of nonzero elements in the constraint matrix */
1255 const int* beg, /**< start index of each column in ind- and val-array */
1256 const int* ind, /**< row indices of constraint matrix entries */
1257 const SCIP_Real* val /**< values of constraint matrix entries */
1258 )
1259{
1260 int* cnt;
1261 int rngcount;
1262 int c;
1263
1264#ifndef NDEBUG
1265 {
1266 int j;
1267 for( j = 0; j < nnonz; j++ )
1268 assert( val[j] != 0 );
1269 }
1270#endif
1271
1272 assert(lpi != NULL);
1273 assert(lpi->cpxlp != NULL);
1274 assert(lpi->cpxenv != NULL);
1275 assert(obj != NULL);
1276 assert(lb != NULL);
1277 assert(ub != NULL);
1278 assert(beg != NULL);
1279 assert(ind != NULL);
1280 assert(val != NULL);
1281
1282 SCIPdebugMessage("loading LP in column format into CPLEX: %d cols, %d rows\n", ncols, nrows);
1283
1284 invalidateSolution(lpi);
1285
1286 SCIP_CALL( ensureSidechgMem(lpi, nrows) );
1287
1288 /* convert lhs/rhs into sen/rhs/range tuples */
1289 convertSides(lpi, nrows, lhs, rhs, 0, &rngcount);
1290
1291 /* calculate column lengths */
1292 SCIP_ALLOC( BMSallocMemoryArray(&cnt, ncols) );
1293 for( c = 0; c < ncols-1; ++c )
1294 {
1295 cnt[c] = beg[c+1] - beg[c];
1296 assert(cnt[c] >= 0);
1297 }
1298 cnt[ncols-1] = nnonz - beg[ncols-1];
1299 assert(cnt[ncols-1] >= 0);
1300
1301 /* copy data into CPLEX */
1302 CHECK_ZERO( lpi->messagehdlr, CPXcopylpwnames(lpi->cpxenv, lpi->cpxlp, ncols, nrows, cpxObjsen(objsen), obj,
1303 lpi->rhsarray, lpi->senarray, beg, cnt, ind, val, lb, ub, lpi->rngarray, colnames, rownames) );
1304
1305 /* free temporary memory */
1306 BMSfreeMemoryArray(&cnt);
1307
1308 assert(CPXgetnumcols(lpi->cpxenv, lpi->cpxlp) == ncols);
1309 assert(CPXgetnumrows(lpi->cpxenv, lpi->cpxlp) == nrows);
1310 assert(CPXgetnumnz(lpi->cpxenv, lpi->cpxlp) == nnonz);
1311
1312 return SCIP_OKAY;
1313}
1314
1315/** adds columns to the LP */
1317 SCIP_LPI* lpi, /**< LP interface structure */
1318 int ncols, /**< number of columns to be added */
1319 const SCIP_Real* obj, /**< objective function values of new columns */
1320 const SCIP_Real* lb, /**< lower bounds of new columns */
1321 const SCIP_Real* ub, /**< upper bounds of new columns */
1322 char** colnames, /**< column names, or NULL */
1323 int nnonz, /**< number of nonzero elements to be added to the constraint matrix */
1324 const int* beg, /**< start index of each column in ind- and val-array, or NULL if nnonz == 0 */
1325 const int* ind, /**< row indices of constraint matrix entries, or NULL if nnonz == 0 */
1326 const SCIP_Real* val /**< values of constraint matrix entries, or NULL if nnonz == 0 */
1327 )
1328{
1329 assert(lpi != NULL);
1330 assert(lpi->cpxlp != NULL);
1331 assert(lpi->cpxenv != NULL);
1332 assert(obj != NULL);
1333 assert(lb != NULL);
1334 assert(ub != NULL);
1335 assert(nnonz == 0 || beg != NULL);
1336 assert(nnonz == 0 || ind != NULL);
1337 assert(nnonz == 0 || val != NULL);
1338 assert(nnonz >= 0);
1339 assert(ncols >= 0);
1340
1341 SCIPdebugMessage("adding %d columns with %d nonzeros to CPLEX\n", ncols, nnonz);
1342
1343 invalidateSolution(lpi);
1344
1345 if( nnonz > 0 )
1346 {
1347#ifndef NDEBUG
1348 /* perform check that no new rows are added - this is forbidden, see the CPLEX documentation */
1349 int nrows;
1350 int j;
1351
1352 nrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
1353 for (j = 0; j < nnonz; ++j)
1354 {
1355 assert( 0 <= ind[j] && ind[j] < nrows );
1356 assert( val[j] != 0.0 );
1357 }
1358#endif
1359
1360 CHECK_ZERO( lpi->messagehdlr, CPXaddcols(lpi->cpxenv, lpi->cpxlp, ncols, nnonz, obj, beg, ind, val, lb, ub, colnames) );
1361 }
1362 else
1363 {
1364 CHECK_ZERO( lpi->messagehdlr, CPXnewcols(lpi->cpxenv, lpi->cpxlp, ncols, obj, lb, ub, NULL, colnames) );
1365 }
1366
1367 return SCIP_OKAY;
1368}
1369
1370/** deletes all columns in the given range from LP */
1372 SCIP_LPI* lpi, /**< LP interface structure */
1373 int firstcol, /**< first column to be deleted */
1374 int lastcol /**< last column to be deleted */
1375 )
1376{
1377 assert(lpi != NULL);
1378 assert(lpi->cpxlp != NULL);
1379 assert(lpi->cpxenv != NULL);
1380 assert(0 <= firstcol && firstcol <= lastcol && lastcol < CPXgetnumcols(lpi->cpxenv, lpi->cpxlp));
1381
1382 SCIPdebugMessage("deleting %d columns from CPLEX\n", lastcol - firstcol + 1);
1383
1384 invalidateSolution(lpi);
1385
1386 CHECK_ZERO( lpi->messagehdlr, CPXdelcols(lpi->cpxenv, lpi->cpxlp, firstcol, lastcol) );
1387
1388 return SCIP_OKAY;
1389}
1390
1391/** deletes columns from SCIP_LP; the new position of a column must not be greater that its old position */
1393 SCIP_LPI* lpi, /**< LP interface structure */
1394 int* dstat /**< deletion status of columns
1395 * input: 1 if column should be deleted, 0 if not
1396 * output: new position of column, -1 if column was deleted */
1397 )
1398{
1399 assert(lpi != NULL);
1400 assert(lpi->cpxlp != NULL);
1401 assert(lpi->cpxenv != NULL);
1402 assert(dstat != NULL);
1403
1404 SCIPdebugMessage("deleting a column set from CPLEX\n");
1405
1406 invalidateSolution(lpi);
1407
1408 CHECK_ZERO( lpi->messagehdlr, CPXdelsetcols(lpi->cpxenv, lpi->cpxlp, dstat) );
1409
1410 return SCIP_OKAY;
1411}
1412
1413/** adds rows to the LP */
1415 SCIP_LPI* lpi, /**< LP interface structure */
1416 int nrows, /**< number of rows to be added */
1417 const SCIP_Real* lhs, /**< left hand sides of new rows */
1418 const SCIP_Real* rhs, /**< right hand sides of new rows */
1419 char** rownames, /**< row names, or NULL */
1420 int nnonz, /**< number of nonzero elements to be added to the constraint matrix */
1421 const int* beg, /**< start index of each row in ind- and val-array, or NULL if nnonz == 0 */
1422 const int* ind, /**< column indices of constraint matrix entries, or NULL if nnonz == 0 */
1423 const SCIP_Real* val /**< values of constraint matrix entries, or NULL if nnonz == 0 */
1424 )
1425{
1426 int rngcount;
1427
1428 assert(lpi != NULL);
1429 assert(lpi->cpxlp != NULL);
1430 assert(lpi->cpxenv != NULL);
1431 assert(lhs != NULL);
1432 assert(rhs != NULL);
1433 assert(nnonz == 0 || beg != NULL);
1434 assert(nnonz == 0 || ind != NULL);
1435 assert(nnonz == 0 || val != NULL);
1436
1437 SCIPdebugMessage("adding %d rows with %d nonzeros to CPLEX\n", nrows, nnonz);
1438
1439 invalidateSolution(lpi);
1440
1441 SCIP_CALL( ensureSidechgMem(lpi, nrows) );
1442
1443 /* convert lhs/rhs into sen/rhs/range tuples */
1444 convertSides(lpi, nrows, lhs, rhs, CPXgetnumrows(lpi->cpxenv, lpi->cpxlp), &rngcount);
1445
1446 /* add rows to LP */
1447 if( nnonz > 0 )
1448 {
1449#ifndef NDEBUG
1450 /* perform check that no new columns are added - this is likely to be a mistake */
1451 int ncols;
1452 int j;
1453
1454 ncols = CPXgetnumcols(lpi->cpxenv, lpi->cpxlp);
1455 for (j = 0; j < nnonz; ++j) {
1456 assert( val[j] != 0.0 );
1457 assert( 0 <= ind[j] && ind[j] < ncols );
1458 }
1459#endif
1460 CHECK_ZERO( lpi->messagehdlr, CPXaddrows(lpi->cpxenv, lpi->cpxlp, 0, nrows, nnonz, lpi->rhsarray, lpi->senarray, beg, ind, val, NULL,
1461 rownames) );
1462 }
1463 else
1464 {
1465 CHECK_ZERO( lpi->messagehdlr, CPXnewrows(lpi->cpxenv, lpi->cpxlp, nrows, lpi->rhsarray, lpi->senarray, NULL, rownames) );
1466 }
1467 if( rngcount > 0 )
1468 {
1469#if (CPX_VERSION <= 1100)
1470 if( lpi->rngfound == FALSE )
1471 {
1473 lpi->rngfound = TRUE;
1474 }
1475#endif
1476 CHECK_ZERO( lpi->messagehdlr, CPXchgrngval(lpi->cpxenv, lpi->cpxlp, rngcount, lpi->rngindarray, lpi->rngarray) );
1477 }
1478
1479 return SCIP_OKAY;
1480}
1481
1482/** deletes all rows in the given range from LP */
1484 SCIP_LPI* lpi, /**< LP interface structure */
1485 int firstrow, /**< first row to be deleted */
1486 int lastrow /**< last row to be deleted */
1487 )
1488{
1489 assert(lpi != NULL);
1490 assert(lpi->cpxlp != NULL);
1491 assert(lpi->cpxenv != NULL);
1492 assert(0 <= firstrow && firstrow <= lastrow && lastrow < CPXgetnumrows(lpi->cpxenv, lpi->cpxlp));
1493
1494 SCIPdebugMessage("deleting %d rows from CPLEX\n", lastrow - firstrow + 1);
1495
1496 invalidateSolution(lpi);
1497
1498 CHECK_ZERO( lpi->messagehdlr, CPXdelrows(lpi->cpxenv, lpi->cpxlp, firstrow, lastrow) );
1499
1500 return SCIP_OKAY;
1501}
1502
1503/** deletes rows from SCIP_LP; the new position of a row must not be greater that its old position */
1505 SCIP_LPI* lpi, /**< LP interface structure */
1506 int* dstat /**< deletion status of rows
1507 * input: 1 if row should be deleted, 0 if not
1508 * output: new position of row, -1 if row was deleted */
1509 )
1510{
1511 assert(lpi != NULL);
1512 assert(lpi->cpxlp != NULL);
1513 assert(lpi->cpxenv != NULL);
1514
1515 SCIPdebugMessage("deleting a row set from CPLEX\n");
1516
1517 invalidateSolution(lpi);
1518
1519 CHECK_ZERO( lpi->messagehdlr, CPXdelsetrows(lpi->cpxenv, lpi->cpxlp, dstat) );
1520
1521 return SCIP_OKAY;
1522}
1523
1524/** clears the whole LP */
1526 SCIP_LPI* lpi /**< LP interface structure */
1527 )
1528{
1529 int ncols;
1530 int nrows;
1531
1532 assert(lpi != NULL);
1533 assert(lpi->cpxlp != NULL);
1534 assert(lpi->cpxenv != NULL);
1535
1536 SCIPdebugMessage("clearing CPLEX LP\n");
1537
1538 invalidateSolution(lpi);
1539
1540 ncols = CPXgetnumcols(lpi->cpxenv, lpi->cpxlp);
1541 nrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
1542 if( ncols >= 1 )
1543 {
1544 CHECK_ZERO( lpi->messagehdlr, CPXdelcols(lpi->cpxenv, lpi->cpxlp, 0, ncols-1) );
1545 }
1546 if( nrows >= 1 )
1547 {
1548 CHECK_ZERO( lpi->messagehdlr, CPXdelrows(lpi->cpxenv, lpi->cpxlp, 0, nrows-1) );
1549 }
1550
1551 return SCIP_OKAY;
1552}
1553
1554/** changes lower and upper bounds of columns */
1556 SCIP_LPI* lpi, /**< LP interface structure */
1557 int ncols, /**< number of columns to change bounds for */
1558 const int* ind, /**< column indices or NULL if ncols is zero */
1559 const SCIP_Real* lb, /**< values for the new lower bounds or NULL if ncols is zero */
1560 const SCIP_Real* ub /**< values for the new upper bounds or NULL if ncols is zero */
1561 )
1562{
1563 int i;
1564
1565 assert(lpi != NULL);
1566 assert(lpi->cpxlp != NULL);
1567 assert(lpi->cpxenv != NULL);
1568 assert(ncols == 0 || (ind != NULL && lb != NULL && ub != NULL));
1569
1570 SCIPdebugMessage("changing %d bounds in CPLEX\n", ncols);
1571 if( ncols <= 0 )
1572 return SCIP_OKAY;
1573
1574 for( i = 0; i < ncols; ++i )
1575 {
1576 SCIPdebugPrintf(" col %d: [%g,%g]\n", ind[i], lb[i], ub[i]);
1577
1578 if ( SCIPlpiIsInfinity(lpi, lb[i]) )
1579 {
1580 SCIPerrorMessage("LP Error: fixing lower bound for variable %d to infinity.\n", ind[i]);
1581 return SCIP_LPERROR;
1582 }
1583 if ( SCIPlpiIsInfinity(lpi, -ub[i]) )
1584 {
1585 SCIPerrorMessage("LP Error: fixing upper bound for variable %d to -infinity.\n", ind[i]);
1586 return SCIP_LPERROR;
1587 }
1588 }
1589
1590 invalidateSolution(lpi);
1591
1592 SCIP_CALL( ensureBoundchgMem(lpi, ncols) );
1593
1594 CHECK_ZERO( lpi->messagehdlr, CPXchgbds(lpi->cpxenv, lpi->cpxlp, ncols, ind, lpi->larray, (SCIP_Real*)lb) );
1595 CHECK_ZERO( lpi->messagehdlr, CPXchgbds(lpi->cpxenv, lpi->cpxlp, ncols, ind, lpi->uarray, (SCIP_Real*)ub) );
1596
1597#ifndef NDEBUG
1598 {
1599 for( i = 0; i < ncols; ++i )
1600 {
1601 SCIP_Real cpxlb;
1602 SCIP_Real cpxub;
1603
1604 CHECK_ZERO( lpi->messagehdlr, CPXgetlb(lpi->cpxenv, lpi->cpxlp, &cpxlb, ind[i], ind[i]) );
1605 CHECK_ZERO( lpi->messagehdlr, CPXgetub(lpi->cpxenv, lpi->cpxlp, &cpxub, ind[i], ind[i]) );
1606
1607 /* Note that CPLEX seems to set bounds below 1e-10 in absolute value to 0.*/
1608 assert( EPSZ(cpxlb, CPX_MAGICZEROCONSTANT) || cpxlb == lb[i] ); /*lint !e777*/
1609 assert( EPSZ(cpxub, CPX_MAGICZEROCONSTANT) || cpxub == ub[i] ); /*lint !e777*/
1610 }
1611 }
1612#endif
1613
1614 return SCIP_OKAY;
1615}
1616
1617/** changes left and right hand sides of rows */
1619 SCIP_LPI* lpi, /**< LP interface structure */
1620 int nrows, /**< number of rows to change sides for */
1621 const int* ind, /**< row indices */
1622 const SCIP_Real* lhs, /**< new values for left hand sides */
1623 const SCIP_Real* rhs /**< new values for right hand sides */
1624 )
1625{
1626 int rngcount;
1627 int i;
1628
1629 assert(lpi != NULL);
1630 assert(lpi->cpxlp != NULL);
1631 assert(lpi->cpxenv != NULL);
1632
1633 if( nrows <= 0 )
1634 return SCIP_OKAY;
1635
1636 SCIPdebugMessage("changing %d sides in CPLEX\n", nrows);
1637
1638 invalidateSolution(lpi);
1639
1640 SCIP_CALL( ensureSidechgMem(lpi, nrows) );
1641
1642 /* convert lhs/rhs into sen/rhs/range tuples */
1643 convertSides(lpi, nrows, lhs, rhs, 0, &rngcount);
1644
1645 /* change row sides */
1646 CHECK_ZERO( lpi->messagehdlr, CPXchgsense(lpi->cpxenv, lpi->cpxlp, nrows, ind, lpi->senarray) );
1647 CHECK_ZERO( lpi->messagehdlr, CPXchgrhs(lpi->cpxenv, lpi->cpxlp, nrows, ind, lpi->rhsarray) );
1648 if( rngcount > 0 )
1649 {
1650 /* adjust the range count indices to the correct row indices */
1651 for( i = 0; i < rngcount; ++i )
1652 {
1653 assert(0 <= lpi->rngindarray[i] && lpi->rngindarray[i] < nrows);
1654 assert(lpi->senarray[lpi->rngindarray[i]] == 'R');
1655 lpi->rngindarray[i] = ind[lpi->rngindarray[i]];
1656 }
1657
1658 /* change the range values in CPLEX */
1659 CHECK_ZERO( lpi->messagehdlr, CPXchgrngval(lpi->cpxenv, lpi->cpxlp, rngcount, lpi->rngindarray, lpi->rngarray) );
1660 }
1661
1662 return SCIP_OKAY;
1663}
1664
1665/** changes a single coefficient */
1667 SCIP_LPI* lpi, /**< LP interface structure */
1668 int row, /**< row number of coefficient to change */
1669 int col, /**< column number of coefficient to change */
1670 SCIP_Real newval /**< new value of coefficient */
1671 )
1672{
1673 assert(lpi != NULL);
1674 assert(lpi->cpxlp != NULL);
1675 assert(lpi->cpxenv != NULL);
1676
1677 SCIPdebugMessage("changing coefficient row %d, column %d in CPLEX to %g\n", row, col, newval);
1678
1679 invalidateSolution(lpi);
1680
1681 CHECK_ZERO( lpi->messagehdlr, CPXchgcoef(lpi->cpxenv, lpi->cpxlp, row, col, newval) );
1682
1683 return SCIP_OKAY;
1684}
1685
1686/** changes the objective sense */
1688 SCIP_LPI* lpi, /**< LP interface structure */
1689 SCIP_OBJSEN objsen /**< new objective sense */
1690 )
1691{
1692 assert(lpi != NULL);
1693 assert(lpi->cpxlp != NULL);
1694 assert(lpi->cpxenv != NULL);
1695
1696 SCIPdebugMessage("changing objective sense in CPLEX to %d\n", objsen);
1697
1698 invalidateSolution(lpi);
1699
1700#if (CPX_VERSION >= 12050000)
1701 CHECK_ZERO( lpi->messagehdlr, CPXchgobjsen(lpi->cpxenv, lpi->cpxlp, cpxObjsen(objsen)) );
1702#else
1703 CPXchgobjsen(lpi->cpxenv, lpi->cpxlp, cpxObjsen(objsen));
1704#endif
1705
1706 return SCIP_OKAY;
1707}
1708
1709/** changes objective values of columns in the LP */
1711 SCIP_LPI* lpi, /**< LP interface structure */
1712 int ncols, /**< number of columns to change objective value for */
1713 const int* ind, /**< column indices to change objective value for */
1714 const SCIP_Real* obj /**< new objective values for columns */
1715 )
1716{
1717 assert(lpi != NULL);
1718 assert(lpi->cpxlp != NULL);
1719 assert(lpi->cpxenv != NULL);
1720 assert(ind != NULL);
1721 assert(obj != NULL);
1722
1723 SCIPdebugMessage("changing %d objective values in CPLEX\n", ncols);
1724
1725 invalidateSolution(lpi);
1726
1727 CHECK_ZERO( lpi->messagehdlr, CPXchgobj(lpi->cpxenv, lpi->cpxlp, ncols, ind, obj) );
1728
1729 return SCIP_OKAY;
1730}
1731
1732/** multiplies a row with a non-zero scalar; for negative scalars, the row's sense is switched accordingly */
1734 SCIP_LPI* lpi, /**< LP interface structure */
1735 int row, /**< row number to scale */
1736 SCIP_Real scaleval /**< scaling multiplier */
1737 )
1738{
1739 SCIP_Real lhs;
1740 SCIP_Real rhs;
1741 int nnonz;
1742 int beg;
1743 int i;
1744
1745 assert(lpi != NULL);
1746 assert(lpi->cpxlp != NULL);
1747 assert(lpi->cpxenv != NULL);
1748 assert(scaleval != 0.0);
1749
1750 SCIPdebugMessage("scaling row %d with factor %g in CPLEX\n", row, scaleval);
1751
1752 invalidateSolution(lpi);
1753
1754 SCIP_CALL( ensureValMem(lpi, CPXgetnumcols(lpi->cpxenv, lpi->cpxlp)) );
1755
1756 /* get the row */
1757 SCIP_CALL( SCIPlpiGetRows(lpi, row, row, &lhs, &rhs, &nnonz, &beg, lpi->indarray, lpi->valarray) );
1758
1759 /* scale row coefficients */
1760 for( i = 0; i < nnonz; ++i )
1761 {
1762 SCIP_CALL( SCIPlpiChgCoef(lpi, row, lpi->indarray[i], lpi->valarray[i] * scaleval) );
1763 }
1764
1765 /* scale row sides */
1766 if( lhs > -CPX_INFBOUND )
1767 lhs *= scaleval;
1768 else if( scaleval < 0.0 )
1769 lhs = CPX_INFBOUND;
1770 if( rhs < CPX_INFBOUND )
1771 rhs *= scaleval;
1772 else if( scaleval < 0.0 )
1773 rhs = -CPX_INFBOUND;
1774 if( scaleval > 0.0 )
1775 {
1776 SCIP_CALL( SCIPlpiChgSides(lpi, 1, &row, &lhs, &rhs) );
1777 }
1778 else
1779 {
1780 SCIP_CALL( SCIPlpiChgSides(lpi, 1, &row, &rhs, &lhs) );
1781 }
1782
1783 return SCIP_OKAY;
1784}
1785
1786/** multiplies a column with a non-zero scalar; the objective value is multiplied with the scalar, and the bounds
1787 * are divided by the scalar; for negative scalars, the column's bounds are switched
1788 */
1790 SCIP_LPI* lpi, /**< LP interface structure */
1791 int col, /**< column number to scale */
1792 SCIP_Real scaleval /**< scaling multiplier */
1793 )
1794{
1795 SCIP_Real lb;
1796 SCIP_Real ub;
1797 SCIP_Real obj;
1798 int nnonz;
1799 int beg;
1800 int i;
1801
1802 assert(lpi != NULL);
1803 assert(lpi->cpxlp != NULL);
1804 assert(lpi->cpxenv != NULL);
1805 assert(scaleval != 0.0);
1806
1807 SCIPdebugMessage("scaling column %d with factor %g in CPLEX\n", col, scaleval);
1808
1809 invalidateSolution(lpi);
1810
1811 SCIP_CALL( ensureValMem(lpi, CPXgetnumrows(lpi->cpxenv, lpi->cpxlp)) );
1812
1813 /* get the column */
1814 SCIP_CALL( SCIPlpiGetCols(lpi, col, col, &lb, &ub, &nnonz, &beg, lpi->indarray, lpi->valarray) );
1815
1816 /* get objective coefficient */
1817 SCIP_CALL( SCIPlpiGetObj(lpi, col, col, &obj) );
1818
1819 /* scale column coefficients */
1820 for( i = 0; i < nnonz; ++i )
1821 {
1822 SCIP_CALL( SCIPlpiChgCoef(lpi, lpi->indarray[i], col, lpi->valarray[i] * scaleval) );
1823 }
1824
1825 /* scale objective value */
1826 obj *= scaleval;
1827 SCIP_CALL( SCIPlpiChgObj(lpi, 1, &col, &obj) );
1828
1829 /* scale column bounds */
1830 if( lb > -CPX_INFBOUND )
1831 lb /= scaleval;
1832 else if( scaleval < 0.0 )
1833 lb = CPX_INFBOUND;
1834 if( ub < CPX_INFBOUND )
1835 ub /= scaleval;
1836 else if( scaleval < 0.0 )
1837 ub = -CPX_INFBOUND;
1838 if( scaleval > 0.0 )
1839 {
1840 SCIP_CALL( SCIPlpiChgBounds(lpi, 1, &col, &lb, &ub) );
1841 }
1842 else
1843 {
1844 SCIP_CALL( SCIPlpiChgBounds(lpi, 1, &col, &ub, &lb) );
1845 }
1846
1847 return SCIP_OKAY;
1848}
1849
1850/**@} */
1851
1852
1853
1854
1855/*
1856 * Data Accessing Methods
1857 */
1858
1859/**@name Data Accessing Methods */
1860/**@{ */
1861
1862/** gets the number of rows in the LP */
1864 SCIP_LPI* lpi, /**< LP interface structure */
1865 int* nrows /**< pointer to store the number of rows */
1866 )
1867{
1868 assert(lpi != NULL);
1869 assert(lpi->cpxenv != NULL);
1870 assert(nrows != NULL);
1871
1872 SCIPdebugMessage("getting number of rows\n");
1873
1874 *nrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
1875
1876 return SCIP_OKAY;
1877}
1878
1879/** gets the number of columns in the LP */
1881 SCIP_LPI* lpi, /**< LP interface structure */
1882 int* ncols /**< pointer to store the number of cols */
1883 )
1884{
1885 assert(lpi != NULL);
1886 assert(lpi->cpxenv != NULL);
1887 assert(ncols != NULL);
1888
1889 SCIPdebugMessage("getting number of columns\n");
1890
1891 *ncols = CPXgetnumcols(lpi->cpxenv, lpi->cpxlp);
1892
1893 return SCIP_OKAY;
1894}
1895
1896/** gets the number of nonzero elements in the LP constraint matrix */
1898 SCIP_LPI* lpi, /**< LP interface structure */
1899 int* nnonz /**< pointer to store the number of nonzeros */
1900 )
1901{
1902 assert(lpi != NULL);
1903 assert(lpi->cpxenv != NULL);
1904 assert(nnonz != NULL);
1905
1906 SCIPdebugMessage("getting number of non-zeros\n");
1907
1908 *nnonz = CPXgetnumnz(lpi->cpxenv, lpi->cpxlp);
1909
1910 return SCIP_OKAY;
1911}
1912
1913/** gets columns from LP problem object; the arrays have to be large enough to store all values
1914 * Either both, lb and ub, have to be NULL, or both have to be non-NULL,
1915 * either nnonz, beg, ind, and val have to be NULL, or all of them have to be non-NULL.
1916 */
1918 SCIP_LPI* lpi, /**< LP interface structure */
1919 int firstcol, /**< first column to get from LP */
1920 int lastcol, /**< last column to get from LP */
1921 SCIP_Real* lb, /**< buffer to store the lower bound vector, or NULL */
1922 SCIP_Real* ub, /**< buffer to store the upper bound vector, or NULL */
1923 int* nnonz, /**< pointer to store the number of nonzero elements returned, or NULL */
1924 int* beg, /**< buffer to store start index of each column in ind- and val-array, or NULL */
1925 int* ind, /**< buffer to store row indices of constraint matrix entries, or NULL */
1926 SCIP_Real* val /**< buffer to store values of constraint matrix entries, or NULL */
1927 )
1928{
1929 assert(lpi != NULL);
1930 assert(lpi->cpxlp != NULL);
1931 assert(lpi->cpxenv != NULL);
1932 assert(0 <= firstcol && firstcol <= lastcol && lastcol < CPXgetnumcols(lpi->cpxenv, lpi->cpxlp));
1933 assert((lb != NULL && ub != NULL) || (lb == NULL && ub == NULL));
1934 assert((nnonz != NULL && beg != NULL && ind != NULL && val != NULL) || (nnonz == NULL && beg == NULL && ind == NULL && val == NULL));
1935
1936 SCIPdebugMessage("getting columns %d to %d\n", firstcol, lastcol);
1937
1938 if( lb != NULL )
1939 {
1940 CHECK_ZERO( lpi->messagehdlr, CPXgetlb(lpi->cpxenv, lpi->cpxlp, lb, firstcol, lastcol) );
1941 CHECK_ZERO( lpi->messagehdlr, CPXgetub(lpi->cpxenv, lpi->cpxlp, ub, firstcol, lastcol) );
1942 }
1943
1944 if( nnonz != NULL )
1945 {
1946 int surplus;
1947
1948 /* get matrix entries */
1949 CHECK_ZERO( lpi->messagehdlr, CPXgetcols(lpi->cpxenv, lpi->cpxlp, nnonz, beg, ind, val,
1950 CPXgetnumnz(lpi->cpxenv, lpi->cpxlp), &surplus, firstcol, lastcol) );
1951 assert(surplus >= 0);
1952 }
1953
1954 return SCIP_OKAY;
1955}
1956
1957/** gets rows from LP problem object; the arrays have to be large enough to store all values.
1958 * Either both, lhs and rhs, have to be NULL, or both have to be non-NULL,
1959 * either nnonz, beg, ind, and val have to be NULL, or all of them have to be non-NULL.
1960 */
1962 SCIP_LPI* lpi, /**< LP interface structure */
1963 int firstrow, /**< first row to get from LP */
1964 int lastrow, /**< last row to get from LP */
1965 SCIP_Real* lhs, /**< buffer to store left hand side vector, or NULL */
1966 SCIP_Real* rhs, /**< buffer to store right hand side vector, or NULL */
1967 int* nnonz, /**< pointer to store the number of nonzero elements returned, or NULL */
1968 int* beg, /**< buffer to store start index of each row in ind- and val-array, or NULL */
1969 int* ind, /**< buffer to store column indices of constraint matrix entries, or NULL */
1970 SCIP_Real* val /**< buffer to store values of constraint matrix entries, or NULL */
1971 )
1972{
1973#if CPX_VERSION < 12070000
1974 int retcode;
1975#endif
1976
1977 assert(lpi != NULL);
1978 assert(lpi->cpxlp != NULL);
1979 assert(lpi->cpxenv != NULL);
1980 assert(0 <= firstrow && firstrow <= lastrow && lastrow < CPXgetnumrows(lpi->cpxenv, lpi->cpxlp));
1981 assert((lhs == NULL && rhs == NULL) || (rhs != NULL && lhs != NULL));
1982 assert((nnonz != NULL && beg != NULL && ind != NULL && val != NULL) || (nnonz == NULL && beg == NULL && ind == NULL && val == NULL));
1983
1984 SCIPdebugMessage("getting rows %d to %d\n", firstrow, lastrow);
1985
1986 if( lhs != NULL )
1987 {
1988 /* get row sense, rhs, and ranges */
1989 SCIP_CALL( ensureSidechgMem(lpi, lastrow - firstrow + 1) );
1990 CHECK_ZERO( lpi->messagehdlr, CPXgetsense(lpi->cpxenv, lpi->cpxlp, lpi->senarray, firstrow, lastrow) );
1991 CHECK_ZERO( lpi->messagehdlr, CPXgetrhs(lpi->cpxenv, lpi->cpxlp, lpi->rhsarray, firstrow, lastrow) );
1992#if CPX_VERSION < 12070000
1993 retcode = CPXgetrngval(lpi->cpxenv, lpi->cpxlp, lpi->rngarray, firstrow, lastrow);
1994 if( retcode != CPXERR_NO_RNGVAL ) /* ignore "No range values" error */
1995 {
1996 CHECK_ZERO( lpi->messagehdlr, retcode );
1997 }
1998 else
1999 BMSclearMemoryArray(lpi->rngarray, lastrow-firstrow+1);
2000#else
2001 CHECK_ZERO( lpi->messagehdlr, CPXgetrngval(lpi->cpxenv, lpi->cpxlp, lpi->rngarray, firstrow, lastrow) );
2002#endif
2003
2004 /* convert sen/rhs/range into lhs/rhs tuples */
2005 reconvertSides(lpi, lastrow - firstrow + 1, lhs, rhs);
2006 }
2007
2008 if( nnonz != NULL )
2009 {
2010 int surplus;
2011
2012 /* get matrix entries */
2013 CHECK_ZERO( lpi->messagehdlr, CPXgetrows(lpi->cpxenv, lpi->cpxlp, nnonz, beg, ind, val,
2014 CPXgetnumnz(lpi->cpxenv, lpi->cpxlp), &surplus, firstrow, lastrow) );
2015 assert(surplus >= 0);
2016 }
2017
2018 return SCIP_OKAY;
2019}
2020
2021/** gets column names */
2023 SCIP_LPI* lpi, /**< LP interface structure */
2024 int firstcol, /**< first column to get name from LP */
2025 int lastcol, /**< last column to get name from LP */
2026 char** colnames, /**< pointers to column names (of size at least lastcol-firstcol+1) or NULL if namestoragesize is zero */
2027 char* namestorage, /**< storage for col names or NULL if namestoragesize is zero */
2028 int namestoragesize, /**< size of namestorage (if 0, storageleft returns the storage needed) */
2029 int* storageleft /**< amount of storage left (if < 0 the namestorage was not big enough) or NULL if namestoragesize is zero */
2030 )
2031{
2032 int retcode;
2033
2034 assert(lpi != NULL);
2035 assert(lpi->cpxlp != NULL);
2036 assert(lpi->cpxenv != NULL);
2037 assert(colnames != NULL || namestoragesize == 0);
2038 assert(namestorage != NULL || namestoragesize == 0);
2039 assert(namestoragesize >= 0);
2040 assert(storageleft != NULL);
2041 assert(0 <= firstcol && firstcol <= lastcol && lastcol < CPXgetnumcols(lpi->cpxenv, lpi->cpxlp));
2042
2043 SCIPdebugMessage("getting column names %d to %d\n", firstcol, lastcol);
2044
2045 retcode = CPXgetcolname(lpi->cpxenv, lpi->cpxlp, colnames, namestorage, namestoragesize, storageleft, firstcol, lastcol);
2046 assert( namestoragesize != 0 || retcode == CPXERR_NEGATIVE_SURPLUS );
2047 if( namestoragesize != 0 )
2048 {
2049 CHECK_ZERO( lpi->messagehdlr, retcode );
2050 }
2051
2052 return SCIP_OKAY;
2053}
2054
2055/** gets row names */
2057 SCIP_LPI* lpi, /**< LP interface structure */
2058 int firstrow, /**< first row to get name from LP */
2059 int lastrow, /**< last row to get name from LP */
2060 char** rownames, /**< pointers to row names (of size at least lastrow-firstrow+1) or NULL if namestoragesize is zero */
2061 char* namestorage, /**< storage for row names or NULL if namestoragesize is zero */
2062 int namestoragesize, /**< size of namestorage (if 0, -storageleft returns the storage needed) */
2063 int* storageleft /**< amount of storage left (if < 0 the namestorage was not big enough) or NULL if namestoragesize is zero */
2064 )
2065{
2066 int retcode;
2067
2068 assert(lpi != NULL);
2069 assert(lpi->cpxlp != NULL);
2070 assert(lpi->cpxenv != NULL);
2071 assert(rownames != NULL || namestoragesize == 0);
2072 assert(namestorage != NULL || namestoragesize == 0);
2073 assert(namestoragesize >= 0);
2074 assert(storageleft != NULL);
2075 assert(0 <= firstrow && firstrow <= lastrow && lastrow < CPXgetnumrows(lpi->cpxenv, lpi->cpxlp));
2076
2077 SCIPdebugMessage("getting row names %d to %d\n", firstrow, lastrow);
2078
2079 retcode = CPXgetrowname(lpi->cpxenv, lpi->cpxlp, rownames, namestorage, namestoragesize, storageleft, firstrow, lastrow);
2080 assert( namestoragesize != 0 || retcode == CPXERR_NEGATIVE_SURPLUS );
2081 if( namestoragesize != 0 )
2082 {
2083 CHECK_ZERO( lpi->messagehdlr, retcode );
2084 }
2085
2086 return SCIP_OKAY;
2087}
2088
2089/** gets objective sense of the LP */
2091 SCIP_LPI* lpi, /**< LP interface structure */
2092 SCIP_OBJSEN* objsen /**< pointer to store objective sense */
2093 )
2094{
2095 assert(lpi != NULL);
2096 assert(lpi->cpxlp != NULL);
2097 assert(lpi->cpxenv != NULL);
2098 assert(objsen != NULL);
2099 assert(CPXgetobjsen(lpi->cpxenv, lpi->cpxlp) == CPX_MIN || CPXgetobjsen(lpi->cpxenv, lpi->cpxlp) == CPX_MAX);
2100
2101 SCIPdebugMessage("getting objective sense\n");
2102
2103 *objsen = (CPXgetobjsen(lpi->cpxenv, lpi->cpxlp) == CPX_MIN) ? SCIP_OBJSEN_MINIMIZE : SCIP_OBJSEN_MAXIMIZE;
2104
2105 return SCIP_OKAY;
2106}
2107
2108/** gets objective coefficients from LP problem object */
2110 SCIP_LPI* lpi, /**< LP interface structure */
2111 int firstcol, /**< first column to get objective coefficient for */
2112 int lastcol, /**< last column to get objective coefficient for */
2113 SCIP_Real* vals /**< array to store objective coefficients */
2114 )
2115{
2116 assert(lpi != NULL);
2117 assert(lpi->cpxlp != NULL);
2118 assert(lpi->cpxenv != NULL);
2119 assert(firstcol <= lastcol);
2120 assert(vals != NULL);
2121
2122 SCIPdebugMessage("getting objective values %d to %d\n", firstcol, lastcol);
2123
2124 CHECK_ZERO( lpi->messagehdlr, CPXgetobj(lpi->cpxenv, lpi->cpxlp, vals, firstcol, lastcol) );
2125
2126 return SCIP_OKAY;
2127}
2128
2129/** gets current bounds from LP problem object */
2131 SCIP_LPI* lpi, /**< LP interface structure */
2132 int firstcol, /**< first column to get bounds for */
2133 int lastcol, /**< last column to get bounds for */
2134 SCIP_Real* lbs, /**< array to store lower bound values, or NULL */
2135 SCIP_Real* ubs /**< array to store upper bound values, or NULL */
2136 )
2137{
2138 assert(lpi != NULL);
2139 assert(lpi->cpxlp != NULL);
2140 assert(lpi->cpxenv != NULL);
2141 assert(firstcol <= lastcol);
2142
2143 SCIPdebugMessage("getting bounds %d to %d\n", firstcol, lastcol);
2144
2145 if( lbs != NULL )
2146 {
2147 CHECK_ZERO( lpi->messagehdlr, CPXgetlb(lpi->cpxenv, lpi->cpxlp, lbs, firstcol, lastcol) );
2148 }
2149
2150 if( ubs != NULL )
2151 {
2152 CHECK_ZERO( lpi->messagehdlr, CPXgetub(lpi->cpxenv, lpi->cpxlp, ubs, firstcol, lastcol) );
2153 }
2154
2155 return SCIP_OKAY;
2156}
2157
2158/** gets current row sides from LP problem object */
2160 SCIP_LPI* lpi, /**< LP interface structure */
2161 int firstrow, /**< first row to get sides for */
2162 int lastrow, /**< last row to get sides for */
2163 SCIP_Real* lhss, /**< array to store left hand side values, or NULL */
2164 SCIP_Real* rhss /**< array to store right hand side values, or NULL */
2165 )
2166{
2167#if CPX_VERSION < 12070000
2168 int retval;
2169#endif
2170
2171 assert(lpi != NULL);
2172 assert(lpi->cpxlp != NULL);
2173 assert(lpi->cpxenv != NULL);
2174 assert(firstrow <= lastrow);
2175
2176 SCIPdebugMessage("getting row sides %d to %d\n", firstrow, lastrow);
2177
2178 /* get row sense, rhs, and ranges */
2179 SCIP_CALL( ensureSidechgMem(lpi, lastrow - firstrow + 1) );
2180 CHECK_ZERO( lpi->messagehdlr, CPXgetsense(lpi->cpxenv, lpi->cpxlp, lpi->senarray, firstrow, lastrow) );
2181 CHECK_ZERO( lpi->messagehdlr, CPXgetrhs(lpi->cpxenv, lpi->cpxlp, lpi->rhsarray, firstrow, lastrow) );
2182#if CPX_VERSION < 12070000
2183 retval = CPXgetrngval(lpi->cpxenv, lpi->cpxlp, lpi->rngarray, firstrow, lastrow);
2184 if( retval != CPXERR_NO_RNGVAL ) /* ignore "No range values" error */
2185 {
2186 CHECK_ZERO( lpi->messagehdlr, retval );
2187 }
2188 else
2189 BMSclearMemoryArray(lpi->rngarray, lastrow-firstrow+1);
2190#else
2191 CHECK_ZERO( lpi->messagehdlr, CPXgetrngval(lpi->cpxenv, lpi->cpxlp, lpi->rngarray, firstrow, lastrow) );
2192#endif
2193
2194 /* convert sen/rhs/range into lhs/rhs tuples */
2195 reconvertSides(lpi, lastrow - firstrow + 1, lhss, rhss);
2196
2197 return SCIP_OKAY;
2198}
2199
2200/** gets a single coefficient */
2202 SCIP_LPI* lpi, /**< LP interface structure */
2203 int row, /**< row number of coefficient */
2204 int col, /**< column number of coefficient */
2205 SCIP_Real* val /**< pointer to store the value of the coefficient */
2206 )
2207{
2208 assert(lpi != NULL);
2209 assert(lpi->cpxlp != NULL);
2210 assert(lpi->cpxenv != NULL);
2211 assert(val != NULL);
2212
2213 SCIPdebugMessage("getting coefficient of row %d col %d\n", row, col);
2214
2215 CHECK_ZERO( lpi->messagehdlr, CPXgetcoef(lpi->cpxenv, lpi->cpxlp, row, col, val) );
2216
2217 return SCIP_OKAY;
2218}
2219
2220/**@} */
2221
2222
2223
2224
2225/*
2226 * Solving Methods
2227 */
2228
2229/**@name Solving Methods */
2230/**@{ */
2231
2232/** calls primal simplex to solve the LP */
2234 SCIP_LPI* lpi /**< LP interface structure */
2235 )
2236{
2237 int retval;
2238 int primalfeasible;
2239 int dualfeasible;
2240 int solntype;
2241#if CPX_VERSION == 12070100
2242 int presolving;
2243#endif
2244
2245 assert(lpi != NULL);
2246 assert(lpi->cpxlp != NULL);
2247 assert(lpi->cpxenv != NULL);
2248
2249 SCIPdebugMessage("calling CPLEX primal simplex: %d cols, %d rows\n",
2250 CPXgetnumcols(lpi->cpxenv, lpi->cpxlp), CPXgetnumrows(lpi->cpxenv, lpi->cpxlp));
2251
2252 invalidateSolution(lpi);
2253
2254#if (CPX_VERSION == 12070000)
2255 {
2256 int scaling;
2257 /* due to a bug in CPLEX 12.7.0, we need to disable scaling for this version */
2258 CHECK_ZERO( lpi->messagehdlr, CPXgetintparam(lpi->cpxenv, CPX_PARAM_SCAIND, &scaling) );
2259 assert( scaling == -1 );
2260 }
2261#endif
2262
2263 setIntParam(lpi, CPX_PARAM_ADVIND, lpi->fromscratch || lpi->clearstate ? CPX_OFF : CPX_ON);
2264 lpi->clearstate = FALSE;
2265
2266 SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
2267
2268#if CPX_VERSION == 12070100
2269 /* due to a bug in CPLEX 12.7.1.0, we need to enable presolving on trivial problems (see comment below) */
2270 if( CPXgetnumrows(lpi->cpxenv, lpi->cpxlp) == 0 )
2271 {
2272 CHECK_ZERO( lpi->messagehdlr, CPXgetintparam(lpi->cpxenv, CPX_PARAM_PREIND, &presolving) );
2273 CHECK_ZERO( lpi->messagehdlr, CPXsetintparam(lpi->cpxenv, CPX_PARAM_PREIND, CPX_ON) );
2274 }
2275#endif
2276
2277 SCIPdebugMessage("calling CPXprimopt()\n");
2278 retval = CPXprimopt(lpi->cpxenv, lpi->cpxlp);
2279
2280#if CPX_VERSION == 12070100
2281 /* restore previous value for presolving */
2282 if( CPXgetnumrows(lpi->cpxenv, lpi->cpxlp) == 0 )
2283 {
2284 CHECK_ZERO( lpi->messagehdlr, CPXsetintparam(lpi->cpxenv, CPX_PARAM_PREIND, presolving) ); /*lint !e644*/
2285 }
2286#endif
2287
2288 switch( retval )
2289 {
2290 case 0:
2291 break;
2292 case CPXERR_NO_MEMORY:
2293 return SCIP_NOMEMORY;
2294 default:
2295 return SCIP_LPERROR;
2296 }
2297
2298 lpi->solstat = CPXgetstat(lpi->cpxenv, lpi->cpxlp);
2299 lpi->method = CPX_ALG_PRIMAL;
2301
2302 /* CPLEX outputs an error if the status is CPX_STAT_INForUNBD and the iterations are determined */
2303 CHECK_ZERO( lpi->messagehdlr, CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, &solntype, &primalfeasible, &dualfeasible) );
2304 if( lpi->solstat != CPX_STAT_INForUNBD && solntype != CPX_NO_SOLN )
2305 lpi->iterations = CPXgetphase1cnt(lpi->cpxenv, lpi->cpxlp) + CPXgetitcnt(lpi->cpxenv, lpi->cpxlp);
2306 else
2307 lpi->iterations = 0;
2308
2309 SCIPdebugMessage(" -> CPLEX returned solstat=%d, pfeas=%d, dfeas=%d (%d iterations)\n",
2310 lpi->solstat, primalfeasible, dualfeasible, lpi->iterations);
2311
2312#if CPX_VERSION == 12070100
2313 /* CPLEX 12.7.1.0 primal simplex without presolve (called next in certain situations) does not return on a problem like
2314 * min x + sum_{i=1}^n 0*y_i when all variables are free and n >= 59
2315 * With this workaround, we claim that LPs without rows, which are returned as infeasible-or-unbounded by CPLEX with presolve,
2316 * are in fact unbounded. This assumes that CPLEX with presolve checked that no variable has an empty domain before.
2317 */
2318 if( lpi->solstat == CPX_STAT_INForUNBD && CPXgetnumrows(lpi->cpxenv, lpi->cpxlp) == 0 )
2319 {
2320 lpi->solstat = CPX_STAT_UNBOUNDED;
2321 primalfeasible = 1;
2322 dualfeasible = 0;
2323 }
2324#endif
2325
2326 if( lpi->solstat == CPX_STAT_INForUNBD
2327 || (lpi->solstat == CPX_STAT_INFEASIBLE && !dualfeasible)
2328 || (lpi->solstat == CPX_STAT_UNBOUNDED && !primalfeasible) )
2329 {
2330 if( getIntParam(lpi, CPX_PARAM_PREIND) == CPX_ON )
2331 {
2332 /* maybe the preprocessor solved the problem; but we need a solution, so solve again without preprocessing */
2333 SCIPdebugMessage("presolver may have solved the problem -> calling CPLEX primal simplex again without presolve\n");
2334
2335 /* switch off preprocessing */
2336 setIntParam(lpi, CPX_PARAM_PREIND, CPX_OFF);
2337 SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
2338
2339 retval = CPXprimopt(lpi->cpxenv, lpi->cpxlp);
2340 switch( retval )
2341 {
2342 case 0:
2343 break;
2344 case CPXERR_NO_MEMORY:
2345 return SCIP_NOMEMORY;
2346 default:
2347 return SCIP_LPERROR;
2348 }
2349
2350 lpi->solstat = CPXgetstat(lpi->cpxenv, lpi->cpxlp);
2352 assert( lpi->solstat != CPX_STAT_INForUNBD );
2353
2354 lpi->iterations += CPXgetphase1cnt(lpi->cpxenv, lpi->cpxlp) + CPXgetitcnt(lpi->cpxenv, lpi->cpxlp);
2355 CHECK_ZERO( lpi->messagehdlr, CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, &solntype, NULL, NULL) );
2356
2357 SCIPdebugMessage(" -> CPLEX returned solstat=%d (%d iterations)\n", lpi->solstat, lpi->iterations);
2358
2359 /* switch on preprocessing again */
2360 setIntParam(lpi, CPX_PARAM_PREIND, CPX_ON);
2361 }
2362
2363 if( lpi->solstat == CPX_STAT_INForUNBD )
2364 {
2365 /* preprocessing was not the problem; issue a warning message and treat LP as infeasible */
2366 SCIPerrorMessage("CPLEX primal simplex returned CPX_STAT_INForUNBD after presolving was turned off.\n");
2367 }
2368 }
2369
2370 /* check whether the solution is basic: if Cplex, e.g., hits a time limit in data setup, this might not be the case,
2371 * also for some pathological cases of infeasibility, e.g., contradictory bounds */
2372 lpi->solisbasic = (solntype == CPX_BASIC_SOLN);
2373 assert( lpi->solisbasic || lpi->solstat != CPX_STAT_OPTIMAL );
2374
2375 return SCIP_OKAY;
2376}
2377
2378/** calls dual simplex to solve the LP */
2380 SCIP_LPI* lpi /**< LP interface structure */
2381 )
2382{
2383 int retval;
2384 int primalfeasible;
2385 int dualfeasible;
2386 int solntype;
2387
2388 assert(lpi != NULL);
2389 assert(lpi->cpxlp != NULL);
2390 assert(lpi->cpxenv != NULL);
2391
2392 SCIPdebugMessage("calling CPLEX dual simplex: %d cols, %d rows\n",
2393 CPXgetnumcols(lpi->cpxenv, lpi->cpxlp), CPXgetnumrows(lpi->cpxenv, lpi->cpxlp));
2394
2395 invalidateSolution(lpi);
2396
2397 setIntParam(lpi, CPX_PARAM_ADVIND, lpi->fromscratch || lpi->clearstate ? CPX_OFF : CPX_ON);
2398 lpi->clearstate = FALSE;
2399
2400 SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
2401
2402#if (CPX_VERSION == 12070000)
2403 {
2404 int scaling;
2405 /* due to a bug in CPLEX 12.7.0 we need to disable scaling */
2406 CHECK_ZERO( lpi->messagehdlr, CPXgetintparam(lpi->cpxenv, CPX_PARAM_SCAIND, &scaling) );
2407 assert( scaling == -1 );
2408 }
2409#endif
2410
2411 SCIPdebugMessage("calling CPXdualopt()\n");
2412 retval = CPXdualopt(lpi->cpxenv, lpi->cpxlp);
2413 switch( retval )
2414 {
2415 case 0:
2416 break;
2417 case CPXERR_NO_MEMORY:
2418 return SCIP_NOMEMORY;
2419 default:
2420 return SCIP_LPERROR;
2421 }
2422
2423 lpi->solstat = CPXgetstat(lpi->cpxenv, lpi->cpxlp);
2424 lpi->method = CPX_ALG_DUAL;
2426
2427 /* CPLEX outputs an error if the status is CPX_STAT_INForUNBD and the iterations are determined */
2428 CHECK_ZERO( lpi->messagehdlr, CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, &solntype, &primalfeasible, &dualfeasible) );
2429 if( lpi->solstat != CPX_STAT_INForUNBD && solntype != CPX_NO_SOLN )
2430 lpi->iterations = CPXgetphase1cnt(lpi->cpxenv, lpi->cpxlp) + CPXgetitcnt(lpi->cpxenv, lpi->cpxlp);
2431 else
2432 lpi->iterations = 0;
2433
2434 SCIPdebugMessage(" -> CPLEX returned solstat=%d, pfeas=%d, dfeas=%d (%d iterations)\n",
2435 lpi->solstat, primalfeasible, dualfeasible, lpi->iterations);
2436
2437 if( lpi->solstat == CPX_STAT_INForUNBD
2438 || (lpi->solstat == CPX_STAT_INFEASIBLE && !dualfeasible)
2439 || (lpi->solstat == CPX_STAT_UNBOUNDED && !primalfeasible) )
2440 {
2441 if( getIntParam(lpi, CPX_PARAM_PREIND) == CPX_ON )
2442 {
2443 /* maybe the preprocessor solved the problem; but we need a solution, so solve again without preprocessing */
2444 SCIPdebugMessage("presolver may have solved the problem -> calling CPLEX dual simplex again without presolve\n");
2445
2446 /* switch off preprocessing */
2447 setIntParam(lpi, CPX_PARAM_PREIND, CPX_OFF);
2448 SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
2449
2450 retval = CPXdualopt(lpi->cpxenv, lpi->cpxlp);
2451 switch( retval )
2452 {
2453 case 0:
2454 break;
2455 case CPXERR_NO_MEMORY:
2456 return SCIP_NOMEMORY;
2457 default:
2458 return SCIP_LPERROR;
2459 }
2460
2461 lpi->solstat = CPXgetstat(lpi->cpxenv, lpi->cpxlp);
2463 assert( lpi->solstat != CPX_STAT_INForUNBD );
2464
2465 lpi->iterations += CPXgetphase1cnt(lpi->cpxenv, lpi->cpxlp) + CPXgetitcnt(lpi->cpxenv, lpi->cpxlp);
2466 CHECK_ZERO( lpi->messagehdlr, CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, &solntype, NULL, NULL) );
2467
2468 SCIPdebugMessage(" -> CPLEX returned solstat=%d (%d iterations)\n", lpi->solstat, lpi->iterations);
2469
2470 /* switch on preprocessing again */
2471 setIntParam(lpi, CPX_PARAM_PREIND, CPX_ON);
2472 }
2473
2474 if( lpi->solstat == CPX_STAT_INForUNBD )
2475 {
2476 /* preprocessing was not the problem; issue a warning message and treat LP as infeasible */
2477 SCIPerrorMessage("CPLEX dual simplex returned CPX_STAT_INForUNBD after presolving was turned off\n");
2478 }
2479 }
2480
2481 /* check whether the solution is basic: if Cplex, e.g., hits a time limit in data setup, this might not be the case,
2482 * also for some pathological cases of infeasibility, e.g., contradictory bounds
2483 */
2484 lpi->solisbasic = (solntype == CPX_BASIC_SOLN);
2485 assert( lpi->solisbasic || lpi->solstat != CPX_STAT_OPTIMAL );
2486
2487#ifdef SCIP_DISABLED_CODE
2488 /* this fixes the strange behavior of CPLEX, that in case of the objective limit exceedance, it returns the
2489 * solution for the basis preceeding the one with exceeding objective limit
2490 * (using this "wrong" dual solution can cause column generation algorithms to fail to find an improving column)
2491 */
2492 if( SCIPlpiIsObjlimExc(lpi) )
2493 {
2494 SCIP_Real objval;
2495 SCIP_Real llim;
2496 SCIP_Real ulim;
2497 SCIP_Real eps;
2498
2499 /* check, if the dual solution returned by CPLEX really exceeds the objective limit;
2500 * CPLEX usually returns the basis one iteration before the one that exceeds the limit
2501 */
2502 SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
2503 llim = getDblParam(lpi, CPX_PARAM_OBJLLIM);
2504 ulim = getDblParam(lpi, CPX_PARAM_OBJULIM);
2505 eps = getDblParam(lpi, CPX_PARAM_EPOPT);
2506 if( objval >= llim - eps && objval <= ulim + eps )
2507 {
2508 int itlim;
2509 int advind;
2510
2511 /* perform one additional simplex iteration without objective limit */
2512 SCIPdebugMessage("dual solution %g does not exceed objective limit [%g,%g] (%d iterations) -> calling CPLEX dual simplex again for one iteration\n",
2513 objval, llim, ulim, lpi->iterations);
2514 itlim = getIntParam(lpi, CPX_PARAM_ITLIM);
2515 setIntParam(lpi, CPX_PARAM_ITLIM, 1);
2516 advind = getIntParam(lpi, CPX_PARAM_ADVIND);
2517 setIntParam(lpi, CPX_PARAM_ADVIND, CPX_ON);
2518 setDblParam(lpi, CPX_PARAM_OBJLLIM, -CPX_INFBOUND);
2519 setDblParam(lpi, CPX_PARAM_OBJULIM, CPX_INFBOUND);
2520 SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
2521 CHECK_ZERO( lpi->messagehdlr, CPXsetintparam(lpi->cpxenv, CPX_PARAM_FINALFACTOR, FALSE) );
2522
2523 retval = CPXdualopt(lpi->cpxenv, lpi->cpxlp);
2524 switch( retval )
2525 {
2526 case 0:
2527 break;
2528 case CPXERR_NO_MEMORY:
2529 return SCIP_NOMEMORY;
2530 default:
2531 return SCIP_LPERROR;
2532 }
2533
2534 lpi->iterations += CPXgetphase1cnt(lpi->cpxenv, lpi->cpxlp) + CPXgetitcnt(lpi->cpxenv, lpi->cpxlp);
2535
2536 /* reset the iteration limit and objective bounds */
2537 setIntParam(lpi, CPX_PARAM_ITLIM, itlim);
2538 setIntParam(lpi, CPX_PARAM_ADVIND, advind);
2539 setDblParam(lpi, CPX_PARAM_OBJLLIM, llim);
2540 setDblParam(lpi, CPX_PARAM_OBJULIM, ulim);
2541 SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
2542 CHECK_ZERO( lpi->messagehdlr, CPXsetintparam(lpi->cpxenv, CPX_PARAM_FINALFACTOR, TRUE) );
2543
2544 /* resolve LP again in order to restore the status of exceeded objective limit */
2545 retval = CPXdualopt(lpi->cpxenv, lpi->cpxlp);
2546 switch( retval )
2547 {
2548 case 0:
2549 break;
2550 case CPXERR_NO_MEMORY:
2551 return SCIP_NOMEMORY;
2552 default:
2553 return SCIP_LPERROR;
2554 }
2555
2556 lpi->iterations += CPXgetphase1cnt(lpi->cpxenv, lpi->cpxlp) + CPXgetitcnt(lpi->cpxenv, lpi->cpxlp);
2557 lpi->solstat = CPXgetstat(lpi->cpxenv, lpi->cpxlp);
2559 SCIPdebugMessage(" -> CPLEX returned solstat=%d (%d iterations)\n", lpi->solstat, lpi->iterations);
2560 }
2561 }
2562#endif
2563
2564 return SCIP_OKAY;
2565}
2566
2567/** calls barrier or interior point algorithm to solve the LP with crossover to simplex basis */
2569 SCIP_LPI* lpi, /**< LP interface structure */
2570 SCIP_Bool crossover /**< perform crossover */
2571 )
2572{
2573 int solntype;
2574 int retval;
2575
2576 assert(lpi != NULL);
2577 assert(lpi->cpxlp != NULL);
2578 assert(lpi->cpxenv != NULL);
2579
2580 SCIPdebugMessage("calling CPLEX barrier: %d cols, %d rows\n",
2581 CPXgetnumcols(lpi->cpxenv, lpi->cpxlp), CPXgetnumrows(lpi->cpxenv, lpi->cpxlp));
2582
2583 invalidateSolution(lpi);
2584
2585 setIntParam(lpi, CPX_PARAM_ADVIND, lpi->fromscratch || lpi->clearstate ? CPX_OFF : CPX_ON);
2586 lpi->clearstate = FALSE;
2587
2588 SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
2589
2590 SCIPdebugMessage("calling CPXhybaropt()\n");
2591 retval = CPXhybbaropt(lpi->cpxenv, lpi->cpxlp, crossover ? 0 : CPX_ALG_NONE);
2592 switch( retval )
2593 {
2594 case 0:
2595 break;
2596 case CPXERR_NO_MEMORY:
2597 return SCIP_NOMEMORY;
2598 default:
2599 return SCIP_LPERROR;
2600 }
2601
2602 CHECK_ZERO( lpi->messagehdlr, CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, &solntype, NULL, NULL) );
2603
2604 lpi->solisbasic = (solntype == CPX_BASIC_SOLN);
2605 lpi->solstat = CPXgetstat(lpi->cpxenv, lpi->cpxlp);
2606 lpi->method = CPX_ALG_BARRIER;
2608
2609 if( lpi->solstat != CPX_STAT_INForUNBD && solntype != CPX_NO_SOLN )
2610 lpi->iterations = CPXgetbaritcnt(lpi->cpxenv, lpi->cpxlp);
2611 else
2612 lpi->iterations = 0;
2613
2614 SCIPdebugMessage(" -> CPLEX returned solstat=%d (%d iterations)\n", lpi->solstat, lpi->iterations);
2615
2616 if( lpi->solstat == CPX_STAT_INForUNBD )
2617 {
2618 /* maybe the preprocessor solved the problem; but we need a solution, so solve again without preprocessing */
2619 SCIPdebugMessage("CPLEX returned INForUNBD -> calling CPLEX barrier again without presolve\n");
2620
2621 /* switch off preprocessing */
2622 setIntParam(lpi, CPX_PARAM_PREIND, CPX_OFF);
2623 SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
2624
2625 retval = CPXhybbaropt(lpi->cpxenv, lpi->cpxlp, crossover ? 0 : CPX_ALG_NONE);
2626 switch( retval )
2627 {
2628 case 0:
2629 break;
2630 case CPXERR_NO_MEMORY:
2631 return SCIP_NOMEMORY;
2632 default:
2633 return SCIP_LPERROR;
2634 }
2635
2636 CHECK_ZERO( lpi->messagehdlr, CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, &solntype, NULL, NULL) );
2637
2638 lpi->solisbasic = (solntype == CPX_BASIC_SOLN);
2639 lpi->solstat = CPXgetstat(lpi->cpxenv, lpi->cpxlp);
2641
2642 lpi->iterations += CPXgetbaritcnt(lpi->cpxenv, lpi->cpxlp);
2643 SCIPdebugMessage(" -> CPLEX returned solstat=%d\n", lpi->solstat);
2644
2645 setIntParam(lpi, CPX_PARAM_PREIND, CPX_ON);
2646
2647 if( lpi->solstat == CPX_STAT_INForUNBD )
2648 {
2649 /* if we could not resolve CPX_STAT_INForUNBD, we use the dual simplex */
2651 }
2652 }
2653
2654 return SCIP_OKAY;
2655}
2656
2657/** manually performs strong branching on one integral variable */
2658static
2660 SCIP_LPI* lpi, /**< LP interface structure */
2661 int col, /**< column to apply strong branching on */
2662 SCIP_Real psol, /**< current integral primal solution value of column */
2663 int itlim, /**< iteration limit for strong branchings */
2664 SCIP_Real* down, /**< stores dual bound after branching column down */
2665 SCIP_Real* up, /**< stores dual bound after branching column up */
2666 SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
2667 * otherwise, it can only be used as an estimate value */
2668 SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
2669 * otherwise, it can only be used as an estimate value */
2670 int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
2671 )
2672{
2673 const char lbound = 'L';
2674 const char ubound = 'U';
2675 SCIP_Real oldlb;
2676 SCIP_Real oldub;
2677 SCIP_Real newlb;
2678 SCIP_Real newub;
2679 int objsen;
2680 int olditlim;
2681 int it;
2682
2683 SCIPdebugMessage(" -> strong branching on integral variable %d\n", col);
2684
2685 assert( EPSISINT(psol, lpi->feastol) );
2686
2687 objsen = CPXgetobjsen(lpi->cpxenv, lpi->cpxlp);
2688
2689 /* results of CPLEX are valid in any case */
2690 *downvalid = TRUE;
2691 *upvalid = TRUE;
2692
2693 /* save current LP basis and bounds*/
2694 SCIP_CALL( getBase(lpi) );
2695 CHECK_ZERO( lpi->messagehdlr, CPXgetlb(lpi->cpxenv, lpi->cpxlp, &oldlb, col, col) );
2696 CHECK_ZERO( lpi->messagehdlr, CPXgetub(lpi->cpxenv, lpi->cpxlp, &oldub, col, col) );
2697
2698 /* save old iteration limit and set iteration limit to strong branching limit */
2699 if( itlim > CPX_INT_MAX )
2700 itlim = CPX_INT_MAX;
2701 olditlim = getIntParam(lpi, CPX_PARAM_ITLIM);
2702 setIntParam(lpi, CPX_PARAM_ITLIM, itlim);
2703
2704 /* down branch */
2705 newub = EPSCEIL(psol-1.0, lpi->feastol);
2706 if( newub >= oldlb - 0.5 )
2707 {
2708 CHECK_ZERO( lpi->messagehdlr, CPXchgbds(lpi->cpxenv, lpi->cpxlp, 1, &col, &ubound, &newub) );
2711 *down = objsen == CPX_MIN ? getDblParam(lpi, CPX_PARAM_OBJULIM) : getDblParam(lpi, CPX_PARAM_OBJLLIM);
2712 else if( SCIPlpiIsOptimal(lpi) || SCIPlpiIsIterlimExc(lpi) )
2713 {
2714 SCIP_CALL( SCIPlpiGetObjval(lpi, down) );
2715 }
2716 else
2717 *down = objsen == CPX_MIN ? getDblParam(lpi, CPX_PARAM_OBJLLIM) : getDblParam(lpi, CPX_PARAM_OBJULIM);
2718 if( iter != NULL )
2719 {
2720 SCIP_CALL( SCIPlpiGetIterations(lpi, &it) );
2721 *iter += it;
2722 }
2723 SCIPdebugMessage(" -> down (x%d <= %g): %g\n", col, newub, *down);
2724
2725 CHECK_ZERO( lpi->messagehdlr, CPXchgbds(lpi->cpxenv, lpi->cpxlp, 1, &col, &ubound, &oldub) );
2726 SCIP_CALL( setBase(lpi) );
2727 }
2728 else
2729 *down = objsen == CPX_MIN ? getDblParam(lpi, CPX_PARAM_OBJULIM) : getDblParam(lpi, CPX_PARAM_OBJLLIM);
2730
2731 /* up branch */
2732 newlb = EPSFLOOR(psol+1.0, lpi->feastol);
2733 if( newlb <= oldub + 0.5 )
2734 {
2735 CHECK_ZERO( lpi->messagehdlr, CPXchgbds(lpi->cpxenv, lpi->cpxlp, 1, &col, &lbound, &newlb) );
2738 *up = objsen == CPX_MIN ? getDblParam(lpi, CPX_PARAM_OBJULIM) : getDblParam(lpi, CPX_PARAM_OBJLLIM);
2739 else if( SCIPlpiIsOptimal(lpi) || SCIPlpiIsIterlimExc(lpi) )
2740 {
2741 SCIP_CALL( SCIPlpiGetObjval(lpi, up) );
2742 }
2743 else
2744 *up = objsen == CPX_MIN ? getDblParam(lpi, CPX_PARAM_OBJLLIM) : getDblParam(lpi, CPX_PARAM_OBJULIM);
2745 if( iter != NULL )
2746 {
2747 SCIP_CALL( SCIPlpiGetIterations(lpi, &it) );
2748 *iter += it;
2749 }
2750 SCIPdebugMessage(" -> up (x%d >= %g): %g\n", col, newlb, *up);
2751
2752 CHECK_ZERO( lpi->messagehdlr, CPXchgbds(lpi->cpxenv, lpi->cpxlp, 1, &col, &lbound, &oldlb) );
2753 SCIP_CALL( setBase(lpi) );
2754 }
2755 else
2756 *up = objsen == CPX_MIN ? getDblParam(lpi, CPX_PARAM_OBJLLIM) : getDblParam(lpi, CPX_PARAM_OBJULIM);
2757
2758 /* reset iteration limit */
2759 setIntParam(lpi, CPX_PARAM_ITLIM, olditlim);
2760
2761 return SCIP_OKAY;
2762}
2763
2764/** start strong branching */
2766 SCIP_LPI* lpi /**< LP interface structure */
2767 )
2768{ /*lint --e{715}*/
2769 assert(lpi != NULL);
2770 assert(lpi->cpxlp != NULL);
2771 assert(lpi->cpxenv != NULL);
2772
2773 /* no work necessary */
2774 return SCIP_OKAY;
2775}
2776
2777/** end strong branching */
2779 SCIP_LPI* lpi /**< LP interface structure */
2780 )
2781{ /*lint --e{715}*/
2782 assert(lpi != NULL);
2783 assert(lpi->cpxlp != NULL);
2784 assert(lpi->cpxenv != NULL);
2785
2786 /* no work necessary */
2787 return SCIP_OKAY;
2788}
2789
2790/** performs strong branching iterations on one @b fractional candidate */
2792 SCIP_LPI* lpi, /**< LP interface structure */
2793 int col, /**< column to apply strong branching on */
2794 SCIP_Real psol, /**< fractional current primal solution value of column */
2795 int itlim, /**< iteration limit for strong branchings */
2796 SCIP_Real* down, /**< stores dual bound after branching column down */
2797 SCIP_Real* up, /**< stores dual bound after branching column up */
2798 SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
2799 * otherwise, it can only be used as an estimate value */
2800 SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
2801 * otherwise, it can only be used as an estimate value */
2802 int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
2803 )
2804{
2805 int retval;
2806
2807 assert(lpi != NULL);
2808 assert(lpi->cpxlp != NULL);
2809 assert(lpi->cpxenv != NULL);
2810 assert(down != NULL);
2811 assert(up != NULL);
2812 assert(downvalid != NULL);
2813 assert(upvalid != NULL);
2814
2815 SCIPdebugMessage("calling CPLEX strongbranching on fractional variable %d (%d iterations)\n", col, itlim);
2816
2817 assert( !EPSISINT(psol, lpi->feastol) );
2818
2819 /* results of CPLEX are valid in any case */
2820 *downvalid = TRUE;
2821 *upvalid = TRUE;
2822
2823 setIntParam(lpi, CPX_PARAM_ADVIND, lpi->fromscratch || lpi->clearstate ? CPX_OFF : CPX_ON);
2824 lpi->clearstate = FALSE;
2825
2826 SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
2827
2828 retval = CPXstrongbranch(lpi->cpxenv, lpi->cpxlp, &col, 1, down, up, itlim);
2829 if( retval == CPXERR_NEED_OPT_SOLN )
2830 {
2831 SCIPdebugMessage(" -> no optimal solution available\n");
2832 return SCIP_LPERROR;
2833 }
2834 else if( retval == CPXERR_TILIM_STRONGBRANCH )
2835 {
2836 SCIPdebugMessage(" -> time limit exceeded during strong branching\n");
2837 return SCIP_LPERROR;
2838 }
2839 else if( retval == CPXERR_SINGULAR )
2840 {
2841 SCIPdebugMessage(" -> numerical troubles (basis singular)\n");
2842 return SCIP_LPERROR;
2843 }
2844 CHECK_ZERO( lpi->messagehdlr, retval );
2845 SCIPdebugMessage(" -> down: %g, up:%g\n", *down, *up);
2846
2847 /* CPLEX is not able to return the iteration counts in strong branching */
2848 if( iter != NULL )
2849 *iter = -1;
2850
2851 return SCIP_OKAY;
2852}
2853
2854/** performs strong branching iterations on given @b fractional candidates */
2856 SCIP_LPI* lpi, /**< LP interface structure */
2857 int* cols, /**< columns to apply strong branching on */
2858 int ncols, /**< number of columns */
2859 SCIP_Real* psols, /**< fractional current primal solution values of columns */
2860 int itlim, /**< iteration limit for strong branchings */
2861 SCIP_Real* down, /**< stores dual bounds after branching columns down */
2862 SCIP_Real* up, /**< stores dual bounds after branching columns up */
2863 SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds;
2864 * otherwise, they can only be used as an estimate values */
2865 SCIP_Bool* upvalid, /**< stores whether the returned up values are a valid dual bounds;
2866 * otherwise, they can only be used as an estimate values */
2867 int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
2868 )
2869{
2870 int retval;
2871 int j;
2872
2873 assert(lpi != NULL);
2874 assert(lpi->cpxlp != NULL);
2875 assert(lpi->cpxenv != NULL);
2876 assert(cols != NULL);
2877 assert(psols != NULL);
2878 assert(down != NULL);
2879 assert(up != NULL);
2880 assert(downvalid != NULL);
2881 assert(upvalid != NULL);
2882
2883 SCIPdebugMessage("calling CPLEX strongbranching on %d fractional variables (%d iterations)\n", ncols, itlim);
2884
2885 setIntParam(lpi, CPX_PARAM_ADVIND, lpi->fromscratch || lpi->clearstate ? CPX_OFF : CPX_ON);
2886 lpi->clearstate = FALSE;
2887
2888 SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
2889
2890 /* initialize */
2891 for( j = 0; j < ncols; ++j )
2892 {
2893 /* results of CPLEX are valid in any case */
2894 downvalid[j] = TRUE;
2895 upvalid[j] = TRUE;
2896
2897 assert( !EPSISINT(psols[j], lpi->feastol) );
2898 }
2899
2900 retval = CPXstrongbranch(lpi->cpxenv, lpi->cpxlp, cols, ncols, down, up, itlim);
2901 if( retval == CPXERR_NEED_OPT_SOLN )
2902 {
2903 SCIPdebugMessage(" -> no optimal solution available\n");
2904 return SCIP_LPERROR;
2905 }
2906 else if( retval == CPXERR_TILIM_STRONGBRANCH )
2907 {
2908 SCIPdebugMessage(" -> time limit exceeded during strong branching\n");
2909 return SCIP_LPERROR;
2910 }
2911 CHECK_ZERO( lpi->messagehdlr, retval );
2912
2913 /* CPLEX is not able to return the iteration counts in strong branching */
2914 if( iter != NULL )
2915 *iter = -1;
2916
2917 return SCIP_OKAY;
2918}
2919
2920/** performs strong branching iterations on one candidate with @b integral value */
2922 SCIP_LPI* lpi, /**< LP interface structure */
2923 int col, /**< column to apply strong branching on */
2924 SCIP_Real psol, /**< current integral primal solution value of column */
2925 int itlim, /**< iteration limit for strong branchings */
2926 SCIP_Real* down, /**< stores dual bound after branching column down */
2927 SCIP_Real* up, /**< stores dual bound after branching column up */
2928 SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
2929 * otherwise, it can only be used as an estimate value */
2930 SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
2931 * otherwise, it can only be used as an estimate value */
2932 int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
2933 )
2934{
2935 assert(lpi != NULL);
2936 assert(lpi->cpxlp != NULL);
2937 assert(down != NULL);
2938 assert(up != NULL);
2939 assert(downvalid != NULL);
2940 assert(upvalid != NULL);
2941
2942 SCIPdebugMessage("calling CPLEX strongbranching on variable %d with integral value (%d iterations)\n", col, itlim);
2943
2944 assert( EPSISINT(psol, lpi->feastol) );
2945
2946 if( iter != NULL )
2947 *iter = 0;
2948
2949 SCIP_CALL( lpiStrongbranchIntegral(lpi, col, psol, itlim, down, up, downvalid, upvalid, iter) );
2950
2951 return SCIP_OKAY;
2952}
2953
2954/** performs strong branching iterations on given candidates with @b integral values */
2956 SCIP_LPI* lpi, /**< LP interface structure */
2957 int* cols, /**< columns to apply strong branching on */
2958 int ncols, /**< number of columns */
2959 SCIP_Real* psols, /**< current integral primal solution values of columns */
2960 int itlim, /**< iteration limit for strong branchings */
2961 SCIP_Real* down, /**< stores dual bounds after branching columns down */
2962 SCIP_Real* up, /**< stores dual bounds after branching columns up */
2963 SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds;
2964 * otherwise, they can only be used as an estimate values */
2965 SCIP_Bool* upvalid, /**< stores whether the returned up values are a valid dual bounds;
2966 * otherwise, they can only be used as an estimate values */
2967 int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
2968 )
2969{
2970 int j;
2971
2972 assert(lpi != NULL);
2973 assert(lpi->cpxlp != NULL);
2974 assert(cols != NULL);
2975 assert(psols != NULL);
2976 assert(down != NULL);
2977 assert(up != NULL);
2978 assert(downvalid != NULL);
2979 assert(upvalid != NULL);
2980
2981 SCIPdebugMessage("calling CPLEX strongbranching on %d variables with integer values (%d iterations)\n", ncols, itlim);
2982
2983 if( iter != NULL )
2984 *iter = 0;
2985
2986 /* initialize */
2987 for( j = 0; j < ncols; ++j )
2988 {
2989 assert( EPSISINT(psols[j], lpi->feastol) );
2990 SCIP_CALL( lpiStrongbranchIntegral(lpi, cols[j], psols[j], itlim, &(down[j]), &(up[j]), &(downvalid[j]), &(upvalid[j]), iter) );
2991 }
2992
2993 return SCIP_OKAY;
2994}
2995/**@} */
2996
2997
2998
2999
3000/*
3001 * Solution Information Methods
3002 */
3003
3004/**@name Solution Information Methods */
3005/**@{ */
3006
3007/** returns whether a solve method was called after the last modification of the LP */
3009 SCIP_LPI* lpi /**< LP interface structure */
3010 )
3011{
3012 assert(lpi != NULL);
3013 assert(lpi->cpxlp != NULL);
3014 assert(lpi->cpxenv != NULL);
3015
3016 return (lpi->solstat != -1);
3017}
3018
3019/** gets information about primal and dual feasibility of the current LP solution
3020 *
3021 * The feasibility information is with respect to the last solving call and it is only relevant if SCIPlpiWasSolved()
3022 * returns true. If the LP is changed, this information might be invalidated.
3023 *
3024 * Note that @a primalfeasible and @a dualfeasible should only return true if the solver has proved the respective LP to
3025 * be feasible. Thus, the return values should be equal to the values of SCIPlpiIsPrimalFeasible() and
3026 * SCIPlpiIsDualFeasible(), respectively. Note that if feasibility cannot be proved, they should return false (even if
3027 * the problem might actually be feasible).
3028 */
3030 SCIP_LPI* lpi, /**< LP interface structure */
3031 SCIP_Bool* primalfeasible, /**< pointer to store primal feasibility status */
3032 SCIP_Bool* dualfeasible /**< pointer to store dual feasibility status */
3033 )
3034{
3035 int pfeas;
3036 int dfeas;
3037
3038 assert(lpi != NULL);
3039 assert(lpi->cpxlp != NULL);
3040 assert(lpi->cpxenv != NULL);
3041 assert(primalfeasible != NULL);
3042 assert(dualfeasible != NULL);
3043
3044 SCIPdebugMessage("getting solution feasibility\n");
3045
3046 CHECK_ZERO( lpi->messagehdlr, CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, NULL, &pfeas, &dfeas) );
3047 *primalfeasible = (SCIP_Bool)pfeas;
3048 *dualfeasible = (SCIP_Bool)dfeas;
3049
3050 return SCIP_OKAY;
3051}
3052
3053/** returns TRUE iff LP is proven to have a primal unbounded ray (but not necessary a primal feasible point);
3054 * this does not necessarily mean, that the solver knows and can return the primal ray
3055 */
3057 SCIP_LPI* lpi /**< LP interface structure */
3058 )
3059{
3060 assert(lpi != NULL);
3061 assert(lpi->cpxlp != NULL);
3062 assert(lpi->solstat >= 0);
3063
3064 return (lpi->solstat == CPX_STAT_UNBOUNDED || lpi->solstat == CPX_STAT_OPTIMAL_FACE_UNBOUNDED);
3065}
3066
3067/** returns TRUE iff LP is proven to have a primal unbounded ray (but not necessary a primal feasible point),
3068 * and the solver knows and can return the primal ray
3069 */
3071 SCIP_LPI* lpi /**< LP interface structure */
3072 )
3073{
3074 assert(lpi != NULL);
3075 assert(lpi->cpxlp != NULL);
3076 assert(lpi->cpxenv != NULL);
3077 assert(lpi->solstat >= 0);
3078
3079 return (lpi->solstat == CPX_STAT_UNBOUNDED );
3080}
3081
3082/** returns TRUE iff LP is proven to be primal unbounded */
3084 SCIP_LPI* lpi /**< LP interface structure */
3085 )
3086{
3087 int primalfeasible;
3088
3089 assert(lpi != NULL);
3090 assert(lpi->cpxlp != NULL);
3091 assert(lpi->cpxenv != NULL);
3092 assert(lpi->solstat >= 0);
3093
3094 SCIPdebugMessage("checking for primal unboundedness\n");
3095
3096 ABORT_ZERO( CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, NULL, &primalfeasible, NULL) );
3097
3098 /* If the solution status of CPLEX is CPX_STAT_UNBOUNDED, it only means, there is an unbounded ray,
3099 * but not necessarily a feasible primal solution. If primalfeasible == FALSE, we cannot conclude,
3100 * that the problem is unbounded.
3101 */
3102 return ((primalfeasible && (lpi->solstat == CPX_STAT_UNBOUNDED || lpi->solstat == CPX_STAT_INForUNBD))
3103 || lpi->solstat == CPX_STAT_OPTIMAL_FACE_UNBOUNDED || (primalfeasible && lpi->solstat == CPX_STAT_ABORT_PRIM_OBJ_LIM && lpi->method == CPX_ALG_BARRIER));
3104}
3105
3106/** returns TRUE iff LP is proven to be primal infeasible */
3108 SCIP_LPI* lpi /**< LP interface structure */
3109 )
3110{
3111 int dualfeasible;
3112
3113 assert(lpi != NULL);
3114 assert(lpi->cpxlp != NULL);
3115 assert(lpi->cpxenv != NULL);
3116 assert(lpi->solstat >= 0);
3117
3118 SCIPdebugMessage("checking for primal infeasibility\n");
3119
3120 ABORT_ZERO( CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, NULL, NULL, &dualfeasible) );
3121
3122 return (lpi->solstat == CPX_STAT_INFEASIBLE || (lpi->solstat == CPX_STAT_INForUNBD && dualfeasible)
3123 || (lpi->solstat == CPX_STAT_ABORT_DUAL_OBJ_LIM && lpi->method == CPX_ALG_BARRIER));
3124}
3125
3126/** returns TRUE iff LP is proven to be primal feasible */
3128 SCIP_LPI* lpi /**< LP interface structure */
3129 )
3130{
3131 int primalfeasible;
3132
3133 assert(lpi != NULL);
3134 assert(lpi->cpxlp != NULL);
3135 assert(lpi->cpxenv != NULL);
3136 assert(lpi->solstat >= 0);
3137
3138 SCIPdebugMessage("checking for primal feasibility\n");
3139
3140 ABORT_ZERO( CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, NULL, &primalfeasible, NULL) );
3141
3142 return (SCIP_Bool)primalfeasible;
3143}
3144
3145/** returns TRUE iff LP is proven to have a dual unbounded ray (but not necessary a dual feasible point);
3146 * this does not necessarily mean, that the solver knows and can return the dual ray
3147 */
3149 SCIP_LPI* lpi /**< LP interface structure */
3150 )
3151{
3152 assert(lpi != NULL);
3153 assert(lpi->solstat >= 0);
3154
3155 return (lpi->solstat == CPX_STAT_INFEASIBLE);
3156}
3157
3158/** returns TRUE iff LP is proven to have a dual unbounded ray (but not necessary a dual feasible point),
3159 * and the solver knows and can return the dual ray
3160 */
3162 SCIP_LPI* lpi /**< LP interface structure */
3163 )
3164{
3165 assert(lpi != NULL);
3166 assert(lpi->cpxlp != NULL);
3167 assert(lpi->cpxenv != NULL);
3168 assert(lpi->solstat >= 0);
3169
3170 return (lpi->solstat == CPX_STAT_INFEASIBLE && lpi->method == CPX_ALG_DUAL);
3171}
3172
3173/** returns TRUE iff LP is proven to be dual unbounded */
3175 SCIP_LPI* lpi /**< LP interface structure */
3176 )
3177{
3178 int dualfeasible;
3179
3180 assert(lpi != NULL);
3181 assert(lpi->cpxlp != NULL);
3182 assert(lpi->cpxenv != NULL);
3183 assert(lpi->solstat >= 0);
3184
3185 SCIPdebugMessage("checking for dual unboundedness\n");
3186
3187 ABORT_ZERO( CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, NULL, NULL, &dualfeasible) );
3188
3189 return (dualfeasible && ((lpi->solstat == CPX_STAT_INFEASIBLE || lpi->solstat == CPX_STAT_INForUNBD)
3190 || (lpi->solstat == CPX_STAT_ABORT_DUAL_OBJ_LIM && lpi->method == CPX_ALG_BARRIER)));
3191}
3192
3193/** returns TRUE iff LP is proven to be dual infeasible */
3195 SCIP_LPI* lpi /**< LP interface structure */
3196 )
3197{
3198 int primalfeasible;
3199
3200 assert(lpi != NULL);
3201 assert(lpi->cpxlp != NULL);
3202 assert(lpi->cpxenv != NULL);
3203 assert(lpi->solstat >= 0);
3204
3205 SCIPdebugMessage("checking for dual infeasibility\n");
3206
3207 ABORT_ZERO( CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, NULL, &primalfeasible, NULL) );
3208
3209 return (lpi->solstat == CPX_STAT_UNBOUNDED
3210 || lpi->solstat == CPX_STAT_OPTIMAL_FACE_UNBOUNDED
3211 || (lpi->solstat == CPX_STAT_INForUNBD && primalfeasible)
3212 || (lpi->solstat == CPX_STAT_ABORT_PRIM_OBJ_LIM && lpi->method == CPX_ALG_BARRIER));
3213}
3214
3215/** returns TRUE iff LP is proven to be dual feasible */
3217 SCIP_LPI* lpi /**< LP interface structure */
3218 )
3219{
3220 int dualfeasible;
3221
3222 assert(lpi != NULL);
3223 assert(lpi->cpxlp != NULL);
3224 assert(lpi->cpxenv != NULL);
3225 assert(lpi->solstat >= 0);
3226
3227 SCIPdebugMessage("checking for dual feasibility\n");
3228
3229 ABORT_ZERO( CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, NULL, NULL, &dualfeasible) );
3230
3231 return (SCIP_Bool)dualfeasible;
3232}
3233
3234/** returns TRUE iff LP was solved to optimality */
3236 SCIP_LPI* lpi /**< LP interface structure */
3237 )
3238{
3239 assert(lpi != NULL);
3240 assert(lpi->solstat >= 0);
3241
3242 return (lpi->solstat == CPX_STAT_OPTIMAL);
3243}
3244
3245/** returns TRUE iff current LP solution is stable
3246 *
3247 * This function should return true if the solution is reliable, i.e., feasible and optimal (or proven
3248 * infeasible/unbounded) with respect to the original problem. The optimality status might be with respect to a scaled
3249 * version of the problem, but the solution might not be feasible to the unscaled original problem; in this case,
3250 * SCIPlpiIsStable() should return false.
3251 */
3253 SCIP_LPI* lpi /**< LP interface structure */
3254 )
3255{
3256 assert(lpi != NULL);
3257 assert(lpi->cpxlp != NULL);
3258 assert(lpi->cpxenv != NULL);
3259 assert(lpi->solstat >= 0);
3260
3261 SCIPdebugMessage("checking for stability: CPLEX solstat = %d\n", lpi->solstat);
3262
3263#ifdef SCIP_DISABLED_CODE
3264 /* The following workaround is not needed anymore for SCIP, since it tries to heuristically construct a feasible
3265 * solution or automatically resolves the problem if the status is "unbounded"; see SCIPlpGetUnboundedSol().
3266 */
3267
3268 /* If the solution status of CPLEX is CPX_STAT_UNBOUNDED, it only means, there is an unbounded ray,
3269 * but not necessarily a feasible primal solution. If primalfeasible == FALSE, we interpret this
3270 * result as instability, s.t. the problem is resolved from scratch
3271 */
3272 if( lpi->solstat == CPX_STAT_UNBOUNDED )
3273 {
3274 int primalfeasible;
3275
3276 ABORT_ZERO( CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, NULL, &primalfeasible, NULL) );
3277
3278 if( !primalfeasible )
3279 return FALSE;
3280 }
3281#endif
3282
3283 /* If the condition number of the basis should be checked, everything above the specified threshold is counted
3284 * as instable.
3285 */
3286 if( lpi->checkcondition && (SCIPlpiIsOptimal(lpi) || SCIPlpiIsObjlimExc(lpi)) )
3287 {
3288 SCIP_Real kappa;
3289 SCIP_RETCODE retcode;
3290
3292 if ( retcode != SCIP_OKAY )
3293 {
3294 SCIPABORT();
3295 return FALSE; /*lint !e527*/
3296 }
3297
3298 /* if the kappa could not be computed (e.g., because we do not have a basis), we cannot check the condition */
3299 if( kappa != SCIP_INVALID || kappa > lpi->conditionlimit ) /*lint !e777*/
3300 return FALSE;
3301 }
3302
3303 return (lpi->solstat != CPX_STAT_NUM_BEST && lpi->solstat != CPX_STAT_OPTIMAL_INFEAS);
3304}
3305
3306/** returns TRUE iff the objective limit was reached */
3308 SCIP_LPI* lpi /**< LP interface structure */
3309 )
3310{
3311 assert(lpi != NULL);
3312 assert(lpi->solstat >= 0);
3313
3314 if( lpi->solstat == CPX_STAT_ABORT_OBJ_LIM )
3315 return TRUE;
3316 else if( lpi->solstat == CPX_STAT_ABORT_DUAL_OBJ_LIM || lpi->solstat == CPX_STAT_ABORT_PRIM_OBJ_LIM )
3317 {
3318 if( lpi->method != CPX_ALG_BARRIER )
3319 return TRUE;
3320 }
3321 return FALSE;
3322}
3323
3324/** returns TRUE iff the iteration limit was reached */
3326 SCIP_LPI* lpi /**< LP interface structure */
3327 )
3328{
3329 assert(lpi != NULL);
3330 assert(lpi->solstat >= 0);
3331
3332 return (lpi->solstat == CPX_STAT_ABORT_IT_LIM);
3333}
3334
3335/** returns TRUE iff the time limit was reached */
3337 SCIP_LPI* lpi /**< LP interface structure */
3338 )
3339{
3340 assert(lpi != NULL);
3341 assert(lpi->solstat >= 0);
3342
3343 return (lpi->solstat == CPX_STAT_ABORT_TIME_LIM);
3344}
3345
3346/** returns the internal solution status of the solver */
3348 SCIP_LPI* lpi /**< LP interface structure */
3349 )
3350{
3351 assert(lpi != NULL);
3352 assert(lpi->cpxlp != NULL);
3353
3354 return lpi->solstat;
3355}
3356
3357/** tries to reset the internal status of the LP solver in order to ignore an instability of the last solving call */
3359 SCIP_LPI* lpi, /**< LP interface structure */
3360 SCIP_Bool* success /**< pointer to store, whether the instability could be ignored */
3361 )
3362{
3363 assert(lpi != NULL);
3364 assert(lpi->cpxlp != NULL);
3365 assert(success != NULL);
3366 assert(lpi->solstat == CPX_STAT_UNBOUNDED
3367 || lpi->solstat == CPX_STAT_NUM_BEST
3368 || lpi->solstat == CPX_STAT_OPTIMAL_INFEAS);
3369
3370 /* replace instable status with optimal status */
3371 if( lpi->solstat == CPX_STAT_NUM_BEST || lpi->solstat == CPX_STAT_OPTIMAL_INFEAS )
3372 lpi->solstat = CPX_STAT_OPTIMAL;
3373
3374 *success = TRUE;
3375 lpi->instabilityignored = TRUE;
3376
3377 return SCIP_OKAY;
3378}
3379
3380/** gets objective value of solution */
3382 SCIP_LPI* lpi, /**< LP interface structure */
3383 SCIP_Real* objval /**< stores the objective value */
3384 )
3385{
3386 int retcode;
3387
3388 assert(lpi != NULL);
3389 assert(lpi->cpxlp != NULL);
3390 assert(lpi->cpxenv != NULL);
3391 assert(objval != NULL);
3392
3393 SCIPdebugMessage("getting solution's objective value\n");
3394
3395 retcode = CPXgetobjval(lpi->cpxenv, lpi->cpxlp, objval);
3396
3397 /* if CPLEX has no solution, e.g., because of a reached time limit, we return -infinity */
3398 if( retcode == CPXERR_NO_SOLN )
3399 {
3400 *objval = -SCIPlpiInfinity(lpi);
3401 }
3402 else
3403 {
3404 CHECK_ZERO( lpi->messagehdlr, retcode );
3405 }
3406
3407 return SCIP_OKAY;
3408}
3409
3410/** gets primal and dual solution vectors for feasible LPs
3411 *
3412 * Before calling this function, the caller must ensure that the LP has been solved to optimality, i.e., that
3413 * SCIPlpiIsOptimal() returns true.
3414 */
3416 SCIP_LPI* lpi, /**< LP interface structure */
3417 SCIP_Real* objval, /**< stores the objective value, may be NULL if not needed */
3418 SCIP_Real* primsol, /**< primal solution vector, may be NULL if not needed */
3419 SCIP_Real* dualsol, /**< dual solution vector, may be NULL if not needed */
3420 SCIP_Real* activity, /**< row activity vector, may be NULL if not needed */
3421 SCIP_Real* redcost /**< reduced cost vector, may be NULL if not needed */
3422 )
3423{
3424 int dummy;
3425
3426 assert(lpi != NULL);
3427 assert(lpi->cpxlp != NULL);
3428 assert(lpi->cpxenv != NULL);
3429 assert(lpi->solstat >= 0);
3430
3431 SCIPdebugMessage("getting solution\n");
3432
3433 CHECK_ZERO( lpi->messagehdlr, CPXsolution(lpi->cpxenv, lpi->cpxlp, &dummy, objval, primsol, dualsol, NULL, redcost) );
3434 assert(dummy == lpi->solstat || lpi->instabilityignored);
3435
3436 if( activity != NULL )
3437 {
3438 CHECK_ZERO( lpi->messagehdlr, CPXgetax(lpi->cpxenv, lpi->cpxlp, activity, 0, CPXgetnumrows(lpi->cpxenv, lpi->cpxlp)-1) );
3439 }
3440
3441 return SCIP_OKAY;
3442}
3443
3444/** gets primal ray for unbounded LPs */
3446 SCIP_LPI* lpi, /**< LP interface structure */
3447 SCIP_Real* ray /**< primal ray */
3448 )
3449{
3450 assert(lpi != NULL);
3451 assert(lpi->cpxlp != NULL);
3452 assert(lpi->cpxenv != NULL);
3453 assert(lpi->solstat >= 0);
3454 assert(ray != NULL);
3455
3456 SCIPdebugMessage("calling CPLEX get primal ray: %d cols, %d rows\n",
3457 CPXgetnumcols(lpi->cpxenv, lpi->cpxlp), CPXgetnumrows(lpi->cpxenv, lpi->cpxlp));
3458
3459 CHECK_ZERO( lpi->messagehdlr, CPXgetray(lpi->cpxenv, lpi->cpxlp, ray) );
3460
3461 return SCIP_OKAY;
3462}
3463
3464/** gets dual Farkas proof for infeasibility */
3466 SCIP_LPI* lpi, /**< LP interface structure */
3467 SCIP_Real* dualfarkas /**< dual Farkas row multipliers */
3468 )
3469{
3470 assert(lpi != NULL);
3471 assert(lpi->cpxlp != NULL);
3472 assert(lpi->cpxenv != NULL);
3473 assert(lpi->solstat >= 0);
3474 assert(dualfarkas != NULL);
3475
3476 SCIPdebugMessage("calling CPLEX dual Farkas: %d cols, %d rows\n",
3477 CPXgetnumcols(lpi->cpxenv, lpi->cpxlp), CPXgetnumrows(lpi->cpxenv, lpi->cpxlp));
3478
3479 CHECK_ZERO( lpi->messagehdlr, CPXdualfarkas(lpi->cpxenv, lpi->cpxlp, dualfarkas, NULL) );
3480
3481 return SCIP_OKAY;
3482}
3483
3484/** gets the number of LP iterations of the last solve call */
3486 SCIP_LPI* lpi, /**< LP interface structure */
3487 int* iterations /**< pointer to store the number of iterations of the last solve call */
3488 )
3489{
3490 assert(lpi != NULL);
3491 assert(iterations != NULL);
3492
3493 *iterations = lpi->iterations;
3494
3495 return SCIP_OKAY;
3496}
3497
3498/** gets information about the quality of an LP solution
3499 *
3500 * Such information is usually only available, if also a (maybe not optimal) solution is available.
3501 * The LPI should return SCIP_INVALID for @p quality, if the requested quantity is not available.
3502 */
3504 SCIP_LPI* lpi, /**< LP interface structure */
3505 SCIP_LPSOLQUALITY qualityindicator, /**< indicates which quality should be returned */
3506 SCIP_Real* quality /**< pointer to store quality number */
3507 )
3508{
3509 int solntype;
3510
3511 assert(lpi != NULL);
3512 assert(lpi->cpxlp != NULL);
3513 assert(lpi->cpxenv != NULL);
3514 assert(quality != NULL);
3515
3516 *quality = SCIP_INVALID;
3517
3518 SCIPdebugMessage("requesting solution quality from CPLEX: quality %d\n", qualityindicator);
3519
3520 CHECK_ZERO( lpi->messagehdlr, CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, &solntype, NULL, NULL) );
3521
3522 if( solntype == CPX_BASIC_SOLN )
3523 {
3524 int what;
3525
3526 switch( qualityindicator )
3527 {
3529 what = CPX_KAPPA;
3530 break;
3531
3533 what = CPX_EXACT_KAPPA;
3534 break;
3535
3536 default:
3537 SCIPerrorMessage("Solution quality %d unknown.\n", qualityindicator);
3538 return SCIP_INVALIDDATA;
3539 }
3540
3541 (void) CPXgetdblquality(lpi->cpxenv, lpi->cpxlp, quality, what);
3542 }
3543
3544 return SCIP_OKAY;
3545}
3546
3547/**@} */
3548
3549
3550
3551
3552/*
3553 * LP Basis Methods
3554 */
3555
3556/**@name LP Basis Methods */
3557/**@{ */
3558
3559/** gets current basis status for columns and rows; arrays must be large enough to store the basis status */
3561 SCIP_LPI* lpi, /**< LP interface structure */
3562 int* cstat, /**< array to store column basis status, or NULL */
3563 int* rstat /**< array to store row basis status, or NULL */
3564 )
3565{
3566 int i;
3567 int nrows;
3568 char sense;
3569
3570 assert(lpi != NULL);
3571 assert(lpi->cpxlp != NULL);
3572 assert(lpi->cpxenv != NULL);
3573
3574 SCIPdebugMessage("saving CPLEX basis into %p/%p\n", (void *) cstat, (void *) rstat);
3575
3576 CHECK_ZERO( lpi->messagehdlr, CPXgetbase(lpi->cpxenv, lpi->cpxlp, cstat, rstat) );
3577
3578 /* correct rstat values for "<=" constraints: Here CPX_AT_LOWER bound means that the slack is 0, i.e., the upper bound is tight */
3579 nrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
3580 for (i = 0; i < nrows; ++i)
3581 {
3582 if ( rstat[i] == CPX_AT_LOWER )
3583 {
3584 CHECK_ZERO( lpi->messagehdlr, CPXgetsense(lpi->cpxenv, lpi->cpxlp, &sense, i, i) );
3585 if ( sense == 'L' )
3586 rstat[i] = (int) SCIP_BASESTAT_UPPER;
3587 }
3588 }
3589
3590 /* because the basis status values are equally defined in SCIP and CPLEX, they don't need to be transformed */
3591 assert((int)SCIP_BASESTAT_LOWER == CPX_AT_LOWER); /*lint !e506*/
3592 assert((int)SCIP_BASESTAT_BASIC == CPX_BASIC); /*lint !e506*/
3593 assert((int)SCIP_BASESTAT_UPPER == CPX_AT_UPPER); /*lint !e506*/
3594 assert((int)SCIP_BASESTAT_ZERO == CPX_FREE_SUPER); /*lint !e506*/
3595
3596 return SCIP_OKAY;
3597}
3598
3599/** sets current basis status for columns and rows */
3601 SCIP_LPI* lpi, /**< LP interface structure */
3602 const int* cstat, /**< array with column basis status */
3603 const int* rstat /**< array with row basis status */
3604 )
3605{
3606 int i;
3607 int nrows;
3608 int ncols;
3609 char sense;
3610
3611 assert(lpi != NULL);
3612 assert(lpi->cpxlp != NULL);
3613 assert(lpi->cpxenv != NULL);
3614
3615 SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
3616 SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
3617
3618 assert(cstat != NULL || ncols == 0);
3619 assert(rstat != NULL || nrows == 0);
3620
3621 SCIPdebugMessage("loading basis %p/%p into CPLEX\n", (void *) cstat, (void *) rstat);
3622
3623 invalidateSolution(lpi);
3624
3625 /* because the basis status values are equally defined in SCIP and CPLEX, they don't need to be transformed */
3626 assert((int)SCIP_BASESTAT_LOWER == CPX_AT_LOWER); /*lint !e506*/
3627 assert((int)SCIP_BASESTAT_BASIC == CPX_BASIC); /*lint !e506*/
3628 assert((int)SCIP_BASESTAT_UPPER == CPX_AT_UPPER); /*lint !e506*/
3629 assert((int)SCIP_BASESTAT_ZERO == CPX_FREE_SUPER); /*lint !e506*/
3630
3631 /* Copy rstat to internal structure and correct rstat values for ">=" constraints: Here CPX_AT_LOWER bound means that
3632 * the slack is 0, i.e., the upper bound is tight. */
3633 SCIP_CALL( ensureRstatMem(lpi, nrows) );
3634 for (i = 0; i < nrows; ++i)
3635 {
3636 if ( rstat[i] == (int) SCIP_BASESTAT_UPPER ) /*lint !e613*/
3637 {
3638 CHECK_ZERO( lpi->messagehdlr, CPXgetsense(lpi->cpxenv, lpi->cpxlp, &sense, i, i) );
3639 if ( sense == 'L' )
3640 lpi->rstat[i] = CPX_AT_LOWER;
3641 }
3642 else
3643 lpi->rstat[i] = rstat[i]; /*lint !e613*/
3644 }
3645
3646 CHECK_ZERO( lpi->messagehdlr, CPXcopybase(lpi->cpxenv, lpi->cpxlp, cstat, lpi->rstat) );
3647
3648 return SCIP_OKAY;
3649}
3650
3651/** returns the indices of the basic columns and rows; basic column n gives value n, basic row m gives value -1-m */
3653 SCIP_LPI* lpi, /**< LP interface structure */
3654 int* bind /**< pointer to store basis indices ready to keep number of rows entries */
3655 )
3656{
3657 int retval;
3658
3659 assert(lpi != NULL);
3660 assert(lpi->cpxlp != NULL);
3661 assert(lpi->cpxenv != NULL);
3662 assert(bind != NULL);
3663
3664 SCIPdebugMessage("getting basis information\n");
3665
3666 /* this might be turned off if the user as called SCIPlpiClearState() or set SCIP_LPPAR_FROMSCRATCH to TRUE */
3667 setIntParam(lpi, CPX_PARAM_ADVIND, CPX_ON);
3668 SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
3669
3670 retval = CPXgetbhead(lpi->cpxenv, lpi->cpxlp, bind, NULL);
3671 if( retval == CPXERR_NO_SOLN || retval == CPXERR_NO_LU_FACTOR || retval == CPXERR_NO_BASIC_SOLN || retval == CPXERR_NO_BASIS )
3672 {
3674 retval = CPXgetbhead(lpi->cpxenv, lpi->cpxlp, bind, NULL);
3675 }
3676 CHECK_ZERO( lpi->messagehdlr, retval );
3677
3678 return SCIP_OKAY;
3679}
3680
3681/** get row of inverse basis matrix B^-1
3682 *
3683 * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
3684 * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
3685 * see also the explanation in lpi.h.
3686 */ /*lint -e{715}*/
3688 SCIP_LPI* lpi, /**< LP interface structure */
3689 int r, /**< row number */
3690 SCIP_Real* coef, /**< pointer to store the coefficients of the row */
3691 int* inds, /**< array to store the non-zero indices, or NULL */
3692 int* ninds /**< pointer to store the number of non-zero indices, or NULL
3693 * (-1: if we do not store sparsity information) */
3694 )
3695{ /*lint --e{715}*/
3696 int retval;
3697 int nrows;
3698
3699 assert(lpi != NULL);
3700 assert(lpi->cpxlp != NULL);
3701 assert(lpi->cpxenv != NULL);
3702 assert(coef != NULL);
3703
3704 SCIPdebugMessage("getting binv-row %d\n", r);
3705
3706 /* can only return dense result */
3707 if ( ninds != NULL )
3708 *ninds = -1;
3709
3710 /* this might be turned off if the user as called SCIPlpiClearState() or set SCIP_LPPAR_FROMSCRATCH to TRUE */
3711 setIntParam(lpi, CPX_PARAM_ADVIND, CPX_ON);
3712 SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
3713
3714 retval = CPXbinvrow(lpi->cpxenv, lpi->cpxlp, r, coef);
3715 if( retval == CPXERR_NO_SOLN || retval == CPXERR_NO_LU_FACTOR || retval == CPXERR_NO_BASIC_SOLN || retval == CPXERR_NO_BASIS )
3716 {
3718 retval = CPXbinvrow(lpi->cpxenv, lpi->cpxlp, r, coef);
3719 }
3720 CHECK_ZERO( lpi->messagehdlr, retval );
3721
3722 /* the LPi expects slack variables with coefficient +1; CPLEX adds slack variables with a coefficient -1 for 'G'
3723 * constraints, so we have to change the sign of the corresponding rows
3724 */
3725 nrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
3726 SCIP_CALL( ensureValMem(lpi, nrows) );
3727 CHECK_ZERO( lpi->messagehdlr, CPXgetbhead(lpi->cpxenv, lpi->cpxlp, lpi->indarray, NULL) );
3728
3729 if( lpi->indarray[r] < 0 )
3730 {
3731 int basicrow;
3732 char rowsense;
3733
3734 basicrow = -lpi->indarray[r] - 1;
3735 assert(basicrow >= 0);
3736 assert(basicrow < nrows);
3737
3738 CHECK_ZERO( lpi->messagehdlr, CPXgetsense(lpi->cpxenv, lpi->cpxlp, &rowsense, basicrow, basicrow) );
3739
3740 /* slacks for 'G' and 'R' rows are added with -1 in CPLEX */
3741 if( rowsense == 'G' || rowsense == 'R' )
3742 {
3743 int i;
3744
3745 for( i = 0; i < nrows; i++ )
3746 coef[i] *= -1.0;
3747 }
3748 }
3749
3750 return SCIP_OKAY;
3751}
3752
3753/** get column of inverse basis matrix B^-1
3754 *
3755 * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
3756 * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
3757 * see also the explanation in lpi.h.
3758 */ /*lint -e{715}*/
3760 SCIP_LPI* lpi, /**< LP interface structure */
3761 int c, /**< column number of B^-1; this is NOT the number of the column in the LP;
3762 * you have to call SCIPlpiGetBasisInd() to get the array which links the
3763 * B^-1 column numbers to the row and column numbers of the LP!
3764 * c must be between 0 and nrows-1, since the basis has the size
3765 * nrows * nrows */
3766 SCIP_Real* coef, /**< pointer to store the coefficients of the column */
3767 int* inds, /**< array to store the non-zero indices, or NULL */
3768 int* ninds /**< pointer to store the number of non-zero indices, or NULL
3769 * (-1: if we do not store sparsity information) */
3770 )
3771{ /*lint --e{715}*/
3772 int retval;
3773 int nrows;
3774 int r;
3775
3776 assert(lpi != NULL);
3777 assert(lpi->cpxlp != NULL);
3778 assert(lpi->cpxenv != NULL);
3779 assert(coef != NULL);
3780
3781 SCIPdebugMessage("getting binv-col %d\n", c);
3782
3783 /* can only return dense result */
3784 if ( ninds != NULL )
3785 *ninds = -1;
3786
3787 /* this might be turned off if the user as called SCIPlpiClearState() or set SCIP_LPPAR_FROMSCRATCH to TRUE */
3788 setIntParam(lpi, CPX_PARAM_ADVIND, CPX_ON);
3789 SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
3790
3791 retval = CPXbinvcol(lpi->cpxenv, lpi->cpxlp, c, coef);
3792 if( retval == CPXERR_NO_SOLN || retval == CPXERR_NO_LU_FACTOR || retval == CPXERR_NO_BASIC_SOLN || retval == CPXERR_NO_BASIS )
3793 {
3795 retval = CPXbinvcol(lpi->cpxenv, lpi->cpxlp, c, coef);
3796 }
3797 CHECK_ZERO( lpi->messagehdlr, retval );
3798
3799 /* the LPi expects slack variables with coefficient +1; CPLEX adds slack variables with a coefficient -1 for 'G'
3800 * constraints, so we have to change the sign of the corresponding rows
3801 */
3802 nrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
3803 SCIP_CALL( ensureValMem(lpi, nrows) );
3804 CHECK_ZERO( lpi->messagehdlr, CPXgetbhead(lpi->cpxenv, lpi->cpxlp, lpi->indarray, NULL) );
3805 SCIP_CALL( ensureSidechgMem(lpi, nrows) );
3806 CHECK_ZERO( lpi->messagehdlr, CPXgetsense(lpi->cpxenv, lpi->cpxlp, lpi->senarray, 0, nrows - 1) );
3807
3808 for( r = 0; r < nrows; r++ )
3809 {
3810 if( lpi->indarray[r] < 0 )
3811 {
3812 int basicrow;
3813
3814 basicrow = -lpi->indarray[r] - 1;
3815 assert(basicrow >= 0);
3816 assert(basicrow < nrows);
3817
3818 /* slacks for 'G' and 'R' rows are added with -1 in CPLEX */
3819 if( basicrow >= 0 && basicrow < nrows && (lpi->senarray[basicrow] == 'G' || lpi->senarray[basicrow] == 'R') )
3820 coef[r] *= -1.0;
3821 }
3822 }
3823
3824 return SCIP_OKAY;
3825}
3826
3827/** get row of inverse basis matrix times constraint matrix B^-1 * A
3828 *
3829 * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
3830 * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
3831 * see also the explanation in lpi.h.
3832 */ /*lint -e{715}*/
3834 SCIP_LPI* lpi, /**< LP interface structure */
3835 int r, /**< row number */
3836 const SCIP_Real* binvrow, /**< row in (A_B)^-1 from prior call to SCIPlpiGetBInvRow(), or NULL */
3837 SCIP_Real* coef, /**< vector to return coefficients of the row */
3838 int* inds, /**< array to store the non-zero indices, or NULL */
3839 int* ninds /**< pointer to store the number of non-zero indices, or NULL
3840 * (-1: if we do not store sparsity information) */
3841 )
3842{ /*lint --e{715}*/
3843 int retval;
3844 int nrows;
3845
3846 assert(lpi != NULL);
3847 assert(lpi->cpxlp != NULL);
3848 assert(lpi->cpxenv != NULL);
3849 assert(coef != NULL);
3850
3851 SCIPdebugMessage("getting binva-row %d\n", r);
3852
3853 /* can only return dense result */
3854 if ( ninds != NULL )
3855 *ninds = -1;
3856
3857 /* this might be turned off if the user as called SCIPlpiClearState() or set SCIP_LPPAR_FROMSCRATCH to TRUE */
3858 setIntParam(lpi, CPX_PARAM_ADVIND, CPX_ON);
3859 SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
3860
3861 retval = CPXbinvarow(lpi->cpxenv, lpi->cpxlp, r, coef);
3862 if( retval == CPXERR_NO_SOLN || retval == CPXERR_NO_LU_FACTOR || retval == CPXERR_NO_BASIC_SOLN || retval == CPXERR_NO_BASIS )
3863 {
3865 retval = CPXbinvarow(lpi->cpxenv, lpi->cpxlp, r, coef);
3866 }
3867 CHECK_ZERO( lpi->messagehdlr, retval );
3868
3869 /* the LPi expects slack variables with coefficient +1; CPLEX adds slack variables with a coefficient -1 for 'G'
3870 * constraints, so we have to change the sign of the corresponding rows
3871 */
3872 nrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
3873 SCIP_CALL( ensureValMem(lpi, nrows) );
3874 CHECK_ZERO( lpi->messagehdlr, CPXgetbhead(lpi->cpxenv, lpi->cpxlp, lpi->indarray, NULL) );
3875
3876 if( lpi->indarray[r] < 0 )
3877 {
3878 int basicrow;
3879 char rowsense;
3880
3881 basicrow = -lpi->indarray[r] - 1;
3882 assert(basicrow >= 0);
3883 assert(basicrow < nrows);
3884
3885 CHECK_ZERO( lpi->messagehdlr, CPXgetsense(lpi->cpxenv, lpi->cpxlp, &rowsense, basicrow, basicrow) );
3886
3887 /* slacks for 'G' and 'R' rows are added with -1 in CPLEX */
3888 if( rowsense == 'G' || rowsense == 'R' )
3889 {
3890 int ncols;
3891 int j;
3892
3893 ncols = CPXgetnumcols(lpi->cpxenv, lpi->cpxlp);
3894 for( j = 0; j < ncols; j++ )
3895 coef[j] *= -1.0;
3896 }
3897 }
3898
3899 return SCIP_OKAY;
3900}
3901
3902/** get column of inverse basis matrix times constraint matrix B^-1 * A
3903 *
3904 * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
3905 * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
3906 * see also the explanation in lpi.h.
3907 *//*lint -e{715}*/
3909 SCIP_LPI* lpi, /**< LP interface structure */
3910 int c, /**< column number */
3911 SCIP_Real* coef, /**< vector to return coefficients of the column */
3912 int* inds, /**< array to store the non-zero indices, or NULL */
3913 int* ninds /**< pointer to store the number of non-zero indices, or NULL
3914 * (-1: if we do not store sparsity information) */
3915 )
3916{ /*lint --e{715}*/
3917 int retval;
3918 int nrows;
3919 int r;
3920
3921 assert(lpi != NULL);
3922 assert(lpi->cpxenv != NULL);
3923 assert(lpi->cpxlp != NULL);
3924 assert(coef != NULL);
3925
3926 SCIPdebugMessage("getting binva-col %d\n", c);
3927
3928 /* can only return dense result */
3929 if ( ninds != NULL )
3930 *ninds = -1;
3931
3932 /* this might be turned off if the user as called SCIPlpiClearState() or set SCIP_LPPAR_FROMSCRATCH to TRUE */
3933 setIntParam(lpi, CPX_PARAM_ADVIND, CPX_ON);
3934 SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
3935
3936 retval = CPXbinvacol(lpi->cpxenv, lpi->cpxlp, c, coef);
3937 if( retval == CPXERR_NO_SOLN || retval == CPXERR_NO_LU_FACTOR || retval == CPXERR_NO_BASIC_SOLN || retval == CPXERR_NO_BASIS )
3938 {
3940 retval = CPXbinvacol(lpi->cpxenv, lpi->cpxlp, c, coef);
3941 }
3942 CHECK_ZERO( lpi->messagehdlr, retval );
3943
3944 /* the LPi expects slack variables with coefficient +1; CPLEX adds slack variables with a coefficient -1 for 'G'
3945 * constraints, so we have to change the sign of the corresponding rows
3946 */
3947 nrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
3948 SCIP_CALL( ensureValMem(lpi, nrows) );
3949 CHECK_ZERO( lpi->messagehdlr, CPXgetbhead(lpi->cpxenv, lpi->cpxlp, lpi->indarray, NULL) );
3950 SCIP_CALL( ensureSidechgMem(lpi, nrows) );
3951 CHECK_ZERO( lpi->messagehdlr, CPXgetsense(lpi->cpxenv, lpi->cpxlp, lpi->senarray, 0, nrows - 1) );
3952
3953 for( r = 0; r < nrows; r++ )
3954 {
3955 if( lpi->indarray[r] < 0 )
3956 {
3957 int basicrow;
3958
3959 basicrow = -lpi->indarray[r] - 1;
3960 assert(basicrow >= 0);
3961 assert(basicrow < nrows);
3962
3963 /* slacks for 'G' and 'R' rows are added with -1 in CPLEX */
3964 if( basicrow >= 0 && basicrow < nrows && (lpi->senarray[basicrow] == 'G' || lpi->senarray[basicrow] == 'R') )
3965 coef[r] *= -1.0;
3966 }
3967 }
3968
3969 return SCIP_OKAY;
3970}
3971
3972/**@} */
3973
3974
3975
3976
3977/*
3978 * LP State Methods
3979 */
3980
3981/**@name LP State Methods */
3982/**@{ */
3983
3984/** stores LPi state (like basis information) into lpistate object */
3986 SCIP_LPI* lpi, /**< LP interface structure */
3987 BMS_BLKMEM* blkmem, /**< block memory */
3988 SCIP_LPISTATE** lpistate /**< pointer to LPi state information (like basis information) */
3989 )
3990{
3991 int ncols;
3992 int nrows;
3993
3994 assert(blkmem != NULL);
3995 assert(lpi != NULL);
3996 assert(lpi->cpxlp != NULL);
3997 assert(lpi->cpxenv != NULL);
3998 assert(lpistate != NULL);
3999
4000 /* if there is no basis information available (e.g. after barrier without crossover), or no state can be saved; if
4001 * SCIPlpiClearState() has been called, do not return the state
4002 */
4003 if( !lpi->solisbasic || lpi->clearstate )
4004 {
4005 *lpistate = NULL;
4006 return SCIP_OKAY;
4007 }
4008
4009 ncols = CPXgetnumcols(lpi->cpxenv, lpi->cpxlp);
4010 nrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
4011 assert(ncols >= 0);
4012 assert(nrows >= 0);
4013
4014 /* allocate lpistate data */
4015 SCIP_CALL( lpistateCreate(lpistate, blkmem, ncols, nrows) );
4016
4017 SCIPdebugMessage("storing CPLEX LPI state in %p (%d cols, %d rows)\n", (void *) *lpistate, ncols, nrows);
4018
4019 /* get unpacked basis information from CPLEX */
4020 SCIP_CALL( getBase(lpi) );
4021
4022 /* pack LPi state data */
4023 (*lpistate)->ncols = ncols;
4024 (*lpistate)->nrows = nrows;
4025 lpistatePack(*lpistate, lpi->cstat, lpi->rstat);
4026
4027 return SCIP_OKAY;
4028}
4029
4030/** loads LPi state (like basis information) into solver; note that the LP might have been extended with additional
4031 * columns and rows since the state was stored with SCIPlpiGetState()
4032 */
4034 SCIP_LPI* lpi, /**< LP interface structure */
4035 BMS_BLKMEM* blkmem, /**< block memory */
4036 const SCIP_LPISTATE* lpistate /**< LPi state information (like basis information), or NULL */
4037 )
4038{
4039 int lpncols;
4040 int lpnrows;
4041 int i;
4042
4043 assert(blkmem != NULL);
4044 assert(lpi != NULL);
4045 assert(lpi->cpxlp != NULL);
4046 assert(lpi->cpxenv != NULL);
4047
4048 /* if there was no basis information available, the LPI state was not stored */
4049 if( lpistate == NULL )
4050 return SCIP_OKAY;
4051
4052 lpncols = CPXgetnumcols(lpi->cpxenv, lpi->cpxlp);
4053 lpnrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
4054 assert(lpistate->ncols <= lpncols);
4055 assert(lpistate->nrows <= lpnrows);
4056
4057 SCIPdebugMessage("loading LPI state %p (%d cols, %d rows) into CPLEX LP with %d cols and %d rows\n",
4058 (void *) lpistate, lpistate->ncols, lpistate->nrows, lpncols, lpnrows);
4059
4060 if( lpistate->ncols == 0 || lpistate->nrows == 0 )
4061 return SCIP_OKAY;
4062
4063 /* allocate enough memory for storing uncompressed basis information */
4064 SCIP_CALL( ensureCstatMem(lpi, lpncols) );
4065 SCIP_CALL( ensureRstatMem(lpi, lpnrows) );
4066
4067 /* unpack LPi state data */
4068 lpistateUnpack(lpistate, lpi->cstat, lpi->rstat);
4069
4070 /* extend the basis to the current LP beyond the previously existing columns */
4071 for( i = lpistate->ncols; i < lpncols; ++i )
4072 {
4073 SCIP_Real bnd;
4074 CHECK_ZERO( lpi->messagehdlr, CPXgetlb(lpi->cpxenv, lpi->cpxlp, &bnd, i, i) );
4075 if ( SCIPlpiIsInfinity(lpi, REALABS(bnd)) )
4076 {
4077 /* if lower bound is +/- infinity -> try upper bound */
4078 CHECK_ZERO( lpi->messagehdlr, CPXgetub(lpi->cpxenv, lpi->cpxlp, &bnd, i, i) );
4079 if ( SCIPlpiIsInfinity(lpi, REALABS(bnd)) )
4080 lpi->cstat[i] = (int) SCIP_BASESTAT_ZERO; /* variable is free -> super basic */
4081 else
4082 lpi->cstat[i] = (int) SCIP_BASESTAT_UPPER; /* use finite upper bound */
4083 }
4084 else
4085 lpi->cstat[i] = (int) SCIP_BASESTAT_LOWER; /* use finite lower bound */
4086 }
4087 for( i = lpistate->nrows; i < lpnrows; ++i )
4088 lpi->rstat[i] = (int) SCIP_BASESTAT_BASIC;
4089
4090 /* load basis information into CPLEX */
4091 SCIP_CALL( setBase(lpi) );
4092
4093 return SCIP_OKAY;
4094}
4095
4096/** clears current LPi state (like basis information) of the solver */
4098 SCIP_LPI* lpi /**< LP interface structure */
4099 )
4100{
4101 assert(lpi != NULL);
4102
4103 /* set CPX_PARAM_ADVIND to CPX_OFF for the next solve */
4104 lpi->clearstate = TRUE;
4105
4106 return SCIP_OKAY;
4107}
4108
4109/** frees LPi state information */
4111 SCIP_LPI* lpi, /**< LP interface structure */
4112 BMS_BLKMEM* blkmem, /**< block memory */
4113 SCIP_LPISTATE** lpistate /**< pointer to LPi state information (like basis information) */
4114 )
4115{
4116 assert(lpi != NULL);
4117 assert(lpistate != NULL);
4118 assert(blkmem != NULL);
4119
4120 if( *lpistate != NULL )
4121 {
4122 lpistateFree(lpistate, blkmem);
4123 }
4124
4125 return SCIP_OKAY;
4126}
4127
4128/** checks, whether the given LP state contains simplex basis information */
4130 SCIP_LPI* lpi, /**< LP interface structure */
4131 SCIP_LPISTATE* lpistate /**< LP state information (like basis information), or NULL */
4132 )
4133{ /*lint --e{715}*/
4134 assert(lpi != NULL);
4135 return (lpistate != NULL);
4136}
4137
4138/** reads LP state (like basis information from a file */
4140 SCIP_LPI* lpi, /**< LP interface structure */
4141 const char* fname /**< file name */
4142 )
4143{
4144 assert(lpi != NULL);
4145 assert(lpi->cpxlp != NULL);
4146 assert(lpi->cpxenv != NULL);
4147 assert(fname != NULL);
4148
4149 SCIPdebugMessage("reading LP state from file <%s>\n", fname);
4150
4151 CHECK_ZERO( lpi->messagehdlr, CPXreadcopybase(lpi->cpxenv, lpi->cpxlp, fname) );
4152
4153 return SCIP_OKAY;
4154}
4155
4156/** writes LPi state (i.e. basis information) to a file */
4158 SCIP_LPI* lpi, /**< LP interface structure */
4159 const char* fname /**< file name */
4160 )
4161{
4162 assert(lpi != NULL);
4163 assert(lpi->cpxlp != NULL);
4164 assert(lpi->cpxenv != NULL);
4165 assert(fname != NULL);
4166
4167 SCIPdebugMessage("writing LP state to file <%s>\n", fname);
4168
4169 CHECK_ZERO( lpi->messagehdlr, CPXmbasewrite(lpi->cpxenv, lpi->cpxlp, fname) );
4170
4171 return SCIP_OKAY;
4172}
4173
4174/**@} */
4175
4176
4177
4178
4179/*
4180 * LP Pricing Norms Methods
4181 */
4182
4183/**@name LP Pricing Norms Methods */
4184/**@{ */
4185
4186/** stores LPi pricing norms information
4187 *
4188 * @todo store primal norms as well?
4189 */
4191 SCIP_LPI* lpi, /**< LP interface structure */
4192 BMS_BLKMEM* blkmem, /**< block memory */
4193 SCIP_LPINORMS** lpinorms /**< pointer to LPi pricing norms information */
4194 )
4195{
4196 int nrows;
4197 int retval;
4198
4199 assert(blkmem != NULL);
4200 assert(lpi != NULL);
4201 assert(lpi->cpxlp != NULL);
4202 assert(lpi->cpxenv != NULL);
4203 assert(lpi->messagehdlr != NULL);
4204 assert(lpinorms != NULL);
4205
4206 /* if there is no basis information available (e.g. after barrier without crossover), norms cannot be saved; if
4207 * SCIPlpiClearState() has been called, do not return the state
4208 */
4209 if( !lpi->solisbasic || lpi->clearstate )
4210 {
4211 *lpinorms = NULL;
4212 return SCIP_OKAY;
4213 }
4214
4215 nrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
4216 assert(nrows >= 0);
4217
4218 /* allocate lpinorms data */
4219 SCIP_ALLOC( BMSallocBlockMemory(blkmem, lpinorms) );
4220 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpinorms)->norm, nrows) );
4221 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpinorms)->head, nrows) );
4222 (*lpinorms)->normlen = 0;
4223
4224 SCIPdebugMessage("storing CPLEX LPI pricing norms in %p (%d rows)\n", (void *) *lpinorms, nrows);
4225
4226 /* get dual norms */
4227 retval = CPXgetdnorms(lpi->cpxenv, lpi->cpxlp, (*lpinorms)->norm, (*lpinorms)->head, &((*lpinorms)->normlen));
4228
4229 /* if CPLEX used the primal simplex in the last optimization call, we do not have dual norms (error 1264) */
4230 if( retval == 1264 )
4231 {
4232 /* no norms available, free lpinorms data */
4233 BMSfreeBlockMemoryArray(blkmem, &(*lpinorms)->head, nrows);
4234 BMSfreeBlockMemoryArray(blkmem, &(*lpinorms)->norm, nrows);
4235 BMSfreeBlockMemory(blkmem, lpinorms);
4236 assert(*lpinorms == NULL);
4237 }
4238 else
4239 {
4240 assert((*lpinorms)->normlen == nrows);
4241 CHECK_ZERO( lpi->messagehdlr, retval );
4242 }
4243
4244 return SCIP_OKAY;
4245}
4246
4247/** loads LPi pricing norms into solver; note that the LP might have been extended with additional
4248 * columns and rows since the state was stored with SCIPlpiGetNorms()
4249 */
4251 SCIP_LPI* lpi, /**< LP interface structure */
4252 BMS_BLKMEM* blkmem, /**< block memory */
4253 const SCIP_LPINORMS* lpinorms /**< LPi pricing norms information, or NULL */
4254 )
4255{
4256 int lpnrows;
4257
4258 assert(blkmem != NULL);
4259 assert(lpi != NULL);
4260 assert(lpi->cpxlp != NULL);
4261 assert(lpi->cpxenv != NULL);
4262
4263 /* if there was no pricing norms information available, the LPI norms were not stored */
4264 if( lpinorms == NULL )
4265 return SCIP_OKAY;
4266
4267 lpnrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
4268 assert(lpinorms->normlen <= lpnrows);
4269
4270 SCIPdebugMessage("loading LPI simplex norms %p (%d rows) into CPLEX LP with %d rows\n",
4271 (void *) lpinorms, lpinorms->normlen, lpnrows);
4272
4273 if( lpinorms->normlen == 0 )
4274 return SCIP_OKAY;
4275
4276 /* load pricing norms information into CPLEX */
4277 CHECK_ZERO( lpi->messagehdlr, CPXcopydnorms(lpi->cpxenv, lpi->cpxlp, lpinorms->norm, lpinorms->head, lpinorms->normlen) );
4278
4279 return SCIP_OKAY;
4280}
4281
4282/** frees pricing norms information */
4284 SCIP_LPI* lpi, /**< LP interface structure */
4285 BMS_BLKMEM* blkmem, /**< block memory */
4286 SCIP_LPINORMS** lpinorms /**< pointer to LPi pricing norms information, or NULL */
4287 )
4288{
4289 assert(lpi != NULL);
4290 assert(lpinorms != NULL);
4291
4292 BMSfreeBlockMemoryArray(blkmem, &(*lpinorms)->head, (*lpinorms)->normlen);
4293 BMSfreeBlockMemoryArray(blkmem, &(*lpinorms)->norm, (*lpinorms)->normlen);
4294 BMSfreeBlockMemory(blkmem, lpinorms);
4295
4296 return SCIP_OKAY;
4297}
4298
4299/**@} */
4300
4301
4302
4303
4304/*
4305 * Parameter Methods
4306 */
4307
4308/**@name Parameter Methods */
4309/**@{ */
4310
4311/** gets integer parameter of LP
4312 *
4313 * CPLEX supported FASTMIP in versions up to 12.6.1. FASTMIP fastens the lp solving process but therefor it might happen
4314 * that there will be a loss in precision (because e.g. the optimal basis will not be factorized again).
4315 */
4317 SCIP_LPI* lpi, /**< LP interface structure */
4318 SCIP_LPPARAM type, /**< parameter number */
4319 int* ival /**< buffer to store the parameter value */
4320 )
4321{
4322 assert(lpi != NULL);
4323 assert(lpi->cpxlp != NULL);
4324 assert(ival != NULL);
4325
4326 SCIPdebugMessage("getting int parameter %d\n", type);
4327
4328 switch( type )
4329 {
4331 *ival = (int) lpi->fromscratch;
4332 break;
4333#if (CPX_VERSION < 12060100)
4334 case SCIP_LPPAR_FASTMIP:
4335 *ival = getIntParam(lpi, CPX_PARAM_FASTMIP);
4336 break;
4337#endif
4338 case SCIP_LPPAR_SCALING:
4339#if (CPX_VERSION <= 1100)
4340 if( lpi->rngfound )
4341 return SCIP_PARAMETERUNKNOWN;
4342#endif
4343 *ival = getIntParam(lpi, CPX_PARAM_SCAIND) + 1;
4344 break;
4346 *ival = (getIntParam(lpi, CPX_PARAM_PREIND) == CPX_ON);
4347 break;
4348 case SCIP_LPPAR_PRICING:
4349 *ival = (int)lpi->pricing; /* store pricing method in LPI struct */
4350 break;
4351 case SCIP_LPPAR_LPINFO:
4352 *ival = (getIntParam(lpi, CPX_PARAM_SCRIND) == CPX_ON);
4353 break;
4354 case SCIP_LPPAR_LPITLIM:
4355 *ival = getIntParam(lpi, CPX_PARAM_ITLIM);
4356#if (CPX_VERSION <= 1230)
4357 if( *ival >= CPX_INT_MAX )
4358 *ival = INT_MAX;
4359#endif
4360 break;
4361 case SCIP_LPPAR_THREADS:
4362#if (CPX_VERSION == 1100 || (CPX_VERSION == 1220 && (CPX_SUBVERSION == 0 || CPX_SUBVERSION == 2)))
4363 /* Due to CPLEX bug, we always set the thread count to 1. In order to fulfill an assert in lp.c, we have to
4364 * return the value set by SCIP and not the real thread count */
4365 *ival = lpi->pseudonthreads;
4366 assert(getIntParam(lpi, CPX_PARAM_THREADS) == 1);
4367#else
4368 *ival = getIntParam(lpi, CPX_PARAM_THREADS);
4369#endif
4370 break;
4371 default:
4372 return SCIP_PARAMETERUNKNOWN;
4373 } /*lint !e788*/
4374
4375 return SCIP_OKAY;
4376}
4377
4378/** sets integer parameter of LP */
4380 SCIP_LPI* lpi, /**< LP interface structure */
4381 SCIP_LPPARAM type, /**< parameter number */
4382 int ival /**< parameter value */
4383 )
4384{
4385 assert(lpi != NULL);
4386 assert(lpi->cpxlp != NULL);
4387
4388 SCIPdebugMessage("setting int parameter %d to %d\n", type, ival);
4389
4390 switch( type )
4391 {
4393 assert(ival == TRUE || ival == FALSE);
4394 lpi->fromscratch = (SCIP_Bool) ival;
4395 break;
4396#if (CPX_VERSION < 12060100)
4397 case SCIP_LPPAR_FASTMIP:
4398 assert(0 <= ival && ival <= 1);
4399 setIntParam(lpi, CPX_PARAM_FASTMIP, ival);
4400 break;
4401#endif
4402 case SCIP_LPPAR_SCALING:
4403 assert(0 <= ival && ival <= 2);
4404#if (CPX_VERSION <= 1100)
4405 if( lpi->rngfound )
4406 return SCIP_PARAMETERUNKNOWN;
4407#endif
4408 setIntParam(lpi, CPX_PARAM_SCAIND, ival - 1);
4409 break;
4411 assert(ival == TRUE || ival == FALSE);
4412 setIntParam(lpi, CPX_PARAM_PREIND, ival == TRUE ? CPX_ON : CPX_OFF);
4413 break;
4414 case SCIP_LPPAR_PRICING:
4415 lpi->pricing = (SCIP_PRICING)ival;
4416 switch( (SCIP_PRICING)ival )
4417 {
4418 case SCIP_PRICING_AUTO:
4419 setIntParam(lpi, CPX_PARAM_PPRIIND, CPX_PPRIIND_AUTO);
4420 setIntParam(lpi, CPX_PARAM_DPRIIND, CPX_DPRIIND_AUTO);
4421 break;
4422 case SCIP_PRICING_FULL:
4423 setIntParam(lpi, CPX_PARAM_PPRIIND, CPX_PPRIIND_FULL);
4424 setIntParam(lpi, CPX_PARAM_DPRIIND, CPX_DPRIIND_FULL);
4425 break;
4427 setIntParam(lpi, CPX_PARAM_PPRIIND, CPX_PPRIIND_PARTIAL);
4428 setIntParam(lpi, CPX_PARAM_DPRIIND, CPX_DPRIIND_AUTO);
4429 break;
4431 case SCIP_PRICING_STEEP:
4432 setIntParam(lpi, CPX_PARAM_PPRIIND, CPX_PPRIIND_STEEP);
4433 setIntParam(lpi, CPX_PARAM_DPRIIND, CPX_DPRIIND_STEEP);
4434 break;
4436 setIntParam(lpi, CPX_PARAM_PPRIIND, CPX_PPRIIND_STEEPQSTART);
4437 setIntParam(lpi, CPX_PARAM_DPRIIND, CPX_DPRIIND_STEEPQSTART);
4438 break;
4439#if (CPX_VERSION >= 900)
4440 case SCIP_PRICING_DEVEX:
4441 setIntParam(lpi, CPX_PARAM_PPRIIND, CPX_PPRIIND_DEVEX);
4442 setIntParam(lpi, CPX_PARAM_DPRIIND, CPX_DPRIIND_DEVEX);
4443 break;
4444#endif
4445 default:
4446 return SCIP_LPERROR;
4447 }
4448 break;
4449 case SCIP_LPPAR_LPINFO:
4450 assert(ival == TRUE || ival == FALSE);
4451 if( ival )
4452 setIntParam(lpi, CPX_PARAM_SCRIND, CPX_ON);
4453 else
4454 setIntParam(lpi, CPX_PARAM_SCRIND, CPX_OFF);
4455 break;
4456 case SCIP_LPPAR_LPITLIM:
4457 assert( ival >= 0 );
4458 /* 0 <= ival, 0 stopping immediately */
4459#if (CPX_VERSION <= 1230)
4460 ival = MIN(ival, CPX_INT_MAX);
4461#endif
4462 setIntParam(lpi, CPX_PARAM_ITLIM, ival);
4463 break;
4464 case SCIP_LPPAR_THREADS:
4465#if (CPX_VERSION == 1100 || (CPX_VERSION == 1220 && (CPX_SUBVERSION == 0 || CPX_SUBVERSION == 2)))
4466 /* Due to CPLEX bug, we always set the thread count to 1. In order to fulfill an assert in lp.c, we have to
4467 * store the value set by SCIP and return it later instead of the real thread count */
4468 lpi->pseudonthreads = ival;
4469 ival = 1;
4470#else
4471 ival = MIN(ival, CPX_INT_MAX);
4472#endif
4473 setIntParam(lpi, CPX_PARAM_THREADS, ival);
4474 break;
4476 setIntParam(lpi, CPX_PARAM_RANDOMSEED, ival % CPX_INT_MAX);
4477 break;
4478 default:
4479 return SCIP_PARAMETERUNKNOWN;
4480 } /*lint !e788*/
4481
4482 return SCIP_OKAY;
4483}
4484
4485/** gets floating point parameter of LP */
4487 SCIP_LPI* lpi, /**< LP interface structure */
4488 SCIP_LPPARAM type, /**< parameter number */
4489 SCIP_Real* dval /**< buffer to store the parameter value */
4490 )
4491{
4492 assert(lpi != NULL);
4493 assert(lpi->cpxlp != NULL);
4494 assert(dval != NULL);
4495
4496 SCIPdebugMessage("getting real parameter %d\n", type);
4497
4498 switch( type )
4499 {
4500 case SCIP_LPPAR_FEASTOL:
4501 *dval = getDblParam(lpi, CPX_PARAM_EPRHS);
4502 break;
4504 *dval = getDblParam(lpi, CPX_PARAM_EPOPT);
4505 break;
4507 *dval = getDblParam(lpi, CPX_PARAM_BAREPCOMP);
4508 break;
4509 case SCIP_LPPAR_OBJLIM:
4510 if ( CPXgetobjsen(lpi->cpxenv, lpi->cpxlp) == CPX_MIN )
4511 *dval = getDblParam(lpi, CPX_PARAM_OBJULIM);
4512 else
4513 *dval = getDblParam(lpi, CPX_PARAM_OBJLLIM);
4514 break;
4515 case SCIP_LPPAR_LPTILIM:
4516 *dval = getDblParam(lpi, CPX_PARAM_TILIM);
4517 break;
4519 *dval = getDblParam(lpi, CPX_PARAM_EPMRK);
4520 break;
4522 *dval = lpi->conditionlimit;
4523 break;
4524 default:
4525 return SCIP_PARAMETERUNKNOWN;
4526 } /*lint !e788*/
4527
4528 return SCIP_OKAY;
4529}
4530
4531/** sets floating point parameter of LP */
4533 SCIP_LPI* lpi, /**< LP interface structure */
4534 SCIP_LPPARAM type, /**< parameter number */
4535 SCIP_Real dval /**< parameter value */
4536 )
4537{
4538 assert(lpi != NULL);
4539 assert(lpi->cpxlp != NULL);
4540
4541 SCIPdebugMessage("setting real parameter %d to %.15g\n", type, dval);
4542
4543 switch( type )
4544 {
4545 case SCIP_LPPAR_FEASTOL:
4546 assert( dval > 0.0 );
4547 /* 1e-09 <= dval <= 1e-04 */
4548 if( dval < 1e-09 )
4549 dval = 1e-09;
4550 else if( dval > 1e-04 )
4551 dval = 1e-04;
4552
4553 setDblParam(lpi, CPX_PARAM_EPRHS, dval);
4554 lpi->feastol = dval;
4555 break;
4557 assert( dval > 0.0 );
4558 /* 1e-09 <= dval <= 1e-04 */
4559 if( dval < 1e-09 )
4560 dval = 1e-09;
4561 else if( dval > 1e-04 )
4562 dval = 1e-04;
4563
4564 setDblParam(lpi, CPX_PARAM_EPOPT, dval);
4565 break;
4567 /* 1e-10 <= dval */
4568 assert( dval >= 0.0 );
4569 if( dval < 1e-10 )
4570 dval = 1e-10;
4571
4572 setDblParam(lpi, CPX_PARAM_BAREPCOMP, dval);
4573 break;
4574 case SCIP_LPPAR_OBJLIM:
4575 /* Cplex poses no restriction on dval */
4576 if ( CPXgetobjsen(lpi->cpxenv, lpi->cpxlp) == CPX_MIN )
4577 setDblParam(lpi, CPX_PARAM_OBJULIM, dval);
4578 else
4579 setDblParam(lpi, CPX_PARAM_OBJLLIM, dval);
4580 break;
4581 case SCIP_LPPAR_LPTILIM:
4582 assert( dval > 0.0 );
4583 /* Cplex requires dval non-negative
4584 *
4585 * However for consistency we assert the timelimit to be strictly positive.
4586 */
4587 setDblParam(lpi, CPX_PARAM_TILIM, dval);
4588 break;
4590 /* 1e-04 <= dval <= .99999 */
4591 if( dval < 1e-04 )
4592 dval = 1e-04;
4593 else if( dval > .99999 )
4594 dval = .99999;
4595
4596 setDblParam(lpi, CPX_PARAM_EPMRK, dval);
4597 break;
4599 lpi->conditionlimit = dval;
4600 lpi->checkcondition = (dval >= 0);
4601 break;
4602 default:
4603 return SCIP_PARAMETERUNKNOWN;
4604 } /*lint !e788*/
4605
4606 return SCIP_OKAY;
4607}
4608
4609/** interrupts the currently ongoing lp solve or disables the interrupt */ /*lint -e{715}*/
4611 SCIP_LPI* lpi, /**< LP interface structure */
4612 SCIP_Bool interrupt /**< TRUE if interrupt should be set, FALSE if it should be disabled */
4613 )
4614{ /*lint --e{715}*/
4615 assert(lpi != NULL);
4616
4617 return SCIP_OKAY;
4618}
4619
4620/**@} */
4621
4622
4623
4624
4625/*
4626 * Numerical Methods
4627 */
4628
4629/**@name Numerical Methods */
4630/**@{ */
4631
4632/** returns value treated as infinity in the LP solver */
4634 SCIP_LPI* lpi /**< LP interface structure */
4635 )
4636{ /*lint --e{715}*/
4637 assert(lpi != NULL);
4638 return CPX_INFBOUND;
4639}
4640
4641/** checks if given value is treated as infinity in the LP solver */
4643 SCIP_LPI* lpi, /**< LP interface structure */
4644 SCIP_Real val /**< value to be checked for infinity */
4645 )
4646{ /*lint --e{715}*/
4647 assert(lpi != NULL);
4648 return (val >= CPX_INFBOUND);
4649}
4650
4651/**@} */
4652
4653
4654
4655
4656/*
4657 * File Interface Methods
4658 */
4659
4660/**@name File Interface Methods */
4661/**@{ */
4662
4663/** reads LP from a file */
4665 SCIP_LPI* lpi, /**< LP interface structure */
4666 const char* fname /**< file name */
4667 )
4668{
4669 int restat;
4670
4671 assert(lpi != NULL);
4672 assert(lpi->cpxlp != NULL);
4673 assert(lpi->cpxenv != NULL);
4674 assert(fname != NULL);
4675
4676 SCIPdebugMessage("reading LP from file <%s>\n", fname);
4677
4678 restat = CPXreadcopyprob(lpi->cpxenv, lpi->cpxlp, fname, NULL);
4679 if( restat != 0 )
4680 {
4681 SCIPerrorMessage("LP Error: CPLEX returned %d\n", restat);
4682 return SCIP_READERROR;
4683 }
4684
4685 return SCIP_OKAY;
4686}
4687
4688/** writes LP to a file */
4690 SCIP_LPI* lpi, /**< LP interface structure */
4691 const char* fname /**< file name */
4692 )
4693{
4694 int restat;
4695
4696 assert(lpi != NULL);
4697 assert(lpi->cpxlp != NULL);
4698 assert(lpi->cpxenv != NULL);
4699 assert(fname != NULL);
4700
4701 SCIPdebugMessage("writing LP to file <%s>\n", fname);
4702
4703 restat = CPXwriteprob(lpi->cpxenv, lpi->cpxlp, fname, NULL);
4704 if( restat != 0 )
4705 {
4706 SCIPerrorMessage("LP Error: CPLEX returned %d\n", restat);
4707 return SCIP_READERROR;
4708 }
4709
4710 return SCIP_OKAY;
4711}
4712
4713/**@} */
void SCIPdecodeDualBit(const SCIP_DUALPACKET *inp, int *out, int count)
Definition: bitencode.c:308
void SCIPencodeDualBit(const int *inp, SCIP_DUALPACKET *out, int count)
Definition: bitencode.c:238
packing single and dual bit values
unsigned int SCIP_DUALPACKET
Definition: bitencode.h:42
SCIP_Real * r
Definition: circlepacking.c:59
#define NULL
Definition: def.h:267
#define EPSISINT(x, eps)
Definition: def.h:210
#define SCIP_INVALID
Definition: def.h:193
#define SCIP_Bool
Definition: def.h:91
#define SCIP_CALL_QUIET(x)
Definition: def.h:349
#define MIN(x, y)
Definition: def.h:243
#define SCIP_ALLOC(x)
Definition: def.h:385
#define SCIP_Real
Definition: def.h:173
#define TRUE
Definition: def.h:93
#define FALSE
Definition: def.h:94
#define MAX(x, y)
Definition: def.h:239
#define EPSCEIL(x, eps)
Definition: def.h:207
#define SCIPABORT()
Definition: def.h:346
#define EPSFLOOR(x, eps)
Definition: def.h:206
#define REALABS(x)
Definition: def.h:197
#define EPSZ(x, eps)
Definition: def.h:203
#define SCIP_CALL(x)
Definition: def.h:374
SCIP_RETCODE SCIPlpiChgSides(SCIP_LPI *lpi, int nrows, const int *ind, const SCIP_Real *lhs, const SCIP_Real *rhs)
Definition: lpi_cpx.c:1618
SCIP_RETCODE SCIPlpiSetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, const SCIP_LPISTATE *lpistate)
Definition: lpi_cpx.c:4033
SCIP_RETCODE SCIPlpiGetBInvACol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_cpx.c:3908
SCIP_RETCODE SCIPlpiGetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real *dval)
Definition: lpi_cpx.c:4486
SCIP_Real SCIPlpiInfinity(SCIP_LPI *lpi)
Definition: lpi_cpx.c:4633
SCIP_Bool SCIPlpiIsObjlimExc(SCIP_LPI *lpi)
Definition: lpi_cpx.c:3307
SCIP_RETCODE SCIPlpiChgObjsen(SCIP_LPI *lpi, SCIP_OBJSEN objsen)
Definition: lpi_cpx.c:1687
SCIP_Bool SCIPlpiIsInfinity(SCIP_LPI *lpi, SCIP_Real val)
Definition: lpi_cpx.c:4642
SCIP_RETCODE SCIPlpiClear(SCIP_LPI *lpi)
Definition: lpi_cpx.c:1525
SCIP_RETCODE SCIPlpiClearState(SCIP_LPI *lpi)
Definition: lpi_cpx.c:4097
SCIP_Bool SCIPlpiExistsDualRay(SCIP_LPI *lpi)
Definition: lpi_cpx.c:3148
SCIP_Bool SCIPlpiExistsPrimalRay(SCIP_LPI *lpi)
Definition: lpi_cpx.c:3056
SCIP_RETCODE SCIPlpiGetBase(SCIP_LPI *lpi, int *cstat, int *rstat)
Definition: lpi_cpx.c:3560
SCIP_RETCODE SCIPlpiReadState(SCIP_LPI *lpi, const char *fname)
Definition: lpi_cpx.c:4139
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_cpx.c:1414
SCIP_RETCODE SCIPlpiGetPrimalRay(SCIP_LPI *lpi, SCIP_Real *ray)
Definition: lpi_cpx.c:3445
SCIP_RETCODE SCIPlpiGetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int *ival)
Definition: lpi_cpx.c:4316
SCIP_RETCODE SCIPlpiWriteLP(SCIP_LPI *lpi, const char *fname)
Definition: lpi_cpx.c:4689
SCIP_RETCODE SCIPlpiSetIntegralityInformation(SCIP_LPI *lpi, int ncols, int *intInfo)
Definition: lpi_cpx.c:1060
SCIP_Bool SCIPlpiIsDualInfeasible(SCIP_LPI *lpi)
Definition: lpi_cpx.c:3194
SCIP_RETCODE SCIPlpiSetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real dval)
Definition: lpi_cpx.c:4532
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_cpx.c:2791
SCIP_RETCODE SCIPlpiSetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, const SCIP_LPINORMS *lpinorms)
Definition: lpi_cpx.c:4250
SCIP_RETCODE SCIPlpiGetNNonz(SCIP_LPI *lpi, int *nnonz)
Definition: lpi_cpx.c:1897
SCIP_Bool SCIPlpiHasPrimalSolve(void)
Definition: lpi_cpx.c:1075
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_cpx.c:2921
SCIP_RETCODE SCIPlpiGetBounds(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *lbs, SCIP_Real *ubs)
Definition: lpi_cpx.c:2130
SCIP_Bool SCIPlpiHasBarrierSolve(void)
Definition: lpi_cpx.c:1091
SCIP_RETCODE SCIPlpiGetDualfarkas(SCIP_LPI *lpi, SCIP_Real *dualfarkas)
Definition: lpi_cpx.c:3465
SCIP_RETCODE SCIPlpiGetObjval(SCIP_LPI *lpi, SCIP_Real *objval)
Definition: lpi_cpx.c:3381
SCIP_RETCODE SCIPlpiScaleCol(SCIP_LPI *lpi, int col, SCIP_Real scaleval)
Definition: lpi_cpx.c:1789
int SCIPlpiGetInternalStatus(SCIP_LPI *lpi)
Definition: lpi_cpx.c:3347
SCIP_RETCODE SCIPlpiStartStrongbranch(SCIP_LPI *lpi)
Definition: lpi_cpx.c:2765
SCIP_RETCODE SCIPlpiGetSolFeasibility(SCIP_LPI *lpi, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
Definition: lpi_cpx.c:3029
SCIP_RETCODE SCIPlpiFreeNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition: lpi_cpx.c:4283
SCIP_Bool SCIPlpiIsIterlimExc(SCIP_LPI *lpi)
Definition: lpi_cpx.c:3325
SCIP_RETCODE SCIPlpiChgBounds(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *lb, const SCIP_Real *ub)
Definition: lpi_cpx.c:1555
SCIP_Bool SCIPlpiIsPrimalUnbounded(SCIP_LPI *lpi)
Definition: lpi_cpx.c:3083
SCIP_RETCODE SCIPlpiIgnoreInstability(SCIP_LPI *lpi, SCIP_Bool *success)
Definition: lpi_cpx.c:3358
SCIP_RETCODE SCIPlpiWriteState(SCIP_LPI *lpi, const char *fname)
Definition: lpi_cpx.c:4157
SCIP_RETCODE SCIPlpiFree(SCIP_LPI **lpi)
Definition: lpi_cpx.c:1196
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_cpx.c:2855
SCIP_RETCODE SCIPlpiGetCoef(SCIP_LPI *lpi, int row, int col, SCIP_Real *val)
Definition: lpi_cpx.c:2201
SCIP_Bool SCIPlpiIsPrimalFeasible(SCIP_LPI *lpi)
Definition: lpi_cpx.c:3127
SCIP_RETCODE SCIPlpiReadLP(SCIP_LPI *lpi, const char *fname)
Definition: lpi_cpx.c:4664
SCIP_RETCODE SCIPlpiGetRealSolQuality(SCIP_LPI *lpi, SCIP_LPSOLQUALITY qualityindicator, SCIP_Real *quality)
Definition: lpi_cpx.c:3503
SCIP_Bool SCIPlpiIsDualFeasible(SCIP_LPI *lpi)
Definition: lpi_cpx.c:3216
SCIP_RETCODE SCIPlpiGetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition: lpi_cpx.c:4190
SCIP_Bool SCIPlpiIsTimelimExc(SCIP_LPI *lpi)
Definition: lpi_cpx.c:3336
SCIP_Bool SCIPlpiHasStateBasis(SCIP_LPI *lpi, SCIP_LPISTATE *lpistate)
Definition: lpi_cpx.c:4129
SCIP_RETCODE SCIPlpiSetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int ival)
Definition: lpi_cpx.c:4379
const char * SCIPlpiGetSolverName(void)
Definition: lpi_cpx.c:1033
SCIP_RETCODE SCIPlpiSetBase(SCIP_LPI *lpi, const int *cstat, const int *rstat)
Definition: lpi_cpx.c:3600
SCIP_Bool SCIPlpiHasPrimalRay(SCIP_LPI *lpi)
Definition: lpi_cpx.c:3070
SCIP_RETCODE SCIPlpiGetBInvRow(SCIP_LPI *lpi, int r, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_cpx.c:3687
SCIP_RETCODE SCIPlpiDelRows(SCIP_LPI *lpi, int firstrow, int lastrow)
Definition: lpi_cpx.c:1483
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_cpx.c:1917
SCIP_RETCODE SCIPlpiGetBInvCol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_cpx.c:3759
SCIP_RETCODE SCIPlpiGetColNames(SCIP_LPI *lpi, int firstcol, int lastcol, char **colnames, char *namestorage, int namestoragesize, int *storageleft)
Definition: lpi_cpx.c:2022
static SCIP_RETCODE lpiStrongbranchIntegral(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_cpx.c:2659
SCIP_RETCODE SCIPlpiGetBInvARow(SCIP_LPI *lpi, int r, const SCIP_Real *binvrow, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_cpx.c:3833
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_cpx.c:1961
SCIP_Bool SCIPlpiWasSolved(SCIP_LPI *lpi)
Definition: lpi_cpx.c:3008
const char * SCIPlpiGetSolverDesc(void)
Definition: lpi_cpx.c:1041
SCIP_RETCODE SCIPlpiSolveBarrier(SCIP_LPI *lpi, SCIP_Bool crossover)
Definition: lpi_cpx.c:2568
SCIP_Bool SCIPlpiIsOptimal(SCIP_LPI *lpi)
Definition: lpi_cpx.c:3235
SCIP_RETCODE SCIPlpiGetRowNames(SCIP_LPI *lpi, int firstrow, int lastrow, char **rownames, char *namestorage, int namestoragesize, int *storageleft)
Definition: lpi_cpx.c:2056
SCIP_Bool SCIPlpiHasDualSolve(void)
Definition: lpi_cpx.c:1083
SCIP_RETCODE SCIPlpiEndStrongbranch(SCIP_LPI *lpi)
Definition: lpi_cpx.c:2778
SCIP_RETCODE SCIPlpiGetSides(SCIP_LPI *lpi, int firstrow, int lastrow, SCIP_Real *lhss, SCIP_Real *rhss)
Definition: lpi_cpx.c:2159
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_cpx.c:2955
SCIP_RETCODE SCIPlpiGetSol(SCIP_LPI *lpi, SCIP_Real *objval, SCIP_Real *primsol, SCIP_Real *dualsol, SCIP_Real *activity, SCIP_Real *redcost)
Definition: lpi_cpx.c:3415
SCIP_Bool SCIPlpiHasDualRay(SCIP_LPI *lpi)
Definition: lpi_cpx.c:3161
SCIP_RETCODE SCIPlpiDelColset(SCIP_LPI *lpi, int *dstat)
Definition: lpi_cpx.c:1392
SCIP_RETCODE SCIPlpiGetObj(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *vals)
Definition: lpi_cpx.c:2109
SCIP_RETCODE SCIPlpiFreeState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lpi_cpx.c:4110
SCIP_Bool SCIPlpiIsPrimalInfeasible(SCIP_LPI *lpi)
Definition: lpi_cpx.c:3107
SCIP_RETCODE SCIPlpiSolveDual(SCIP_LPI *lpi)
Definition: lpi_cpx.c:2379
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_cpx.c:1316
SCIP_RETCODE SCIPlpiSolvePrimal(SCIP_LPI *lpi)
Definition: lpi_cpx.c:2233
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_cpx.c:1242
SCIP_Bool SCIPlpiIsDualUnbounded(SCIP_LPI *lpi)
Definition: lpi_cpx.c:3174
SCIP_RETCODE SCIPlpiGetIterations(SCIP_LPI *lpi, int *iterations)
Definition: lpi_cpx.c:3485
SCIP_RETCODE SCIPlpiGetBasisInd(SCIP_LPI *lpi, int *bind)
Definition: lpi_cpx.c:3652
SCIP_RETCODE SCIPlpiCreate(SCIP_LPI **lpi, SCIP_MESSAGEHDLR *messagehdlr, const char *name, SCIP_OBJSEN objsen)
Definition: lpi_cpx.c:1111
void * SCIPlpiGetSolverPointer(SCIP_LPI *lpi)
Definition: lpi_cpx.c:1052
SCIP_RETCODE SCIPlpiChgObj(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *obj)
Definition: lpi_cpx.c:1710
SCIP_RETCODE SCIPlpiGetObjsen(SCIP_LPI *lpi, SCIP_OBJSEN *objsen)
Definition: lpi_cpx.c:2090
SCIP_Bool SCIPlpiIsStable(SCIP_LPI *lpi)
Definition: lpi_cpx.c:3252
SCIP_RETCODE SCIPlpiGetNCols(SCIP_LPI *lpi, int *ncols)
Definition: lpi_cpx.c:1880
SCIP_RETCODE SCIPlpiInterrupt(SCIP_LPI *lpi, SCIP_Bool interrupt)
Definition: lpi_cpx.c:4610
SCIP_RETCODE SCIPlpiDelCols(SCIP_LPI *lpi, int firstcol, int lastcol)
Definition: lpi_cpx.c:1371
SCIP_RETCODE SCIPlpiDelRowset(SCIP_LPI *lpi, int *dstat)
Definition: lpi_cpx.c:1504
SCIP_RETCODE SCIPlpiScaleRow(SCIP_LPI *lpi, int row, SCIP_Real scaleval)
Definition: lpi_cpx.c:1733
SCIP_RETCODE SCIPlpiGetNRows(SCIP_LPI *lpi, int *nrows)
Definition: lpi_cpx.c:1863
SCIP_RETCODE SCIPlpiGetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lpi_cpx.c:3985
SCIP_RETCODE SCIPlpiChgCoef(SCIP_LPI *lpi, int row, int col, SCIP_Real newval)
Definition: lpi_cpx.c:1666
interface methods for specific LP solvers
SCIP_DUALPACKET ROWPACKET
Definition: lpi_clp.cpp:128
SCIP_DUALPACKET COLPACKET
Definition: lpi_clp.cpp:126
static SCIP_RETCODE setBase(SCIP_LPI *lpi)
Definition: lpi_cpx.c:360
static void reconvertSides(SCIP_LPI *lpi, int nrows, SCIP_Real *lhs, SCIP_Real *rhs)
Definition: lpi_cpx.c:957
static void lpistatePack(SCIP_LPISTATE *lpistate, const int *cstat, const int *rstat)
Definition: lpi_cpx.c:408
static void lpistateUnpack(const SCIP_LPISTATE *lpistate, int *cstat, int *rstat)
Definition: lpi_cpx.c:424
static int rowpacketNum(int nrows)
Definition: lpi_cpx.c:399
static void invalidateSolution(SCIP_LPI *const lpi)
Definition: lpi_cpx.c:709
SCIP_DUALPACKET ROWPACKET
Definition: lpi_cpx.c:85
#define CPX_SUBVERSION
Definition: lpi_cpx.c:46
static SCIP_RETCODE ensureCstatMem(SCIP_LPI *lpi, int num)
Definition: lpi_cpx.c:289
static SCIP_RETCODE setParameterValues(SCIP_LPI *const lpi, SCIP_CPXPARAM *const cpxparam)
Definition: lpi_cpx.c:539
static void convertSides(SCIP_LPI *lpi, int nrows, const SCIP_Real *lhs, const SCIP_Real *rhs, int indoffset, int *rngcount)
Definition: lpi_cpx.c:740
static SCIP_RETCODE checkParameterValues(SCIP_LPI *const lpi)
Definition: lpi_cpx.c:509
#define CPX_INT_MAX
Definition: lpi_cpx.c:72
#define COLS_PER_PACKET
Definition: lpi_cpx.c:84
static int getIntParam(SCIP_LPI *lpi, int const param)
Definition: lpi_cpx.c:601
static void setDblParam(SCIP_LPI *lpi, int const param, double parval)
Definition: lpi_cpx.c:679
static SCIP_RETCODE ensureBoundchgMem(SCIP_LPI *lpi, int num)
Definition: lpi_cpx.c:212
static const char cpxname[]
Definition: lpi_cpx.c:1013
static void lpistateFree(SCIP_LPISTATE **lpistate, BMS_BLKMEM *blkmem)
Definition: lpi_cpx.c:461
static void setIntParam(SCIP_LPI *lpi, int const param, int const parval)
Definition: lpi_cpx.c:654
static const int intparam[NUMINTPARAM]
Definition: lpi_cpx.c:94
static SCIP_RETCODE getBase(SCIP_LPI *lpi)
Definition: lpi_cpx.c:333
SCIP_DUALPACKET COLPACKET
Definition: lpi_cpx.c:83
static SCIP_RETCODE getParameterValues(SCIP_LPI *lpi, SCIP_CPXPARAM *cpxparam)
Definition: lpi_cpx.c:483
static SCIP_RETCODE restoreLPData(SCIP_LPI *lpi)
Definition: lpi_cpx.c:975
static int cpxObjsen(SCIP_OBJSEN const objsen)
Definition: lpi_cpx.c:721
#define CHECK_ZERO(messagehdlr, x)
Definition: lpi_cpx.c:54
static const double dblparammin[NUMDBLPARAM]
Definition: lpi_cpx.c:123
static void reconvertBothSides(SCIP_LPI *lpi, int nrows, SCIP_Real *lhs, SCIP_Real *rhs)
Definition: lpi_cpx.c:804
#define NUMINTPARAM
Definition: lpi_cpx.c:90
static SCIP_RETCODE ensureRstatMem(SCIP_LPI *lpi, int num)
Definition: lpi_cpx.c:311
static int colpacketNum(int ncols)
Definition: lpi_cpx.c:390
static SCIP_RETCODE ensureSidechgMem(SCIP_LPI *lpi, int num)
Definition: lpi_cpx.c:241
static void copyParameterValues(SCIP_CPXPARAM *dest, SCIP_CPXPARAM *const source)
Definition: lpi_cpx.c:586
#define ABORT_ZERO(x)
Definition: lpi_cpx.c:63
#define CPX_REFACTORMAXITERS
Definition: lpi_cpx.c:77
static const int dblparam[NUMDBLPARAM]
Definition: lpi_cpx.c:112
static void reconvertLhs(SCIP_LPI *lpi, int nrows, SCIP_Real *lhs)
Definition: lpi_cpx.c:861
#define NUMDBLPARAM
Definition: lpi_cpx.c:111
static void reconvertRhs(SCIP_LPI *lpi, int nrows, SCIP_Real *rhs)
Definition: lpi_cpx.c:909
static double getDblParam(SCIP_LPI *lpi, int const param)
Definition: lpi_cpx.c:623
static SCIP_RETCODE lpistateCreate(SCIP_LPISTATE **lpistate, BMS_BLKMEM *blkmem, int ncols, int nrows)
Definition: lpi_cpx.c:440
#define ROWS_PER_PACKET
Definition: lpi_cpx.c:86
#define CPX_MAGICZEROCONSTANT
Definition: lpi_cpx.c:81
static SCIP_RETCODE ensureValMem(SCIP_LPI *lpi, int num)
Definition: lpi_cpx.c:266
#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 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
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
double dblparval[NUMDBLPARAM]
Definition: lpi_cpx.c:138
int intparval[NUMINTPARAM]
Definition: lpi_cpx.c:137
double * norm
Definition: lpi_cpx.c:201
int * head
Definition: lpi_cpx.c:202
COLPACKET * packcstat
Definition: lpi_clp.cpp:136
ROWPACKET * packrstat
Definition: lpi_clp.cpp:137
SCIP_Bool clearstate
Definition: lpi_cpx.c:172
int iterations
Definition: lpi_cpx.c:167
SCIP_Real * valarray
Definition: lpi_cpx.c:157
int valsize
Definition: lpi_cpx.c:164
CPXLPptr cpxlp
Definition: lpi_cpx.c:148
char * uarray
Definition: lpi_cpx.c:153
int boundchgsize
Definition: lpi_cpx.c:162
SCIP_CPXPARAM curparam
Definition: lpi_cpx.c:147
int method
Definition: lpi_cpx.c:150
SCIP_Bool instabilityignored
Definition: lpi_cpx.c:170
int * indarray
Definition: lpi_cpx.c:161
SCIP_Real conditionlimit
Definition: lpi_cpx.c:174
int * cstat
Definition: lpi_clp.cpp:107
CPXENVptr cpxenv
Definition: lpi_cpx.c:145
SCIP_CPXPARAM cpxparam
Definition: lpi_cpx.c:151
SCIP_Bool solisbasic
Definition: lpi_cpx.c:169
int solstat
Definition: lpi_cpx.c:149
SCIP_Bool rngfound
Definition: lpi_cpx.c:177
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_Real feastol
Definition: lpi_cpx.c:173
SCIP_MESSAGEHDLR * messagehdlr
Definition: lpi_cpx.c:185
SCIP_Real * rngarray
Definition: lpi_cpx.c:156
int * rngindarray
Definition: lpi_cpx.c:158
char * larray
Definition: lpi_cpx.c:152
SCIP_Bool checkcondition
Definition: lpi_cpx.c:175
SCIP_CPXPARAM defparam
Definition: lpi_cpx.c:146
@ 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_READERROR
Definition: type_retcode.h:45
@ 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