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