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-2025 Zuse Institute Berlin (ZIB) */
7/* */
8/* Licensed under the Apache License, Version 2.0 (the "License"); */
9/* you may not use this file except in compliance with the License. */
10/* You may obtain a copy of the License at */
11/* */
12/* http://www.apache.org/licenses/LICENSE-2.0 */
13/* */
14/* Unless required by applicable law or agreed to in writing, software */
15/* distributed under the License is distributed on an "AS IS" BASIS, */
16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17/* See the License for the specific language governing permissions and */
18/* limitations under the License. */
19/* */
20/* You should have received a copy of the Apache-2.0 license */
21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
22/* */
23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24
25/**@file lpi_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(firstcol >= 0);
1381 assert(lastcol < CPXgetnumcols(lpi->cpxenv, lpi->cpxlp));
1382 assert(firstcol <= lastcol + 1);
1383
1384 SCIPdebugMessage("deleting %d columns from CPLEX\n", lastcol - firstcol + 1);
1385
1386 /* handle empty range */
1387 if( firstcol > lastcol )
1388 return SCIP_OKAY;
1389
1390 invalidateSolution(lpi);
1391
1392 CHECK_ZERO( lpi->messagehdlr, CPXdelcols(lpi->cpxenv, lpi->cpxlp, firstcol, lastcol) );
1393
1394 return SCIP_OKAY;
1395}
1396
1397/** deletes columns from SCIP_LP; the new position of a column must not be greater that its old position */
1399 SCIP_LPI* lpi, /**< LP interface structure */
1400 int* dstat /**< deletion status of columns
1401 * input: 1 if column should be deleted, 0 if not
1402 * output: new position of column, -1 if column was deleted */
1403 )
1404{
1405 assert(lpi != NULL);
1406 assert(lpi->cpxlp != NULL);
1407 assert(lpi->cpxenv != NULL);
1408 assert(dstat != NULL);
1409
1410 SCIPdebugMessage("deleting a column set from CPLEX\n");
1411
1412 invalidateSolution(lpi);
1413
1414 CHECK_ZERO( lpi->messagehdlr, CPXdelsetcols(lpi->cpxenv, lpi->cpxlp, dstat) );
1415
1416 return SCIP_OKAY;
1417}
1418
1419/** adds rows to the LP */
1421 SCIP_LPI* lpi, /**< LP interface structure */
1422 int nrows, /**< number of rows to be added */
1423 const SCIP_Real* lhs, /**< left hand sides of new rows */
1424 const SCIP_Real* rhs, /**< right hand sides of new rows */
1425 char** rownames, /**< row names, or NULL */
1426 int nnonz, /**< number of nonzero elements to be added to the constraint matrix */
1427 const int* beg, /**< start index of each row in ind- and val-array, or NULL if nnonz == 0 */
1428 const int* ind, /**< column indices of constraint matrix entries, or NULL if nnonz == 0 */
1429 const SCIP_Real* val /**< values of constraint matrix entries, or NULL if nnonz == 0 */
1430 )
1431{
1432 int rngcount;
1433
1434 assert(lpi != NULL);
1435 assert(lpi->cpxlp != NULL);
1436 assert(lpi->cpxenv != NULL);
1437 assert(lhs != NULL);
1438 assert(rhs != NULL);
1439 assert(nnonz == 0 || beg != NULL);
1440 assert(nnonz == 0 || ind != NULL);
1441 assert(nnonz == 0 || val != NULL);
1442
1443 SCIPdebugMessage("adding %d rows with %d nonzeros to CPLEX\n", nrows, nnonz);
1444
1445 invalidateSolution(lpi);
1446
1447 SCIP_CALL( ensureSidechgMem(lpi, nrows) );
1448
1449 /* convert lhs/rhs into sen/rhs/range tuples */
1450 convertSides(lpi, nrows, lhs, rhs, CPXgetnumrows(lpi->cpxenv, lpi->cpxlp), &rngcount);
1451
1452 /* add rows to LP */
1453 if( nnonz > 0 )
1454 {
1455#ifndef NDEBUG
1456 /* perform check that no new columns are added - this is likely to be a mistake */
1457 int ncols;
1458 int j;
1459
1460 ncols = CPXgetnumcols(lpi->cpxenv, lpi->cpxlp);
1461 for (j = 0; j < nnonz; ++j) {
1462 assert( val[j] != 0.0 );
1463 assert( 0 <= ind[j] && ind[j] < ncols );
1464 }
1465#endif
1466 CHECK_ZERO( lpi->messagehdlr, CPXaddrows(lpi->cpxenv, lpi->cpxlp, 0, nrows, nnonz, lpi->rhsarray, lpi->senarray, beg, ind, val, NULL,
1467 rownames) );
1468 }
1469 else
1470 {
1471 CHECK_ZERO( lpi->messagehdlr, CPXnewrows(lpi->cpxenv, lpi->cpxlp, nrows, lpi->rhsarray, lpi->senarray, NULL, rownames) );
1472 }
1473 if( rngcount > 0 )
1474 {
1475#if (CPX_VERSION <= 1100)
1476 if( lpi->rngfound == FALSE )
1477 {
1479 lpi->rngfound = TRUE;
1480 }
1481#endif
1482 CHECK_ZERO( lpi->messagehdlr, CPXchgrngval(lpi->cpxenv, lpi->cpxlp, rngcount, lpi->rngindarray, lpi->rngarray) );
1483 }
1484
1485 return SCIP_OKAY;
1486}
1487
1488/** deletes all rows in the given range from LP */
1490 SCIP_LPI* lpi, /**< LP interface structure */
1491 int firstrow, /**< first row to be deleted */
1492 int lastrow /**< last row to be deleted */
1493 )
1494{
1495 assert(lpi != NULL);
1496 assert(lpi->cpxlp != NULL);
1497 assert(lpi->cpxenv != NULL);
1498 assert(firstrow >= 0);
1499 assert(lastrow < CPXgetnumrows(lpi->cpxenv, lpi->cpxlp));
1500 assert(firstrow <= lastrow + 1);
1501
1502 SCIPdebugMessage("deleting %d rows from CPLEX\n", lastrow - firstrow + 1);
1503
1504 /* handle empty range */
1505 if( firstrow > lastrow )
1506 return SCIP_OKAY;
1507
1508 invalidateSolution(lpi);
1509
1510 CHECK_ZERO( lpi->messagehdlr, CPXdelrows(lpi->cpxenv, lpi->cpxlp, firstrow, lastrow) );
1511
1512 return SCIP_OKAY;
1513}
1514
1515/** deletes rows from SCIP_LP; the new position of a row must not be greater that its old position */
1517 SCIP_LPI* lpi, /**< LP interface structure */
1518 int* dstat /**< deletion status of rows
1519 * input: 1 if row should be deleted, 0 if not
1520 * output: new position of row, -1 if row was deleted */
1521 )
1522{
1523 assert(lpi != NULL);
1524 assert(lpi->cpxlp != NULL);
1525 assert(lpi->cpxenv != NULL);
1526
1527 SCIPdebugMessage("deleting a row set from CPLEX\n");
1528
1529 invalidateSolution(lpi);
1530
1531 CHECK_ZERO( lpi->messagehdlr, CPXdelsetrows(lpi->cpxenv, lpi->cpxlp, dstat) );
1532
1533 return SCIP_OKAY;
1534}
1535
1536/** clears the whole LP */
1538 SCIP_LPI* lpi /**< LP interface structure */
1539 )
1540{
1541 int ncols;
1542 int nrows;
1543
1544 assert(lpi != NULL);
1545 assert(lpi->cpxlp != NULL);
1546 assert(lpi->cpxenv != NULL);
1547
1548 SCIPdebugMessage("clearing CPLEX LP\n");
1549
1550 invalidateSolution(lpi);
1551
1552 ncols = CPXgetnumcols(lpi->cpxenv, lpi->cpxlp);
1553 nrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
1554 if( ncols >= 1 )
1555 {
1556 CHECK_ZERO( lpi->messagehdlr, CPXdelcols(lpi->cpxenv, lpi->cpxlp, 0, ncols-1) );
1557 }
1558 if( nrows >= 1 )
1559 {
1560 CHECK_ZERO( lpi->messagehdlr, CPXdelrows(lpi->cpxenv, lpi->cpxlp, 0, nrows-1) );
1561 }
1562
1563 return SCIP_OKAY;
1564}
1565
1566/** changes lower and upper bounds of columns */
1568 SCIP_LPI* lpi, /**< LP interface structure */
1569 int ncols, /**< number of columns to change bounds for */
1570 const int* ind, /**< column indices or NULL if ncols is zero */
1571 const SCIP_Real* lb, /**< values for the new lower bounds or NULL if ncols is zero */
1572 const SCIP_Real* ub /**< values for the new upper bounds or NULL if ncols is zero */
1573 )
1574{
1575 int i;
1576
1577 assert(lpi != NULL);
1578 assert(lpi->cpxlp != NULL);
1579 assert(lpi->cpxenv != NULL);
1580 assert(ncols == 0 || (ind != NULL && lb != NULL && ub != NULL));
1581
1582 SCIPdebugMessage("changing %d bounds in CPLEX\n", ncols);
1583 if( ncols <= 0 )
1584 return SCIP_OKAY;
1585
1586 for( i = 0; i < ncols; ++i )
1587 {
1588 SCIPdebugPrintf(" col %d: [%g,%g]\n", ind[i], lb[i], ub[i]);
1589
1590 if ( SCIPlpiIsInfinity(lpi, lb[i]) )
1591 {
1592 SCIPerrorMessage("LP Error: fixing lower bound for variable %d to infinity.\n", ind[i]);
1593 return SCIP_LPERROR;
1594 }
1595 if ( SCIPlpiIsInfinity(lpi, -ub[i]) )
1596 {
1597 SCIPerrorMessage("LP Error: fixing upper bound for variable %d to -infinity.\n", ind[i]);
1598 return SCIP_LPERROR;
1599 }
1600 }
1601
1602 invalidateSolution(lpi);
1603
1604 SCIP_CALL( ensureBoundchgMem(lpi, ncols) );
1605
1606 CHECK_ZERO( lpi->messagehdlr, CPXchgbds(lpi->cpxenv, lpi->cpxlp, ncols, ind, lpi->larray, (SCIP_Real*)lb) );
1607 CHECK_ZERO( lpi->messagehdlr, CPXchgbds(lpi->cpxenv, lpi->cpxlp, ncols, ind, lpi->uarray, (SCIP_Real*)ub) );
1608
1609#ifndef NDEBUG
1610 {
1611 for( i = 0; i < ncols; ++i )
1612 {
1613 SCIP_Real cpxlb;
1614 SCIP_Real cpxub;
1615
1616 CHECK_ZERO( lpi->messagehdlr, CPXgetlb(lpi->cpxenv, lpi->cpxlp, &cpxlb, ind[i], ind[i]) );
1617 CHECK_ZERO( lpi->messagehdlr, CPXgetub(lpi->cpxenv, lpi->cpxlp, &cpxub, ind[i], ind[i]) );
1618
1619 /* Note that CPLEX seems to set bounds below 1e-10 in absolute value to 0.*/
1620 assert( EPSZ(cpxlb, CPX_MAGICZEROCONSTANT) || cpxlb == lb[i] ); /*lint !e777*/
1621 assert( EPSZ(cpxub, CPX_MAGICZEROCONSTANT) || cpxub == ub[i] ); /*lint !e777*/
1622 }
1623 }
1624#endif
1625
1626 return SCIP_OKAY;
1627}
1628
1629/** changes left and right hand sides of rows */
1631 SCIP_LPI* lpi, /**< LP interface structure */
1632 int nrows, /**< number of rows to change sides for */
1633 const int* ind, /**< row indices */
1634 const SCIP_Real* lhs, /**< new values for left hand sides */
1635 const SCIP_Real* rhs /**< new values for right hand sides */
1636 )
1637{
1638 int rngcount;
1639 int i;
1640
1641 assert(lpi != NULL);
1642 assert(lpi->cpxlp != NULL);
1643 assert(lpi->cpxenv != NULL);
1644
1645 if( nrows <= 0 )
1646 return SCIP_OKAY;
1647
1648 SCIPdebugMessage("changing %d sides in CPLEX\n", nrows);
1649
1650 invalidateSolution(lpi);
1651
1652 SCIP_CALL( ensureSidechgMem(lpi, nrows) );
1653
1654 /* convert lhs/rhs into sen/rhs/range tuples */
1655 convertSides(lpi, nrows, lhs, rhs, 0, &rngcount);
1656
1657 /* change row sides */
1658 CHECK_ZERO( lpi->messagehdlr, CPXchgsense(lpi->cpxenv, lpi->cpxlp, nrows, ind, lpi->senarray) );
1659 CHECK_ZERO( lpi->messagehdlr, CPXchgrhs(lpi->cpxenv, lpi->cpxlp, nrows, ind, lpi->rhsarray) );
1660 if( rngcount > 0 )
1661 {
1662 /* adjust the range count indices to the correct row indices */
1663 for( i = 0; i < rngcount; ++i )
1664 {
1665 assert(0 <= lpi->rngindarray[i] && lpi->rngindarray[i] < nrows);
1666 assert(lpi->senarray[lpi->rngindarray[i]] == 'R');
1667 lpi->rngindarray[i] = ind[lpi->rngindarray[i]];
1668 }
1669
1670 /* change the range values in CPLEX */
1671 CHECK_ZERO( lpi->messagehdlr, CPXchgrngval(lpi->cpxenv, lpi->cpxlp, rngcount, lpi->rngindarray, lpi->rngarray) );
1672 }
1673
1674 return SCIP_OKAY;
1675}
1676
1677/** changes a single coefficient */
1679 SCIP_LPI* lpi, /**< LP interface structure */
1680 int row, /**< row number of coefficient to change */
1681 int col, /**< column number of coefficient to change */
1682 SCIP_Real newval /**< new value of coefficient */
1683 )
1684{
1685 assert(lpi != NULL);
1686 assert(lpi->cpxlp != NULL);
1687 assert(lpi->cpxenv != NULL);
1688
1689 SCIPdebugMessage("changing coefficient row %d, column %d in CPLEX to %g\n", row, col, newval);
1690
1691 invalidateSolution(lpi);
1692
1693 CHECK_ZERO( lpi->messagehdlr, CPXchgcoef(lpi->cpxenv, lpi->cpxlp, row, col, newval) );
1694
1695 return SCIP_OKAY;
1696}
1697
1698/** changes the objective sense */
1700 SCIP_LPI* lpi, /**< LP interface structure */
1701 SCIP_OBJSEN objsen /**< new objective sense */
1702 )
1703{
1704 assert(lpi != NULL);
1705 assert(lpi->cpxlp != NULL);
1706 assert(lpi->cpxenv != NULL);
1707
1708 SCIPdebugMessage("changing objective sense in CPLEX to %d\n", objsen);
1709
1710 invalidateSolution(lpi);
1711
1712#if (CPX_VERSION >= 12050000)
1713 CHECK_ZERO( lpi->messagehdlr, CPXchgobjsen(lpi->cpxenv, lpi->cpxlp, cpxObjsen(objsen)) );
1714#else
1715 CPXchgobjsen(lpi->cpxenv, lpi->cpxlp, cpxObjsen(objsen));
1716#endif
1717
1718 return SCIP_OKAY;
1719}
1720
1721/** changes objective values of columns in the LP */
1723 SCIP_LPI* lpi, /**< LP interface structure */
1724 int ncols, /**< number of columns to change objective value for */
1725 const int* ind, /**< column indices to change objective value for */
1726 const SCIP_Real* obj /**< new objective values for columns */
1727 )
1728{
1729 assert(lpi != NULL);
1730 assert(lpi->cpxlp != NULL);
1731 assert(lpi->cpxenv != NULL);
1732 assert(ind != NULL);
1733 assert(obj != NULL);
1734
1735 SCIPdebugMessage("changing %d objective values in CPLEX\n", ncols);
1736
1737 invalidateSolution(lpi);
1738
1739 CHECK_ZERO( lpi->messagehdlr, CPXchgobj(lpi->cpxenv, lpi->cpxlp, ncols, ind, obj) );
1740
1741 return SCIP_OKAY;
1742}
1743
1744/** multiplies a row with a non-zero scalar; for negative scalars, the row's sense is switched accordingly */
1746 SCIP_LPI* lpi, /**< LP interface structure */
1747 int row, /**< row number to scale */
1748 SCIP_Real scaleval /**< scaling multiplier */
1749 )
1750{
1751 SCIP_Real lhs;
1752 SCIP_Real rhs;
1753 int nnonz;
1754 int beg;
1755 int i;
1756
1757 assert(lpi != NULL);
1758 assert(lpi->cpxlp != NULL);
1759 assert(lpi->cpxenv != NULL);
1760 assert(scaleval != 0.0);
1761
1762 SCIPdebugMessage("scaling row %d with factor %g in CPLEX\n", row, scaleval);
1763
1764 invalidateSolution(lpi);
1765
1766 SCIP_CALL( ensureValMem(lpi, CPXgetnumcols(lpi->cpxenv, lpi->cpxlp)) );
1767
1768 /* get the row */
1769 SCIP_CALL( SCIPlpiGetRows(lpi, row, row, &lhs, &rhs, &nnonz, &beg, lpi->indarray, lpi->valarray) );
1770
1771 /* scale row coefficients */
1772 for( i = 0; i < nnonz; ++i )
1773 {
1774 SCIP_CALL( SCIPlpiChgCoef(lpi, row, lpi->indarray[i], lpi->valarray[i] * scaleval) );
1775 }
1776
1777 /* scale row sides */
1778 if( lhs > -CPX_INFBOUND )
1779 lhs *= scaleval;
1780 else if( scaleval < 0.0 )
1781 lhs = CPX_INFBOUND;
1782 if( rhs < CPX_INFBOUND )
1783 rhs *= scaleval;
1784 else if( scaleval < 0.0 )
1785 rhs = -CPX_INFBOUND;
1786 if( scaleval > 0.0 )
1787 {
1788 SCIP_CALL( SCIPlpiChgSides(lpi, 1, &row, &lhs, &rhs) );
1789 }
1790 else
1791 {
1792 SCIP_CALL( SCIPlpiChgSides(lpi, 1, &row, &rhs, &lhs) );
1793 }
1794
1795 return SCIP_OKAY;
1796}
1797
1798/** multiplies a column with a non-zero scalar; the objective value is multiplied with the scalar, and the bounds
1799 * are divided by the scalar; for negative scalars, the column's bounds are switched
1800 */
1802 SCIP_LPI* lpi, /**< LP interface structure */
1803 int col, /**< column number to scale */
1804 SCIP_Real scaleval /**< scaling multiplier */
1805 )
1806{
1807 SCIP_Real lb;
1808 SCIP_Real ub;
1809 SCIP_Real obj;
1810 int nnonz;
1811 int beg;
1812 int i;
1813
1814 assert(lpi != NULL);
1815 assert(lpi->cpxlp != NULL);
1816 assert(lpi->cpxenv != NULL);
1817 assert(scaleval != 0.0);
1818
1819 SCIPdebugMessage("scaling column %d with factor %g in CPLEX\n", col, scaleval);
1820
1821 invalidateSolution(lpi);
1822
1823 SCIP_CALL( ensureValMem(lpi, CPXgetnumrows(lpi->cpxenv, lpi->cpxlp)) );
1824
1825 /* get the column */
1826 SCIP_CALL( SCIPlpiGetCols(lpi, col, col, &lb, &ub, &nnonz, &beg, lpi->indarray, lpi->valarray) );
1827
1828 /* get objective coefficient */
1829 SCIP_CALL( SCIPlpiGetObj(lpi, col, col, &obj) );
1830
1831 /* scale column coefficients */
1832 for( i = 0; i < nnonz; ++i )
1833 {
1834 SCIP_CALL( SCIPlpiChgCoef(lpi, lpi->indarray[i], col, lpi->valarray[i] * scaleval) );
1835 }
1836
1837 /* scale objective value */
1838 obj *= scaleval;
1839 SCIP_CALL( SCIPlpiChgObj(lpi, 1, &col, &obj) );
1840
1841 /* scale column bounds */
1842 if( lb > -CPX_INFBOUND )
1843 lb /= scaleval;
1844 else if( scaleval < 0.0 )
1845 lb = CPX_INFBOUND;
1846 if( ub < CPX_INFBOUND )
1847 ub /= scaleval;
1848 else if( scaleval < 0.0 )
1849 ub = -CPX_INFBOUND;
1850 if( scaleval > 0.0 )
1851 {
1852 SCIP_CALL( SCIPlpiChgBounds(lpi, 1, &col, &lb, &ub) );
1853 }
1854 else
1855 {
1856 SCIP_CALL( SCIPlpiChgBounds(lpi, 1, &col, &ub, &lb) );
1857 }
1858
1859 return SCIP_OKAY;
1860}
1861
1862/**@} */
1863
1864
1865
1866
1867/*
1868 * Data Accessing Methods
1869 */
1870
1871/**@name Data Accessing Methods */
1872/**@{ */
1873
1874/** gets the number of rows in the LP */
1876 SCIP_LPI* lpi, /**< LP interface structure */
1877 int* nrows /**< pointer to store the number of rows */
1878 )
1879{
1880 assert(lpi != NULL);
1881 assert(lpi->cpxenv != NULL);
1882 assert(nrows != NULL);
1883
1884 SCIPdebugMessage("getting number of rows\n");
1885
1886 *nrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
1887
1888 return SCIP_OKAY;
1889}
1890
1891/** gets the number of columns in the LP */
1893 SCIP_LPI* lpi, /**< LP interface structure */
1894 int* ncols /**< pointer to store the number of cols */
1895 )
1896{
1897 assert(lpi != NULL);
1898 assert(lpi->cpxenv != NULL);
1899 assert(ncols != NULL);
1900
1901 SCIPdebugMessage("getting number of columns\n");
1902
1903 *ncols = CPXgetnumcols(lpi->cpxenv, lpi->cpxlp);
1904
1905 return SCIP_OKAY;
1906}
1907
1908/** gets the number of nonzero elements in the LP constraint matrix */
1910 SCIP_LPI* lpi, /**< LP interface structure */
1911 int* nnonz /**< pointer to store the number of nonzeros */
1912 )
1913{
1914 assert(lpi != NULL);
1915 assert(lpi->cpxenv != NULL);
1916 assert(nnonz != NULL);
1917
1918 SCIPdebugMessage("getting number of non-zeros\n");
1919
1920 *nnonz = CPXgetnumnz(lpi->cpxenv, lpi->cpxlp);
1921
1922 return SCIP_OKAY;
1923}
1924
1925/** gets columns from LP problem object; the arrays have to be large enough to store all values
1926 * Either both, lb and ub, have to be NULL, or both have to be non-NULL,
1927 * either nnonz, beg, ind, and val have to be NULL, or all of them have to be non-NULL.
1928 */
1930 SCIP_LPI* lpi, /**< LP interface structure */
1931 int firstcol, /**< first column to get from LP */
1932 int lastcol, /**< last column to get from LP */
1933 SCIP_Real* lb, /**< buffer to store the lower bound vector, or NULL */
1934 SCIP_Real* ub, /**< buffer to store the upper bound vector, or NULL */
1935 int* nnonz, /**< pointer to store the number of nonzero elements returned, or NULL */
1936 int* beg, /**< buffer to store start index of each column in ind- and val-array, or NULL */
1937 int* ind, /**< buffer to store row indices of constraint matrix entries, or NULL */
1938 SCIP_Real* val /**< buffer to store values of constraint matrix entries, or NULL */
1939 )
1940{
1941 assert(lpi != NULL);
1942 assert(lpi->cpxlp != NULL);
1943 assert(lpi->cpxenv != NULL);
1944 assert((lb != NULL && ub != NULL) || (lb == NULL && ub == NULL));
1945 assert((nnonz != NULL && beg != NULL && ind != NULL && val != NULL) || (nnonz == NULL && beg == NULL && ind == NULL && val == NULL));
1946 assert(firstcol >= 0);
1947 assert(lastcol < CPXgetnumcols(lpi->cpxenv, lpi->cpxlp));
1948 assert(firstcol <= lastcol + 1);
1949
1950 SCIPdebugMessage("getting columns %d to %d\n", firstcol, lastcol);
1951
1952 if( lb != NULL )
1953 {
1954 CHECK_ZERO( lpi->messagehdlr, CPXgetlb(lpi->cpxenv, lpi->cpxlp, lb, firstcol, lastcol) );
1955 CHECK_ZERO( lpi->messagehdlr, CPXgetub(lpi->cpxenv, lpi->cpxlp, ub, firstcol, lastcol) );
1956 }
1957
1958 if( nnonz != NULL )
1959 {
1960 int surplus;
1961
1962 /* get matrix entries */
1963 CHECK_ZERO( lpi->messagehdlr, CPXgetcols(lpi->cpxenv, lpi->cpxlp, nnonz, beg, ind, val,
1964 CPXgetnumnz(lpi->cpxenv, lpi->cpxlp), &surplus, firstcol, lastcol) );
1965 assert(surplus >= 0);
1966 }
1967
1968 return SCIP_OKAY;
1969}
1970
1971/** gets rows from LP problem object; the arrays have to be large enough to store all values.
1972 * Either both, lhs and rhs, have to be NULL, or both have to be non-NULL,
1973 * either nnonz, beg, ind, and val have to be NULL, or all of them have to be non-NULL.
1974 */
1976 SCIP_LPI* lpi, /**< LP interface structure */
1977 int firstrow, /**< first row to get from LP */
1978 int lastrow, /**< last row to get from LP */
1979 SCIP_Real* lhs, /**< buffer to store left hand side vector, or NULL */
1980 SCIP_Real* rhs, /**< buffer to store right hand side vector, or NULL */
1981 int* nnonz, /**< pointer to store the number of nonzero elements returned, or NULL */
1982 int* beg, /**< buffer to store start index of each row in ind- and val-array, or NULL */
1983 int* ind, /**< buffer to store column indices of constraint matrix entries, or NULL */
1984 SCIP_Real* val /**< buffer to store values of constraint matrix entries, or NULL */
1985 )
1986{
1987#if CPX_VERSION < 12070000
1988 int retcode;
1989#endif
1990
1991 assert(lpi != NULL);
1992 assert(lpi->cpxlp != NULL);
1993 assert(lpi->cpxenv != NULL);
1994 assert((lhs == NULL && rhs == NULL) || (rhs != NULL && lhs != NULL));
1995 assert((nnonz != NULL && beg != NULL && ind != NULL && val != NULL) || (nnonz == NULL && beg == NULL && ind == NULL && val == NULL));
1996 assert(firstrow >= 0);
1997 assert(lastrow < CPXgetnumrows(lpi->cpxenv, lpi->cpxlp));
1998 assert(firstrow <= lastrow + 1);
1999
2000 SCIPdebugMessage("getting rows %d to %d\n", firstrow, lastrow);
2001
2002 if( lhs != NULL )
2003 {
2004 /* get row sense, rhs, and ranges */
2005 SCIP_CALL( ensureSidechgMem(lpi, lastrow - firstrow + 1) );
2006 CHECK_ZERO( lpi->messagehdlr, CPXgetsense(lpi->cpxenv, lpi->cpxlp, lpi->senarray, firstrow, lastrow) );
2007 CHECK_ZERO( lpi->messagehdlr, CPXgetrhs(lpi->cpxenv, lpi->cpxlp, lpi->rhsarray, firstrow, lastrow) );
2008#if CPX_VERSION < 12070000
2009 retcode = CPXgetrngval(lpi->cpxenv, lpi->cpxlp, lpi->rngarray, firstrow, lastrow);
2010 if( retcode != CPXERR_NO_RNGVAL ) /* ignore "No range values" error */
2011 {
2012 CHECK_ZERO( lpi->messagehdlr, retcode );
2013 }
2014 else
2015 BMSclearMemoryArray(lpi->rngarray, lastrow-firstrow+1);
2016#else
2017 CHECK_ZERO( lpi->messagehdlr, CPXgetrngval(lpi->cpxenv, lpi->cpxlp, lpi->rngarray, firstrow, lastrow) );
2018#endif
2019
2020 /* convert sen/rhs/range into lhs/rhs tuples */
2021 reconvertSides(lpi, lastrow - firstrow + 1, lhs, rhs);
2022 }
2023
2024 if( nnonz != NULL )
2025 {
2026 int surplus;
2027
2028 /* get matrix entries */
2029 CHECK_ZERO( lpi->messagehdlr, CPXgetrows(lpi->cpxenv, lpi->cpxlp, nnonz, beg, ind, val,
2030 CPXgetnumnz(lpi->cpxenv, lpi->cpxlp), &surplus, firstrow, lastrow) );
2031 assert(surplus >= 0);
2032 }
2033
2034 return SCIP_OKAY;
2035}
2036
2037/** gets column names */
2039 SCIP_LPI* lpi, /**< LP interface structure */
2040 int firstcol, /**< first column to get name from LP */
2041 int lastcol, /**< last column to get name from LP */
2042 char** colnames, /**< pointers to column names (of size at least lastcol-firstcol+1) or NULL if namestoragesize is zero */
2043 char* namestorage, /**< storage for col names or NULL if namestoragesize is zero */
2044 int namestoragesize, /**< size of namestorage (if 0, storageleft returns the storage needed) */
2045 int* storageleft /**< amount of storage left (if < 0 the namestorage was not big enough) or NULL if namestoragesize is zero */
2046 )
2047{
2048 int retcode;
2049
2050 assert(lpi != NULL);
2051 assert(lpi->cpxlp != NULL);
2052 assert(lpi->cpxenv != NULL);
2053 assert(colnames != NULL || namestoragesize == 0);
2054 assert(namestorage != NULL || namestoragesize == 0);
2055 assert(namestoragesize >= 0);
2056 assert(storageleft != NULL);
2057 assert(firstcol >= 0);
2058 assert(lastcol < CPXgetnumcols(lpi->cpxenv, lpi->cpxlp));
2059 assert(firstcol <= lastcol + 1);
2060
2061 SCIPdebugMessage("getting column names %d to %d\n", firstcol, lastcol);
2062
2063 retcode = CPXgetcolname(lpi->cpxenv, lpi->cpxlp, colnames, namestorage, namestoragesize, storageleft, firstcol, lastcol);
2064 assert( namestoragesize != 0 || retcode == CPXERR_NEGATIVE_SURPLUS );
2065 if( namestoragesize != 0 )
2066 {
2067 CHECK_ZERO( lpi->messagehdlr, retcode );
2068 }
2069
2070 return SCIP_OKAY;
2071}
2072
2073/** gets row names */
2075 SCIP_LPI* lpi, /**< LP interface structure */
2076 int firstrow, /**< first row to get name from LP */
2077 int lastrow, /**< last row to get name from LP */
2078 char** rownames, /**< pointers to row names (of size at least lastrow-firstrow+1) or NULL if namestoragesize is zero */
2079 char* namestorage, /**< storage for row names or NULL if namestoragesize is zero */
2080 int namestoragesize, /**< size of namestorage (if 0, -storageleft returns the storage needed) */
2081 int* storageleft /**< amount of storage left (if < 0 the namestorage was not big enough) or NULL if namestoragesize is zero */
2082 )
2083{
2084 int retcode;
2085
2086 assert(lpi != NULL);
2087 assert(lpi->cpxlp != NULL);
2088 assert(lpi->cpxenv != NULL);
2089 assert(rownames != NULL || namestoragesize == 0);
2090 assert(namestorage != NULL || namestoragesize == 0);
2091 assert(namestoragesize >= 0);
2092 assert(storageleft != NULL);
2093 assert(firstrow >= 0);
2094 assert(lastrow < CPXgetnumrows(lpi->cpxenv, lpi->cpxlp));
2095 assert(firstrow <= lastrow + 1);
2096
2097 SCIPdebugMessage("getting row names %d to %d\n", firstrow, lastrow);
2098
2099 retcode = CPXgetrowname(lpi->cpxenv, lpi->cpxlp, rownames, namestorage, namestoragesize, storageleft, firstrow, lastrow);
2100 assert( namestoragesize != 0 || retcode == CPXERR_NEGATIVE_SURPLUS );
2101 if( namestoragesize != 0 )
2102 {
2103 CHECK_ZERO( lpi->messagehdlr, retcode );
2104 }
2105
2106 return SCIP_OKAY;
2107}
2108
2109/** gets objective sense of the LP */
2111 SCIP_LPI* lpi, /**< LP interface structure */
2112 SCIP_OBJSEN* objsen /**< pointer to store objective sense */
2113 )
2114{
2115 assert(lpi != NULL);
2116 assert(lpi->cpxlp != NULL);
2117 assert(lpi->cpxenv != NULL);
2118 assert(objsen != NULL);
2119 assert(CPXgetobjsen(lpi->cpxenv, lpi->cpxlp) == CPX_MIN || CPXgetobjsen(lpi->cpxenv, lpi->cpxlp) == CPX_MAX);
2120
2121 SCIPdebugMessage("getting objective sense\n");
2122
2123 *objsen = (CPXgetobjsen(lpi->cpxenv, lpi->cpxlp) == CPX_MIN) ? SCIP_OBJSEN_MINIMIZE : SCIP_OBJSEN_MAXIMIZE;
2124
2125 return SCIP_OKAY;
2126}
2127
2128/** gets objective coefficients from LP problem object */
2130 SCIP_LPI* lpi, /**< LP interface structure */
2131 int firstcol, /**< first column to get objective coefficient for */
2132 int lastcol, /**< last column to get objective coefficient for */
2133 SCIP_Real* vals /**< array to store objective coefficients */
2134 )
2135{
2136 assert(lpi != NULL);
2137 assert(lpi->cpxlp != NULL);
2138 assert(lpi->cpxenv != NULL);
2139 assert(vals != NULL);
2140 assert(firstcol >= 0);
2141 assert(lastcol < CPXgetnumcols(lpi->cpxenv, lpi->cpxlp));
2142 assert(firstcol <= lastcol + 1);
2143
2144 SCIPdebugMessage("getting objective values %d to %d\n", firstcol, lastcol);
2145
2146 CHECK_ZERO( lpi->messagehdlr, CPXgetobj(lpi->cpxenv, lpi->cpxlp, vals, firstcol, lastcol) );
2147
2148 return SCIP_OKAY;
2149}
2150
2151/** gets current bounds from LP problem object */
2153 SCIP_LPI* lpi, /**< LP interface structure */
2154 int firstcol, /**< first column to get bounds for */
2155 int lastcol, /**< last column to get bounds for */
2156 SCIP_Real* lbs, /**< array to store lower bound values, or NULL */
2157 SCIP_Real* ubs /**< array to store upper bound values, or NULL */
2158 )
2159{
2160 assert(lpi != NULL);
2161 assert(lpi->cpxlp != NULL);
2162 assert(lpi->cpxenv != NULL);
2163 assert(firstcol >= 0);
2164 assert(lastcol < CPXgetnumcols(lpi->cpxenv, lpi->cpxlp));
2165 assert(firstcol <= lastcol + 1);
2166
2167 SCIPdebugMessage("getting bounds %d to %d\n", firstcol, lastcol);
2168
2169 if( lbs != NULL )
2170 {
2171 CHECK_ZERO( lpi->messagehdlr, CPXgetlb(lpi->cpxenv, lpi->cpxlp, lbs, firstcol, lastcol) );
2172 }
2173
2174 if( ubs != NULL )
2175 {
2176 CHECK_ZERO( lpi->messagehdlr, CPXgetub(lpi->cpxenv, lpi->cpxlp, ubs, firstcol, lastcol) );
2177 }
2178
2179 return SCIP_OKAY;
2180}
2181
2182/** gets current row sides from LP problem object */
2184 SCIP_LPI* lpi, /**< LP interface structure */
2185 int firstrow, /**< first row to get sides for */
2186 int lastrow, /**< last row to get sides for */
2187 SCIP_Real* lhss, /**< array to store left hand side values, or NULL */
2188 SCIP_Real* rhss /**< array to store right hand side values, or NULL */
2189 )
2190{
2191#if CPX_VERSION < 12070000
2192 int retval;
2193#endif
2194
2195 assert(lpi != NULL);
2196 assert(lpi->cpxlp != NULL);
2197 assert(lpi->cpxenv != NULL);
2198 assert(firstrow >= 0);
2199 assert(lastrow < CPXgetnumrows(lpi->cpxenv, lpi->cpxlp));
2200 assert(firstrow <= lastrow + 1);
2201
2202 SCIPdebugMessage("getting row sides %d to %d\n", firstrow, lastrow);
2203
2204 /* get row sense, rhs, and ranges */
2205 SCIP_CALL( ensureSidechgMem(lpi, lastrow - firstrow + 1) );
2206 CHECK_ZERO( lpi->messagehdlr, CPXgetsense(lpi->cpxenv, lpi->cpxlp, lpi->senarray, firstrow, lastrow) );
2207 CHECK_ZERO( lpi->messagehdlr, CPXgetrhs(lpi->cpxenv, lpi->cpxlp, lpi->rhsarray, firstrow, lastrow) );
2208#if CPX_VERSION < 12070000
2209 retval = CPXgetrngval(lpi->cpxenv, lpi->cpxlp, lpi->rngarray, firstrow, lastrow);
2210 if( retval != CPXERR_NO_RNGVAL ) /* ignore "No range values" error */
2211 {
2212 CHECK_ZERO( lpi->messagehdlr, retval );
2213 }
2214 else
2215 BMSclearMemoryArray(lpi->rngarray, lastrow-firstrow+1);
2216#else
2217 CHECK_ZERO( lpi->messagehdlr, CPXgetrngval(lpi->cpxenv, lpi->cpxlp, lpi->rngarray, firstrow, lastrow) );
2218#endif
2219
2220 /* convert sen/rhs/range into lhs/rhs tuples */
2221 reconvertSides(lpi, lastrow - firstrow + 1, lhss, rhss);
2222
2223 return SCIP_OKAY;
2224}
2225
2226/** gets a single coefficient */
2228 SCIP_LPI* lpi, /**< LP interface structure */
2229 int row, /**< row number of coefficient */
2230 int col, /**< column number of coefficient */
2231 SCIP_Real* val /**< pointer to store the value of the coefficient */
2232 )
2233{
2234 assert(lpi != NULL);
2235 assert(lpi->cpxlp != NULL);
2236 assert(lpi->cpxenv != NULL);
2237 assert(val != NULL);
2238
2239 SCIPdebugMessage("getting coefficient of row %d col %d\n", row, col);
2240
2241 CHECK_ZERO( lpi->messagehdlr, CPXgetcoef(lpi->cpxenv, lpi->cpxlp, row, col, val) );
2242
2243 return SCIP_OKAY;
2244}
2245
2246/**@} */
2247
2248
2249
2250
2251/*
2252 * Solving Methods
2253 */
2254
2255/**@name Solving Methods */
2256/**@{ */
2257
2258/** calls primal simplex to solve the LP */
2260 SCIP_LPI* lpi /**< LP interface structure */
2261 )
2262{
2263 int retval;
2264 int primalfeasible;
2265 int dualfeasible;
2266 int solntype;
2267#if CPX_VERSION == 12070100
2268 int presolving;
2269#endif
2270
2271 assert(lpi != NULL);
2272 assert(lpi->cpxlp != NULL);
2273 assert(lpi->cpxenv != NULL);
2274
2275 SCIPdebugMessage("calling CPLEX primal simplex: %d cols, %d rows\n",
2276 CPXgetnumcols(lpi->cpxenv, lpi->cpxlp), CPXgetnumrows(lpi->cpxenv, lpi->cpxlp));
2277
2278 invalidateSolution(lpi);
2279
2280#if (CPX_VERSION == 12070000)
2281 {
2282 int scaling;
2283 /* due to a bug in CPLEX 12.7.0, we need to disable scaling for this version */
2284 CHECK_ZERO( lpi->messagehdlr, CPXgetintparam(lpi->cpxenv, CPX_PARAM_SCAIND, &scaling) );
2285 assert( scaling == -1 );
2286 }
2287#endif
2288
2289 setIntParam(lpi, CPX_PARAM_ADVIND, lpi->fromscratch || lpi->clearstate ? CPX_OFF : CPX_ON);
2290 lpi->clearstate = FALSE;
2291
2292 SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
2293
2294#if CPX_VERSION == 12070100
2295 /* due to a bug in CPLEX 12.7.1.0, we need to enable presolving on trivial problems (see comment below) */
2296 if( CPXgetnumrows(lpi->cpxenv, lpi->cpxlp) == 0 )
2297 {
2298 CHECK_ZERO( lpi->messagehdlr, CPXgetintparam(lpi->cpxenv, CPX_PARAM_PREIND, &presolving) );
2299 CHECK_ZERO( lpi->messagehdlr, CPXsetintparam(lpi->cpxenv, CPX_PARAM_PREIND, CPX_ON) );
2300 }
2301#endif
2302
2303 SCIPdebugMessage("calling CPXprimopt()\n");
2304 retval = CPXprimopt(lpi->cpxenv, lpi->cpxlp);
2305
2306#if CPX_VERSION == 12070100
2307 /* restore previous value for presolving */
2308 if( CPXgetnumrows(lpi->cpxenv, lpi->cpxlp) == 0 )
2309 {
2310 CHECK_ZERO( lpi->messagehdlr, CPXsetintparam(lpi->cpxenv, CPX_PARAM_PREIND, presolving) ); /*lint !e644*/
2311 }
2312#endif
2313
2314 switch( retval )
2315 {
2316 case 0:
2317 break;
2318 case CPXERR_NO_MEMORY:
2319 return SCIP_NOMEMORY;
2320 default:
2321 return SCIP_LPERROR;
2322 }
2323
2324 lpi->solstat = CPXgetstat(lpi->cpxenv, lpi->cpxlp);
2325 lpi->method = CPX_ALG_PRIMAL;
2327
2328 /* CPLEX outputs an error if the status is CPX_STAT_INForUNBD and the iterations are determined */
2329 CHECK_ZERO( lpi->messagehdlr, CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, &solntype, &primalfeasible, &dualfeasible) );
2330 if( lpi->solstat != CPX_STAT_INForUNBD && solntype != CPX_NO_SOLN )
2331 lpi->iterations = CPXgetphase1cnt(lpi->cpxenv, lpi->cpxlp) + CPXgetitcnt(lpi->cpxenv, lpi->cpxlp);
2332 else
2333 lpi->iterations = 0;
2334
2335 SCIPdebugMessage(" -> CPLEX returned solstat=%d, pfeas=%d, dfeas=%d (%d iterations)\n",
2336 lpi->solstat, primalfeasible, dualfeasible, lpi->iterations);
2337
2338#if CPX_VERSION == 12070100
2339 /* CPLEX 12.7.1.0 primal simplex without presolve (called next in certain situations) does not return on a problem like
2340 * min x + sum_{i=1}^n 0*y_i when all variables are free and n >= 59
2341 * With this workaround, we claim that LPs without rows, which are returned as infeasible-or-unbounded by CPLEX with presolve,
2342 * are in fact unbounded. This assumes that CPLEX with presolve checked that no variable has an empty domain before.
2343 */
2344 if( lpi->solstat == CPX_STAT_INForUNBD && CPXgetnumrows(lpi->cpxenv, lpi->cpxlp) == 0 )
2345 {
2346 lpi->solstat = CPX_STAT_UNBOUNDED;
2347 primalfeasible = 1;
2348 dualfeasible = 0;
2349 }
2350#endif
2351
2352 if( lpi->solstat == CPX_STAT_INForUNBD
2353 || (lpi->solstat == CPX_STAT_INFEASIBLE && !dualfeasible)
2354 || (lpi->solstat == CPX_STAT_UNBOUNDED && !primalfeasible) )
2355 {
2356 if( getIntParam(lpi, CPX_PARAM_PREIND) == CPX_ON )
2357 {
2358 /* maybe the preprocessor solved the problem; but we need a solution, so solve again without preprocessing */
2359 SCIPdebugMessage("presolver may have solved the problem -> calling CPLEX primal simplex again without presolve\n");
2360
2361 /* switch off preprocessing */
2362 setIntParam(lpi, CPX_PARAM_PREIND, CPX_OFF);
2363 SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
2364
2365 retval = CPXprimopt(lpi->cpxenv, lpi->cpxlp);
2366 switch( retval )
2367 {
2368 case 0:
2369 break;
2370 case CPXERR_NO_MEMORY:
2371 return SCIP_NOMEMORY;
2372 default:
2373 return SCIP_LPERROR;
2374 }
2375
2376 lpi->solstat = CPXgetstat(lpi->cpxenv, lpi->cpxlp);
2378 assert( lpi->solstat != CPX_STAT_INForUNBD );
2379
2380 lpi->iterations += CPXgetphase1cnt(lpi->cpxenv, lpi->cpxlp) + CPXgetitcnt(lpi->cpxenv, lpi->cpxlp);
2381 CHECK_ZERO( lpi->messagehdlr, CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, &solntype, NULL, NULL) );
2382
2383 SCIPdebugMessage(" -> CPLEX returned solstat=%d (%d iterations)\n", lpi->solstat, lpi->iterations);
2384
2385 /* switch on preprocessing again */
2386 setIntParam(lpi, CPX_PARAM_PREIND, CPX_ON);
2387 }
2388
2389 if( lpi->solstat == CPX_STAT_INForUNBD )
2390 {
2391 /* preprocessing was not the problem; issue a warning message and treat LP as infeasible */
2392 SCIPerrorMessage("CPLEX primal simplex returned CPX_STAT_INForUNBD after presolving was turned off.\n");
2393 }
2394 }
2395
2396 /* check whether the solution is basic: if Cplex, e.g., hits a time limit in data setup, this might not be the case,
2397 * also for some pathological cases of infeasibility, e.g., contradictory bounds */
2398 lpi->solisbasic = (solntype == CPX_BASIC_SOLN);
2399 assert( lpi->solisbasic || lpi->solstat != CPX_STAT_OPTIMAL );
2400
2401 return SCIP_OKAY;
2402}
2403
2404/** calls dual simplex to solve the LP */
2406 SCIP_LPI* lpi /**< LP interface structure */
2407 )
2408{
2409 int retval;
2410 int primalfeasible;
2411 int dualfeasible;
2412 int solntype;
2413
2414 assert(lpi != NULL);
2415 assert(lpi->cpxlp != NULL);
2416 assert(lpi->cpxenv != NULL);
2417
2418 SCIPdebugMessage("calling CPLEX dual simplex: %d cols, %d rows\n",
2419 CPXgetnumcols(lpi->cpxenv, lpi->cpxlp), CPXgetnumrows(lpi->cpxenv, lpi->cpxlp));
2420
2421 invalidateSolution(lpi);
2422
2423 setIntParam(lpi, CPX_PARAM_ADVIND, lpi->fromscratch || lpi->clearstate ? CPX_OFF : CPX_ON);
2424 lpi->clearstate = FALSE;
2425
2426 SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
2427
2428#if (CPX_VERSION == 12070000)
2429 {
2430 int scaling;
2431 /* due to a bug in CPLEX 12.7.0 we need to disable scaling */
2432 CHECK_ZERO( lpi->messagehdlr, CPXgetintparam(lpi->cpxenv, CPX_PARAM_SCAIND, &scaling) );
2433 assert( scaling == -1 );
2434 }
2435#endif
2436
2437 SCIPdebugMessage("calling CPXdualopt()\n");
2438 retval = CPXdualopt(lpi->cpxenv, lpi->cpxlp);
2439 switch( retval )
2440 {
2441 case 0:
2442 break;
2443 case CPXERR_NO_MEMORY:
2444 return SCIP_NOMEMORY;
2445 default:
2446 return SCIP_LPERROR;
2447 }
2448
2449 lpi->solstat = CPXgetstat(lpi->cpxenv, lpi->cpxlp);
2450 lpi->method = CPX_ALG_DUAL;
2452
2453 /* CPLEX outputs an error if the status is CPX_STAT_INForUNBD and the iterations are determined */
2454 CHECK_ZERO( lpi->messagehdlr, CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, &solntype, &primalfeasible, &dualfeasible) );
2455 if( lpi->solstat != CPX_STAT_INForUNBD && solntype != CPX_NO_SOLN )
2456 lpi->iterations = CPXgetphase1cnt(lpi->cpxenv, lpi->cpxlp) + CPXgetitcnt(lpi->cpxenv, lpi->cpxlp);
2457 else
2458 lpi->iterations = 0;
2459
2460 SCIPdebugMessage(" -> CPLEX returned solstat=%d, pfeas=%d, dfeas=%d (%d iterations)\n",
2461 lpi->solstat, primalfeasible, dualfeasible, lpi->iterations);
2462
2463 if( lpi->solstat == CPX_STAT_INForUNBD
2464 || (lpi->solstat == CPX_STAT_INFEASIBLE && !dualfeasible)
2465 || (lpi->solstat == CPX_STAT_UNBOUNDED && !primalfeasible) )
2466 {
2467 if( getIntParam(lpi, CPX_PARAM_PREIND) == CPX_ON )
2468 {
2469 /* maybe the preprocessor solved the problem; but we need a solution, so solve again without preprocessing */
2470 SCIPdebugMessage("presolver may have solved the problem -> calling CPLEX dual simplex again without presolve\n");
2471
2472 /* switch off preprocessing */
2473 setIntParam(lpi, CPX_PARAM_PREIND, CPX_OFF);
2474 SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
2475
2476 retval = CPXdualopt(lpi->cpxenv, lpi->cpxlp);
2477 switch( retval )
2478 {
2479 case 0:
2480 break;
2481 case CPXERR_NO_MEMORY:
2482 return SCIP_NOMEMORY;
2483 default:
2484 return SCIP_LPERROR;
2485 }
2486
2487 lpi->solstat = CPXgetstat(lpi->cpxenv, lpi->cpxlp);
2489 assert( lpi->solstat != CPX_STAT_INForUNBD );
2490
2491 lpi->iterations += CPXgetphase1cnt(lpi->cpxenv, lpi->cpxlp) + CPXgetitcnt(lpi->cpxenv, lpi->cpxlp);
2492 CHECK_ZERO( lpi->messagehdlr, CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, &solntype, NULL, NULL) );
2493
2494 SCIPdebugMessage(" -> CPLEX returned solstat=%d (%d iterations)\n", lpi->solstat, lpi->iterations);
2495
2496 /* switch on preprocessing again */
2497 setIntParam(lpi, CPX_PARAM_PREIND, CPX_ON);
2498 }
2499
2500 if( lpi->solstat == CPX_STAT_INForUNBD )
2501 {
2502 /* preprocessing was not the problem; issue a warning message and treat LP as infeasible */
2503 SCIPerrorMessage("CPLEX dual simplex returned CPX_STAT_INForUNBD after presolving was turned off\n");
2504 }
2505 }
2506
2507 /* check whether the solution is basic: if Cplex, e.g., hits a time limit in data setup, this might not be the case,
2508 * also for some pathological cases of infeasibility, e.g., contradictory bounds
2509 */
2510 lpi->solisbasic = (solntype == CPX_BASIC_SOLN);
2511 assert( lpi->solisbasic || lpi->solstat != CPX_STAT_OPTIMAL );
2512
2513#ifdef SCIP_DISABLED_CODE
2514 /* this fixes the strange behavior of CPLEX, that in case of the objective limit exceedance, it returns the
2515 * solution for the basis preceeding the one with exceeding objective limit
2516 * (using this "wrong" dual solution can cause column generation algorithms to fail to find an improving column)
2517 */
2518 if( SCIPlpiIsObjlimExc(lpi) )
2519 {
2520 SCIP_Real objval;
2521 SCIP_Real llim;
2522 SCIP_Real ulim;
2523 SCIP_Real eps;
2524
2525 /* check, if the dual solution returned by CPLEX really exceeds the objective limit;
2526 * CPLEX usually returns the basis one iteration before the one that exceeds the limit
2527 */
2528 SCIP_CALL( SCIPlpiGetObjval(lpi, &objval) );
2529 llim = getDblParam(lpi, CPX_PARAM_OBJLLIM);
2530 ulim = getDblParam(lpi, CPX_PARAM_OBJULIM);
2531 eps = getDblParam(lpi, CPX_PARAM_EPOPT);
2532 if( objval >= llim - eps && objval <= ulim + eps )
2533 {
2534 int itlim;
2535 int advind;
2536
2537 /* perform one additional simplex iteration without objective limit */
2538 SCIPdebugMessage("dual solution %g does not exceed objective limit [%g,%g] (%d iterations) -> calling CPLEX dual simplex again for one iteration\n",
2539 objval, llim, ulim, lpi->iterations);
2540 itlim = getIntParam(lpi, CPX_PARAM_ITLIM);
2541 setIntParam(lpi, CPX_PARAM_ITLIM, 1);
2542 advind = getIntParam(lpi, CPX_PARAM_ADVIND);
2543 setIntParam(lpi, CPX_PARAM_ADVIND, CPX_ON);
2544 setDblParam(lpi, CPX_PARAM_OBJLLIM, -CPX_INFBOUND);
2545 setDblParam(lpi, CPX_PARAM_OBJULIM, CPX_INFBOUND);
2546 SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
2547 CHECK_ZERO( lpi->messagehdlr, CPXsetintparam(lpi->cpxenv, CPX_PARAM_FINALFACTOR, FALSE) );
2548
2549 retval = CPXdualopt(lpi->cpxenv, lpi->cpxlp);
2550 switch( retval )
2551 {
2552 case 0:
2553 break;
2554 case CPXERR_NO_MEMORY:
2555 return SCIP_NOMEMORY;
2556 default:
2557 return SCIP_LPERROR;
2558 }
2559
2560 lpi->iterations += CPXgetphase1cnt(lpi->cpxenv, lpi->cpxlp) + CPXgetitcnt(lpi->cpxenv, lpi->cpxlp);
2561
2562 /* reset the iteration limit and objective bounds */
2563 setIntParam(lpi, CPX_PARAM_ITLIM, itlim);
2564 setIntParam(lpi, CPX_PARAM_ADVIND, advind);
2565 setDblParam(lpi, CPX_PARAM_OBJLLIM, llim);
2566 setDblParam(lpi, CPX_PARAM_OBJULIM, ulim);
2567 SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
2568 CHECK_ZERO( lpi->messagehdlr, CPXsetintparam(lpi->cpxenv, CPX_PARAM_FINALFACTOR, TRUE) );
2569
2570 /* resolve LP again in order to restore the status of exceeded objective limit */
2571 retval = CPXdualopt(lpi->cpxenv, lpi->cpxlp);
2572 switch( retval )
2573 {
2574 case 0:
2575 break;
2576 case CPXERR_NO_MEMORY:
2577 return SCIP_NOMEMORY;
2578 default:
2579 return SCIP_LPERROR;
2580 }
2581
2582 lpi->iterations += CPXgetphase1cnt(lpi->cpxenv, lpi->cpxlp) + CPXgetitcnt(lpi->cpxenv, lpi->cpxlp);
2583 lpi->solstat = CPXgetstat(lpi->cpxenv, lpi->cpxlp);
2585 SCIPdebugMessage(" -> CPLEX returned solstat=%d (%d iterations)\n", lpi->solstat, lpi->iterations);
2586 }
2587 }
2588#endif
2589
2590 return SCIP_OKAY;
2591}
2592
2593/** calls barrier or interior point algorithm to solve the LP with crossover to simplex basis */
2595 SCIP_LPI* lpi, /**< LP interface structure */
2596 SCIP_Bool crossover /**< perform crossover */
2597 )
2598{
2599 int solntype;
2600 int retval;
2601
2602 assert(lpi != NULL);
2603 assert(lpi->cpxlp != NULL);
2604 assert(lpi->cpxenv != NULL);
2605
2606 SCIPdebugMessage("calling CPLEX barrier: %d cols, %d rows\n",
2607 CPXgetnumcols(lpi->cpxenv, lpi->cpxlp), CPXgetnumrows(lpi->cpxenv, lpi->cpxlp));
2608
2609 invalidateSolution(lpi);
2610
2611 setIntParam(lpi, CPX_PARAM_ADVIND, lpi->fromscratch || lpi->clearstate ? CPX_OFF : CPX_ON);
2612 lpi->clearstate = FALSE;
2613
2614 SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
2615
2616 SCIPdebugMessage("calling CPXhybaropt()\n");
2617 retval = CPXhybbaropt(lpi->cpxenv, lpi->cpxlp, crossover ? 0 : CPX_ALG_NONE);
2618 switch( retval )
2619 {
2620 case 0:
2621 break;
2622 case CPXERR_NO_MEMORY:
2623 return SCIP_NOMEMORY;
2624 default:
2625 return SCIP_LPERROR;
2626 }
2627
2628 CHECK_ZERO( lpi->messagehdlr, CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, &solntype, NULL, NULL) );
2629
2630 lpi->solisbasic = (solntype == CPX_BASIC_SOLN);
2631 lpi->solstat = CPXgetstat(lpi->cpxenv, lpi->cpxlp);
2632 lpi->method = CPX_ALG_BARRIER;
2634
2635 if( lpi->solstat != CPX_STAT_INForUNBD && solntype != CPX_NO_SOLN )
2636 lpi->iterations = CPXgetbaritcnt(lpi->cpxenv, lpi->cpxlp);
2637 else
2638 lpi->iterations = 0;
2639
2640 SCIPdebugMessage(" -> CPLEX returned solstat=%d (%d iterations)\n", lpi->solstat, lpi->iterations);
2641
2642 if( lpi->solstat == CPX_STAT_INForUNBD )
2643 {
2644 /* maybe the preprocessor solved the problem; but we need a solution, so solve again without preprocessing */
2645 SCIPdebugMessage("CPLEX returned INForUNBD -> calling CPLEX barrier again without presolve\n");
2646
2647 /* switch off preprocessing */
2648 setIntParam(lpi, CPX_PARAM_PREIND, CPX_OFF);
2649 SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
2650
2651 retval = CPXhybbaropt(lpi->cpxenv, lpi->cpxlp, crossover ? 0 : CPX_ALG_NONE);
2652 switch( retval )
2653 {
2654 case 0:
2655 break;
2656 case CPXERR_NO_MEMORY:
2657 return SCIP_NOMEMORY;
2658 default:
2659 return SCIP_LPERROR;
2660 }
2661
2662 CHECK_ZERO( lpi->messagehdlr, CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, &solntype, NULL, NULL) );
2663
2664 lpi->solisbasic = (solntype == CPX_BASIC_SOLN);
2665 lpi->solstat = CPXgetstat(lpi->cpxenv, lpi->cpxlp);
2667
2668 lpi->iterations += CPXgetbaritcnt(lpi->cpxenv, lpi->cpxlp);
2669 SCIPdebugMessage(" -> CPLEX returned solstat=%d\n", lpi->solstat);
2670
2671 setIntParam(lpi, CPX_PARAM_PREIND, CPX_ON);
2672
2673 if( lpi->solstat == CPX_STAT_INForUNBD )
2674 {
2675 /* if we could not resolve CPX_STAT_INForUNBD, we use the dual simplex */
2677 }
2678 }
2679
2680 return SCIP_OKAY;
2681}
2682
2683/** manually performs strong branching on one integral variable */
2684static
2686 SCIP_LPI* lpi, /**< LP interface structure */
2687 int col, /**< column to apply strong branching on */
2688 SCIP_Real psol, /**< current integral primal solution value of column */
2689 int itlim, /**< iteration limit for strong branchings */
2690 SCIP_Real* down, /**< stores dual bound after branching column down */
2691 SCIP_Real* up, /**< stores dual bound after branching column up */
2692 SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
2693 * otherwise, it can only be used as an estimate value */
2694 SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
2695 * otherwise, it can only be used as an estimate value */
2696 int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
2697 )
2698{
2699 const char lbound = 'L';
2700 const char ubound = 'U';
2701 SCIP_Real oldlb;
2702 SCIP_Real oldub;
2703 SCIP_Real newlb;
2704 SCIP_Real newub;
2705 int objsen;
2706 int olditlim;
2707 int it;
2708
2709 SCIPdebugMessage(" -> strong branching on integral variable %d\n", col);
2710
2711 assert( EPSISINT(psol, lpi->feastol) );
2712
2713 objsen = CPXgetobjsen(lpi->cpxenv, lpi->cpxlp);
2714
2715 /* results of CPLEX are valid in any case */
2716 *downvalid = TRUE;
2717 *upvalid = TRUE;
2718
2719 /* save current LP basis and bounds*/
2720 SCIP_CALL( getBase(lpi) );
2721 CHECK_ZERO( lpi->messagehdlr, CPXgetlb(lpi->cpxenv, lpi->cpxlp, &oldlb, col, col) );
2722 CHECK_ZERO( lpi->messagehdlr, CPXgetub(lpi->cpxenv, lpi->cpxlp, &oldub, col, col) );
2723
2724 /* save old iteration limit and set iteration limit to strong branching limit */
2725 if( itlim > CPX_INT_MAX )
2726 itlim = CPX_INT_MAX;
2727 olditlim = getIntParam(lpi, CPX_PARAM_ITLIM);
2728 setIntParam(lpi, CPX_PARAM_ITLIM, itlim);
2729
2730 /* down branch */
2731 newub = EPSCEIL(psol-1.0, lpi->feastol);
2732 if( newub >= oldlb - 0.5 )
2733 {
2734 CHECK_ZERO( lpi->messagehdlr, CPXchgbds(lpi->cpxenv, lpi->cpxlp, 1, &col, &ubound, &newub) );
2737 *down = objsen == CPX_MIN ? getDblParam(lpi, CPX_PARAM_OBJULIM) : getDblParam(lpi, CPX_PARAM_OBJLLIM);
2738 else if( SCIPlpiIsOptimal(lpi) || SCIPlpiIsIterlimExc(lpi) )
2739 {
2740 SCIP_CALL( SCIPlpiGetObjval(lpi, down) );
2741 }
2742 else
2743 *down = objsen == CPX_MIN ? getDblParam(lpi, CPX_PARAM_OBJLLIM) : getDblParam(lpi, CPX_PARAM_OBJULIM);
2744 if( iter != NULL )
2745 {
2746 SCIP_CALL( SCIPlpiGetIterations(lpi, &it) );
2747 *iter += it;
2748 }
2749 SCIPdebugMessage(" -> down (x%d <= %g): %g\n", col, newub, *down);
2750
2751 CHECK_ZERO( lpi->messagehdlr, CPXchgbds(lpi->cpxenv, lpi->cpxlp, 1, &col, &ubound, &oldub) );
2752 SCIP_CALL( setBase(lpi) );
2753 }
2754 else
2755 *down = objsen == CPX_MIN ? getDblParam(lpi, CPX_PARAM_OBJULIM) : getDblParam(lpi, CPX_PARAM_OBJLLIM);
2756
2757 /* up branch */
2758 newlb = EPSFLOOR(psol+1.0, lpi->feastol);
2759 if( newlb <= oldub + 0.5 )
2760 {
2761 CHECK_ZERO( lpi->messagehdlr, CPXchgbds(lpi->cpxenv, lpi->cpxlp, 1, &col, &lbound, &newlb) );
2764 *up = objsen == CPX_MIN ? getDblParam(lpi, CPX_PARAM_OBJULIM) : getDblParam(lpi, CPX_PARAM_OBJLLIM);
2765 else if( SCIPlpiIsOptimal(lpi) || SCIPlpiIsIterlimExc(lpi) )
2766 {
2767 SCIP_CALL( SCIPlpiGetObjval(lpi, up) );
2768 }
2769 else
2770 *up = objsen == CPX_MIN ? getDblParam(lpi, CPX_PARAM_OBJLLIM) : getDblParam(lpi, CPX_PARAM_OBJULIM);
2771 if( iter != NULL )
2772 {
2773 SCIP_CALL( SCIPlpiGetIterations(lpi, &it) );
2774 *iter += it;
2775 }
2776 SCIPdebugMessage(" -> up (x%d >= %g): %g\n", col, newlb, *up);
2777
2778 CHECK_ZERO( lpi->messagehdlr, CPXchgbds(lpi->cpxenv, lpi->cpxlp, 1, &col, &lbound, &oldlb) );
2779 SCIP_CALL( setBase(lpi) );
2780 }
2781 else
2782 *up = objsen == CPX_MIN ? getDblParam(lpi, CPX_PARAM_OBJLLIM) : getDblParam(lpi, CPX_PARAM_OBJULIM);
2783
2784 /* reset iteration limit */
2785 setIntParam(lpi, CPX_PARAM_ITLIM, olditlim);
2786
2787 return SCIP_OKAY;
2788}
2789
2790/** start strong branching */
2792 SCIP_LPI* lpi /**< LP interface structure */
2793 )
2794{ /*lint --e{715}*/
2795 assert(lpi != NULL);
2796 assert(lpi->cpxlp != NULL);
2797 assert(lpi->cpxenv != NULL);
2798
2799 /* no work necessary */
2800 return SCIP_OKAY;
2801}
2802
2803/** end strong branching */
2805 SCIP_LPI* lpi /**< LP interface structure */
2806 )
2807{ /*lint --e{715}*/
2808 assert(lpi != NULL);
2809 assert(lpi->cpxlp != NULL);
2810 assert(lpi->cpxenv != NULL);
2811
2812 /* no work necessary */
2813 return SCIP_OKAY;
2814}
2815
2816/** performs strong branching iterations on one @b fractional candidate */
2818 SCIP_LPI* lpi, /**< LP interface structure */
2819 int col, /**< column to apply strong branching on */
2820 SCIP_Real psol, /**< fractional current primal solution value of column */
2821 int itlim, /**< iteration limit for strong branchings */
2822 SCIP_Real* down, /**< stores dual bound after branching column down */
2823 SCIP_Real* up, /**< stores dual bound after branching column up */
2824 SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
2825 * otherwise, it can only be used as an estimate value */
2826 SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
2827 * otherwise, it can only be used as an estimate value */
2828 int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
2829 )
2830{
2831 int retval;
2832
2833 assert(lpi != NULL);
2834 assert(lpi->cpxlp != NULL);
2835 assert(lpi->cpxenv != NULL);
2836 assert(down != NULL);
2837 assert(up != NULL);
2838 assert(downvalid != NULL);
2839 assert(upvalid != NULL);
2840
2841 SCIPdebugMessage("calling CPLEX strongbranching on fractional variable %d (%d iterations)\n", col, itlim);
2842
2843 assert( !EPSISINT(psol, lpi->feastol) );
2844
2845 /* results of CPLEX are valid in any case */
2846 *downvalid = TRUE;
2847 *upvalid = TRUE;
2848
2849 setIntParam(lpi, CPX_PARAM_ADVIND, lpi->fromscratch || lpi->clearstate ? CPX_OFF : CPX_ON);
2850 lpi->clearstate = FALSE;
2851
2852 SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
2853
2854 retval = CPXstrongbranch(lpi->cpxenv, lpi->cpxlp, &col, 1, down, up, itlim);
2855 if( retval == CPXERR_NEED_OPT_SOLN )
2856 {
2857 SCIPdebugMessage(" -> no optimal solution available\n");
2858 return SCIP_LPERROR;
2859 }
2860 else if( retval == CPXERR_TILIM_STRONGBRANCH )
2861 {
2862 SCIPdebugMessage(" -> time limit exceeded during strong branching\n");
2863 return SCIP_LPERROR;
2864 }
2865 else if( retval == CPXERR_SINGULAR )
2866 {
2867 SCIPdebugMessage(" -> numerical troubles (basis singular)\n");
2868 return SCIP_LPERROR;
2869 }
2870 CHECK_ZERO( lpi->messagehdlr, retval );
2871 SCIPdebugMessage(" -> down: %g, up:%g\n", *down, *up);
2872
2873 /* CPLEX is not able to return the iteration counts in strong branching */
2874 if( iter != NULL )
2875 *iter = -1;
2876
2877 return SCIP_OKAY;
2878}
2879
2880/** performs strong branching iterations on given @b fractional candidates */
2882 SCIP_LPI* lpi, /**< LP interface structure */
2883 int* cols, /**< columns to apply strong branching on */
2884 int ncols, /**< number of columns */
2885 SCIP_Real* psols, /**< fractional current primal solution values of columns */
2886 int itlim, /**< iteration limit for strong branchings */
2887 SCIP_Real* down, /**< stores dual bounds after branching columns down */
2888 SCIP_Real* up, /**< stores dual bounds after branching columns up */
2889 SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds;
2890 * otherwise, they can only be used as an estimate values */
2891 SCIP_Bool* upvalid, /**< stores whether the returned up values are a valid dual bounds;
2892 * otherwise, they can only be used as an estimate values */
2893 int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
2894 )
2895{
2896 int retval;
2897 int j;
2898
2899 assert(lpi != NULL);
2900 assert(lpi->cpxlp != NULL);
2901 assert(lpi->cpxenv != NULL);
2902 assert(cols != NULL);
2903 assert(psols != NULL);
2904 assert(down != NULL);
2905 assert(up != NULL);
2906 assert(downvalid != NULL);
2907 assert(upvalid != NULL);
2908
2909 SCIPdebugMessage("calling CPLEX strongbranching on %d fractional variables (%d iterations)\n", ncols, itlim);
2910
2911 setIntParam(lpi, CPX_PARAM_ADVIND, lpi->fromscratch || lpi->clearstate ? CPX_OFF : CPX_ON);
2912 lpi->clearstate = FALSE;
2913
2914 SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
2915
2916 /* initialize */
2917 for( j = 0; j < ncols; ++j )
2918 {
2919 /* results of CPLEX are valid in any case */
2920 downvalid[j] = TRUE;
2921 upvalid[j] = TRUE;
2922
2923 assert( !EPSISINT(psols[j], lpi->feastol) );
2924 }
2925
2926 retval = CPXstrongbranch(lpi->cpxenv, lpi->cpxlp, cols, ncols, down, up, itlim);
2927 if( retval == CPXERR_NEED_OPT_SOLN )
2928 {
2929 SCIPdebugMessage(" -> no optimal solution available\n");
2930 return SCIP_LPERROR;
2931 }
2932 else if( retval == CPXERR_TILIM_STRONGBRANCH )
2933 {
2934 SCIPdebugMessage(" -> time limit exceeded during strong branching\n");
2935 return SCIP_LPERROR;
2936 }
2937 CHECK_ZERO( lpi->messagehdlr, retval );
2938
2939 /* CPLEX is not able to return the iteration counts in strong branching */
2940 if( iter != NULL )
2941 *iter = -1;
2942
2943 return SCIP_OKAY;
2944}
2945
2946/** performs strong branching iterations on one candidate with @b integral value */
2948 SCIP_LPI* lpi, /**< LP interface structure */
2949 int col, /**< column to apply strong branching on */
2950 SCIP_Real psol, /**< current integral primal solution value of column */
2951 int itlim, /**< iteration limit for strong branchings */
2952 SCIP_Real* down, /**< stores dual bound after branching column down */
2953 SCIP_Real* up, /**< stores dual bound after branching column up */
2954 SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
2955 * otherwise, it can only be used as an estimate value */
2956 SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
2957 * otherwise, it can only be used as an estimate value */
2958 int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
2959 )
2960{
2961 assert(lpi != NULL);
2962 assert(lpi->cpxlp != NULL);
2963 assert(down != NULL);
2964 assert(up != NULL);
2965 assert(downvalid != NULL);
2966 assert(upvalid != NULL);
2967
2968 SCIPdebugMessage("calling CPLEX strongbranching on variable %d with integral value (%d iterations)\n", col, itlim);
2969
2970 assert( EPSISINT(psol, lpi->feastol) );
2971
2972 if( iter != NULL )
2973 *iter = 0;
2974
2975 SCIP_CALL( lpiStrongbranchIntegral(lpi, col, psol, itlim, down, up, downvalid, upvalid, iter) );
2976
2977 return SCIP_OKAY;
2978}
2979
2980/** performs strong branching iterations on given candidates with @b integral values */
2982 SCIP_LPI* lpi, /**< LP interface structure */
2983 int* cols, /**< columns to apply strong branching on */
2984 int ncols, /**< number of columns */
2985 SCIP_Real* psols, /**< current integral primal solution values of columns */
2986 int itlim, /**< iteration limit for strong branchings */
2987 SCIP_Real* down, /**< stores dual bounds after branching columns down */
2988 SCIP_Real* up, /**< stores dual bounds after branching columns up */
2989 SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds;
2990 * otherwise, they can only be used as an estimate values */
2991 SCIP_Bool* upvalid, /**< stores whether the returned up values are a valid dual bounds;
2992 * otherwise, they can only be used as an estimate values */
2993 int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
2994 )
2995{
2996 int j;
2997
2998 assert(lpi != NULL);
2999 assert(lpi->cpxlp != NULL);
3000 assert(cols != NULL);
3001 assert(psols != NULL);
3002 assert(down != NULL);
3003 assert(up != NULL);
3004 assert(downvalid != NULL);
3005 assert(upvalid != NULL);
3006
3007 SCIPdebugMessage("calling CPLEX strongbranching on %d variables with integer values (%d iterations)\n", ncols, itlim);
3008
3009 if( iter != NULL )
3010 *iter = 0;
3011
3012 /* initialize */
3013 for( j = 0; j < ncols; ++j )
3014 {
3015 assert( EPSISINT(psols[j], lpi->feastol) );
3016 SCIP_CALL( lpiStrongbranchIntegral(lpi, cols[j], psols[j], itlim, &(down[j]), &(up[j]), &(downvalid[j]), &(upvalid[j]), iter) );
3017 }
3018
3019 return SCIP_OKAY;
3020}
3021/**@} */
3022
3023
3024
3025
3026/*
3027 * Solution Information Methods
3028 */
3029
3030/**@name Solution Information Methods */
3031/**@{ */
3032
3033/** returns whether a solve method was called after the last modification of the LP */
3035 SCIP_LPI* lpi /**< LP interface structure */
3036 )
3037{
3038 assert(lpi != NULL);
3039 assert(lpi->cpxlp != NULL);
3040 assert(lpi->cpxenv != NULL);
3041
3042 return (lpi->solstat != -1);
3043}
3044
3045/** gets information about primal and dual feasibility of the current LP solution
3046 *
3047 * The feasibility information is with respect to the last solving call and it is only relevant if SCIPlpiWasSolved()
3048 * returns true. If the LP is changed, this information might be invalidated.
3049 *
3050 * Note that @a primalfeasible and @a dualfeasible should only return true if the solver has proved the respective LP to
3051 * be feasible. Thus, the return values should be equal to the values of SCIPlpiIsPrimalFeasible() and
3052 * SCIPlpiIsDualFeasible(), respectively. Note that if feasibility cannot be proved, they should return false (even if
3053 * the problem might actually be feasible).
3054 */
3056 SCIP_LPI* lpi, /**< LP interface structure */
3057 SCIP_Bool* primalfeasible, /**< pointer to store primal feasibility status */
3058 SCIP_Bool* dualfeasible /**< pointer to store dual feasibility status */
3059 )
3060{
3061 int pfeas;
3062 int dfeas;
3063
3064 assert(lpi != NULL);
3065 assert(lpi->cpxlp != NULL);
3066 assert(lpi->cpxenv != NULL);
3067 assert(primalfeasible != NULL);
3068 assert(dualfeasible != NULL);
3069
3070 SCIPdebugMessage("getting solution feasibility\n");
3071
3072 CHECK_ZERO( lpi->messagehdlr, CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, NULL, &pfeas, &dfeas) );
3073 *primalfeasible = (SCIP_Bool)pfeas;
3074 *dualfeasible = (SCIP_Bool)dfeas;
3075
3076 return SCIP_OKAY;
3077}
3078
3079/** returns TRUE iff LP is proven to have a primal unbounded ray (but not necessary a primal feasible point);
3080 * this does not necessarily mean, that the solver knows and can return the primal ray
3081 */
3083 SCIP_LPI* lpi /**< LP interface structure */
3084 )
3085{
3086 assert(lpi != NULL);
3087 assert(lpi->cpxlp != NULL);
3088 assert(lpi->solstat >= 0);
3089
3090 return (lpi->solstat == CPX_STAT_UNBOUNDED || lpi->solstat == CPX_STAT_OPTIMAL_FACE_UNBOUNDED);
3091}
3092
3093/** returns TRUE iff LP is proven to have a primal unbounded ray (but not necessary a primal feasible point),
3094 * and the solver knows and can return the primal ray
3095 */
3097 SCIP_LPI* lpi /**< LP interface structure */
3098 )
3099{
3100 assert(lpi != NULL);
3101 assert(lpi->cpxlp != NULL);
3102 assert(lpi->cpxenv != NULL);
3103 assert(lpi->solstat >= 0);
3104
3105 return (lpi->solstat == CPX_STAT_UNBOUNDED );
3106}
3107
3108/** returns TRUE iff LP is proven to be primal unbounded */
3110 SCIP_LPI* lpi /**< LP interface structure */
3111 )
3112{
3113 int primalfeasible;
3114
3115 assert(lpi != NULL);
3116 assert(lpi->cpxlp != NULL);
3117 assert(lpi->cpxenv != NULL);
3118 assert(lpi->solstat >= 0);
3119
3120 SCIPdebugMessage("checking for primal unboundedness\n");
3121
3122 ABORT_ZERO( CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, NULL, &primalfeasible, NULL) );
3123
3124 /* If the solution status of CPLEX is CPX_STAT_UNBOUNDED, it only means, there is an unbounded ray,
3125 * but not necessarily a feasible primal solution. If primalfeasible == FALSE, we cannot conclude,
3126 * that the problem is unbounded.
3127 */
3128 return ((primalfeasible && (lpi->solstat == CPX_STAT_UNBOUNDED || lpi->solstat == CPX_STAT_INForUNBD))
3129 || lpi->solstat == CPX_STAT_OPTIMAL_FACE_UNBOUNDED || (primalfeasible && lpi->solstat == CPX_STAT_ABORT_PRIM_OBJ_LIM && lpi->method == CPX_ALG_BARRIER));
3130}
3131
3132/** returns TRUE iff LP is proven to be primal infeasible */
3134 SCIP_LPI* lpi /**< LP interface structure */
3135 )
3136{
3137 int dualfeasible;
3138
3139 assert(lpi != NULL);
3140 assert(lpi->cpxlp != NULL);
3141 assert(lpi->cpxenv != NULL);
3142 assert(lpi->solstat >= 0);
3143
3144 SCIPdebugMessage("checking for primal infeasibility\n");
3145
3146 ABORT_ZERO( CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, NULL, NULL, &dualfeasible) );
3147
3148 return (lpi->solstat == CPX_STAT_INFEASIBLE || (lpi->solstat == CPX_STAT_INForUNBD && dualfeasible)
3149 || (lpi->solstat == CPX_STAT_ABORT_DUAL_OBJ_LIM && lpi->method == CPX_ALG_BARRIER));
3150}
3151
3152/** returns TRUE iff LP is proven to be primal feasible */
3154 SCIP_LPI* lpi /**< LP interface structure */
3155 )
3156{
3157 int primalfeasible;
3158
3159 assert(lpi != NULL);
3160 assert(lpi->cpxlp != NULL);
3161 assert(lpi->cpxenv != NULL);
3162 assert(lpi->solstat >= 0);
3163
3164 SCIPdebugMessage("checking for primal feasibility\n");
3165
3166 ABORT_ZERO( CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, NULL, &primalfeasible, NULL) );
3167
3168 return (SCIP_Bool)primalfeasible;
3169}
3170
3171/** returns TRUE iff LP is proven to have a dual unbounded ray (but not necessary a dual feasible point);
3172 * this does not necessarily mean, that the solver knows and can return the dual ray
3173 */
3175 SCIP_LPI* lpi /**< LP interface structure */
3176 )
3177{
3178 assert(lpi != NULL);
3179 assert(lpi->solstat >= 0);
3180
3181 return (lpi->solstat == CPX_STAT_INFEASIBLE);
3182}
3183
3184/** returns TRUE iff LP is proven to have a dual unbounded ray (but not necessary a dual feasible point),
3185 * and the solver knows and can return the dual ray
3186 */
3188 SCIP_LPI* lpi /**< LP interface structure */
3189 )
3190{
3191 assert(lpi != NULL);
3192 assert(lpi->cpxlp != NULL);
3193 assert(lpi->cpxenv != NULL);
3194 assert(lpi->solstat >= 0);
3195
3196 return (lpi->solstat == CPX_STAT_INFEASIBLE && lpi->method == CPX_ALG_DUAL);
3197}
3198
3199/** returns TRUE iff LP is proven to be dual unbounded */
3201 SCIP_LPI* lpi /**< LP interface structure */
3202 )
3203{
3204 int dualfeasible;
3205
3206 assert(lpi != NULL);
3207 assert(lpi->cpxlp != NULL);
3208 assert(lpi->cpxenv != NULL);
3209 assert(lpi->solstat >= 0);
3210
3211 SCIPdebugMessage("checking for dual unboundedness\n");
3212
3213 ABORT_ZERO( CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, NULL, NULL, &dualfeasible) );
3214
3215 return (dualfeasible && ((lpi->solstat == CPX_STAT_INFEASIBLE || lpi->solstat == CPX_STAT_INForUNBD)
3216 || (lpi->solstat == CPX_STAT_ABORT_DUAL_OBJ_LIM && lpi->method == CPX_ALG_BARRIER)));
3217}
3218
3219/** returns TRUE iff LP is proven to be dual infeasible */
3221 SCIP_LPI* lpi /**< LP interface structure */
3222 )
3223{
3224 int primalfeasible;
3225
3226 assert(lpi != NULL);
3227 assert(lpi->cpxlp != NULL);
3228 assert(lpi->cpxenv != NULL);
3229 assert(lpi->solstat >= 0);
3230
3231 SCIPdebugMessage("checking for dual infeasibility\n");
3232
3233 ABORT_ZERO( CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, NULL, &primalfeasible, NULL) );
3234
3235 return (lpi->solstat == CPX_STAT_UNBOUNDED
3236 || lpi->solstat == CPX_STAT_OPTIMAL_FACE_UNBOUNDED
3237 || (lpi->solstat == CPX_STAT_INForUNBD && primalfeasible)
3238 || (lpi->solstat == CPX_STAT_ABORT_PRIM_OBJ_LIM && lpi->method == CPX_ALG_BARRIER));
3239}
3240
3241/** returns TRUE iff LP is proven to be dual feasible */
3243 SCIP_LPI* lpi /**< LP interface structure */
3244 )
3245{
3246 int dualfeasible;
3247
3248 assert(lpi != NULL);
3249 assert(lpi->cpxlp != NULL);
3250 assert(lpi->cpxenv != NULL);
3251 assert(lpi->solstat >= 0);
3252
3253 SCIPdebugMessage("checking for dual feasibility\n");
3254
3255 ABORT_ZERO( CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, NULL, NULL, &dualfeasible) );
3256
3257 return (SCIP_Bool)dualfeasible;
3258}
3259
3260/** returns TRUE iff LP was solved to optimality */
3262 SCIP_LPI* lpi /**< LP interface structure */
3263 )
3264{
3265 assert(lpi != NULL);
3266 assert(lpi->solstat >= 0);
3267
3268 return (lpi->solstat == CPX_STAT_OPTIMAL);
3269}
3270
3271/** returns TRUE iff current LP solution is stable
3272 *
3273 * This function should return true if the solution is reliable, i.e., feasible and optimal (or proven
3274 * infeasible/unbounded) with respect to the original problem. The optimality status might be with respect to a scaled
3275 * version of the problem, but the solution might not be feasible to the unscaled original problem; in this case,
3276 * SCIPlpiIsStable() should return false.
3277 */
3279 SCIP_LPI* lpi /**< LP interface structure */
3280 )
3281{
3282 assert(lpi != NULL);
3283 assert(lpi->cpxlp != NULL);
3284 assert(lpi->cpxenv != NULL);
3285 assert(lpi->solstat >= 0);
3286
3287 SCIPdebugMessage("checking for stability: CPLEX solstat = %d\n", lpi->solstat);
3288
3289#ifdef SCIP_DISABLED_CODE
3290 /* The following workaround is not needed anymore for SCIP, since it tries to heuristically construct a feasible
3291 * solution or automatically resolves the problem if the status is "unbounded"; see SCIPlpGetUnboundedSol().
3292 */
3293
3294 /* If the solution status of CPLEX is CPX_STAT_UNBOUNDED, it only means, there is an unbounded ray,
3295 * but not necessarily a feasible primal solution. If primalfeasible == FALSE, we interpret this
3296 * result as instability, s.t. the problem is resolved from scratch
3297 */
3298 if( lpi->solstat == CPX_STAT_UNBOUNDED )
3299 {
3300 int primalfeasible;
3301
3302 ABORT_ZERO( CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, NULL, &primalfeasible, NULL) );
3303
3304 if( !primalfeasible )
3305 return FALSE;
3306 }
3307#endif
3308
3309 /* If the condition number of the basis should be checked, everything above the specified threshold is counted
3310 * as instable.
3311 */
3312 if( lpi->checkcondition && (SCIPlpiIsOptimal(lpi) || SCIPlpiIsObjlimExc(lpi)) )
3313 {
3314 SCIP_Real kappa;
3315 SCIP_RETCODE retcode;
3316
3318 if ( retcode != SCIP_OKAY )
3319 {
3320 SCIPABORT();
3321 return FALSE; /*lint !e527*/
3322 }
3323
3324 /* if the kappa could not be computed (e.g., because we do not have a basis), we cannot check the condition */
3325 if( kappa != SCIP_INVALID || kappa > lpi->conditionlimit ) /*lint !e777*/
3326 return FALSE;
3327 }
3328
3329 return (lpi->solstat != CPX_STAT_NUM_BEST && lpi->solstat != CPX_STAT_OPTIMAL_INFEAS);
3330}
3331
3332/** returns TRUE iff the objective limit was reached */
3334 SCIP_LPI* lpi /**< LP interface structure */
3335 )
3336{
3337 assert(lpi != NULL);
3338 assert(lpi->solstat >= 0);
3339
3340 if( lpi->solstat == CPX_STAT_ABORT_OBJ_LIM )
3341 return TRUE;
3342 else if( lpi->solstat == CPX_STAT_ABORT_DUAL_OBJ_LIM || lpi->solstat == CPX_STAT_ABORT_PRIM_OBJ_LIM )
3343 {
3344 if( lpi->method != CPX_ALG_BARRIER )
3345 return TRUE;
3346 }
3347 return FALSE;
3348}
3349
3350/** returns TRUE iff the iteration limit was reached */
3352 SCIP_LPI* lpi /**< LP interface structure */
3353 )
3354{
3355 assert(lpi != NULL);
3356 assert(lpi->solstat >= 0);
3357
3358 return (lpi->solstat == CPX_STAT_ABORT_IT_LIM);
3359}
3360
3361/** returns TRUE iff the time limit was reached */
3363 SCIP_LPI* lpi /**< LP interface structure */
3364 )
3365{
3366 assert(lpi != NULL);
3367 assert(lpi->solstat >= 0);
3368
3369 return (lpi->solstat == CPX_STAT_ABORT_TIME_LIM);
3370}
3371
3372/** returns the internal solution status of the solver */
3374 SCIP_LPI* lpi /**< LP interface structure */
3375 )
3376{
3377 assert(lpi != NULL);
3378 assert(lpi->cpxlp != NULL);
3379
3380 return lpi->solstat;
3381}
3382
3383/** tries to reset the internal status of the LP solver in order to ignore an instability of the last solving call */
3385 SCIP_LPI* lpi, /**< LP interface structure */
3386 SCIP_Bool* success /**< pointer to store, whether the instability could be ignored */
3387 )
3388{
3389 assert(lpi != NULL);
3390 assert(lpi->cpxlp != NULL);
3391 assert(success != NULL);
3392 assert(lpi->solstat == CPX_STAT_UNBOUNDED
3393 || lpi->solstat == CPX_STAT_NUM_BEST
3394 || lpi->solstat == CPX_STAT_OPTIMAL_INFEAS);
3395
3396 /* replace instable status with optimal status */
3397 if( lpi->solstat == CPX_STAT_NUM_BEST || lpi->solstat == CPX_STAT_OPTIMAL_INFEAS )
3398 lpi->solstat = CPX_STAT_OPTIMAL;
3399
3400 *success = TRUE;
3401 lpi->instabilityignored = TRUE;
3402
3403 return SCIP_OKAY;
3404}
3405
3406/** gets objective value of solution */
3408 SCIP_LPI* lpi, /**< LP interface structure */
3409 SCIP_Real* objval /**< stores the objective value */
3410 )
3411{
3412 int retcode;
3413
3414 assert(lpi != NULL);
3415 assert(lpi->cpxlp != NULL);
3416 assert(lpi->cpxenv != NULL);
3417 assert(objval != NULL);
3418
3419 SCIPdebugMessage("getting solution's objective value\n");
3420
3421 retcode = CPXgetobjval(lpi->cpxenv, lpi->cpxlp, objval);
3422
3423 /* if CPLEX has no solution, e.g., because of a reached time limit, we return -infinity */
3424 if( retcode == CPXERR_NO_SOLN )
3425 {
3426 *objval = -SCIPlpiInfinity(lpi);
3427 }
3428 else
3429 {
3430 CHECK_ZERO( lpi->messagehdlr, retcode );
3431 }
3432
3433 return SCIP_OKAY;
3434}
3435
3436/** gets primal and dual solution vectors for feasible LPs
3437 *
3438 * Before calling this function, the caller must ensure that the LP has been solved to optimality, i.e., that
3439 * SCIPlpiIsOptimal() returns true.
3440 */
3442 SCIP_LPI* lpi, /**< LP interface structure */
3443 SCIP_Real* objval, /**< stores the objective value, may be NULL if not needed */
3444 SCIP_Real* primsol, /**< primal solution vector, may be NULL if not needed */
3445 SCIP_Real* dualsol, /**< dual solution vector, may be NULL if not needed */
3446 SCIP_Real* activity, /**< row activity vector, may be NULL if not needed */
3447 SCIP_Real* redcost /**< reduced cost vector, may be NULL if not needed */
3448 )
3449{
3450 int dummy;
3451
3452 assert(lpi != NULL);
3453 assert(lpi->cpxlp != NULL);
3454 assert(lpi->cpxenv != NULL);
3455 assert(lpi->solstat >= 0);
3456
3457 SCIPdebugMessage("getting solution\n");
3458
3459 CHECK_ZERO( lpi->messagehdlr, CPXsolution(lpi->cpxenv, lpi->cpxlp, &dummy, objval, primsol, dualsol, NULL, redcost) );
3460 assert(dummy == lpi->solstat || lpi->instabilityignored);
3461
3462 if( activity != NULL )
3463 {
3464 CHECK_ZERO( lpi->messagehdlr, CPXgetax(lpi->cpxenv, lpi->cpxlp, activity, 0, CPXgetnumrows(lpi->cpxenv, lpi->cpxlp)-1) );
3465 }
3466
3467 return SCIP_OKAY;
3468}
3469
3470/** gets primal ray for unbounded LPs */
3472 SCIP_LPI* lpi, /**< LP interface structure */
3473 SCIP_Real* ray /**< primal ray */
3474 )
3475{
3476 assert(lpi != NULL);
3477 assert(lpi->cpxlp != NULL);
3478 assert(lpi->cpxenv != NULL);
3479 assert(lpi->solstat >= 0);
3480 assert(ray != NULL);
3481
3482 SCIPdebugMessage("calling CPLEX get primal ray: %d cols, %d rows\n",
3483 CPXgetnumcols(lpi->cpxenv, lpi->cpxlp), CPXgetnumrows(lpi->cpxenv, lpi->cpxlp));
3484
3485 CHECK_ZERO( lpi->messagehdlr, CPXgetray(lpi->cpxenv, lpi->cpxlp, ray) );
3486
3487 return SCIP_OKAY;
3488}
3489
3490/** gets dual Farkas proof for infeasibility */
3492 SCIP_LPI* lpi, /**< LP interface structure */
3493 SCIP_Real* dualfarkas /**< dual Farkas row multipliers */
3494 )
3495{
3496 assert(lpi != NULL);
3497 assert(lpi->cpxlp != NULL);
3498 assert(lpi->cpxenv != NULL);
3499 assert(lpi->solstat >= 0);
3500 assert(dualfarkas != NULL);
3501
3502 SCIPdebugMessage("calling CPLEX dual Farkas: %d cols, %d rows\n",
3503 CPXgetnumcols(lpi->cpxenv, lpi->cpxlp), CPXgetnumrows(lpi->cpxenv, lpi->cpxlp));
3504
3505 CHECK_ZERO( lpi->messagehdlr, CPXdualfarkas(lpi->cpxenv, lpi->cpxlp, dualfarkas, NULL) );
3506
3507 return SCIP_OKAY;
3508}
3509
3510/** gets the number of LP iterations of the last solve call */
3512 SCIP_LPI* lpi, /**< LP interface structure */
3513 int* iterations /**< pointer to store the number of iterations of the last solve call */
3514 )
3515{
3516 assert(lpi != NULL);
3517 assert(iterations != NULL);
3518
3519 *iterations = lpi->iterations;
3520
3521 return SCIP_OKAY;
3522}
3523
3524/** gets information about the quality of an LP solution
3525 *
3526 * Such information is usually only available, if also a (maybe not optimal) solution is available.
3527 * The LPI should return SCIP_INVALID for @p quality, if the requested quantity is not available.
3528 */
3530 SCIP_LPI* lpi, /**< LP interface structure */
3531 SCIP_LPSOLQUALITY qualityindicator, /**< indicates which quality should be returned */
3532 SCIP_Real* quality /**< pointer to store quality number */
3533 )
3534{
3535 int solntype;
3536
3537 assert(lpi != NULL);
3538 assert(lpi->cpxlp != NULL);
3539 assert(lpi->cpxenv != NULL);
3540 assert(quality != NULL);
3541
3542 *quality = SCIP_INVALID;
3543
3544 SCIPdebugMessage("requesting solution quality from CPLEX: quality %d\n", qualityindicator);
3545
3546 CHECK_ZERO( lpi->messagehdlr, CPXsolninfo(lpi->cpxenv, lpi->cpxlp, NULL, &solntype, NULL, NULL) );
3547
3548 if( solntype == CPX_BASIC_SOLN )
3549 {
3550 int what;
3551
3552 switch( qualityindicator )
3553 {
3555 what = CPX_KAPPA;
3556 break;
3557
3559 what = CPX_EXACT_KAPPA;
3560 break;
3561
3562 default:
3563 SCIPerrorMessage("Solution quality %d unknown.\n", qualityindicator);
3564 return SCIP_INVALIDDATA;
3565 }
3566
3567 (void) CPXgetdblquality(lpi->cpxenv, lpi->cpxlp, quality, what);
3568 }
3569
3570 return SCIP_OKAY;
3571}
3572
3573/**@} */
3574
3575
3576
3577
3578/*
3579 * LP Basis Methods
3580 */
3581
3582/**@name LP Basis Methods */
3583/**@{ */
3584
3585/** gets current basis status for columns and rows; arrays must be large enough to store the basis status */
3587 SCIP_LPI* lpi, /**< LP interface structure */
3588 int* cstat, /**< array to store column basis status, or NULL */
3589 int* rstat /**< array to store row basis status, or NULL */
3590 )
3591{
3592 int i;
3593 int nrows;
3594 char sense;
3595
3596 assert(lpi != NULL);
3597 assert(lpi->cpxlp != NULL);
3598 assert(lpi->cpxenv != NULL);
3599
3600 SCIPdebugMessage("saving CPLEX basis into %p/%p\n", (void *) cstat, (void *) rstat);
3601
3602 CHECK_ZERO( lpi->messagehdlr, CPXgetbase(lpi->cpxenv, lpi->cpxlp, cstat, rstat) );
3603
3604 /* correct rstat values for "<=" constraints: Here CPX_AT_LOWER bound means that the slack is 0, i.e., the upper bound is tight */
3605 nrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
3606 for (i = 0; i < nrows; ++i)
3607 {
3608 if ( rstat[i] == CPX_AT_LOWER )
3609 {
3610 CHECK_ZERO( lpi->messagehdlr, CPXgetsense(lpi->cpxenv, lpi->cpxlp, &sense, i, i) );
3611 if ( sense == 'L' )
3612 rstat[i] = (int) SCIP_BASESTAT_UPPER;
3613 }
3614 }
3615
3616 /* because the basis status values are equally defined in SCIP and CPLEX, they don't need to be transformed */
3617 assert((int)SCIP_BASESTAT_LOWER == CPX_AT_LOWER); /*lint !e506*/
3618 assert((int)SCIP_BASESTAT_BASIC == CPX_BASIC); /*lint !e506*/
3619 assert((int)SCIP_BASESTAT_UPPER == CPX_AT_UPPER); /*lint !e506*/
3620 assert((int)SCIP_BASESTAT_ZERO == CPX_FREE_SUPER); /*lint !e506*/
3621
3622 return SCIP_OKAY;
3623}
3624
3625/** sets current basis status for columns and rows */
3627 SCIP_LPI* lpi, /**< LP interface structure */
3628 const int* cstat, /**< array with column basis status */
3629 const int* rstat /**< array with row basis status */
3630 )
3631{
3632 int i;
3633 int nrows;
3634 int ncols;
3635 char sense;
3636
3637 assert(lpi != NULL);
3638 assert(lpi->cpxlp != NULL);
3639 assert(lpi->cpxenv != NULL);
3640
3641 SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
3642 SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
3643
3644 assert(cstat != NULL || ncols == 0);
3645 assert(rstat != NULL || nrows == 0);
3646
3647 SCIPdebugMessage("loading basis %p/%p into CPLEX\n", (void *) cstat, (void *) rstat);
3648
3649 invalidateSolution(lpi);
3650
3651 /* because the basis status values are equally defined in SCIP and CPLEX, they don't need to be transformed */
3652 assert((int)SCIP_BASESTAT_LOWER == CPX_AT_LOWER); /*lint !e506*/
3653 assert((int)SCIP_BASESTAT_BASIC == CPX_BASIC); /*lint !e506*/
3654 assert((int)SCIP_BASESTAT_UPPER == CPX_AT_UPPER); /*lint !e506*/
3655 assert((int)SCIP_BASESTAT_ZERO == CPX_FREE_SUPER); /*lint !e506*/
3656
3657 /* Copy rstat to internal structure and correct rstat values for ">=" constraints: Here CPX_AT_LOWER bound means that
3658 * the slack is 0, i.e., the upper bound is tight. */
3659 SCIP_CALL( ensureRstatMem(lpi, nrows) );
3660 for (i = 0; i < nrows; ++i)
3661 {
3662 if ( rstat[i] == (int) SCIP_BASESTAT_UPPER ) /*lint !e613*/
3663 {
3664 CHECK_ZERO( lpi->messagehdlr, CPXgetsense(lpi->cpxenv, lpi->cpxlp, &sense, i, i) );
3665 if ( sense == 'L' )
3666 lpi->rstat[i] = CPX_AT_LOWER;
3667 }
3668 else
3669 lpi->rstat[i] = rstat[i]; /*lint !e613*/
3670 }
3671
3672 CHECK_ZERO( lpi->messagehdlr, CPXcopybase(lpi->cpxenv, lpi->cpxlp, cstat, lpi->rstat) );
3673
3674 return SCIP_OKAY;
3675}
3676
3677/** returns the indices of the basic columns and rows; basic column n gives value n, basic row m gives value -1-m */
3679 SCIP_LPI* lpi, /**< LP interface structure */
3680 int* bind /**< pointer to store basis indices ready to keep number of rows entries */
3681 )
3682{
3683 int retval;
3684
3685 assert(lpi != NULL);
3686 assert(lpi->cpxlp != NULL);
3687 assert(lpi->cpxenv != NULL);
3688 assert(bind != NULL);
3689
3690 SCIPdebugMessage("getting basis information\n");
3691
3692 /* this might be turned off if the user as called SCIPlpiClearState() or set SCIP_LPPAR_FROMSCRATCH to TRUE */
3693 setIntParam(lpi, CPX_PARAM_ADVIND, CPX_ON);
3694 SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
3695
3696 retval = CPXgetbhead(lpi->cpxenv, lpi->cpxlp, bind, NULL);
3697 if( retval == CPXERR_NO_SOLN || retval == CPXERR_NO_LU_FACTOR || retval == CPXERR_NO_BASIC_SOLN || retval == CPXERR_NO_BASIS )
3698 {
3700 retval = CPXgetbhead(lpi->cpxenv, lpi->cpxlp, bind, NULL);
3701 }
3702 CHECK_ZERO( lpi->messagehdlr, retval );
3703
3704 return SCIP_OKAY;
3705}
3706
3707/** get row of inverse basis matrix B^-1
3708 *
3709 * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
3710 * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
3711 * see also the explanation in lpi.h.
3712 */ /*lint -e{715}*/
3714 SCIP_LPI* lpi, /**< LP interface structure */
3715 int r, /**< row number */
3716 SCIP_Real* coef, /**< pointer to store the coefficients of the row */
3717 int* inds, /**< array to store the non-zero indices, or NULL */
3718 int* ninds /**< pointer to store the number of non-zero indices, or NULL
3719 * (-1: if we do not store sparsity information) */
3720 )
3721{ /*lint --e{715}*/
3722 int retval;
3723 int nrows;
3724
3725 assert(lpi != NULL);
3726 assert(lpi->cpxlp != NULL);
3727 assert(lpi->cpxenv != NULL);
3728 assert(coef != NULL);
3729
3730 SCIPdebugMessage("getting binv-row %d\n", r);
3731
3732 /* can only return dense result */
3733 if ( ninds != NULL )
3734 *ninds = -1;
3735
3736 /* this might be turned off if the user as called SCIPlpiClearState() or set SCIP_LPPAR_FROMSCRATCH to TRUE */
3737 setIntParam(lpi, CPX_PARAM_ADVIND, CPX_ON);
3738 SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
3739
3740 retval = CPXbinvrow(lpi->cpxenv, lpi->cpxlp, r, coef);
3741 if( retval == CPXERR_NO_SOLN || retval == CPXERR_NO_LU_FACTOR || retval == CPXERR_NO_BASIC_SOLN || retval == CPXERR_NO_BASIS )
3742 {
3744 retval = CPXbinvrow(lpi->cpxenv, lpi->cpxlp, r, coef);
3745 }
3746 CHECK_ZERO( lpi->messagehdlr, retval );
3747
3748 /* the LPi expects slack variables with coefficient +1; CPLEX adds slack variables with a coefficient -1 for 'G'
3749 * constraints, so we have to change the sign of the corresponding rows
3750 */
3751 nrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
3752 SCIP_CALL( ensureValMem(lpi, nrows) );
3753 CHECK_ZERO( lpi->messagehdlr, CPXgetbhead(lpi->cpxenv, lpi->cpxlp, lpi->indarray, NULL) );
3754
3755 if( lpi->indarray[r] < 0 )
3756 {
3757 int basicrow;
3758 char rowsense;
3759
3760 basicrow = -lpi->indarray[r] - 1;
3761 assert(basicrow >= 0);
3762 assert(basicrow < nrows);
3763
3764 CHECK_ZERO( lpi->messagehdlr, CPXgetsense(lpi->cpxenv, lpi->cpxlp, &rowsense, basicrow, basicrow) );
3765
3766 /* slacks for 'G' and 'R' rows are added with -1 in CPLEX */
3767 if( rowsense == 'G' || rowsense == 'R' )
3768 {
3769 int i;
3770
3771 for( i = 0; i < nrows; i++ )
3772 coef[i] *= -1.0;
3773 }
3774 }
3775
3776 return SCIP_OKAY;
3777}
3778
3779/** get column of inverse basis matrix B^-1
3780 *
3781 * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
3782 * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
3783 * see also the explanation in lpi.h.
3784 */ /*lint -e{715}*/
3786 SCIP_LPI* lpi, /**< LP interface structure */
3787 int c, /**< column number of B^-1; this is NOT the number of the column in the LP;
3788 * you have to call SCIPlpiGetBasisInd() to get the array which links the
3789 * B^-1 column numbers to the row and column numbers of the LP!
3790 * c must be between 0 and nrows-1, since the basis has the size
3791 * nrows * nrows */
3792 SCIP_Real* coef, /**< pointer to store the coefficients of the column */
3793 int* inds, /**< array to store the non-zero indices, or NULL */
3794 int* ninds /**< pointer to store the number of non-zero indices, or NULL
3795 * (-1: if we do not store sparsity information) */
3796 )
3797{ /*lint --e{715}*/
3798 int retval;
3799 int nrows;
3800 int r;
3801
3802 assert(lpi != NULL);
3803 assert(lpi->cpxlp != NULL);
3804 assert(lpi->cpxenv != NULL);
3805 assert(coef != NULL);
3806
3807 SCIPdebugMessage("getting binv-col %d\n", c);
3808
3809 /* can only return dense result */
3810 if ( ninds != NULL )
3811 *ninds = -1;
3812
3813 /* this might be turned off if the user as called SCIPlpiClearState() or set SCIP_LPPAR_FROMSCRATCH to TRUE */
3814 setIntParam(lpi, CPX_PARAM_ADVIND, CPX_ON);
3815 SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
3816
3817 retval = CPXbinvcol(lpi->cpxenv, lpi->cpxlp, c, coef);
3818 if( retval == CPXERR_NO_SOLN || retval == CPXERR_NO_LU_FACTOR || retval == CPXERR_NO_BASIC_SOLN || retval == CPXERR_NO_BASIS )
3819 {
3821 retval = CPXbinvcol(lpi->cpxenv, lpi->cpxlp, c, coef);
3822 }
3823 CHECK_ZERO( lpi->messagehdlr, retval );
3824
3825 /* the LPi expects slack variables with coefficient +1; CPLEX adds slack variables with a coefficient -1 for 'G'
3826 * constraints, so we have to change the sign of the corresponding rows
3827 */
3828 nrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
3829 SCIP_CALL( ensureValMem(lpi, nrows) );
3830 CHECK_ZERO( lpi->messagehdlr, CPXgetbhead(lpi->cpxenv, lpi->cpxlp, lpi->indarray, NULL) );
3831 SCIP_CALL( ensureSidechgMem(lpi, nrows) );
3832 CHECK_ZERO( lpi->messagehdlr, CPXgetsense(lpi->cpxenv, lpi->cpxlp, lpi->senarray, 0, nrows - 1) );
3833
3834 for( r = 0; r < nrows; r++ )
3835 {
3836 if( lpi->indarray[r] < 0 )
3837 {
3838 int basicrow;
3839
3840 basicrow = -lpi->indarray[r] - 1;
3841 assert(basicrow >= 0);
3842 assert(basicrow < nrows);
3843
3844 /* slacks for 'G' and 'R' rows are added with -1 in CPLEX */
3845 if( basicrow >= 0 && basicrow < nrows && (lpi->senarray[basicrow] == 'G' || lpi->senarray[basicrow] == 'R') )
3846 coef[r] *= -1.0;
3847 }
3848 }
3849
3850 return SCIP_OKAY;
3851}
3852
3853/** get row of inverse basis matrix times constraint matrix B^-1 * A
3854 *
3855 * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
3856 * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
3857 * see also the explanation in lpi.h.
3858 */ /*lint -e{715}*/
3860 SCIP_LPI* lpi, /**< LP interface structure */
3861 int r, /**< row number */
3862 const SCIP_Real* binvrow, /**< row in (A_B)^-1 from prior call to SCIPlpiGetBInvRow(), or NULL */
3863 SCIP_Real* coef, /**< vector to return coefficients of the row */
3864 int* inds, /**< array to store the non-zero indices, or NULL */
3865 int* ninds /**< pointer to store the number of non-zero indices, or NULL
3866 * (-1: if we do not store sparsity information) */
3867 )
3868{ /*lint --e{715}*/
3869 int retval;
3870 int nrows;
3871
3872 assert(lpi != NULL);
3873 assert(lpi->cpxlp != NULL);
3874 assert(lpi->cpxenv != NULL);
3875 assert(coef != NULL);
3876
3877 SCIPdebugMessage("getting binva-row %d\n", r);
3878
3879 /* can only return dense result */
3880 if ( ninds != NULL )
3881 *ninds = -1;
3882
3883 /* this might be turned off if the user as called SCIPlpiClearState() or set SCIP_LPPAR_FROMSCRATCH to TRUE */
3884 setIntParam(lpi, CPX_PARAM_ADVIND, CPX_ON);
3885 SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
3886
3887 retval = CPXbinvarow(lpi->cpxenv, lpi->cpxlp, r, coef);
3888 if( retval == CPXERR_NO_SOLN || retval == CPXERR_NO_LU_FACTOR || retval == CPXERR_NO_BASIC_SOLN || retval == CPXERR_NO_BASIS )
3889 {
3891 retval = CPXbinvarow(lpi->cpxenv, lpi->cpxlp, r, coef);
3892 }
3893 CHECK_ZERO( lpi->messagehdlr, retval );
3894
3895 /* the LPi expects slack variables with coefficient +1; CPLEX adds slack variables with a coefficient -1 for 'G'
3896 * constraints, so we have to change the sign of the corresponding rows
3897 */
3898 nrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
3899 SCIP_CALL( ensureValMem(lpi, nrows) );
3900 CHECK_ZERO( lpi->messagehdlr, CPXgetbhead(lpi->cpxenv, lpi->cpxlp, lpi->indarray, NULL) );
3901
3902 if( lpi->indarray[r] < 0 )
3903 {
3904 int basicrow;
3905 char rowsense;
3906
3907 basicrow = -lpi->indarray[r] - 1;
3908 assert(basicrow >= 0);
3909 assert(basicrow < nrows);
3910
3911 CHECK_ZERO( lpi->messagehdlr, CPXgetsense(lpi->cpxenv, lpi->cpxlp, &rowsense, basicrow, basicrow) );
3912
3913 /* slacks for 'G' and 'R' rows are added with -1 in CPLEX */
3914 if( rowsense == 'G' || rowsense == 'R' )
3915 {
3916 int ncols;
3917 int j;
3918
3919 ncols = CPXgetnumcols(lpi->cpxenv, lpi->cpxlp);
3920 for( j = 0; j < ncols; j++ )
3921 coef[j] *= -1.0;
3922 }
3923 }
3924
3925 return SCIP_OKAY;
3926}
3927
3928/** get column of inverse basis matrix times constraint matrix B^-1 * A
3929 *
3930 * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
3931 * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
3932 * see also the explanation in lpi.h.
3933 *//*lint -e{715}*/
3935 SCIP_LPI* lpi, /**< LP interface structure */
3936 int c, /**< column number */
3937 SCIP_Real* coef, /**< vector to return coefficients of the column */
3938 int* inds, /**< array to store the non-zero indices, or NULL */
3939 int* ninds /**< pointer to store the number of non-zero indices, or NULL
3940 * (-1: if we do not store sparsity information) */
3941 )
3942{ /*lint --e{715}*/
3943 int retval;
3944 int nrows;
3945 int r;
3946
3947 assert(lpi != NULL);
3948 assert(lpi->cpxenv != NULL);
3949 assert(lpi->cpxlp != NULL);
3950 assert(coef != NULL);
3951
3952 SCIPdebugMessage("getting binva-col %d\n", c);
3953
3954 /* can only return dense result */
3955 if ( ninds != NULL )
3956 *ninds = -1;
3957
3958 /* this might be turned off if the user as called SCIPlpiClearState() or set SCIP_LPPAR_FROMSCRATCH to TRUE */
3959 setIntParam(lpi, CPX_PARAM_ADVIND, CPX_ON);
3960 SCIP_CALL( setParameterValues(lpi, &(lpi->cpxparam)) );
3961
3962 retval = CPXbinvacol(lpi->cpxenv, lpi->cpxlp, c, coef);
3963 if( retval == CPXERR_NO_SOLN || retval == CPXERR_NO_LU_FACTOR || retval == CPXERR_NO_BASIC_SOLN || retval == CPXERR_NO_BASIS )
3964 {
3966 retval = CPXbinvacol(lpi->cpxenv, lpi->cpxlp, c, coef);
3967 }
3968 CHECK_ZERO( lpi->messagehdlr, retval );
3969
3970 /* the LPi expects slack variables with coefficient +1; CPLEX adds slack variables with a coefficient -1 for 'G'
3971 * constraints, so we have to change the sign of the corresponding rows
3972 */
3973 nrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
3974 SCIP_CALL( ensureValMem(lpi, nrows) );
3975 CHECK_ZERO( lpi->messagehdlr, CPXgetbhead(lpi->cpxenv, lpi->cpxlp, lpi->indarray, NULL) );
3976 SCIP_CALL( ensureSidechgMem(lpi, nrows) );
3977 CHECK_ZERO( lpi->messagehdlr, CPXgetsense(lpi->cpxenv, lpi->cpxlp, lpi->senarray, 0, nrows - 1) );
3978
3979 for( r = 0; r < nrows; r++ )
3980 {
3981 if( lpi->indarray[r] < 0 )
3982 {
3983 int basicrow;
3984
3985 basicrow = -lpi->indarray[r] - 1;
3986 assert(basicrow >= 0);
3987 assert(basicrow < nrows);
3988
3989 /* slacks for 'G' and 'R' rows are added with -1 in CPLEX */
3990 if( basicrow >= 0 && basicrow < nrows && (lpi->senarray[basicrow] == 'G' || lpi->senarray[basicrow] == 'R') )
3991 coef[r] *= -1.0;
3992 }
3993 }
3994
3995 return SCIP_OKAY;
3996}
3997
3998/**@} */
3999
4000
4001
4002
4003/*
4004 * LP State Methods
4005 */
4006
4007/**@name LP State Methods */
4008/**@{ */
4009
4010/** stores LPi state (like basis information) into lpistate object */
4012 SCIP_LPI* lpi, /**< LP interface structure */
4013 BMS_BLKMEM* blkmem, /**< block memory */
4014 SCIP_LPISTATE** lpistate /**< pointer to LPi state information (like basis information) */
4015 )
4016{
4017 int ncols;
4018 int nrows;
4019
4020 assert(blkmem != NULL);
4021 assert(lpi != NULL);
4022 assert(lpi->cpxlp != NULL);
4023 assert(lpi->cpxenv != NULL);
4024 assert(lpistate != NULL);
4025
4026 /* if there is no basis information available (e.g. after barrier without crossover), or no state can be saved; if
4027 * SCIPlpiClearState() has been called, do not return the state
4028 */
4029 if( !lpi->solisbasic || lpi->clearstate )
4030 {
4031 *lpistate = NULL;
4032 return SCIP_OKAY;
4033 }
4034
4035 ncols = CPXgetnumcols(lpi->cpxenv, lpi->cpxlp);
4036 nrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
4037 assert(ncols >= 0);
4038 assert(nrows >= 0);
4039
4040 /* allocate lpistate data */
4041 SCIP_CALL( lpistateCreate(lpistate, blkmem, ncols, nrows) );
4042
4043 SCIPdebugMessage("storing CPLEX LPI state in %p (%d cols, %d rows)\n", (void *) *lpistate, ncols, nrows);
4044
4045 /* get unpacked basis information from CPLEX */
4046 SCIP_CALL( getBase(lpi) );
4047
4048 /* pack LPi state data */
4049 (*lpistate)->ncols = ncols;
4050 (*lpistate)->nrows = nrows;
4051 lpistatePack(*lpistate, lpi->cstat, lpi->rstat);
4052
4053 return SCIP_OKAY;
4054}
4055
4056/** loads LPi state (like basis information) into solver; note that the LP might have been extended with additional
4057 * columns and rows since the state was stored with SCIPlpiGetState()
4058 */
4060 SCIP_LPI* lpi, /**< LP interface structure */
4061 BMS_BLKMEM* blkmem, /**< block memory */
4062 const SCIP_LPISTATE* lpistate /**< LPi state information (like basis information), or NULL */
4063 )
4064{
4065 int lpncols;
4066 int lpnrows;
4067 int i;
4068
4069 assert(blkmem != NULL);
4070 assert(lpi != NULL);
4071 assert(lpi->cpxlp != NULL);
4072 assert(lpi->cpxenv != NULL);
4073
4074 /* if there was no basis information available, the LPI state was not stored */
4075 if( lpistate == NULL )
4076 return SCIP_OKAY;
4077
4078 lpncols = CPXgetnumcols(lpi->cpxenv, lpi->cpxlp);
4079 lpnrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
4080 assert(lpistate->ncols <= lpncols);
4081 assert(lpistate->nrows <= lpnrows);
4082
4083 SCIPdebugMessage("loading LPI state %p (%d cols, %d rows) into CPLEX LP with %d cols and %d rows\n",
4084 (void *) lpistate, lpistate->ncols, lpistate->nrows, lpncols, lpnrows);
4085
4086 if( lpistate->ncols == 0 || lpistate->nrows == 0 )
4087 return SCIP_OKAY;
4088
4089 /* allocate enough memory for storing uncompressed basis information */
4090 SCIP_CALL( ensureCstatMem(lpi, lpncols) );
4091 SCIP_CALL( ensureRstatMem(lpi, lpnrows) );
4092
4093 /* unpack LPi state data */
4094 lpistateUnpack(lpistate, lpi->cstat, lpi->rstat);
4095
4096 /* extend the basis to the current LP beyond the previously existing columns */
4097 for( i = lpistate->ncols; i < lpncols; ++i )
4098 {
4099 SCIP_Real bnd;
4100 CHECK_ZERO( lpi->messagehdlr, CPXgetlb(lpi->cpxenv, lpi->cpxlp, &bnd, i, i) );
4101 if ( SCIPlpiIsInfinity(lpi, REALABS(bnd)) )
4102 {
4103 /* if lower bound is +/- infinity -> try upper bound */
4104 CHECK_ZERO( lpi->messagehdlr, CPXgetub(lpi->cpxenv, lpi->cpxlp, &bnd, i, i) );
4105 if ( SCIPlpiIsInfinity(lpi, REALABS(bnd)) )
4106 lpi->cstat[i] = (int) SCIP_BASESTAT_ZERO; /* variable is free -> super basic */
4107 else
4108 lpi->cstat[i] = (int) SCIP_BASESTAT_UPPER; /* use finite upper bound */
4109 }
4110 else
4111 lpi->cstat[i] = (int) SCIP_BASESTAT_LOWER; /* use finite lower bound */
4112 }
4113 for( i = lpistate->nrows; i < lpnrows; ++i )
4114 lpi->rstat[i] = (int) SCIP_BASESTAT_BASIC;
4115
4116 /* load basis information into CPLEX */
4117 SCIP_CALL( setBase(lpi) );
4118
4119 return SCIP_OKAY;
4120}
4121
4122/** clears current LPi state (like basis information) of the solver */
4124 SCIP_LPI* lpi /**< LP interface structure */
4125 )
4126{
4127 assert(lpi != NULL);
4128
4129 /* set CPX_PARAM_ADVIND to CPX_OFF for the next solve */
4130 lpi->clearstate = TRUE;
4131
4132 return SCIP_OKAY;
4133}
4134
4135/** frees LPi state information */
4137 SCIP_LPI* lpi, /**< LP interface structure */
4138 BMS_BLKMEM* blkmem, /**< block memory */
4139 SCIP_LPISTATE** lpistate /**< pointer to LPi state information (like basis information) */
4140 )
4141{
4142 assert(lpi != NULL);
4143 assert(lpistate != NULL);
4144 assert(blkmem != NULL);
4145
4146 if( *lpistate != NULL )
4147 {
4148 lpistateFree(lpistate, blkmem);
4149 }
4150
4151 return SCIP_OKAY;
4152}
4153
4154/** checks, whether the given LP state contains simplex basis information */
4156 SCIP_LPI* lpi, /**< LP interface structure */
4157 SCIP_LPISTATE* lpistate /**< LP state information (like basis information), or NULL */
4158 )
4159{ /*lint --e{715}*/
4160 assert(lpi != NULL);
4161 return (lpistate != NULL);
4162}
4163
4164/** reads LP state (like basis information from a file */
4166 SCIP_LPI* lpi, /**< LP interface structure */
4167 const char* fname /**< file name */
4168 )
4169{
4170 assert(lpi != NULL);
4171 assert(lpi->cpxlp != NULL);
4172 assert(lpi->cpxenv != NULL);
4173 assert(fname != NULL);
4174
4175 SCIPdebugMessage("reading LP state from file <%s>\n", fname);
4176
4177 CHECK_ZERO( lpi->messagehdlr, CPXreadcopybase(lpi->cpxenv, lpi->cpxlp, fname) );
4178
4179 return SCIP_OKAY;
4180}
4181
4182/** writes LPi state (i.e. basis information) to a file */
4184 SCIP_LPI* lpi, /**< LP interface structure */
4185 const char* fname /**< file name */
4186 )
4187{
4188 assert(lpi != NULL);
4189 assert(lpi->cpxlp != NULL);
4190 assert(lpi->cpxenv != NULL);
4191 assert(fname != NULL);
4192
4193 SCIPdebugMessage("writing LP state to file <%s>\n", fname);
4194
4195 CHECK_ZERO( lpi->messagehdlr, CPXmbasewrite(lpi->cpxenv, lpi->cpxlp, fname) );
4196
4197 return SCIP_OKAY;
4198}
4199
4200/**@} */
4201
4202
4203
4204
4205/*
4206 * LP Pricing Norms Methods
4207 */
4208
4209/**@name LP Pricing Norms Methods */
4210/**@{ */
4211
4212/** stores LPi pricing norms information
4213 *
4214 * @todo store primal norms as well?
4215 */
4217 SCIP_LPI* lpi, /**< LP interface structure */
4218 BMS_BLKMEM* blkmem, /**< block memory */
4219 SCIP_LPINORMS** lpinorms /**< pointer to LPi pricing norms information */
4220 )
4221{
4222 int nrows;
4223 int retval;
4224
4225 assert(blkmem != NULL);
4226 assert(lpi != NULL);
4227 assert(lpi->cpxlp != NULL);
4228 assert(lpi->cpxenv != NULL);
4229 assert(lpi->messagehdlr != NULL);
4230 assert(lpinorms != NULL);
4231
4232 /* if there is no basis information available (e.g. after barrier without crossover), norms cannot be saved; if
4233 * SCIPlpiClearState() has been called, do not return the state
4234 */
4235 if( !lpi->solisbasic || lpi->clearstate )
4236 {
4237 *lpinorms = NULL;
4238 return SCIP_OKAY;
4239 }
4240
4241 nrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
4242 assert(nrows >= 0);
4243
4244 /* allocate lpinorms data */
4245 SCIP_ALLOC( BMSallocBlockMemory(blkmem, lpinorms) );
4246 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpinorms)->norm, nrows) );
4247 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpinorms)->head, nrows) );
4248 (*lpinorms)->normlen = 0;
4249
4250 SCIPdebugMessage("storing CPLEX LPI pricing norms in %p (%d rows)\n", (void *) *lpinorms, nrows);
4251
4252 /* get dual norms */
4253 retval = CPXgetdnorms(lpi->cpxenv, lpi->cpxlp, (*lpinorms)->norm, (*lpinorms)->head, &((*lpinorms)->normlen));
4254
4255 /* if CPLEX used the primal simplex in the last optimization call, we do not have dual norms (error 1264) */
4256 if( retval == 1264 )
4257 {
4258 /* no norms available, free lpinorms data */
4259 BMSfreeBlockMemoryArray(blkmem, &(*lpinorms)->head, nrows);
4260 BMSfreeBlockMemoryArray(blkmem, &(*lpinorms)->norm, nrows);
4261 BMSfreeBlockMemory(blkmem, lpinorms);
4262 assert(*lpinorms == NULL);
4263 }
4264 else
4265 {
4266 assert((*lpinorms)->normlen == nrows);
4267 CHECK_ZERO( lpi->messagehdlr, retval );
4268 }
4269
4270 return SCIP_OKAY;
4271}
4272
4273/** loads LPi pricing norms into solver; note that the LP might have been extended with additional
4274 * columns and rows since the state was stored with SCIPlpiGetNorms()
4275 */
4277 SCIP_LPI* lpi, /**< LP interface structure */
4278 BMS_BLKMEM* blkmem, /**< block memory */
4279 const SCIP_LPINORMS* lpinorms /**< LPi pricing norms information, or NULL */
4280 )
4281{
4282 int lpnrows;
4283
4284 assert(blkmem != NULL);
4285 assert(lpi != NULL);
4286 assert(lpi->cpxlp != NULL);
4287 assert(lpi->cpxenv != NULL);
4288
4289 /* if there was no pricing norms information available, the LPI norms were not stored */
4290 if( lpinorms == NULL )
4291 return SCIP_OKAY;
4292
4293 lpnrows = CPXgetnumrows(lpi->cpxenv, lpi->cpxlp);
4294 assert(lpinorms->normlen <= lpnrows);
4295
4296 SCIPdebugMessage("loading LPI simplex norms %p (%d rows) into CPLEX LP with %d rows\n",
4297 (void *) lpinorms, lpinorms->normlen, lpnrows);
4298
4299 if( lpinorms->normlen == 0 )
4300 return SCIP_OKAY;
4301
4302 /* load pricing norms information into CPLEX */
4303 CHECK_ZERO( lpi->messagehdlr, CPXcopydnorms(lpi->cpxenv, lpi->cpxlp, lpinorms->norm, lpinorms->head, lpinorms->normlen) );
4304
4305 return SCIP_OKAY;
4306}
4307
4308/** frees pricing norms information */
4310 SCIP_LPI* lpi, /**< LP interface structure */
4311 BMS_BLKMEM* blkmem, /**< block memory */
4312 SCIP_LPINORMS** lpinorms /**< pointer to LPi pricing norms information, or NULL */
4313 )
4314{
4315 assert(lpi != NULL);
4316 assert(lpinorms != NULL);
4317
4318 BMSfreeBlockMemoryArray(blkmem, &(*lpinorms)->head, (*lpinorms)->normlen);
4319 BMSfreeBlockMemoryArray(blkmem, &(*lpinorms)->norm, (*lpinorms)->normlen);
4320 BMSfreeBlockMemory(blkmem, lpinorms);
4321
4322 return SCIP_OKAY;
4323}
4324
4325/**@} */
4326
4327
4328
4329
4330/*
4331 * Parameter Methods
4332 */
4333
4334/**@name Parameter Methods */
4335/**@{ */
4336
4337/** gets integer parameter of LP
4338 *
4339 * CPLEX supported FASTMIP in versions up to 12.6.1. FASTMIP fastens the lp solving process but therefor it might happen
4340 * that there will be a loss in precision (because e.g. the optimal basis will not be factorized again).
4341 */
4343 SCIP_LPI* lpi, /**< LP interface structure */
4344 SCIP_LPPARAM type, /**< parameter number */
4345 int* ival /**< buffer to store the parameter value */
4346 )
4347{
4348 assert(lpi != NULL);
4349 assert(lpi->cpxlp != NULL);
4350 assert(ival != NULL);
4351
4352 SCIPdebugMessage("getting int parameter %d\n", type);
4353
4354 switch( type )
4355 {
4357 *ival = (int) lpi->fromscratch;
4358 break;
4359#if (CPX_VERSION < 12060100)
4360 case SCIP_LPPAR_FASTMIP:
4361 *ival = getIntParam(lpi, CPX_PARAM_FASTMIP);
4362 break;
4363#endif
4364 case SCIP_LPPAR_SCALING:
4365#if (CPX_VERSION <= 1100)
4366 if( lpi->rngfound )
4367 return SCIP_PARAMETERUNKNOWN;
4368#endif
4369 *ival = getIntParam(lpi, CPX_PARAM_SCAIND) + 1;
4370 break;
4372 *ival = (getIntParam(lpi, CPX_PARAM_PREIND) == CPX_ON);
4373 break;
4374 case SCIP_LPPAR_PRICING:
4375 *ival = (int)lpi->pricing; /* store pricing method in LPI struct */
4376 break;
4377 case SCIP_LPPAR_LPINFO:
4378 *ival = (getIntParam(lpi, CPX_PARAM_SCRIND) == CPX_ON);
4379 break;
4380 case SCIP_LPPAR_LPITLIM:
4381 *ival = getIntParam(lpi, CPX_PARAM_ITLIM);
4382#if (CPX_VERSION <= 1230)
4383 if( *ival >= CPX_INT_MAX )
4384 *ival = INT_MAX;
4385#endif
4386 break;
4387 case SCIP_LPPAR_THREADS:
4388#if (CPX_VERSION == 1100 || (CPX_VERSION == 1220 && (CPX_SUBVERSION == 0 || CPX_SUBVERSION == 2)))
4389 /* Due to CPLEX bug, we always set the thread count to 1. In order to fulfill an assert in lp.c, we have to
4390 * return the value set by SCIP and not the real thread count */
4391 *ival = lpi->pseudonthreads;
4392 assert(getIntParam(lpi, CPX_PARAM_THREADS) == 1);
4393#else
4394 *ival = getIntParam(lpi, CPX_PARAM_THREADS);
4395#endif
4396 break;
4397 default:
4398 return SCIP_PARAMETERUNKNOWN;
4399 } /*lint !e788*/
4400
4401 return SCIP_OKAY;
4402}
4403
4404/** sets integer parameter of LP */
4406 SCIP_LPI* lpi, /**< LP interface structure */
4407 SCIP_LPPARAM type, /**< parameter number */
4408 int ival /**< parameter value */
4409 )
4410{
4411 assert(lpi != NULL);
4412 assert(lpi->cpxlp != NULL);
4413
4414 SCIPdebugMessage("setting int parameter %d to %d\n", type, ival);
4415
4416 switch( type )
4417 {
4419 assert(ival == TRUE || ival == FALSE);
4420 lpi->fromscratch = (SCIP_Bool) ival;
4421 break;
4422#if (CPX_VERSION < 12060100)
4423 case SCIP_LPPAR_FASTMIP:
4424 assert(0 <= ival && ival <= 1);
4425 setIntParam(lpi, CPX_PARAM_FASTMIP, ival);
4426 break;
4427#endif
4428 case SCIP_LPPAR_SCALING:
4429 assert(0 <= ival && ival <= 2);
4430#if (CPX_VERSION <= 1100)
4431 if( lpi->rngfound )
4432 return SCIP_PARAMETERUNKNOWN;
4433#endif
4434 setIntParam(lpi, CPX_PARAM_SCAIND, ival - 1);
4435 break;
4437 assert(ival == TRUE || ival == FALSE);
4438 setIntParam(lpi, CPX_PARAM_PREIND, ival == TRUE ? CPX_ON : CPX_OFF);
4439 break;
4440 case SCIP_LPPAR_PRICING:
4441 lpi->pricing = (SCIP_PRICING)ival;
4442 switch( (SCIP_PRICING)ival )
4443 {
4444 case SCIP_PRICING_AUTO:
4445 setIntParam(lpi, CPX_PARAM_PPRIIND, CPX_PPRIIND_AUTO);
4446 setIntParam(lpi, CPX_PARAM_DPRIIND, CPX_DPRIIND_AUTO);
4447 break;
4448 case SCIP_PRICING_FULL:
4449 setIntParam(lpi, CPX_PARAM_PPRIIND, CPX_PPRIIND_FULL);
4450 setIntParam(lpi, CPX_PARAM_DPRIIND, CPX_DPRIIND_FULL);
4451 break;
4453 setIntParam(lpi, CPX_PARAM_PPRIIND, CPX_PPRIIND_PARTIAL);
4454 setIntParam(lpi, CPX_PARAM_DPRIIND, CPX_DPRIIND_AUTO);
4455 break;
4457 case SCIP_PRICING_STEEP:
4458 setIntParam(lpi, CPX_PARAM_PPRIIND, CPX_PPRIIND_STEEP);
4459 setIntParam(lpi, CPX_PARAM_DPRIIND, CPX_DPRIIND_STEEP);
4460 break;
4462 setIntParam(lpi, CPX_PARAM_PPRIIND, CPX_PPRIIND_STEEPQSTART);
4463 setIntParam(lpi, CPX_PARAM_DPRIIND, CPX_DPRIIND_STEEPQSTART);
4464 break;
4465#if (CPX_VERSION >= 900)
4466 case SCIP_PRICING_DEVEX:
4467 setIntParam(lpi, CPX_PARAM_PPRIIND, CPX_PPRIIND_DEVEX);
4468 setIntParam(lpi, CPX_PARAM_DPRIIND, CPX_DPRIIND_DEVEX);
4469 break;
4470#endif
4471 default:
4472 return SCIP_LPERROR;
4473 }
4474 break;
4475 case SCIP_LPPAR_LPINFO:
4476 assert(ival == TRUE || ival == FALSE);
4477 if( ival )
4478 setIntParam(lpi, CPX_PARAM_SCRIND, CPX_ON);
4479 else
4480 setIntParam(lpi, CPX_PARAM_SCRIND, CPX_OFF);
4481 break;
4482 case SCIP_LPPAR_LPITLIM:
4483 assert( ival >= 0 );
4484 /* 0 <= ival, 0 stopping immediately */
4485#if (CPX_VERSION <= 1230)
4486 ival = MIN(ival, CPX_INT_MAX);
4487#endif
4488 setIntParam(lpi, CPX_PARAM_ITLIM, ival);
4489 break;
4490 case SCIP_LPPAR_THREADS:
4491#if (CPX_VERSION == 1100 || (CPX_VERSION == 1220 && (CPX_SUBVERSION == 0 || CPX_SUBVERSION == 2)))
4492 /* Due to CPLEX bug, we always set the thread count to 1. In order to fulfill an assert in lp.c, we have to
4493 * store the value set by SCIP and return it later instead of the real thread count */
4494 lpi->pseudonthreads = ival;
4495 ival = 1;
4496#else
4497 ival = MIN(ival, CPX_INT_MAX);
4498#endif
4499 setIntParam(lpi, CPX_PARAM_THREADS, ival);
4500 break;
4502 setIntParam(lpi, CPX_PARAM_RANDOMSEED, ival % CPX_INT_MAX);
4503 break;
4504 default:
4505 return SCIP_PARAMETERUNKNOWN;
4506 } /*lint !e788*/
4507
4508 return SCIP_OKAY;
4509}
4510
4511/** gets floating point parameter of LP */
4513 SCIP_LPI* lpi, /**< LP interface structure */
4514 SCIP_LPPARAM type, /**< parameter number */
4515 SCIP_Real* dval /**< buffer to store the parameter value */
4516 )
4517{
4518 assert(lpi != NULL);
4519 assert(lpi->cpxlp != NULL);
4520 assert(dval != NULL);
4521
4522 SCIPdebugMessage("getting real parameter %d\n", type);
4523
4524 switch( type )
4525 {
4526 case SCIP_LPPAR_FEASTOL:
4527 *dval = getDblParam(lpi, CPX_PARAM_EPRHS);
4528 break;
4530 *dval = getDblParam(lpi, CPX_PARAM_EPOPT);
4531 break;
4533 *dval = getDblParam(lpi, CPX_PARAM_BAREPCOMP);
4534 break;
4535 case SCIP_LPPAR_OBJLIM:
4536 if ( CPXgetobjsen(lpi->cpxenv, lpi->cpxlp) == CPX_MIN )
4537 *dval = getDblParam(lpi, CPX_PARAM_OBJULIM);
4538 else
4539 *dval = getDblParam(lpi, CPX_PARAM_OBJLLIM);
4540 break;
4541 case SCIP_LPPAR_LPTILIM:
4542 *dval = getDblParam(lpi, CPX_PARAM_TILIM);
4543 break;
4545 *dval = getDblParam(lpi, CPX_PARAM_EPMRK);
4546 break;
4548 *dval = lpi->conditionlimit;
4549 break;
4550 default:
4551 return SCIP_PARAMETERUNKNOWN;
4552 } /*lint !e788*/
4553
4554 return SCIP_OKAY;
4555}
4556
4557/** sets floating point parameter of LP */
4559 SCIP_LPI* lpi, /**< LP interface structure */
4560 SCIP_LPPARAM type, /**< parameter number */
4561 SCIP_Real dval /**< parameter value */
4562 )
4563{
4564 assert(lpi != NULL);
4565 assert(lpi->cpxlp != NULL);
4566
4567 SCIPdebugMessage("setting real parameter %d to %.15g\n", type, dval);
4568
4569 switch( type )
4570 {
4571 case SCIP_LPPAR_FEASTOL:
4572 assert( dval > 0.0 );
4573 /* 1e-09 <= dval <= 1e-01 */
4574 if( dval < 1e-09 )
4575 dval = 1e-09;
4576 else if( dval > 1e-01 )
4577 dval = 1e-01;
4578
4579 setDblParam(lpi, CPX_PARAM_EPRHS, dval);
4580 lpi->feastol = dval;
4581 break;
4583 assert( dval > 0.0 );
4584 /* 1e-09 <= dval <= 1e-01 */
4585 if( dval < 1e-09 )
4586 dval = 1e-09;
4587 else if( dval > 1e-01 )
4588 dval = 1e-01;
4589
4590 setDblParam(lpi, CPX_PARAM_EPOPT, dval);
4591 break;
4593 /* 1e-12 <= dval */
4594 assert( dval >= 0.0 );
4595 if( dval < 1e-12 )
4596 dval = 1e-12;
4597
4598 setDblParam(lpi, CPX_PARAM_BAREPCOMP, dval);
4599 break;
4600 case SCIP_LPPAR_OBJLIM:
4601 /* Cplex poses no restriction on dval */
4602 if ( CPXgetobjsen(lpi->cpxenv, lpi->cpxlp) == CPX_MIN )
4603 setDblParam(lpi, CPX_PARAM_OBJULIM, dval);
4604 else
4605 setDblParam(lpi, CPX_PARAM_OBJLLIM, dval);
4606 break;
4607 case SCIP_LPPAR_LPTILIM:
4608 assert( dval > 0.0 );
4609 /* Cplex requires dval non-negative
4610 *
4611 * However for consistency we assert the timelimit to be strictly positive.
4612 */
4613 setDblParam(lpi, CPX_PARAM_TILIM, dval);
4614 break;
4616 /* 1e-04 <= dval <= .99999 */
4617 if( dval < 1e-04 )
4618 dval = 1e-04;
4619 else if( dval > .99999 )
4620 dval = .99999;
4621
4622 setDblParam(lpi, CPX_PARAM_EPMRK, dval);
4623 break;
4625 lpi->conditionlimit = dval;
4626 lpi->checkcondition = (dval >= 0);
4627 break;
4628 default:
4629 return SCIP_PARAMETERUNKNOWN;
4630 } /*lint !e788*/
4631
4632 return SCIP_OKAY;
4633}
4634
4635/** interrupts the currently ongoing lp solve or disables the interrupt */ /*lint -e{715}*/
4637 SCIP_LPI* lpi, /**< LP interface structure */
4638 SCIP_Bool interrupt /**< TRUE if interrupt should be set, FALSE if it should be disabled */
4639 )
4640{ /*lint --e{715}*/
4641 assert(lpi != NULL);
4642
4643 return SCIP_OKAY;
4644}
4645
4646/**@} */
4647
4648
4649
4650
4651/*
4652 * Numerical Methods
4653 */
4654
4655/**@name Numerical Methods */
4656/**@{ */
4657
4658/** returns value treated as infinity in the LP solver */
4660 SCIP_LPI* lpi /**< LP interface structure */
4661 )
4662{ /*lint --e{715}*/
4663 assert(lpi != NULL);
4664 return CPX_INFBOUND;
4665}
4666
4667/** checks if given value is treated as infinity in the LP solver */
4669 SCIP_LPI* lpi, /**< LP interface structure */
4670 SCIP_Real val /**< value to be checked for infinity */
4671 )
4672{ /*lint --e{715}*/
4673 assert(lpi != NULL);
4674 return (val >= CPX_INFBOUND);
4675}
4676
4677/**@} */
4678
4679
4680
4681
4682/*
4683 * File Interface Methods
4684 */
4685
4686/**@name File Interface Methods */
4687/**@{ */
4688
4689/** reads LP from a file */
4691 SCIP_LPI* lpi, /**< LP interface structure */
4692 const char* fname /**< file name */
4693 )
4694{
4695 int restat;
4696
4697 assert(lpi != NULL);
4698 assert(lpi->cpxlp != NULL);
4699 assert(lpi->cpxenv != NULL);
4700 assert(fname != NULL);
4701
4702 SCIPdebugMessage("reading LP from file <%s>\n", fname);
4703
4704 restat = CPXreadcopyprob(lpi->cpxenv, lpi->cpxlp, fname, NULL);
4705 if( restat != 0 )
4706 {
4707 SCIPerrorMessage("LP Error: CPLEX returned %d\n", restat);
4708 return SCIP_READERROR;
4709 }
4710
4711 return SCIP_OKAY;
4712}
4713
4714/** writes LP to a file */
4716 SCIP_LPI* lpi, /**< LP interface structure */
4717 const char* fname /**< file name */
4718 )
4719{
4720 int restat;
4721
4722 assert(lpi != NULL);
4723 assert(lpi->cpxlp != NULL);
4724 assert(lpi->cpxenv != NULL);
4725 assert(fname != NULL);
4726
4727 SCIPdebugMessage("writing LP to file <%s>\n", fname);
4728
4729 restat = CPXwriteprob(lpi->cpxenv, lpi->cpxlp, fname, NULL);
4730 if( restat != 0 )
4731 {
4732 SCIPerrorMessage("LP Error: CPLEX returned %d\n", restat);
4733 return SCIP_READERROR;
4734 }
4735
4736 return SCIP_OKAY;
4737}
4738
4739/**@} */
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:262
#define EPSISINT(x, eps)
Definition: def.h:209
#define SCIP_INVALID
Definition: def.h:192
#define SCIP_Bool
Definition: def.h:91
#define SCIP_CALL_QUIET(x)
Definition: def.h:344
#define MIN(x, y)
Definition: def.h:238
#define SCIP_ALLOC(x)
Definition: def.h:380
#define SCIP_Real
Definition: def.h:172
#define TRUE
Definition: def.h:93
#define FALSE
Definition: def.h:94
#define MAX(x, y)
Definition: def.h:234
#define EPSCEIL(x, eps)
Definition: def.h:206
#define SCIPABORT()
Definition: def.h:341
#define EPSFLOOR(x, eps)
Definition: def.h:205
#define REALABS(x)
Definition: def.h:196
#define EPSZ(x, eps)
Definition: def.h:202
#define SCIP_CALL(x)
Definition: def.h:369
SCIP_RETCODE SCIPlpiChgSides(SCIP_LPI *lpi, int nrows, const int *ind, const SCIP_Real *lhs, const SCIP_Real *rhs)
Definition: lpi_cpx.c:1630
SCIP_RETCODE SCIPlpiSetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, const SCIP_LPISTATE *lpistate)
Definition: lpi_cpx.c:4059
SCIP_RETCODE SCIPlpiGetBInvACol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_cpx.c:3934
SCIP_RETCODE SCIPlpiGetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real *dval)
Definition: lpi_cpx.c:4512
SCIP_Real SCIPlpiInfinity(SCIP_LPI *lpi)
Definition: lpi_cpx.c:4659
SCIP_Bool SCIPlpiIsObjlimExc(SCIP_LPI *lpi)
Definition: lpi_cpx.c:3333
SCIP_RETCODE SCIPlpiChgObjsen(SCIP_LPI *lpi, SCIP_OBJSEN objsen)
Definition: lpi_cpx.c:1699
SCIP_Bool SCIPlpiIsInfinity(SCIP_LPI *lpi, SCIP_Real val)
Definition: lpi_cpx.c:4668
SCIP_RETCODE SCIPlpiClear(SCIP_LPI *lpi)
Definition: lpi_cpx.c:1537
SCIP_RETCODE SCIPlpiClearState(SCIP_LPI *lpi)
Definition: lpi_cpx.c:4123
SCIP_Bool SCIPlpiExistsDualRay(SCIP_LPI *lpi)
Definition: lpi_cpx.c:3174
SCIP_Bool SCIPlpiExistsPrimalRay(SCIP_LPI *lpi)
Definition: lpi_cpx.c:3082
SCIP_RETCODE SCIPlpiGetBase(SCIP_LPI *lpi, int *cstat, int *rstat)
Definition: lpi_cpx.c:3586
SCIP_RETCODE SCIPlpiReadState(SCIP_LPI *lpi, const char *fname)
Definition: lpi_cpx.c:4165
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:1420
SCIP_RETCODE SCIPlpiGetPrimalRay(SCIP_LPI *lpi, SCIP_Real *ray)
Definition: lpi_cpx.c:3471
SCIP_RETCODE SCIPlpiGetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int *ival)
Definition: lpi_cpx.c:4342
SCIP_RETCODE SCIPlpiWriteLP(SCIP_LPI *lpi, const char *fname)
Definition: lpi_cpx.c:4715
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:3220
SCIP_RETCODE SCIPlpiSetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real dval)
Definition: lpi_cpx.c:4558
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:2817
SCIP_RETCODE SCIPlpiSetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, const SCIP_LPINORMS *lpinorms)
Definition: lpi_cpx.c:4276
SCIP_RETCODE SCIPlpiGetNNonz(SCIP_LPI *lpi, int *nnonz)
Definition: lpi_cpx.c:1909
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:2947
SCIP_RETCODE SCIPlpiGetBounds(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *lbs, SCIP_Real *ubs)
Definition: lpi_cpx.c:2152
SCIP_Bool SCIPlpiHasBarrierSolve(void)
Definition: lpi_cpx.c:1091
SCIP_RETCODE SCIPlpiGetDualfarkas(SCIP_LPI *lpi, SCIP_Real *dualfarkas)
Definition: lpi_cpx.c:3491
SCIP_RETCODE SCIPlpiGetObjval(SCIP_LPI *lpi, SCIP_Real *objval)
Definition: lpi_cpx.c:3407
SCIP_RETCODE SCIPlpiScaleCol(SCIP_LPI *lpi, int col, SCIP_Real scaleval)
Definition: lpi_cpx.c:1801
int SCIPlpiGetInternalStatus(SCIP_LPI *lpi)
Definition: lpi_cpx.c:3373
SCIP_RETCODE SCIPlpiStartStrongbranch(SCIP_LPI *lpi)
Definition: lpi_cpx.c:2791
SCIP_RETCODE SCIPlpiGetSolFeasibility(SCIP_LPI *lpi, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
Definition: lpi_cpx.c:3055
SCIP_RETCODE SCIPlpiFreeNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition: lpi_cpx.c:4309
SCIP_Bool SCIPlpiIsIterlimExc(SCIP_LPI *lpi)
Definition: lpi_cpx.c:3351
SCIP_RETCODE SCIPlpiChgBounds(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *lb, const SCIP_Real *ub)
Definition: lpi_cpx.c:1567
SCIP_Bool SCIPlpiIsPrimalUnbounded(SCIP_LPI *lpi)
Definition: lpi_cpx.c:3109
SCIP_RETCODE SCIPlpiIgnoreInstability(SCIP_LPI *lpi, SCIP_Bool *success)
Definition: lpi_cpx.c:3384
SCIP_RETCODE SCIPlpiWriteState(SCIP_LPI *lpi, const char *fname)
Definition: lpi_cpx.c:4183
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:2881
SCIP_RETCODE SCIPlpiGetCoef(SCIP_LPI *lpi, int row, int col, SCIP_Real *val)
Definition: lpi_cpx.c:2227
SCIP_Bool SCIPlpiIsPrimalFeasible(SCIP_LPI *lpi)
Definition: lpi_cpx.c:3153
SCIP_RETCODE SCIPlpiReadLP(SCIP_LPI *lpi, const char *fname)
Definition: lpi_cpx.c:4690
SCIP_RETCODE SCIPlpiGetRealSolQuality(SCIP_LPI *lpi, SCIP_LPSOLQUALITY qualityindicator, SCIP_Real *quality)
Definition: lpi_cpx.c:3529
SCIP_Bool SCIPlpiIsDualFeasible(SCIP_LPI *lpi)
Definition: lpi_cpx.c:3242
SCIP_RETCODE SCIPlpiGetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition: lpi_cpx.c:4216
SCIP_Bool SCIPlpiIsTimelimExc(SCIP_LPI *lpi)
Definition: lpi_cpx.c:3362
SCIP_Bool SCIPlpiHasStateBasis(SCIP_LPI *lpi, SCIP_LPISTATE *lpistate)
Definition: lpi_cpx.c:4155
SCIP_RETCODE SCIPlpiSetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int ival)
Definition: lpi_cpx.c:4405
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:3626
SCIP_Bool SCIPlpiHasPrimalRay(SCIP_LPI *lpi)
Definition: lpi_cpx.c:3096
SCIP_RETCODE SCIPlpiGetBInvRow(SCIP_LPI *lpi, int r, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_cpx.c:3713
SCIP_RETCODE SCIPlpiDelRows(SCIP_LPI *lpi, int firstrow, int lastrow)
Definition: lpi_cpx.c:1489
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:1929
SCIP_RETCODE SCIPlpiGetBInvCol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_cpx.c:3785
SCIP_RETCODE SCIPlpiGetColNames(SCIP_LPI *lpi, int firstcol, int lastcol, char **colnames, char *namestorage, int namestoragesize, int *storageleft)
Definition: lpi_cpx.c:2038
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:2685
SCIP_RETCODE SCIPlpiGetBInvARow(SCIP_LPI *lpi, int r, const SCIP_Real *binvrow, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_cpx.c:3859
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:1975
SCIP_Bool SCIPlpiWasSolved(SCIP_LPI *lpi)
Definition: lpi_cpx.c:3034
const char * SCIPlpiGetSolverDesc(void)
Definition: lpi_cpx.c:1041
SCIP_RETCODE SCIPlpiSolveBarrier(SCIP_LPI *lpi, SCIP_Bool crossover)
Definition: lpi_cpx.c:2594
SCIP_Bool SCIPlpiIsOptimal(SCIP_LPI *lpi)
Definition: lpi_cpx.c:3261
SCIP_RETCODE SCIPlpiGetRowNames(SCIP_LPI *lpi, int firstrow, int lastrow, char **rownames, char *namestorage, int namestoragesize, int *storageleft)
Definition: lpi_cpx.c:2074
SCIP_Bool SCIPlpiHasDualSolve(void)
Definition: lpi_cpx.c:1083
SCIP_RETCODE SCIPlpiEndStrongbranch(SCIP_LPI *lpi)
Definition: lpi_cpx.c:2804
SCIP_RETCODE SCIPlpiGetSides(SCIP_LPI *lpi, int firstrow, int lastrow, SCIP_Real *lhss, SCIP_Real *rhss)
Definition: lpi_cpx.c:2183
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:2981
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:3441
SCIP_Bool SCIPlpiHasDualRay(SCIP_LPI *lpi)
Definition: lpi_cpx.c:3187
SCIP_RETCODE SCIPlpiDelColset(SCIP_LPI *lpi, int *dstat)
Definition: lpi_cpx.c:1398
SCIP_RETCODE SCIPlpiGetObj(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *vals)
Definition: lpi_cpx.c:2129
SCIP_RETCODE SCIPlpiFreeState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lpi_cpx.c:4136
SCIP_Bool SCIPlpiIsPrimalInfeasible(SCIP_LPI *lpi)
Definition: lpi_cpx.c:3133
SCIP_RETCODE SCIPlpiSolveDual(SCIP_LPI *lpi)
Definition: lpi_cpx.c:2405
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:2259
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:3200
SCIP_RETCODE SCIPlpiGetIterations(SCIP_LPI *lpi, int *iterations)
Definition: lpi_cpx.c:3511
SCIP_RETCODE SCIPlpiGetBasisInd(SCIP_LPI *lpi, int *bind)
Definition: lpi_cpx.c:3678
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:1722
SCIP_RETCODE SCIPlpiGetObjsen(SCIP_LPI *lpi, SCIP_OBJSEN *objsen)
Definition: lpi_cpx.c:2110
SCIP_Bool SCIPlpiIsStable(SCIP_LPI *lpi)
Definition: lpi_cpx.c:3278
SCIP_RETCODE SCIPlpiGetNCols(SCIP_LPI *lpi, int *ncols)
Definition: lpi_cpx.c:1892
SCIP_RETCODE SCIPlpiInterrupt(SCIP_LPI *lpi, SCIP_Bool interrupt)
Definition: lpi_cpx.c:4636
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:1516
SCIP_RETCODE SCIPlpiScaleRow(SCIP_LPI *lpi, int row, SCIP_Real scaleval)
Definition: lpi_cpx.c:1745
SCIP_RETCODE SCIPlpiGetNRows(SCIP_LPI *lpi, int *nrows)
Definition: lpi_cpx.c:1875
SCIP_RETCODE SCIPlpiGetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lpi_cpx.c:4011
SCIP_RETCODE SCIPlpiChgCoef(SCIP_LPI *lpi, int row, int col, SCIP_Real newval)
Definition: lpi_cpx.c:1678
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