Scippy

SCIP

Solving Constraint Integer Programs

lpi_xprs.c
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the program and library */
4/* SCIP --- Solving Constraint Integer Programs */
5/* */
6/* Copyright (c) 2002-2025 Zuse Institute Berlin (ZIB) */
7/* */
8/* Licensed under the Apache License, Version 2.0 (the "License"); */
9/* you may not use this file except in compliance with the License. */
10/* You may obtain a copy of the License at */
11/* */
12/* http://www.apache.org/licenses/LICENSE-2.0 */
13/* */
14/* Unless required by applicable law or agreed to in writing, software */
15/* distributed under the License is distributed on an "AS IS" BASIS, */
16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17/* See the License for the specific language governing permissions and */
18/* limitations under the License. */
19/* */
20/* You should have received a copy of the Apache-2.0 license */
21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
22/* */
23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24
25/**@file lpi_xprs.c
26 * @ingroup LPIS
27 * @brief LP interface for Xpress-MP
28 * @author Tobias Achterberg
29 * @author Michael Perregaard
30 * @author Livio Bertacco
31 * @author Stefan Heinz
32 *
33 * This interface was revised for Xpress 26. Therefore, we removed all legacy code.
34 *
35 * Xpress requires that column and row names are unique. Since column and row names are not needed we ignore all column
36 * and row names to avoid the uniqueness issue.
37 */
38
39/*--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
40
41#include <assert.h>
42#include <string.h>
43#if defined(_WIN32) || defined(_WIN64)
44#else
45#include <strings.h> /*lint --e{766}*/
46#endif
47
48#include "xprs.h"
49#include "scip/bitencode.h"
50#include "scip/pub_misc.h"
51#include "scip/pub_message.h"
52#include "lpi/lpi.h"
53#include "tinycthread/tinycthread.h"
54
55#ifndef XPRS_LPQUICKPRESOLVE
56#define XPRS_LPQUICKPRESOLVE 8207
57#endif
58
59/* For SCIP we need an extra LP status which is optimal with scaled infeasibilities. */
60#define XPRS_LP_OPTIMAL_SCALEDINFEAS 16
61
62#define CHECK_ZERO(messagehdlr, x) { int _restat_; \
63 if( (_restat_ = (x)) != 0 ) \
64 { \
65 SCIPmessagePrintWarning((messagehdlr), "%s:%d: LP Error: Xpress returned %d\n", __FILE__, __LINE__, _restat_); \
66 return SCIP_LPERROR; \
67 } \
68 }
69
70/* this macro is only called in functions returning SCIP_Bool; thus, we return retval if there is an error in optimized mode */
71#define ABORT_ZERO(messagehdlr, retval, x) { int _restat_; \
72 if( (_restat_ = (x)) != 0 ) \
73 { \
74 SCIPmessagePrintWarning((messagehdlr), "LP Error: Xpress returned %d\n", _restat_); \
75 SCIPABORT(); \
76 return retval; \
77 } \
78 }
79
80
81typedef SCIP_DUALPACKET COLPACKET; /* each column needs two bits of information (basic/on_lower/on_upper) */
82#define COLS_PER_PACKET SCIP_DUALPACKETSIZE
83typedef SCIP_DUALPACKET ROWPACKET; /* each row needs two bit of information (basic/on_lower/on_upper) */
84#define ROWS_PER_PACKET SCIP_DUALPACKETSIZE
85
86/** LP interface */
87struct SCIP_LPi
88{
89 XPRSprob xprslp; /**< Xpress LP pointer */
90 char name[200]; /**< problem name */
91
92 SCIP_PRICING pricing; /**< SCIP pricing setting */
93 int notfromscratch; /**< do we not want to solve the lp from scratch */
94 int solstat; /**< solution status of last optimization call */
95 char solmethod; /**< method used to solve the LP */
96
97 char* larray; /**< array with 'L' entries for changing lower bounds */
98 char* uarray; /**< array with 'U' entries for changing upper bounds */
99 char* senarray; /**< array for storing row senses */
100 SCIP_Real* rhsarray; /**< array for storing rhs values */
101 SCIP_Real* rngarray; /**< array for storing range values */
102 SCIP_Real* valarray; /**< array for storing coefficient values */
103 int* cstat; /**< array for storing column basis status */
104 int* rstat; /**< array for storing row basis status (row status w.r.t. slack columns) */
105 int* indarray; /**< array for storing coefficient indices */
106
107 int boundchgsize; /**< size of larray and uarray */
108 int sidechgsize; /**< size of senarray and rngarray */
109 int valsize; /**< size of valarray and indarray */
110 int cstatsize; /**< size of cstat array */
111 int rstatsize; /**< size of rstat array */
112
113 int iterations; /**< number of iterations used in the last solving call */
114 SCIP_Bool solisbasic; /**< is current LP solution a basic solution? */
115 SCIP_Bool clearstate; /**< should the current basis be ignored with the next LP solve */
116
117 SCIP_Real par_lobjlim; /**< objective lower bound */
118 SCIP_Real par_uobjlim; /**< objective upper bound */
119 int par_fastlp; /**< special meta parameter for making LP reoptimize go faster */
120 int par_presolve; /**< need to distinguish between the users setting and the optimizer setting of presolve */
121
122 SCIP_MESSAGEHDLR* messagehdlr; /**< messagehdlr handler to printing messages, or NULL */
123};
124
125/** LPi state stores basis information */
126struct SCIP_LPiState
127{
128 int ncols; /**< number of LP columns */
129 int nrows; /**< number of LP rows */
130 COLPACKET* packcstat; /**< column basis status in compressed form */
131 ROWPACKET* packrstat; /**< row basis status in compressed form (row status w.r.t. slack columns) */
132};
133
134/**@name Debug check methods
135 *
136 * @{
137 */
138
139#ifndef NDEBUG
140
141/** check that the column range fits */
142static
144 SCIP_LPI* lpi, /**< LP interface structure */
145 int firstcol, /**< first column to be deleted */
146 int lastcol /**< last column to be deleted */
147 )
148{
149 int ncols;
150
151 assert(lpi != NULL);
152 assert(firstcol >= 0);
153 assert(firstcol <= lastcol + 1);
154 (void)XPRSgetintattrib(lpi->xprslp, XPRS_COLS, &ncols);
155 assert(lastcol < ncols);
156}
157
158/** check that the row range fits */
159static
161 SCIP_LPI* lpi, /**< LP interface structure */
162 int firstrow, /**< first row to be deleted */
163 int lastrow /**< last row to be deleted */
164 )
165{
166 int nrows;
167
168 assert(lpi != NULL);
169 assert(firstrow >= 0);
170 assert(firstrow <= lastrow + 1);
171 (void)XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows);
172 assert(lastrow < nrows);
173}
174
175#else
176
177/* in optimized mode the checks are replaced with an empty command */
178#define debugCheckColrang(lpi, firstcol, lastcol) /* */
179#define debugCheckRowrang(lpi, firstrow, lastrow) /* */
180#endif
181
182/**@} */
183
184
185/**@name Dynamic memory arrays
186 *
187 * @{
188 */
189
190/** resizes larray and uarray to have at least num entries and fill it with 'L' and 'U' for the lower and upper bound
191 * markers
192 */
193static
195 SCIP_LPI* lpi, /**< LP interface structure */
196 int num /**< minimal number of entries in array */
197 )
198{
199 assert(lpi != NULL);
200
201 if( num > lpi->boundchgsize )
202 {
203 int newsize;
204 int i;
205
206 newsize = MAX(2*lpi->boundchgsize, num);
207 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->larray, newsize) );
208 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->uarray, newsize) );
209 for( i = lpi->boundchgsize; i < newsize; ++i )
210 {
211 lpi->larray[i] = 'L';
212 lpi->uarray[i] = 'U';
213 }
214 lpi->boundchgsize = newsize;
215 }
216 assert(num <= lpi->boundchgsize);
217
218 return SCIP_OKAY;
219}
220
221/** resizes senarray, rngarray, and rhsarray to have at least num entries */
222static
224 SCIP_LPI* lpi, /**< LP interface structure */
225 int num /**< minimal number of entries in array */
226 )
227{
228 assert(lpi != NULL);
229
230 if( num > lpi->sidechgsize )
231 {
232 int newsize;
233
234 newsize = MAX(2*lpi->sidechgsize, num);
235 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->senarray, newsize) );
236 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->rhsarray, newsize) );
237 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->rngarray, newsize) );
238 lpi->sidechgsize = newsize;
239 }
240 assert(num <= lpi->sidechgsize);
241
242 return SCIP_OKAY;
243}
244
245/** resizes valarray and indarray to have at least num entries */
246static
248 SCIP_LPI* lpi, /**< LP interface structure */
249 int num /**< minimal number of entries in array */
250 )
251{
252 assert(lpi != NULL);
253
254 if( num > lpi->valsize )
255 {
256 int newsize;
257
258 newsize = MAX(2*lpi->valsize, num);
259 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->valarray, newsize) );
260 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->indarray, newsize) );
261 lpi->valsize = newsize;
262 }
263 assert(num <= lpi->valsize);
264
265 return SCIP_OKAY;
266}
267
268/** resizes cstat array to have at least num entries */
269static
271 SCIP_LPI* lpi, /**< LP interface structure */
272 int num /**< minimal number of entries in array */
273 )
274{
275 assert(lpi != NULL);
276
277 if( num > lpi->cstatsize )
278 {
279 int newsize;
280
281 newsize = MAX(2*lpi->cstatsize, num);
282 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->cstat, newsize) );
283 lpi->cstatsize = newsize;
284 }
285 assert(num <= lpi->cstatsize);
286
287 return SCIP_OKAY;
288}
289
290/** resizes rstat array to have at least num entries */
291static
293 SCIP_LPI* lpi, /**< LP interface structure */
294 int num /**< minimal number of entries in array */
295 )
296{
297 assert(lpi != NULL);
298
299 if( num > lpi->rstatsize )
300 {
301 int newsize;
302
303 newsize = MAX(2*lpi->rstatsize, num);
304 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->rstat, newsize) );
305 lpi->rstatsize = newsize;
306 }
307 assert(num <= lpi->rstatsize);
308
309 return SCIP_OKAY;
310}
311
312/**@} */
313
314
315/**@name LPi state methods
316 *
317 * @{
318 */
319
320/** returns the number of packets needed to store column packet information */
321static
323 int ncols /**< number of columns to store */
324 )
325{
326 return (ncols+(int)COLS_PER_PACKET-1)/(int)COLS_PER_PACKET;
327}
328
329/** returns the number of packets needed to store row packet information */
330static
332 int nrows /**< number of rows to store */
333 )
334{
335 return (nrows+(int)ROWS_PER_PACKET-1)/(int)ROWS_PER_PACKET;
336}
337
338/** store row and column basis status in a packed LPi state object */
339static
341 SCIP_LPISTATE* lpistate, /**< pointer to LPi state data */
342 const int* cstat, /**< basis status of columns in unpacked format */
343 const int* rstat /**< basis status of rows in unpacked format (row status w.r.t. slack columns) */
344 )
345{
346 assert(lpistate != NULL);
347 assert(lpistate->packcstat != NULL);
348 assert(lpistate->packrstat != NULL);
349
350 SCIPencodeDualBit(cstat, lpistate->packcstat, lpistate->ncols);
351 SCIPencodeDualBit(rstat, lpistate->packrstat, lpistate->nrows);
352}
353
354/** unpacks row and column basis status from a packed LPi state object */
355static
357 const SCIP_LPISTATE* lpistate, /**< pointer to LPi state data */
358 int* cstat, /**< buffer for storing basis status of columns in unpacked format */
359 int* rstat /**< buffer for storing basis status of rows in unpacked format (row status w.r.t. slack columns) */
360 )
361{
362 assert(lpistate != NULL);
363 assert(lpistate->packcstat != NULL);
364 assert(lpistate->packrstat != NULL);
365
366 SCIPdecodeDualBit(lpistate->packcstat, cstat, lpistate->ncols);
367 SCIPdecodeDualBit(lpistate->packrstat, rstat, lpistate->nrows);
368}
369
370/** creates LPi state information object */
371static
373 SCIP_LPISTATE** lpistate, /**< pointer to LPi state */
374 BMS_BLKMEM* blkmem, /**< block memory */
375 int ncols, /**< number of columns to store */
376 int nrows /**< number of rows to store */
377 )
378{
379 assert(lpistate != NULL);
380 assert(blkmem != NULL);
381 assert(ncols >= 0);
382 assert(nrows >= 0);
383
384 SCIP_ALLOC( BMSallocBlockMemory(blkmem, lpistate) );
385 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpistate)->packcstat, colpacketNum(ncols)) );
386 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpistate)->packrstat, rowpacketNum(nrows)) );
387
388 return SCIP_OKAY;
389}
390
391/** frees LPi state information */
392static
394 SCIP_LPISTATE** lpistate, /**< pointer to LPi state information (like basis information) */
395 BMS_BLKMEM* blkmem /**< block memory */
396 )
397{
398 assert(blkmem != NULL);
399 assert(lpistate != NULL);
400 assert(*lpistate != NULL);
401
402 BMSfreeBlockMemoryArray(blkmem, &(*lpistate)->packcstat, colpacketNum((*lpistate)->ncols));
403 BMSfreeBlockMemoryArray(blkmem, &(*lpistate)->packrstat, rowpacketNum((*lpistate)->nrows));
404 BMSfreeBlockMemory(blkmem, lpistate);
405}
406
407/**@} */
408
409
410/**@name Conversion methods
411 *
412 * @{
413 */
414
415/** converts SCIP's objective sense into CPLEX's objective sense */
416static
418 SCIP_OBJSEN const objsen /**< objective sense */
419 )
420{
421 switch( objsen )
422 {
424 return XPRS_OBJ_MAXIMIZE;
426 return XPRS_OBJ_MINIMIZE;
427 default:
428 SCIPerrorMessage("invalid objective sense\n");
429 SCIPABORT();
430 return 0; /*lint !e527*/
431 }
432}
433
434/** converts SCIP's lhs/rhs pairs into Xpress' sen/rhs/rng */
435static
437 SCIP_LPI* lpi, /**< LP interface structure */
438 int nrows, /**< number of rows */
439 const SCIP_Real* lhss, /**< left hand side vector */
440 const SCIP_Real* rhss /**< right hand side vector */
441 )
442{
443 int i;
444
445 assert(lpi != NULL);
446 assert(nrows >= 0);
447 assert(lhss != NULL);
448 assert(rhss != NULL);
449
450 /* convert lhs/rhs into sen/rhs/rng */
451 for( i = 0; i < nrows; ++i )
452 {
453 assert(lhss[i] <= rhss[i]);
454 if( lhss[i] == rhss[i] ) /*lint !e777*/
455 {
456 assert(XPRS_MINUSINFINITY < rhss[i] && rhss[i] < XPRS_PLUSINFINITY);
457 lpi->senarray[i] = 'E';
458 lpi->rhsarray[i] = rhss[i];
459 lpi->rngarray[i] = 0.0;
460 }
461 else if( lhss[i] <= XPRS_MINUSINFINITY )
462 {
463 lpi->senarray[i] = 'L';
464 lpi->rhsarray[i] = rhss[i];
465 lpi->rngarray[i] = XPRS_PLUSINFINITY;
466 }
467 else if( rhss[i] >= XPRS_PLUSINFINITY )
468 {
469 lpi->senarray[i] = 'G';
470 lpi->rhsarray[i] = lhss[i];
471 lpi->rngarray[i] = XPRS_PLUSINFINITY;
472 }
473 else
474 {
475 /* Xpress defines a ranged row to be within rhs-rng and rhs. */
476 lpi->senarray[i] = 'R';
477 lpi->rhsarray[i] = rhss[i];
478 lpi->rngarray[i] = rhss[i] - lhss[i];
479 }
480 }
481}
482
483/** converts Xpress' sen/rhs/rng triplets into SCIP's lhs/rhs pairs */
484static
486 SCIP_LPI* lpi, /**< LP interface structure */
487 int nrows, /**< number of rows */
488 SCIP_Real* lhss, /**< buffer to store the left hand side vector */
489 SCIP_Real* rhss /**< buffer to store the right hand side vector */
490 )
491{
492 int i;
493
494 assert(lpi != NULL);
495 assert(nrows >= 0);
496 assert(lhss != NULL);
497 assert(rhss != NULL);
498
499 for( i = 0; i < nrows; ++i )
500 {
501 switch( lpi->senarray[i] )
502 {
503 case 'E':
504 lhss[i] = lpi->rhsarray[i];
505 rhss[i] = lpi->rhsarray[i];
506 break;
507
508 case 'L':
509 lhss[i] = XPRS_MINUSINFINITY;
510 rhss[i] = lpi->rhsarray[i];
511 break;
512
513 case 'G':
514 lhss[i] = lpi->rhsarray[i];
515 rhss[i] = XPRS_PLUSINFINITY;
516 break;
517
518 case 'R':
519 assert(lpi->rngarray[i] >= 0.0);
520 rhss[i] = lpi->rhsarray[i];
521 lhss[i] = lpi->rhsarray[i] - lpi->rngarray[i];
522 break;
523
524 default:
525 SCIPerrorMessage("invalid row sense\n");
526 SCIPABORT();
527 }
528 assert(lhss[i] <= rhss[i]);
529 }
530}
531
532/** converts Xpress' sen/rhs/rng triplets into SCIP's lhs/rhs pairs, only storing the left hand side */
533static
535 SCIP_LPI* lpi, /**< LP interface structure */
536 int nrows, /**< number of rows */
537 SCIP_Real* lhss /**< buffer to store the left hand side vector */
538 )
539{
540 int i;
541
542 assert(lpi != NULL);
543 assert(nrows >= 0);
544 assert(lhss != NULL);
545
546 for( i = 0; i < nrows; ++i )
547 {
548 switch( lpi->senarray[i] )
549 {
550 case 'E':
551 assert(lpi->rngarray[i] == 0.0);
552 lhss[i] = lpi->rhsarray[i];
553 break;
554
555 case 'L':
556 assert(lpi->rngarray[i] == 0.0);
557 lhss[i] = XPRS_MINUSINFINITY;
558 break;
559
560 case 'G':
561 assert(lpi->rngarray[i] == 0.0);
562 lhss[i] = lpi->rhsarray[i];
563 break;
564
565 case 'R':
566 assert(lpi->rngarray[i] >= 0.0);
567 lhss[i] = lpi->rhsarray[i] - lpi->rngarray[i];
568 break;
569
570 default:
571 SCIPerrorMessage("invalid row sense\n");
572 SCIPABORT();
573 }
574 }
575}
576
577/** converts Xpress' sen/rhs/rng triplets into SCIP's lhs/rhs pairs, only storing the right hand side */
578static
580 SCIP_LPI* lpi, /**< LP interface structure */
581 int nrows, /**< number of rows */
582 SCIP_Real* rhss /**< buffer to store the right hand side vector */
583 )
584{
585 int i;
586
587 assert(lpi != NULL);
588 assert(nrows >= 0);
589 assert(rhss != NULL);
590
591 for( i = 0; i < nrows; ++i )
592 {
593 switch( lpi->senarray[i] )
594 {
595 case 'E':
596 assert(lpi->rngarray[i] == 0.0);
597 rhss[i] = lpi->rhsarray[i];
598 break;
599
600 case 'L':
601 assert(lpi->rngarray[i] == 0.0);
602 rhss[i] = lpi->rhsarray[i];
603 break;
604
605 case 'G':
606 assert(lpi->rngarray[i] == 0.0);
607 rhss[i] = XPRS_PLUSINFINITY;
608 break;
609
610 case 'R':
611 assert(lpi->rngarray[i] >= 0.0);
612 rhss[i] = lpi->rhsarray[i];
613 break;
614
615 default:
616 SCIPerrorMessage("invalid row sense\n");
617 SCIPABORT();
618 }
619 }
620}
621
622/** converts Xpress' sen/rhs/rng triplets into SCIP's lhs/rhs pairs */
623static
625 SCIP_LPI* lpi, /**< LP interface structure */
626 int nrows, /**< number of rows */
627 SCIP_Real* lhs, /**< buffer to store the left hand side vector, or NULL */
628 SCIP_Real* rhs /**< buffer to store the right hand side vector, or NULL */
629 )
630{
631 if( lhs != NULL && rhs != NULL )
632 reconvertBothSides(lpi, nrows, lhs, rhs);
633 else if( lhs != NULL )
634 reconvertLhs(lpi, nrows, lhs);
635 else if( rhs != NULL )
636 reconvertRhs(lpi, nrows, rhs);
637}
638
639/**@} */
640
641
642/** marks the current LP to be unsolved */
643static
645 SCIP_LPI* lpi
646 )
647{
648 assert(lpi != NULL);
649 lpi->solstat = -1;
650}
651
652/*
653 * LP Interface Methods
654 */
655
656/**@name Miscellaneous Methods
657 *
658 * @{
659 */
660
661#ifdef _Thread_local
662static _Thread_local char xprsname[100];
663#else
664static char xprsname[] = {'X', 'p', 'r', 'e', 's', 's', ' ', '0' + XPVERSION / 10, '0' + XPVERSION % 10, '\0'};
665#endif
666/** gets name and version of LP solver */
668 void
669 )
670{
671#ifdef _Thread_local
672 char version[16];
673
674 /* get version of Xpress */
675 if( XPRSgetversion(version) == 0 )
676 (void) sprintf(xprsname, "Xpress %s", version);
677 else
678 (void) sprintf(xprsname, "Xpress %d", XPVERSION);
679#endif
680 return xprsname;
681}
682
683/** gets description of LP solver (developer, webpage, ...) */
685 void
686 )
687{
688 return "Linear Programming Solver developed by FICO (www.fico.com/en/products/fico-xpress-optimization)";
689}
690
691/** gets pointer for LP solver - use only with great care
692 *
693 * Here we return the pointer to the LP environment.
694 */
696 SCIP_LPI* lpi /**< pointer to an LP interface structure */
697 )
698{ /*lint --e{715}*/
699 return (void*) lpi->xprslp;
700}
701
702/** pass integrality information to LP solver */
704 SCIP_LPI* lpi, /**< pointer to an LP interface structure */
705 int ncols, /**< length of integrality array */
706 int* intInfo /**< integrality array (0: continuous, 1: integer). May be NULL iff ncols is 0. */
707 )
708{ /*lint --e{715}*/
709 assert(lpi != NULL);
710 assert(ncols >= 0);
711 assert(ncols == 0 || intInfo != NULL);
712
713 SCIPerrorMessage("SCIPlpiSetIntegralityInformation() has not been implemented yet.\n");
714 return SCIP_LPERROR;
715}
716
717/** informs about availability of a primal simplex solving method */
719 void
720 )
721{
722 return TRUE;
723}
724
725/** informs about availability of a dual simplex solving method */
727 void
728 )
729{
730 return TRUE;
731}
732
733/** informs about availability of a barrier solving method */
735 void
736 )
737{
738 return TRUE;
739}
740
741/**@} */
742
743
744/**@name LPI Creation and Destruction Methods
745 *
746 * @{
747 */
748
749/** creates an LP problem object */
751 SCIP_LPI** lpi, /**< pointer to an LP interface structure */
752 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler to use for printing messages, or NULL */
753 const char* name, /**< problem name */
754 SCIP_OBJSEN objsen /**< objective sense */
755 )
756{
757 int zero = 0;
758
759 assert(sizeof(SCIP_Real) == sizeof(double)); /*lint !e506*/ /* Xpress only works with doubles as floating points */
760 assert(sizeof(SCIP_Bool) == sizeof(int)); /*lint !e506*/ /* Xpress only works with ints as bools */
761 assert(lpi != NULL);
762 assert(name != NULL);
763
764 SCIPdebugMessage("SCIPlpiCreate()\n");
765
766 /* the interface is revised for Xpress 26 or higher */
767 if( XPVERSION < 26 ) /*lint !e506 !e774*/
768 {
769 SCIPmessagePrintWarning(messagehdlr, "Please use Xpress version 26 or higher, you are using %d\n", XPVERSION);
770 return SCIP_LPERROR;
771 }
772
773 /* initialize the Xpress library (licensing) */
774 CHECK_ZERO( messagehdlr, XPRSinit(NULL) );
775
776 /* create LPi data structure */
778
779 /* copy the problem name */
780 (void)strncpy((*lpi)->name, name, 199);
781 (*lpi)->name[199] = '\0';
782
783 (*lpi)->larray = NULL;
784 (*lpi)->uarray = NULL;
785 (*lpi)->senarray = NULL;
786 (*lpi)->rhsarray = NULL;
787 (*lpi)->rngarray = NULL;
788 (*lpi)->indarray = NULL;
789 (*lpi)->valarray = NULL;
790 (*lpi)->cstat = NULL;
791 (*lpi)->rstat = NULL;
792 (*lpi)->boundchgsize = 0;
793 (*lpi)->sidechgsize = 0;
794 (*lpi)->valsize = 0;
795 (*lpi)->cstatsize = 0;
796 (*lpi)->rstatsize = 0;
797 (*lpi)->iterations = 0;
798 (*lpi)->solisbasic = TRUE;
799 (*lpi)->clearstate = FALSE;
800 (*lpi)->solmethod = ' ';
801 (*lpi)->par_lobjlim = -1e+40;
802 (*lpi)->par_uobjlim = +1e+40;
803 (*lpi)->par_fastlp = 0;
804 (*lpi)->par_presolve = 0;
805 (*lpi)->messagehdlr = messagehdlr;
806
807 CHECK_ZERO( messagehdlr, XPRScreateprob(&(*lpi)->xprslp) );
808 invalidateSolution(*lpi);
809
810 /* turn logging off until the user explicitly turns it on; this should prevent any unwanted Xpress output from
811 * appearing in the SCIP log.
812 */
813 CHECK_ZERO( messagehdlr, XPRSsetintcontrol((*lpi)->xprslp, XPRS_OUTPUTLOG, 0) );
814
815 /* we need to create an empty LP in this prob since SCIP might attempt to add rows or columns to it */
816 CHECK_ZERO( messagehdlr, XPRSloadlp((*lpi)->xprslp, (*lpi)->name, 0, 0, NULL, NULL, NULL, NULL, &zero, NULL, NULL, NULL, NULL, NULL) );
817
818 /* set objective sense */
819 SCIP_CALL( SCIPlpiChgObjsen(*lpi, objsen) );
820
821 return SCIP_OKAY;
822}
823
824/** deletes an LP problem object */
826 SCIP_LPI** lpi /**< pointer to an LP interface structure */
827 )
828{
829 assert(lpi != NULL);
830 assert(*lpi != NULL);
831 assert((*lpi)->xprslp != NULL);
832
833 SCIPdebugMessage("SCIPlpiFree()\n");
834
835 /* free LP */
836 CHECK_ZERO( (*lpi)->messagehdlr, XPRSdestroyprob(((*lpi)->xprslp)) );
837
838 /* free environment */
839 CHECK_ZERO( (*lpi)->messagehdlr, XPRSfree() );
840
841 /* free memory */
842 BMSfreeMemoryArrayNull(&(*lpi)->larray);
843 BMSfreeMemoryArrayNull(&(*lpi)->uarray);
844 BMSfreeMemoryArrayNull(&(*lpi)->senarray);
845 BMSfreeMemoryArrayNull(&(*lpi)->rhsarray);
846 BMSfreeMemoryArrayNull(&(*lpi)->rngarray);
847 BMSfreeMemoryArrayNull(&(*lpi)->indarray);
848 BMSfreeMemoryArrayNull(&(*lpi)->valarray);
849 BMSfreeMemoryArrayNull(&(*lpi)->cstat);
850 BMSfreeMemoryArrayNull(&(*lpi)->rstat);
851 BMSfreeMemory(lpi);
852
853 return SCIP_OKAY;
854}
855
856/**@} */
857
858
859/**@name Modification Methods
860 *
861 * @{
862 */
863
864/** copies LP data with column matrix into LP solver */
866 SCIP_LPI* lpi, /**< LP interface structure */
867 SCIP_OBJSEN objsen, /**< objective sense */
868 int ncols, /**< number of columns */
869 const SCIP_Real* obj, /**< objective function values of columns */
870 const SCIP_Real* lb, /**< lower bounds of columns */
871 const SCIP_Real* ub, /**< upper bounds of columns */
872 char** colnames, /**< column names, or NULL */
873 int nrows, /**< number of rows */
874 const SCIP_Real* lhs, /**< left hand sides of rows */
875 const SCIP_Real* rhs, /**< right hand sides of rows */
876 char** rownames, /**< row names, or NULL */
877 int nnonz, /**< number of nonzero elements in the constraint matrix */
878 const int* beg, /**< start index of each column in ind- and val-array */
879 const int* ind, /**< row indices of constraint matrix entries */
880 const SCIP_Real* val /**< values of constraint matrix entries */
881 )
882{ /*lint --e{715}*/
883 int c;
884
885#ifndef NDEBUG
886 {
887 int j;
888 for( j = 0; j < nnonz; j++ )
889 assert( val[j] != 0 );
890 }
891#endif
892
893 assert(lpi != NULL);
894 assert(lpi->xprslp != NULL);
895 assert(obj != NULL);
896 assert(lb != NULL);
897 assert(ub != NULL);
898 assert(beg != NULL);
899 assert(ind != NULL);
900 assert(val != NULL);
901 SCIP_UNUSED(colnames);
902 SCIP_UNUSED(rownames);
903
904 SCIPdebugMessage("loading LP in column format into Xpress: %d cols, %d rows\n", ncols, nrows);
905
907
908 /* ensure that the temporary arrays for the side conversion are long enough */
909 SCIP_CALL( ensureSidechgMem(lpi, nrows) );
910
911 /* convert lhs/rhs into sen/rhs/range tuples the sen/rhs/range are stored in the temporary arrays in lpi structure */
912 convertSides(lpi, nrows, lhs, rhs);
913
914 /* ensure that the temporary arrays are large enough */
915 SCIP_CALL( ensureValMem(lpi, ncols) );
916
917 /* calculate column lengths */
918 for( c = 0; c < ncols-1; ++c )
919 {
920 lpi->indarray[c] = beg[c+1] - beg[c];
921 assert(lpi->indarray[c] >= 0);
922 }
923 lpi->indarray[ncols-1] = nnonz - beg[ncols-1];
924 assert(lpi->indarray[ncols-1] >= 0);
925
926 /* copy data into Xpress */
927 CHECK_ZERO( lpi->messagehdlr, XPRSloadlp(lpi->xprslp, lpi->name, ncols, nrows, lpi->senarray, lpi->rhsarray,
928 lpi->rngarray, obj, beg, lpi->indarray, ind, val, lb, ub) );
929
930 /* set objective sense */
931 SCIP_CALL( SCIPlpiChgObjsen(lpi, objsen) );
932
933 return SCIP_OKAY;
934}
935
936/** adds columns to the LP */
938 SCIP_LPI* lpi, /**< LP interface structure */
939 int ncols, /**< number of columns to be added */
940 const SCIP_Real* obj, /**< objective function values of new columns */
941 const SCIP_Real* lb, /**< lower bounds of new columns */
942 const SCIP_Real* ub, /**< upper bounds of new columns */
943 char** colnames, /**< column names, or NULL */
944 int nnonz, /**< number of nonzero elements to be added to the constraint matrix */
945 const int* beg, /**< start index of each column in ind- and val-array, or NULL if nnonz == 0 */
946 const int* ind, /**< row indices of constraint matrix entries, or NULL if nnonz == 0 */
947 const SCIP_Real* val /**< values of constraint matrix entries, or NULL if nnonz == 0 */
948 )
949{ /*lint --e{715}*/
950 int c;
951
952 assert(lpi != NULL);
953 assert(lpi->xprslp != NULL);
954 assert(ncols > 0);
955 assert(obj != NULL);
956 assert(lb != NULL);
957 assert(ub != NULL);
958 assert(nnonz >= 0);
959 assert(nnonz == 0 || beg != NULL);
960 assert(nnonz == 0 || ind != NULL);
961 assert(nnonz == 0 || val != NULL);
962 SCIP_UNUSED(colnames);
963
964 SCIPdebugMessage("adding %d columns with %d nonzeros to Xpress\n", ncols, nnonz);
965
967
968 /* ensure that the temporary arrays are large enough */
969 SCIP_CALL( ensureValMem(lpi, ncols+1) );
970
971#ifndef NDEBUG
972 {
973 /* perform check that no new rows are added - this is forbidden */
974 int nrows;
975 int j;
976
977 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows) );
978 for (j = 0; j < nnonz; ++j)
979 {
980 assert( val[j] != 0.0 );
981 assert( 0 <= ind[j] && ind[j] < nrows );
982 }
983 }
984#endif
985
986 /* only collect the start array if we have at least one non-zero */
987 if( nnonz > 0 )
988 {
989 /* we need ncol+1 entries in the start array for Xpress */
990 for( c = 0; c < ncols; c++ )
991 lpi->indarray[c] = beg[c];
992 lpi->indarray[ncols] = nnonz;
993 }
994
995 /* add the columns with (potential) non-zeros to the Xpress */
996 CHECK_ZERO( lpi->messagehdlr, XPRSaddcols(lpi->xprslp, ncols, nnonz, obj, lpi->indarray, ind, val, lb, ub) );
997
998 return SCIP_OKAY;
999}
1000
1001/** deletes all columns in the given range from LP */
1003 SCIP_LPI* lpi, /**< LP interface structure */
1004 int firstcol, /**< first column to be deleted */
1005 int lastcol /**< last column to be deleted */
1006 )
1007{
1008 int c;
1009
1010 debugCheckColrang(lpi, firstcol, lastcol);
1011
1012 SCIPdebugMessage("deleting %d columns from Xpress\n", lastcol - firstcol + 1);
1013
1014 /* handle empty range */
1015 if( firstcol > lastcol )
1016 return SCIP_OKAY;
1017
1018 invalidateSolution(lpi);
1019
1020 /* ensure that the temporary arrays are large enough */
1021 SCIP_CALL( ensureValMem(lpi, lastcol-firstcol+1) );
1022
1023 /* collect the columns indices to be deleted */
1024 for( c = firstcol; c <= lastcol; c++ )
1025 lpi->indarray[c-firstcol] = c;
1026
1027 CHECK_ZERO( lpi->messagehdlr, XPRSdelcols(lpi->xprslp, lastcol-firstcol+1, lpi->indarray) );
1028
1029 return SCIP_OKAY;
1030}
1031
1032/** deletes columns from SCIP_LP; the new position of a column must not be greater that its old position */
1034 SCIP_LPI* lpi, /**< LP interface structure */
1035 int* dstat /**< deletion status of columns
1036 * input: 1 if column should be deleted, 0 if not
1037 * output: new position of column, -1 if column was deleted */
1038 )
1039{
1040 int nkeptcols;
1041 int ndelcols;
1042 int ncols;
1043 int c;
1044
1045 assert(lpi != NULL);
1046 assert(lpi->xprslp != NULL);
1047 assert(dstat != NULL);
1048
1049 SCIPdebugMessage("deleting a column set from Xpress\n");
1050
1051 invalidateSolution(lpi);
1052
1053 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_COLS, &ncols) );
1054
1055 nkeptcols = 0;
1056 ndelcols = 0;
1057
1058 /* ensure that the temporary arrays are large enough */
1059 SCIP_CALL( ensureValMem(lpi, ncols) );
1060
1061 /* collect the column indecies which should be deleted and create a the new column ordering */
1062 for( c = 0; c < ncols; c++ )
1063 {
1064 if( dstat[c] == 1 )
1065 {
1066 dstat[c] = -1;
1067 lpi->indarray[ndelcols] = c;
1068 ndelcols++;
1069 }
1070 else
1071 {
1072 dstat[c] = nkeptcols;
1073 nkeptcols++;
1074 }
1075 }
1076
1077 CHECK_ZERO( lpi->messagehdlr, XPRSdelcols(lpi->xprslp, ndelcols, lpi->indarray) );
1078
1079 return SCIP_OKAY;
1080}
1081
1082/** adds rows to the LP */
1084 SCIP_LPI* lpi, /**< LP interface structure */
1085 int nrows, /**< number of rows to be added */
1086 const SCIP_Real* lhs, /**< left hand sides of new rows */
1087 const SCIP_Real* rhs, /**< right hand sides of new rows */
1088 char** rownames, /**< row names, or NULL */
1089 int nnonz, /**< number of nonzero elements to be added to the constraint matrix */
1090 const int* beg, /**< start index of each row in ind- and val-array, or NULL if nnonz == 0 */
1091 const int* ind, /**< column indices of constraint matrix entries, or NULL if nnonz == 0 */
1092 const SCIP_Real* val /**< values of constraint matrix entries, or NULL if nnonz == 0 */
1093 )
1094{ /*lint --e{715}*/
1095 int r;
1096
1097 assert(lpi != NULL);
1098 assert(lpi->xprslp != NULL);
1099 assert(nrows >= 0);
1100 assert(lhs != NULL);
1101 assert(rhs != NULL);
1102 assert(nnonz >= 0);
1103 assert(nnonz == 0 || beg != NULL);
1104 assert(nnonz == 0 || ind != NULL);
1105 assert(nnonz == 0 || val != NULL);
1106 SCIP_UNUSED(rownames);
1107
1108 SCIPdebugMessage("adding %d rows with %d nonzeros to Xpress\n", nrows, nnonz);
1109
1110 invalidateSolution(lpi);
1111
1112#ifndef NDEBUG
1113 {
1114 /* perform check that no new cols are added - this is forbidden */
1115 int ncols;
1116 int j;
1117
1118 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_COLS, &ncols) );
1119 for (j = 0; j < nnonz; ++j)
1120 {
1121 assert( val[j] != 0.0 );
1122 assert( 0 <= ind[j] && ind[j] < ncols );
1123 }
1124 }
1125#endif
1126
1127 /* ensure that the temporary arrays are large enough */
1128 SCIP_CALL( ensureSidechgMem(lpi, nrows) );
1129 SCIP_CALL( ensureValMem(lpi, nrows+1) );
1130
1131 /* convert lhs/rhs into sen/rhs/range tuples */
1132 convertSides(lpi, nrows, lhs, rhs);
1133
1134 /* only collect the start array if we have at least one non-zero */
1135 if( nnonz > 0 )
1136 {
1137 for( r = 0; r < nrows; r++ )
1138 lpi->indarray[r] = beg[r];
1139 lpi->indarray[nrows] = nnonz;
1140 }
1141
1142 CHECK_ZERO( lpi->messagehdlr, XPRSaddrows(lpi->xprslp, nrows, nnonz, lpi->senarray, lpi->rhsarray, lpi->rngarray, lpi->indarray, ind, val) );
1143
1144 return SCIP_OKAY;
1145}
1146
1147/** deletes all rows in the given range from LP */
1149 SCIP_LPI* lpi, /**< LP interface structure */
1150 int firstrow, /**< first row to be deleted */
1151 int lastrow /**< last row to be deleted */
1152 )
1153{
1154 int r;
1155
1156 debugCheckRowrang(lpi, firstrow, lastrow);
1157
1158 SCIPdebugMessage("deleting %d rows from Xpress\n", lastrow - firstrow + 1);
1159
1160 /* handle empty range */
1161 if( firstrow > lastrow )
1162 return SCIP_OKAY;
1163
1164 invalidateSolution(lpi);
1165
1166 /* ensure that the temporary arrays are large enough */
1167 SCIP_CALL( ensureValMem(lpi, lastrow-firstrow+1) );
1168
1169 for( r = firstrow; r <= lastrow; r++ )
1170 lpi->indarray[r-firstrow] = r;
1171
1172 CHECK_ZERO( lpi->messagehdlr, XPRSdelrows(lpi->xprslp, lastrow-firstrow+1, lpi->indarray) );
1173
1174 return SCIP_OKAY;
1175}
1176
1177/** deletes rows from SCIP_LP; the new position of a row must not be greater that its old position */
1179 SCIP_LPI* lpi, /**< LP interface structure */
1180 int* dstat /**< deletion status of rows
1181 * input: 1 if row should be deleted, 0 if not
1182 * output: new position of row, -1 if row was deleted */
1183 )
1184{
1185 int nkeptrows;
1186 int ndelrows;
1187 int nrows;
1188 int r;
1189
1190 assert(lpi != NULL);
1191 assert(lpi->xprslp != NULL);
1192
1193 SCIPdebugMessage("deleting a row set from Xpress\n");
1194
1195 invalidateSolution(lpi);
1196
1197 nkeptrows = 0;
1198 ndelrows = 0;
1199
1200 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows) );
1201
1202 /* ensure that the temporary arrays are large enough */
1203 SCIP_CALL( ensureValMem(lpi, nrows) );
1204
1205 /* collect the row indecies which should be deleted and create a the new row ordering */
1206 for( r = 0; r < nrows; r++ )
1207 {
1208 if( dstat[r] == 1 )
1209 {
1210 dstat[r] = -1;
1211 lpi->indarray[ndelrows] = r;
1212 ndelrows++;
1213 }
1214 else
1215 {
1216 dstat[r] = nkeptrows;
1217 nkeptrows++;
1218 }
1219 }
1220
1221 CHECK_ZERO( lpi->messagehdlr, XPRSdelrows(lpi->xprslp, ndelrows, lpi->indarray) );
1222
1223 return SCIP_OKAY;
1224}
1225
1226/** clears the whole LP */
1228 SCIP_LPI* lpi /**< LP interface structure */
1229 )
1230{
1231 int zero = 0;
1232
1233 assert(lpi != NULL);
1234 assert(lpi->xprslp != NULL);
1235
1236 SCIPdebugMessage("clearing Xpress LP\n");
1237
1238 invalidateSolution(lpi);
1239
1240 /* create an empty LP in this */
1241 CHECK_ZERO( lpi->messagehdlr, XPRSloadlp(lpi->xprslp, lpi->name, 0, 0, NULL, NULL, NULL, NULL, &zero, NULL, NULL, NULL, NULL, NULL) );
1242
1243 return SCIP_OKAY;
1244}
1245
1246/** changes lower and upper bounds of columns */
1248 SCIP_LPI* lpi, /**< LP interface structure */
1249 int ncols, /**< number of columns to change bounds for */
1250 const int* ind, /**< column indices or NULL if ncols is zero */
1251 const SCIP_Real* lb, /**< values for the new lower bounds or NULL if ncols is zero */
1252 const SCIP_Real* ub /**< values for the new upper bounds or NULL if ncols is zero */
1253 )
1254{
1255 int j;
1256
1257 assert(lpi != NULL);
1258 assert(lpi->xprslp != NULL);
1259 assert(ncols == 0 || (ind != NULL && lb != NULL && ub != NULL));
1260
1261 SCIPdebugMessage("changing %d bounds in Xpress\n", ncols);
1262 if( ncols <= 0 )
1263 return SCIP_OKAY;
1264
1265 invalidateSolution(lpi);
1266
1267 for (j = 0; j < ncols; ++j)
1268 {
1269 if ( SCIPlpiIsInfinity(lpi, lb[j]) )
1270 {
1271 SCIPerrorMessage("LP Error: fixing lower bound for variable %d to infinity.\n", ind[j]);
1272 return SCIP_LPERROR;
1273 }
1274 if ( SCIPlpiIsInfinity(lpi, -ub[j]) )
1275 {
1276 SCIPerrorMessage("LP Error: fixing upper bound for variable %d to -infinity.\n", ind[j]);
1277 return SCIP_LPERROR;
1278 }
1279 }
1280
1281 /* ensure that the temporary arrays are large enough */
1282 SCIP_CALL( ensureBoundchgMem(lpi, ncols) );
1283
1284 CHECK_ZERO( lpi->messagehdlr, XPRSchgbounds(lpi->xprslp, ncols, ind, lpi->larray, (SCIP_Real*)lb) );
1285 CHECK_ZERO( lpi->messagehdlr, XPRSchgbounds(lpi->xprslp, ncols, ind, lpi->uarray, (SCIP_Real*)ub) );
1286
1287 return SCIP_OKAY;
1288}
1289
1290/** changes left and right hand sides of rows */
1292 SCIP_LPI* lpi, /**< LP interface structure */
1293 int nrows, /**< number of rows to change sides for */
1294 const int* ind, /**< row indices */
1295 const SCIP_Real* lhs, /**< new values for left hand sides */
1296 const SCIP_Real* rhs /**< new values for right hand sides */
1297 )
1298{
1299 assert(lpi != NULL);
1300 assert(lpi->xprslp != NULL);
1301 assert(ind != NULL);
1302
1303 SCIPdebugMessage("changing %d sides in Xpress\n", nrows);
1304 if( nrows <= 0 )
1305 return SCIP_OKAY;
1306
1307 invalidateSolution(lpi);
1308
1309 /* ensure that the temporary arrays are large enough */
1310 SCIP_CALL( ensureSidechgMem(lpi, nrows) );
1311
1312 /* convert lhs/rhs into sen/rhs/range tuples */
1313 convertSides(lpi, nrows, lhs, rhs);
1314
1315 /* change row sides */
1316 CHECK_ZERO( lpi->messagehdlr, XPRSchgrowtype(lpi->xprslp, nrows, ind, lpi->senarray) );
1317 CHECK_ZERO( lpi->messagehdlr, XPRSchgrhs(lpi->xprslp, nrows, ind, lpi->rhsarray) );
1318 CHECK_ZERO( lpi->messagehdlr, XPRSchgrhsrange(lpi->xprslp, nrows, ind, lpi->rngarray) );
1319
1320 return SCIP_OKAY;
1321}
1322
1323/** changes a single coefficient */
1325 SCIP_LPI* lpi, /**< LP interface structure */
1326 int row, /**< row number of coefficient to change */
1327 int col, /**< column number of coefficient to change */
1328 SCIP_Real newval /**< new value of coefficient */
1329 )
1330{
1331 assert(lpi != NULL);
1332 assert(lpi->xprslp != NULL);
1333
1334 SCIPdebugMessage("changing coefficient row %d, column %d in Xpress to %g\n", row, col, newval);
1335
1336 invalidateSolution(lpi);
1337
1338 CHECK_ZERO( lpi->messagehdlr, XPRSchgcoef(lpi->xprslp, row, col, newval) );
1339
1340 return SCIP_OKAY;
1341}
1342
1343/** changes the objective sense */
1345 SCIP_LPI* lpi, /**< LP interface structure */
1346 SCIP_OBJSEN objsense /**< new objective sense */
1347 )
1348{
1349 assert(lpi != NULL);
1350 assert(lpi->xprslp != NULL);
1351
1352 SCIPdebugMessage("changing objective sense in Xpress to %d\n", objsense);
1353
1354 invalidateSolution(lpi);
1355
1356 CHECK_ZERO( lpi->messagehdlr, XPRSchgobjsense(lpi->xprslp, xprsObjsen(objsense)) );
1357
1358 return SCIP_OKAY;
1359}
1360
1361/** changes objective values of columns in the LP */
1363 SCIP_LPI* lpi, /**< LP interface structure */
1364 int ncols, /**< number of columns to change objective value for */
1365 const int* ind, /**< column indices to change objective value for */
1366 const SCIP_Real* obj /**< new objective values for columns */
1367 )
1368{
1369 assert(lpi != NULL);
1370 assert(lpi->xprslp != NULL);
1371 assert(ind != NULL);
1372 assert(obj != NULL);
1373
1374 SCIPdebugMessage("changing %d objective values in Xpress\n", ncols);
1375
1376 invalidateSolution(lpi);
1377
1378 CHECK_ZERO( lpi->messagehdlr, XPRSchgobj(lpi->xprslp, ncols, ind, obj) );
1379
1380 return SCIP_OKAY;
1381}
1382
1383/** multiplies a row with a non-zero scalar; for negative scalars, the row's sense is switched accordingly */
1385 SCIP_LPI* lpi, /**< LP interface structure */
1386 int row, /**< row number to scale */
1387 SCIP_Real scaleval /**< scaling multiplier */
1388 )
1389{
1390 SCIP_Real lhs;
1391 SCIP_Real rhs;
1392 int nnonz;
1393 int ncols;
1394 int i;
1395
1396 assert(lpi != NULL);
1397 assert(lpi->xprslp != NULL);
1398 assert(scaleval != 0.0);
1399
1400 SCIPdebugMessage("scaling row %d with factor %g in Xpress\n", row, scaleval);
1401
1402 invalidateSolution(lpi);
1403
1404 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_COLS, &ncols) );
1405 SCIP_CALL( ensureValMem(lpi, ncols) );
1406
1407 /* get the row */
1408 SCIP_CALL( SCIPlpiGetSides(lpi, row, row, &lhs, &rhs) );
1409 CHECK_ZERO( lpi->messagehdlr, XPRSgetrows(lpi->xprslp, NULL, lpi->indarray, lpi->valarray, ncols, &nnonz, row, row) );
1410 assert(nnonz <= ncols);
1411
1412 /* scale row coefficients */
1413 for( i = 0; i < nnonz; ++i )
1414 {
1415 SCIP_CALL( SCIPlpiChgCoef(lpi, row, lpi->indarray[i], lpi->valarray[i] * scaleval) );
1416 }
1417
1418 /* scale row sides */
1419 if( lhs > XPRS_MINUSINFINITY )
1420 lhs *= scaleval;
1421 else if( scaleval < 0.0 )
1422 lhs = XPRS_PLUSINFINITY;
1423 if( rhs < XPRS_PLUSINFINITY )
1424 rhs *= scaleval;
1425 else if( scaleval < 0.0 )
1426 rhs = XPRS_MINUSINFINITY;
1427
1428 if( scaleval > 0.0 )
1429 {
1430 SCIP_CALL( SCIPlpiChgSides(lpi, 1, &row, &lhs, &rhs) );
1431 }
1432 else
1433 {
1434 SCIP_CALL( SCIPlpiChgSides(lpi, 1, &row, &rhs, &lhs) );
1435 }
1436
1437 return SCIP_OKAY;
1438}
1439
1440/** multiplies a column with a non-zero scalar; the objective value is multiplied with the scalar, and the bounds
1441 * are divided by the scalar; for negative scalars, the column's bounds are switched
1442 */
1444 SCIP_LPI* lpi, /**< LP interface structure */
1445 int col, /**< column number to scale */
1446 SCIP_Real scaleval /**< scaling multiplier */
1447 )
1448{
1449 SCIP_Real lb;
1450 SCIP_Real ub;
1451 SCIP_Real obj;
1452 int nnonz;
1453 int nrows;
1454 int i;
1455
1456 assert(lpi != NULL);
1457 assert(lpi->xprslp != NULL);
1458 assert(scaleval != 0.0);
1459
1460 SCIPdebugMessage("scaling column %d with factor %g in Xpress\n", col, scaleval);
1461
1462 invalidateSolution(lpi);
1463
1464 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows) );
1465 SCIP_CALL( ensureValMem(lpi, nrows) );
1466
1467 /* get the column */
1468 CHECK_ZERO( lpi->messagehdlr, XPRSgetlb(lpi->xprslp, &lb, col, col) );
1469 CHECK_ZERO( lpi->messagehdlr, XPRSgetub(lpi->xprslp, &ub, col, col) );
1470 CHECK_ZERO( lpi->messagehdlr, XPRSgetcols(lpi->xprslp, NULL, lpi->indarray, lpi->valarray, nrows, &nnonz, col, col) );
1471 assert(nnonz <= nrows);
1472
1473 /* get objective coefficient */
1474 SCIP_CALL( SCIPlpiGetObj(lpi, col, col, &obj) );
1475
1476 /* scale column coefficients */
1477 for( i = 0; i < nnonz; ++i )
1478 {
1479 SCIP_CALL( SCIPlpiChgCoef(lpi, lpi->indarray[i], col, lpi->valarray[i] * scaleval) );
1480 }
1481
1482 /* scale objective value */
1483 obj *= scaleval;
1484 SCIP_CALL( SCIPlpiChgObj(lpi, 1, &col, &obj) );
1485
1486 /* scale column bounds */
1487 if( lb > XPRS_MINUSINFINITY )
1488 lb /= scaleval;
1489 else if( scaleval < 0.0 )
1490 lb = XPRS_PLUSINFINITY;
1491 if( ub < XPRS_PLUSINFINITY )
1492 ub /= scaleval;
1493 else if( scaleval < 0.0 )
1494 ub = XPRS_MINUSINFINITY;
1495
1496 if( scaleval > 0.0 )
1497 {
1498 SCIP_CALL( SCIPlpiChgBounds(lpi, 1, &col, &lb, &ub) );
1499 }
1500 else
1501 {
1502 SCIP_CALL( SCIPlpiChgBounds(lpi, 1, &col, &ub, &lb) );
1503 }
1504
1505 return SCIP_OKAY;
1506}
1507
1508/**@} */
1509
1510
1511/**@name Data Accessing Methods
1512 *
1513 * @{
1514 */
1515
1516/** gets the number of rows in the LP */
1518 SCIP_LPI* lpi, /**< LP interface structure */
1519 int* nrows /**< pointer to store the number of rows */
1520 )
1521{
1522 assert(lpi != NULL);
1523 assert(lpi->xprslp != NULL);
1524 assert(nrows != NULL);
1525
1526 SCIPdebugMessage("getting number of rows\n");
1527
1528 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, nrows) );
1529
1530 return SCIP_OKAY;
1531}
1532
1533/** gets the number of columns in the LP */
1535 SCIP_LPI* lpi, /**< LP interface structure */
1536 int* ncols /**< pointer to store the number of cols */
1537 )
1538{
1539 assert(lpi != NULL);
1540 assert(lpi->xprslp != NULL);
1541 assert(ncols != NULL);
1542
1543 SCIPdebugMessage("getting number of columns\n");
1544
1545 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_COLS, ncols) );
1546
1547 return SCIP_OKAY;
1548}
1549
1550/** gets the number of nonzero elements in the LP constraint matrix */
1552 SCIP_LPI* lpi, /**< LP interface structure */
1553 int* nnonz /**< pointer to store the number of nonzeros */
1554 )
1555{
1556 assert(lpi != NULL);
1557 assert(lpi->xprslp != NULL);
1558 assert(nnonz != NULL);
1559
1560 SCIPdebugMessage("getting number of non-zeros\n");
1561
1562 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ELEMS, nnonz) );
1563
1564 return SCIP_OKAY;
1565}
1566
1567/** gets columns from LP problem object; the arrays have to be large enough to store all values
1568 * Either both, lb and ub, have to be NULL, or both have to be non-NULL,
1569 * either nnonz, beg, ind, and val have to be NULL, or all of them have to be non-NULL.
1570 */
1572 SCIP_LPI* lpi, /**< LP interface structure */
1573 int firstcol, /**< first column to get from LP */
1574 int lastcol, /**< last column to get from LP */
1575 SCIP_Real* lb, /**< buffer to store the lower bound vector, or NULL */
1576 SCIP_Real* ub, /**< buffer to store the upper bound vector, or NULL */
1577 int* nnonz, /**< pointer to store the number of nonzero elements returned, or NULL */
1578 int* beg, /**< buffer to store start index of each column in ind- and val-array, or NULL */
1579 int* ind, /**< buffer to store row indices of constraint matrix entries, or NULL */
1580 SCIP_Real* val /**< buffer to store values of constraint matrix entries, or NULL */
1581 )
1582{
1583 assert((lb != NULL && ub != NULL) || (lb == NULL && ub == NULL));
1584 assert((nnonz != NULL && beg != NULL && ind != NULL && val != NULL) || (nnonz == NULL && beg == NULL && ind == NULL && val == NULL));
1585
1586 debugCheckColrang(lpi, firstcol, lastcol);
1587
1588 SCIPdebugMessage("getting columns %d to %d\n", firstcol, lastcol);
1589
1590 if( lb != NULL )
1591 {
1592 CHECK_ZERO( lpi->messagehdlr, XPRSgetlb(lpi->xprslp, lb, firstcol, lastcol) );
1593 CHECK_ZERO( lpi->messagehdlr, XPRSgetub(lpi->xprslp, ub, firstcol, lastcol) );
1594 }
1595
1596 if( nnonz != NULL )
1597 {
1598 int ntotalnonz;
1599 int c;
1600
1601 /* ensure that the temporary buffer array is large enough */
1602 SCIP_CALL( ensureValMem(lpi, lastcol-firstcol+2) );
1603
1604 /* get number of nonzero in the whole problem; needed to pass a proper size to XPRSgetcols() function call
1605 *
1606 * @note We are assuming that the arrays given by SCIP are large enough. Otherwise we are getting invalid writes
1607 */
1608 SCIP_CALL( SCIPlpiGetNNonz(lpi, &ntotalnonz) );
1609
1610 /* get matrix entries */
1611 CHECK_ZERO( lpi->messagehdlr, XPRSgetcols(lpi->xprslp, lpi->indarray, ind, val, ntotalnonz, nnonz, firstcol, lastcol) );
1612 assert(*nnonz <= ntotalnonz);
1613 assert(lpi->indarray[lastcol-firstcol+1] == *nnonz);
1614
1615 assert(beg != NULL); /* for lint */
1616 for( c = 0; c < lastcol-firstcol+1; c++ )
1617 beg[c] = lpi->indarray[c];
1618 }
1619
1620 return SCIP_OKAY;
1621}
1622
1623/** gets rows from LP problem object; the arrays have to be large enough to store all values.
1624 * Either both, lhs and rhs, have to be NULL, or both have to be non-NULL,
1625 * either nnonz, beg, ind, and val have to be NULL, or all of them have to be non-NULL.
1626 */
1628 SCIP_LPI* lpi, /**< LP interface structure */
1629 int firstrow, /**< first row to get from LP */
1630 int lastrow, /**< last row to get from LP */
1631 SCIP_Real* lhss, /**< buffer to store left hand side vector, or NULL */
1632 SCIP_Real* rhss, /**< buffer to store right hand side vector, or NULL */
1633 int* nnonz, /**< pointer to store the number of nonzero elements returned, or NULL */
1634 int* beg, /**< buffer to store start index of each row in ind- and val-array, or NULL */
1635 int* ind, /**< buffer to store column indices of constraint matrix entries, or NULL */
1636 SCIP_Real* val /**< buffer to store values of constraint matrix entries, or NULL */
1637 )
1638{
1639 assert((lhss != NULL && rhss != NULL) || (lhss == NULL && rhss == NULL));
1640 assert((nnonz != NULL && beg != NULL && ind != NULL && val != NULL) || (nnonz == NULL && beg == NULL && ind == NULL && val == NULL));
1641
1642 debugCheckRowrang(lpi, firstrow, lastrow);
1643
1644 SCIPdebugMessage("getting rows %d to %d\n", firstrow, lastrow);
1645
1646 if( lhss != NULL )
1647 {
1648 /* get left and right sides */
1649 SCIP_CALL( SCIPlpiGetSides(lpi, firstrow, lastrow, lhss, rhss) );
1650 }
1651
1652 if( nnonz != NULL )
1653 {
1654 int ntotalnonz;
1655 int r;
1656
1657 /* ensure that the temporary buffer array is large enough */
1658 SCIP_CALL( ensureValMem(lpi, lastrow-firstrow+2) );
1659
1660 /* get number of nonzero in the whole problem; needed to pass a proper size to XPRSgetrows() function call
1661 *
1662 * @note We are assuming that the arrays given by SCIP are large enough. Otherwise we are getting invalid writes
1663 */
1664 SCIP_CALL( SCIPlpiGetNNonz(lpi, &ntotalnonz) );
1665
1666 /* get matrix entries */
1667 CHECK_ZERO( lpi->messagehdlr, XPRSgetrows(lpi->xprslp, lpi->indarray, ind, val, ntotalnonz, nnonz, firstrow, lastrow) );
1668 assert(*nnonz <= ntotalnonz);
1669 assert(lpi->indarray[lastrow-firstrow+1] == *nnonz);
1670
1671 assert(beg != NULL); /* for lint */
1672 for( r = 0; r < lastrow-firstrow+1; r++ )
1673 beg[r] = lpi->indarray[r];
1674 }
1675
1676 return SCIP_OKAY;
1677}
1678
1679/** gets column names */
1681 SCIP_LPI* lpi, /**< LP interface structure */
1682 int firstcol, /**< first column to get name from LP */
1683 int lastcol, /**< last column to get name from LP */
1684 char** colnames, /**< pointers to column names (of size at least lastcol-firstcol+1) or NULL if namestoragesize is zero */
1685 char* namestorage, /**< storage for col names or NULL if namestoragesize is zero */
1686 int namestoragesize, /**< size of namestorage (if 0, storageleft returns the storage needed) */
1687 int* storageleft /**< amount of storage left (if < 0 the namestorage was not big enough) or NULL if namestoragesize is zero */
1688 )
1689{ /*lint --e{715}*/
1690 assert(colnames != NULL || namestoragesize == 0);
1691 assert(namestorage != NULL || namestoragesize == 0);
1692 assert(namestoragesize >= 0);
1693 assert(storageleft != NULL);
1694
1695 debugCheckColrang(lpi, firstcol, lastcol);
1696
1697 SCIPerrorMessage("SCIPlpiGetColNames() has not been implemented yet.\n");
1698
1699 return SCIP_LPERROR;
1700}
1701
1702/** gets row names */
1704 SCIP_LPI* lpi, /**< LP interface structure */
1705 int firstrow, /**< first row to get name from LP */
1706 int lastrow, /**< last row to get name from LP */
1707 char** rownames, /**< pointers to row names (of size at least lastrow-firstrow+1) or NULL if namestoragesize is zero */
1708 char* namestorage, /**< storage for row names or NULL if namestoragesize is zero */
1709 int namestoragesize, /**< size of namestorage (if 0, -storageleft returns the storage needed) */
1710 int* storageleft /**< amount of storage left (if < 0 the namestorage was not big enough) or NULL if namestoragesize is zero */
1711 )
1712{ /*lint --e{715}*/
1713 assert(rownames != NULL || namestoragesize == 0);
1714 assert(namestorage != NULL || namestoragesize == 0);
1715 assert(namestoragesize >= 0);
1716 assert(storageleft != NULL);
1717
1718 debugCheckRowrang(lpi, firstrow, lastrow);
1719
1720 SCIPerrorMessage("SCIPlpiGetRowNames() has not been implemented yet.\n");
1721
1722 return SCIP_LPERROR;
1723}
1724
1725/** gets the objective sense of the LP */
1727 SCIP_LPI* lpi, /**< LP interface structure */
1728 SCIP_OBJSEN* objsen /**< pointer to store objective sense */
1729 )
1730{
1731 double xprsobjsen;
1732 assert(lpi != NULL);
1733 assert(lpi->xprslp != NULL);
1734 assert(objsen != NULL);
1735
1736 /* check the objective sense attribute for the current objective sense set in Xpress */
1737 CHECK_ZERO( lpi->messagehdlr, XPRSgetdblattrib(lpi->xprslp, XPRS_OBJSENSE, &xprsobjsen) );
1738
1739 /* convert the Xpress objective sense attribute to a SCIP objective sense */
1740 if( xprsobjsen < 0.0 )
1741 (*objsen) = SCIP_OBJSEN_MAXIMIZE;
1742 else
1743 (*objsen) = SCIP_OBJSEN_MINIMIZE;
1744
1745 return SCIP_OKAY;
1746}
1747
1748/** gets objective coefficients from LP problem object */
1750 SCIP_LPI* lpi, /**< LP interface structure */
1751 int firstcol, /**< first column to get objective coefficient for */
1752 int lastcol, /**< last column to get objective coefficient for */
1753 SCIP_Real* vals /**< array to store objective coefficients */
1754 )
1755{
1756 assert(vals != NULL);
1757
1758 debugCheckColrang(lpi, firstcol, lastcol);
1759
1760 SCIPdebugMessage("getting objective values %d to %d\n", firstcol, lastcol);
1761
1762 CHECK_ZERO( lpi->messagehdlr, XPRSgetobj(lpi->xprslp, vals, firstcol, lastcol) );
1763
1764 return SCIP_OKAY;
1765}
1766
1767/** gets current bounds from LP problem object */
1769 SCIP_LPI* lpi, /**< LP interface structure */
1770 int firstcol, /**< first column to get bounds for */
1771 int lastcol, /**< last column to get bounds for */
1772 SCIP_Real* lbs, /**< array to store lower bound values, or NULL */
1773 SCIP_Real* ubs /**< array to store upper bound values, or NULL */
1774 )
1775{
1776 debugCheckColrang(lpi, firstcol, lastcol);
1777
1778 SCIPdebugMessage("getting bounds %d to %d\n", firstcol, lastcol);
1779
1780 if( lbs != NULL )
1781 {
1782 CHECK_ZERO( lpi->messagehdlr, XPRSgetlb(lpi->xprslp, lbs, firstcol, lastcol) );
1783 }
1784
1785 if( ubs != NULL )
1786 {
1787 CHECK_ZERO( lpi->messagehdlr, XPRSgetub(lpi->xprslp, ubs, firstcol, lastcol) );
1788 }
1789
1790 return SCIP_OKAY;
1791}
1792
1793/** gets current row sides from LP problem object */
1795 SCIP_LPI* lpi, /**< LP interface structure */
1796 int firstrow, /**< first row to get sides for */
1797 int lastrow, /**< last row to get sides for */
1798 SCIP_Real* lhss, /**< array to store left hand side values, or NULL */
1799 SCIP_Real* rhss /**< array to store right hand side values, or NULL */
1800 )
1801{
1802 debugCheckRowrang(lpi, firstrow, lastrow);
1803
1804 SCIPdebugMessage("getting row sides %d to %d\n", firstrow, lastrow);
1805
1806 /* ensure the array size of the temporary buffers */
1807 SCIP_CALL( ensureSidechgMem(lpi, lastrow - firstrow + 1) );
1808
1809 /* get row sense, rhs, and ranges */
1810 CHECK_ZERO( lpi->messagehdlr, XPRSgetrowtype(lpi->xprslp, lpi->senarray, firstrow, lastrow) );
1811 CHECK_ZERO( lpi->messagehdlr, XPRSgetrhs(lpi->xprslp, lpi->rhsarray, firstrow, lastrow) );
1812 CHECK_ZERO( lpi->messagehdlr, XPRSgetrhsrange(lpi->xprslp, lpi->rngarray, firstrow, lastrow) );
1813
1814 /* convert sen/rhs/range into lhs/rhs tuples */
1815 reconvertSides(lpi, lastrow - firstrow + 1, lhss, rhss);
1816
1817 return SCIP_OKAY;
1818}
1819
1820/** gets a single coefficient */
1822 SCIP_LPI* lpi, /**< LP interface structure */
1823 int row, /**< row number of coefficient */
1824 int col, /**< column number of coefficient */
1825 SCIP_Real* val /**< pointer to store the value of the coefficient */
1826 )
1827{
1828 assert(lpi != NULL);
1829 assert(lpi->xprslp != NULL);
1830 assert(val != NULL);
1831
1832 /* get the coefficient of the column in the corresponding row */
1833 CHECK_ZERO( lpi->messagehdlr, XPRSgetcoef(lpi->xprslp, row, col, val) );
1834
1835 return SCIP_OKAY;
1836}
1837
1838/**@} */
1839
1840
1841/**@name Solving Methods
1842 *
1843 * @{
1844 */
1845
1846/** solve LP */
1848 SCIP_LPI* lpi, /**< LP interface structure */
1849 const char* method /**< indicates the method to use ('p' - primal, 'd' - dual, 'b' - barrier) */
1850 )
1851{
1852 int primalinfeasible;
1853 int dualinfeasible;
1854 int state;
1855
1856 assert(lpi != NULL);
1857 assert(lpi->xprslp != NULL);
1858
1859 invalidateSolution(lpi);
1860
1861 /* check if the current basis should be ignored */
1862 if( lpi->clearstate )
1863 {
1864 CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_KEEPBASIS, 0) );
1865 lpi->clearstate = FALSE;
1866 }
1867
1868 CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_PRESOLVE, 0) );
1869 CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_LPQUICKPRESOLVE, (lpi->par_presolve) ? 1 : 0) );
1870
1871 if( lpi->par_fastlp )
1872 {
1873 /* Don't refactorize at the end of the solve. */
1874 CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_REFACTOR, 0) );
1875 }
1876 else
1877 {
1878 /* Use default settings for solving an lp (hopefully) robustly. */
1879 CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_REFACTOR, 1) );
1880 }
1881
1882 /* solve the LP */
1883 CHECK_ZERO( lpi->messagehdlr, XPRSlpoptimize(lpi->xprslp, method) );
1884
1885 /* evaluate the result */
1886 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_LPSTATUS, &lpi->solstat) );
1887
1888 /* Make sure the LP is postsolved in case it was interrupted. */
1889 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_PRESOLVESTATE, &state) );
1890
1891 if( state & (2|4) )
1892 {
1893 /* Problem is in a presolve state - postsolve it. */
1894 CHECK_ZERO( lpi->messagehdlr, XPRSpostsolve(lpi->xprslp) );
1895 }
1896
1897 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_SIMPLEXITER, &lpi->iterations) );
1898 lpi->solisbasic = TRUE;
1899
1900 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_PRIMALINFEAS, &primalinfeasible) );
1901 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_DUALINFEAS, &dualinfeasible) );
1902 SCIPdebugMessage(" -> Xpress returned solstat=%d, pinfeas=%d, dinfeas=%d (%d iterations)\n",
1903 lpi->solstat, primalinfeasible, dualinfeasible, lpi->iterations);
1904
1905 /* Make sure that always a primal / dual ray exists */
1906 if( lpi->solstat == XPRS_LP_INFEAS || lpi->solstat == XPRS_LP_UNBOUNDED )
1907 {
1908 int hasray;
1909 int presolving;
1910
1911 /* check whether a dual ray exists, in that case we don't need to resolve the LP w/o presolving */
1912 CHECK_ZERO( lpi->messagehdlr, XPRSgetdualray(lpi->xprslp, NULL, &hasray) );
1913
1914 if( hasray == 1 )
1915 goto TERMINATE;
1916
1917 /* get the current presolving setting */
1918 CHECK_ZERO( lpi->messagehdlr, XPRSgetintcontrol(lpi->xprslp, XPRS_LPQUICKPRESOLVE, &presolving) );
1919
1920 if( presolving != 0 )
1921 {
1922 int iterations;
1923
1924 /* maybe the preprocessor solved the problem; but we need a solution, so solve again without preprocessing */
1925 SCIPdebugMessage("presolver may have solved the problem -> calling Xpress %s again without presolve\n",
1926 strcmp(method, "p") == 0 ? "primal simplex" : strcmp(method, "d") == 0 ? "dual simplex" : "barrier");
1927
1928 /* switch off preprocessing */
1929 CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_LPQUICKPRESOLVE, 0) );
1930
1931 /* resolve w/o presolving */
1932 CHECK_ZERO( lpi->messagehdlr, XPRSlpoptimize(lpi->xprslp, method) );
1933
1934 /* evaluate the result */
1935 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_LPSTATUS, &lpi->solstat) );
1936
1937 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_SIMPLEXITER, &iterations) );
1938 lpi->iterations += iterations;
1939 lpi->solisbasic = TRUE;
1940
1941 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_PRIMALINFEAS, &primalinfeasible) );
1942 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_DUALINFEAS, &dualinfeasible) );
1943 SCIPdebugMessage(" -> Xpress returned solstat=%d, pinfeas=%d, dinfeas=%d (%d iterations)\n",
1944 lpi->solstat, primalinfeasible, dualinfeasible, lpi->iterations);
1945
1946 /* reinstall the previous setting */
1947 CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_LPQUICKPRESOLVE, presolving) );
1948 }
1949 }
1950
1951 TERMINATE:
1952 if( (lpi->solstat == XPRS_LP_OPTIMAL) && (primalinfeasible || dualinfeasible) )
1954
1955 return SCIP_OKAY;
1956}
1957
1958/** calls primal simplex to solve the LP */
1960 SCIP_LPI* lpi /**< LP interface structure */
1961 )
1962{
1963 assert(lpi != NULL);
1964 assert(lpi->xprslp != NULL);
1965
1966 lpi->solmethod = 'p';
1967 return lpiSolve(lpi, "p");
1968}
1969
1970/** calls dual simplex to solve the LP */
1972 SCIP_LPI* lpi /**< LP interface structure */
1973 )
1974{
1975 assert(lpi != NULL);
1976 assert(lpi->xprslp != NULL);
1977
1978 lpi->solmethod = 'd';
1979 return lpiSolve(lpi, "d");
1980}
1981
1982/** calls barrier or interior point algorithm to solve the LP with crossover to simplex basis */
1984 SCIP_LPI* lpi, /**< LP interface structure */
1985 SCIP_Bool crossover /**< perform crossover */
1986 )
1987{
1988 SCIP_RETCODE retval;
1989
1990 assert(lpi != NULL);
1991 assert(lpi->xprslp != NULL);
1992
1993 lpi->solmethod = 'b';
1994
1995 /* enable or disable cross over */
1996 CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_CROSSOVER, crossover == TRUE ? -1 : 0) );
1997
1998 retval = lpiSolve(lpi, "b");
1999 lpi->solisbasic = crossover;
2000
2001 return retval;
2002}
2003
2004/** start strong branching - call before any strong branching */
2006 SCIP_LPI* lpi /**< LP interface structure */
2007 )
2008{ /*lint --e{715}*/
2009 assert(lpi != NULL);
2010 assert(lpi->xprslp != NULL);
2011
2012 /* currently do nothing */
2013 return SCIP_OKAY;
2014}
2015
2016/** end strong branching - call after any strong branching */
2018 SCIP_LPI* lpi /**< LP interface structure */
2019 )
2020{ /*lint --e{715}*/
2021 assert(lpi != NULL);
2022 assert(lpi->xprslp != NULL);
2023
2024 /* currently do nothing */
2025 return SCIP_OKAY;
2026}
2027
2028/** performs strong branching iterations on one candidate */
2029static
2031 SCIP_LPI* lpi, /**< LP interface structure */
2032 int col, /**< column to apply strong branching on */
2033 SCIP_Real psol, /**< current primal solution value of column */
2034 int itlim, /**< iteration limit for strong branchings */
2035 SCIP_Real* down, /**< stores dual bound after branching column down */
2036 SCIP_Real* up, /**< stores dual bound after branching column up */
2037 SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
2038 * otherwise, it can only be used as an estimate value */
2039 SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
2040 * otherwise, it can only be used as an estimate value */
2041 int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
2042 )
2043{
2044 SCIP_OBJSEN objsen;
2045 double dbndval[2];
2046 double dobjval[2];
2047 char cbndtype[2];
2048 int mbndind[2];
2049 int mstatus[2];
2050
2051 assert(lpi != NULL);
2052 assert(lpi->xprslp != NULL);
2053 assert(down != NULL);
2054 assert(up != NULL);
2055 assert(downvalid != NULL);
2056 assert(upvalid != NULL);
2057
2058 SCIPdebugMessage("calling Xpress strong branching on variable %d (%d iterations)\n", col, itlim);
2059
2060 /* results of Xpress are valid in any case */
2061 *downvalid = TRUE;
2062 *upvalid = TRUE;
2063
2064 SCIPdebugMessage(" -> strong branching on integral variable\n");
2065
2066 if( iter != NULL )
2067 *iter = 0;
2068
2069 /* get objective sense of the current LP */
2070 SCIP_CALL( SCIPlpiGetObjsen(lpi, &objsen) );
2071
2072 /* Set the branching bounds (down first, up second). */
2073 mbndind[0] = col;
2074 dbndval[0] = EPSCEIL(psol-1.0, 1e-06);
2075 cbndtype[0] = 'U';
2076 mbndind[1] = col;
2077 dbndval[1] = EPSFLOOR(psol+1.0, 1e-06);
2078 cbndtype[1] = 'L';
2079
2080 /* Apply strong branching to the two branches. */
2081 CHECK_ZERO( lpi->messagehdlr, XPRSstrongbranch(lpi->xprslp, 2, mbndind, cbndtype, dbndval, itlim, dobjval, mstatus) );
2082
2083 /* Get the objective of the down branch. */
2084 if( (mstatus[0] == XPRS_LP_INFEAS) || (mstatus[0] == XPRS_LP_CUTOFF_IN_DUAL) )
2085 *down = objsen == SCIP_OBJSEN_MINIMIZE ? 1e+40 : -1e+40;
2086 else if( (mstatus[0] == XPRS_LP_OPTIMAL) || (mstatus[0] == XPRS_LP_UNFINISHED) )
2087 *down = dobjval[0];
2088 else
2089 {
2090 /* Something weird happened. */
2091 *downvalid = FALSE;
2092 }
2093
2094 /* Get the objective of the up branch. */
2095 if( (mstatus[1] == XPRS_LP_INFEAS) || (mstatus[1] == XPRS_LP_CUTOFF_IN_DUAL) )
2096 *up = objsen == SCIP_OBJSEN_MINIMIZE ? 1e+40 : -1e+40;
2097 else if( (mstatus[1] == XPRS_LP_OPTIMAL) || (mstatus[1] == XPRS_LP_UNFINISHED) )
2098 *up = dobjval[1];
2099 else
2100 {
2101 /* Something weird happened. */
2102 *upvalid = FALSE;
2103 }
2104
2105 /* When using the XPRSstrongbranch function we are unable to provide an iteration count */
2106 if( iter != NULL )
2107 *iter = -1;
2108
2109 return SCIP_OKAY;
2110}
2111
2112/** performs strong branching iterations on given candidates */
2113static
2115 SCIP_LPI* lpi, /**< LP interface structure */
2116 int* cols, /**< columns to apply strong branching on */
2117 int ncols, /**< number of columns */
2118 SCIP_Real* psols, /**< current primal solution values of columns (might be integral) */
2119 int itlim, /**< iteration limit for strong branchings */
2120 SCIP_Real* down, /**< stores dual bounds after branching columns down */
2121 SCIP_Real* up, /**< stores dual bounds after branching columns up */
2122 SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds;
2123 * otherwise, they can only be used as an estimate values */
2124 SCIP_Bool* upvalid, /**< stores whether the returned up values are a valid dual bounds;
2125 * otherwise, they can only be used as an estimate values */
2126 int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
2127 )
2128{
2129 double* dbndval;
2130 double* dobjval;
2131 char* cbndtype;
2132 int* mbndind;
2133 int* mstatus;
2134 SCIP_OBJSEN objsen;
2135 int nbranches;
2136 int j;
2137
2138 assert( lpi != NULL );
2139 assert( lpi->xprslp != NULL );
2140 assert( cols != NULL );
2141 assert( psols != NULL );
2142 assert( down != NULL );
2143 assert( up != NULL );
2144 assert( downvalid != NULL );
2145 assert( upvalid != NULL );
2146
2147 SCIPdebugMessage("calling Xpress strong branching on %d variables (%d iterations)\n", ncols, itlim);
2148
2149 if( iter != NULL )
2150 *iter = 0;
2151
2152 /* compute the number of branches; for each column we have 2 branches */
2153 nbranches = 2*ncols;
2154
2155 /* get objective sense of the current LP */
2156 SCIP_CALL( SCIPlpiGetObjsen(lpi, &objsen) );
2157
2158 /* Set the branching bounds (down first, up second). */
2159 SCIP_ALLOC( BMSallocMemoryArray(&mbndind, nbranches) );
2160 SCIP_ALLOC( BMSallocMemoryArray(&dbndval, nbranches) );
2161 SCIP_ALLOC( BMSallocMemoryArray(&cbndtype, nbranches) );
2162 SCIP_ALLOC( BMSallocMemoryArray(&dobjval, nbranches) );
2163 SCIP_ALLOC( BMSallocMemoryArray(&mstatus, nbranches) );
2164
2165 /* construct the bounds for the strong branches */
2166 for( j = 0; j < ncols; ++j )
2167 {
2168 mbndind[2*j] = cols[j];
2169 dbndval[2*j] = EPSCEIL(psols[j] - 1.0, 1e-06);
2170 cbndtype[2*j] = 'U';
2171
2172 mbndind[2*j+1] = cols[j];
2173 dbndval[2*j+1] = EPSFLOOR(psols[j] + 1.0, 1e-06);
2174 cbndtype[2*j+1] = 'L';
2175 }
2176
2177 /* apply strong branching to the 2*ncols branches. */
2178 CHECK_ZERO( lpi->messagehdlr, XPRSstrongbranch(lpi->xprslp, nbranches, mbndind, cbndtype, dbndval, itlim, dobjval, mstatus) );
2179
2180 for( j = 0; j < ncols; ++j )
2181 {
2182 upvalid[j] = TRUE;
2183 downvalid[j] = TRUE;
2184
2185 /* Get the objective of the down branch. */
2186 if( (mstatus[2*j] == XPRS_LP_INFEAS) || (mstatus[2*j] == XPRS_LP_CUTOFF_IN_DUAL) )
2187 down[j] = objsen == SCIP_OBJSEN_MINIMIZE ? 1e+40 : -1e+40;
2188 else if( (mstatus[2*j] == XPRS_LP_OPTIMAL) || (mstatus[2*j] == XPRS_LP_UNFINISHED) )
2189 down[j] = dobjval[2*j];
2190 else
2191 {
2192 /* Something weird happened. */
2193 downvalid[j] = FALSE;
2194 }
2195
2196 /* Get the objective of the up branch. */
2197 if( (mstatus[2*j+1] == XPRS_LP_INFEAS) || (mstatus[2*j+1] == XPRS_LP_CUTOFF_IN_DUAL) )
2198 up[j] = objsen == SCIP_OBJSEN_MINIMIZE ? 1e+40 : -1e+40;
2199 else if( (mstatus[2*j+1] == XPRS_LP_OPTIMAL) || (mstatus[2*j+1] == XPRS_LP_UNFINISHED) )
2200 up[j] = dobjval[2*j+1];
2201 else
2202 {
2203 /* Something weird happened. */
2204 upvalid[j] = FALSE;
2205 }
2206 }
2207
2208 /* When using the XPRSstrongbranch function we are unable to provide
2209 * an iteration count.
2210 */
2211 if( iter != NULL )
2212 *iter = -1;
2213
2214 BMSfreeMemoryArray(&mstatus);
2215 BMSfreeMemoryArray(&dobjval);
2216 BMSfreeMemoryArray(&cbndtype);
2217 BMSfreeMemoryArray(&dbndval);
2218 BMSfreeMemoryArray(&mbndind);
2219
2220 return SCIP_OKAY;
2221}
2222
2223/** performs strong branching iterations on one @b fractional candidate */
2225 SCIP_LPI* lpi, /**< LP interface structure */
2226 int col, /**< column to apply strong branching on */
2227 SCIP_Real psol, /**< fractional current primal solution value of column */
2228 int itlim, /**< iteration limit for strong branchings */
2229 SCIP_Real* down, /**< stores dual bound after branching column down */
2230 SCIP_Real* up, /**< stores dual bound after branching column up */
2231 SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
2232 * otherwise, it can only be used as an estimate value */
2233 SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
2234 * otherwise, it can only be used as an estimate value */
2235 int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
2236 )
2237{
2238 /* pass call on to lpiStrongbranch() */
2239 SCIP_CALL( lpiStrongbranch(lpi, col, psol, itlim, down, up, downvalid, upvalid, iter) );
2240
2241 return SCIP_OKAY;
2242}
2243
2244/** performs strong branching iterations on given @b fractional candidates */
2246 SCIP_LPI* lpi, /**< LP interface structure */
2247 int* cols, /**< columns to apply strong branching on */
2248 int ncols, /**< number of columns */
2249 SCIP_Real* psols, /**< fractional current primal solution values of columns */
2250 int itlim, /**< iteration limit for strong branchings */
2251 SCIP_Real* down, /**< stores dual bounds after branching columns down */
2252 SCIP_Real* up, /**< stores dual bounds after branching columns up */
2253 SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds;
2254 * otherwise, they can only be used as an estimate values */
2255 SCIP_Bool* upvalid, /**< stores whether the returned up values are a valid dual bounds;
2256 * otherwise, they can only be used as an estimate values */
2257 int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
2258 )
2259{
2260 /* pass call on to lpiStrongbranches() */
2261 SCIP_CALL( lpiStrongbranches(lpi, cols, ncols, psols, itlim, down, up, downvalid, upvalid, iter) );
2262
2263 return SCIP_OKAY;
2264}
2265
2266/** performs strong branching iterations on one candidate with @b integral value */
2268 SCIP_LPI* lpi, /**< LP interface structure */
2269 int col, /**< column to apply strong branching on */
2270 SCIP_Real psol, /**< current integral primal solution value of column */
2271 int itlim, /**< iteration limit for strong branchings */
2272 SCIP_Real* down, /**< stores dual bound after branching column down */
2273 SCIP_Real* up, /**< stores dual bound after branching column up */
2274 SCIP_Bool* downvalid, /**< stores whether the returned down value is a valid dual bound;
2275 * otherwise, it can only be used as an estimate value */
2276 SCIP_Bool* upvalid, /**< stores whether the returned up value is a valid dual bound;
2277 * otherwise, it can only be used as an estimate value */
2278 int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
2279 )
2280{
2281 /* pass call on to lpiStrongbranch() */
2282 SCIP_CALL( lpiStrongbranch(lpi, col, psol, itlim, down, up, downvalid, upvalid, iter) );
2283
2284 return SCIP_OKAY;
2285}
2286
2287/** performs strong branching iterations on given candidates with @b integral values */
2289 SCIP_LPI* lpi, /**< LP interface structure */
2290 int* cols, /**< columns to apply strong branching on */
2291 int ncols, /**< number of columns */
2292 SCIP_Real* psols, /**< current integral primal solution values of columns */
2293 int itlim, /**< iteration limit for strong branchings */
2294 SCIP_Real* down, /**< stores dual bounds after branching columns down */
2295 SCIP_Real* up, /**< stores dual bounds after branching columns up */
2296 SCIP_Bool* downvalid, /**< stores whether the returned down values are valid dual bounds;
2297 * otherwise, they can only be used as an estimate values */
2298 SCIP_Bool* upvalid, /**< stores whether the returned up values are a valid dual bounds;
2299 * otherwise, they can only be used as an estimate values */
2300 int* iter /**< stores total number of strong branching iterations, or -1; may be NULL */
2301 )
2302{
2303 /* pass call on to lpiStrongbranches() */
2304 SCIP_CALL( lpiStrongbranches(lpi, cols, ncols, psols, itlim, down, up, downvalid, upvalid, iter) );
2305
2306 return SCIP_OKAY;
2307}
2308
2309/**@} */
2310
2311
2312/**@name Solution Information Methods
2313 *
2314 * @{
2315 */
2316
2317/** returns whether a solve method was called after the last modification of the LP */
2319 SCIP_LPI* lpi /**< LP interface structure */
2320 )
2321{
2322 assert(lpi != NULL);
2323
2324 return (lpi->solstat != -1);
2325}
2326
2327/** gets information about primal and dual feasibility of the current LP solution
2328 *
2329 * The feasibility information is with respect to the last solving call and it is only relevant if SCIPlpiWasSolved()
2330 * returns true. If the LP is changed, this information might be invalidated.
2331 *
2332 * Note that @a primalfeasible and @a dualfeasible should only return true if the solver has proved the respective LP to
2333 * be feasible. Thus, the return values should be equal to the values of SCIPlpiIsPrimalFeasible() and
2334 * SCIPlpiIsDualFeasible(), respectively. Note that if feasibility cannot be proved, they should return false (even if
2335 * the problem might actually be feasible).
2336 */
2338 SCIP_LPI* lpi, /**< LP interface structure */
2339 SCIP_Bool* primalfeasible, /**< pointer to store primal feasibility status */
2340 SCIP_Bool* dualfeasible /**< pointer to store dual feasibility status */
2341 )
2342{
2343 assert(lpi != NULL);
2344 assert(lpi->xprslp != NULL);
2345 assert(primalfeasible != NULL);
2346 assert(dualfeasible != NULL);
2347
2348 SCIPdebugMessage("getting solution feasibility\n");
2349
2350 *primalfeasible = SCIPlpiIsPrimalFeasible(lpi);
2351 *dualfeasible = SCIPlpiIsDualFeasible(lpi);
2352
2353 return SCIP_OKAY;
2354}
2355
2356/** returns TRUE iff LP is proven to have a primal unbounded ray (but not necessary a primal feasible point);
2357 * this does not necessarily mean, that the solver knows and can return the primal ray
2358 */
2360 SCIP_LPI* lpi /**< LP interface structure */
2361 )
2362{
2363 assert(lpi != NULL);
2364 assert(lpi->xprslp != NULL);
2365 assert(lpi->solstat >= 0);
2366
2367 return (lpi->solstat == XPRS_LP_UNBOUNDED);
2368}
2369
2370/** returns TRUE iff LP is proven to have a primal unbounded ray (but not necessary a primal feasible point),
2371 * and the solver knows and can return the primal ray
2372 */
2374 SCIP_LPI* lpi /**< LP interface structure */
2375 )
2376{
2377 int hasRay;
2378
2379 assert(lpi != NULL);
2380 assert(lpi->xprslp != NULL);
2381 assert(lpi->solstat >= 0);
2382
2383 /* check if the LP solution status is unbounded and that primal was solving the LP */
2384 if (lpi->solstat != XPRS_LP_UNBOUNDED || lpi->solmethod != 'p')
2385 return FALSE;
2386
2387 /* check if we can construct a primal ray */
2388 ABORT_ZERO( lpi->messagehdlr, FALSE, XPRSgetprimalray(lpi->xprslp, NULL, &hasRay) );
2389
2390 return (SCIP_Bool)hasRay;
2391}
2392
2393/** returns TRUE iff LP is proven to be primal feasible and unbounded */
2395 SCIP_LPI* lpi /**< LP interface structure */
2396 )
2397{
2398 assert(lpi != NULL);
2399 assert(lpi->xprslp != NULL);
2400 assert(lpi->solstat >= 0);
2401
2402 SCIPdebugMessage("checking for primal unboundedness\n");
2403
2404 /* If the solution status of Xpress is XPRS_LP_UNBOUNDED, it only means, there is an unbounded ray,
2405 * but not necessarily a feasible primal solution. If problem is declared LP_UNBOUNDED by dual,
2406 * we have no way to decide primal feasibility.
2407 */
2408
2409 return lpi->solstat == XPRS_LP_UNBOUNDED && lpi->solmethod == 'p';
2410}
2411
2412/** returns TRUE iff LP is proven to be primal infeasible */
2414 SCIP_LPI* lpi /**< LP interface structure */
2415 )
2416{
2417 assert(lpi != NULL);
2418 assert(lpi->xprslp != NULL);
2419 assert(lpi->solstat >= 0);
2420
2421 SCIPdebugMessage("checking for primal infeasibility\n");
2422
2423 return (lpi->solstat == XPRS_LP_INFEAS);
2424}
2425
2426/** returns TRUE iff LP is proven to be primal feasible */
2428 SCIP_LPI* lpi /**< LP interface structure */
2429 )
2430{
2431 int nInfeasible;
2432 int nIter;
2433
2434 assert(lpi != NULL);
2435 assert(lpi->xprslp != NULL);
2436 assert(lpi->solstat >= 0);
2437
2438 SCIPdebugMessage("checking for primal feasibility\n");
2439
2440 /* check if problem is solved to optimality */
2441 if (lpi->solstat == XPRS_LP_OPTIMAL || lpi->solstat == XPRS_LP_OPTIMAL_SCALEDINFEAS)
2442 return TRUE;
2443
2444 /* check if problem is unbounded (found by primal) */
2445 if (lpi->solstat == XPRS_LP_UNBOUNDED && lpi->solmethod == 'p')
2446 return TRUE;
2447
2448 /* get number of primal infeasibilities and number of simplex iterations */
2449 ABORT_ZERO( lpi->messagehdlr, FALSE, XPRSgetintattrib(lpi->xprslp, XPRS_PRIMALINFEAS, &nInfeasible) );
2450 ABORT_ZERO( lpi->messagehdlr, FALSE, XPRSgetintattrib(lpi->xprslp, XPRS_SIMPLEXITER, &nIter) );
2451
2452 /* check if the number of primal infeasibilities is zero
2453 * We need to make sure that the LP was indeed solved by primal, otherwise infeasibility might have been found
2454 * in setup (e.g. if conflicting bounds x >= 1, x <= 0 are present),
2455 */
2456 if (nInfeasible == 0 && nIter > 0 && lpi->solmethod == 'p')
2457 return TRUE;
2458
2459 return FALSE;
2460}
2461
2462/** returns TRUE iff LP is proven to have a dual unbounded ray (but not necessary a dual feasible point);
2463 * this does not necessarily mean, that the solver knows and can return the dual ray
2464 */
2466 SCIP_LPI* lpi /**< LP interface structure */
2467 )
2468{
2469 assert(lpi != NULL);
2470 assert(lpi->xprslp != NULL);
2471 assert(lpi->solstat >= 0);
2472
2473 return (lpi->solstat == XPRS_LP_INFEAS);
2474}
2475
2476/** returns TRUE iff LP is proven to have a dual unbounded ray (but not necessary a dual feasible point),
2477 * and the solver knows and can return the dual ray
2478 */
2480 SCIP_LPI* lpi /**< LP interface structure */
2481 )
2482{
2483 int hasRay;
2484
2485 assert(lpi != NULL);
2486 assert(lpi->xprslp != NULL);
2487 assert(lpi->solstat >= 0);
2488
2489 ABORT_ZERO( lpi->messagehdlr, FALSE, XPRSgetdualray(lpi->xprslp, NULL, &hasRay) );
2490
2491 return (SCIP_Bool) hasRay;
2492}
2493
2494/** returns TRUE iff LP is proven to be dual unbounded */
2496 SCIP_LPI* lpi /**< LP interface structure */
2497 )
2498{
2499 assert(lpi != NULL);
2500 assert(lpi->xprslp != NULL);
2501 assert(lpi->solstat >= 0);
2502
2503 SCIPdebugMessage("checking for dual unboundedness\n");
2504
2505 return ((lpi->solstat == XPRS_LP_INFEAS) && (lpi->solmethod == 'd'));
2506}
2507
2508/** returns TRUE iff LP is proven to be dual infeasible */
2510 SCIP_LPI* lpi /**< LP interface structure */
2511 )
2512{
2513 assert(lpi != NULL);
2514 assert(lpi->xprslp != NULL);
2515 assert(lpi->solstat >= 0);
2516
2517 SCIPdebugMessage("checking for dual infeasibility\n");
2518
2519 return (lpi->solstat == XPRS_LP_UNBOUNDED);
2520}
2521
2522/** returns TRUE iff LP is proven to be dual feasible */
2524 SCIP_LPI* lpi /**< LP interface structure */
2525 )
2526{
2527 int nInfeasible;
2528 int nIter;
2529
2530 assert(lpi != NULL);
2531 assert(lpi->xprslp != NULL);
2532 assert(lpi->solstat >= 0);
2533
2534 SCIPdebugMessage("checking for dual feasibility\n");
2535
2536 /* check if problem solved to optimality */
2537 if (lpi->solstat == XPRS_LP_OPTIMAL || lpi->solstat == XPRS_LP_OPTIMAL_SCALEDINFEAS)
2538 return TRUE;
2539
2540 /* check if problem infeasibility detected by dual */
2541 if (lpi->solstat == XPRS_LP_INFEAS && lpi->solmethod == 'd')
2542 return TRUE;
2543
2544 /* get number of dual infeasibilities and number of simplex iterations */
2545 ABORT_ZERO( lpi->messagehdlr, FALSE, XPRSgetintattrib(lpi->xprslp, XPRS_DUALINFEAS, &nInfeasible) );
2546 ABORT_ZERO( lpi->messagehdlr, FALSE, XPRSgetintattrib(lpi->xprslp, XPRS_SIMPLEXITER, &nIter) );
2547
2548 /* check if the number of dual infeasibilities is zero
2549 * We need to make sure that the LP was indeed solved by primal, otherwise infeasibility might have been found
2550 * in setup (e.g. if conflicting bounds x >= 1, x <= 0 are present),
2551 */
2552 if (nInfeasible == 0 && nIter > 0 && lpi->solmethod == 'd')
2553 return TRUE;
2554
2555 return FALSE;
2556}
2557
2558/** returns TRUE iff LP was solved to optimality */
2560 SCIP_LPI* lpi /**< LP interface structure */
2561 )
2562{
2563 assert(lpi != NULL);
2564 assert(lpi->xprslp != NULL);
2565 assert(lpi->solstat >= 0);
2566
2567 return (lpi->solstat == XPRS_LP_OPTIMAL) || (lpi->solstat == XPRS_LP_OPTIMAL_SCALEDINFEAS);
2568}
2569
2570/** returns TRUE iff current LP solution is stable
2571 *
2572 * This function should return true if the solution is reliable, i.e., feasible and optimal (or proven
2573 * infeasible/unbounded) with respect to the original problem. The optimality status might be with respect to a scaled
2574 * version of the problem, but the solution might not be feasible to the unscaled original problem; in this case,
2575 * SCIPlpiIsStable() should return false.
2576 */
2578 SCIP_LPI* lpi /**< LP interface structure */
2579 )
2580{
2581 assert(lpi != NULL);
2582 assert(lpi->xprslp != NULL);
2583 assert(lpi->solstat >= 0);
2584
2585 SCIPdebugMessage("checking for stability: Xpress solstat = %d\n", lpi->solstat);
2586
2587#ifdef SCIP_DISABLED_CODE
2588 /* The following workaround is not needed anymore for SCIP, since it tries to heuristically construct a feasible
2589 * solution or automatically resolves the problem if the status is "unbounded"; see SCIPlpGetUnboundedSol().
2590 */
2591
2592 /* If the solution status of Xpress is XPRS_LP_UNBOUNDED, it only means, there is an unbounded ray,
2593 * but not necessarily a feasible primal solution. If primalfeasible == FALSE, we interpret this
2594 * result as instability, s.t. the problem is resolved from scratch
2595 */
2596 if( lpi->solstat == XPRS_LP_UNBOUNDED )
2597 {
2598 int retcode;
2599 int pinfeas;
2600
2601 retcode = XPRSgetintattrib(lpi->xprslp, XPRS_PRIMALINFEAS, &pinfeas);
2602
2603 if( retcode != 0 || pinfeas )
2604 return FALSE;
2605 }
2606#endif
2607
2609 {
2610 /* presolved problem was solved to optimality but infeasibilities were introduced by postsolve */
2611 return FALSE;
2612 }
2613
2614 return TRUE;
2615}
2616
2617/** returns TRUE iff the objective limit was reached */
2619 SCIP_LPI* lpi /**< LP interface structure */
2620 )
2621{
2622 assert(lpi != NULL);
2623 assert(lpi->xprslp != NULL);
2624 assert(lpi->solstat >= 0);
2625
2626 return (lpi->solstat == XPRS_LP_CUTOFF || lpi->solstat == XPRS_LP_CUTOFF_IN_DUAL);
2627}
2628
2629/** returns TRUE iff the iteration limit was reached */
2631 SCIP_LPI* lpi /**< LP interface structure */
2632 )
2633{
2634 int lpiter;
2635 int lpiterlimit;
2636
2637 assert(lpi != NULL);
2638 assert(lpi->xprslp != NULL);
2639 assert(lpi->solstat >= 0);
2640
2641 ABORT_ZERO( lpi->messagehdlr, TRUE, XPRSgetintattrib(lpi->xprslp, XPRS_SIMPLEXITER, &lpiter) );
2642 ABORT_ZERO( lpi->messagehdlr, TRUE, XPRSgetintcontrol(lpi->xprslp, XPRS_LPITERLIMIT, &lpiterlimit) );
2643
2644 if( (lpi->solstat == XPRS_LP_UNFINISHED) && (lpiter >= lpiterlimit) )
2645 return TRUE;
2646 else
2647 return FALSE;
2648}
2649
2650/** returns TRUE iff the time limit was reached */
2652 SCIP_LPI* lpi /**< LP interface structure */
2653 )
2654{
2655 int lpiter;
2656 int lpiterlimit;
2657
2658 assert(lpi != NULL);
2659 assert(lpi->xprslp != NULL);
2660 assert(lpi->solstat >= 0);
2661
2662 ABORT_ZERO( lpi->messagehdlr, TRUE, XPRSgetintattrib(lpi->xprslp, XPRS_SIMPLEXITER, &lpiter) );
2663 ABORT_ZERO( lpi->messagehdlr, TRUE, XPRSgetintcontrol(lpi->xprslp, XPRS_LPITERLIMIT, &lpiterlimit) );
2664
2665 if( (lpi->solstat == XPRS_LP_UNFINISHED) && (lpiter < lpiterlimit) )
2666 return TRUE;
2667 else
2668 return FALSE;
2669}
2670
2671/** returns the internal solution status of the solver */
2673 SCIP_LPI* lpi /**< LP interface structure */
2674 )
2675{
2676 assert(lpi != NULL);
2677 assert(lpi->xprslp != NULL);
2678
2679 return lpi->solstat;
2680}
2681
2682/** tries to reset the internal status of the LP solver in order to ignore an instability of the last solving call */
2684 SCIP_LPI* lpi, /**< LP interface structure */
2685 SCIP_Bool* success /**< pointer to store, whether the instability could be ignored */
2686 )
2687{
2688 assert(lpi != NULL);
2689 assert(lpi->xprslp != NULL);
2690 assert(success != NULL);
2691
2692 /* Nothing to do here for Xpress. */
2693 *success = TRUE;
2694
2695 return SCIP_OKAY;
2696}
2697
2698/** gets objective value of solution */
2700 SCIP_LPI* lpi, /**< LP interface structure */
2701 SCIP_Real* objval /**< stores the objective value */
2702 )
2703{
2704 assert(lpi != NULL);
2705 assert(lpi->xprslp != NULL);
2706 assert(objval != NULL);
2707
2708 SCIPdebugMessage("getting solution's objective value\n");
2709
2710 CHECK_ZERO( lpi->messagehdlr, XPRSgetdblattrib(lpi->xprslp, XPRS_LPOBJVAL, objval) );
2711
2712 return SCIP_OKAY;
2713}
2714
2715/** gets primal and dual solution vectors for feasible LPs
2716 *
2717 * Before calling this function, the caller must ensure that the LP has been solved to optimality, i.e., that
2718 * SCIPlpiIsOptimal() returns true.
2719 */
2721 SCIP_LPI* lpi, /**< LP interface structure */
2722 SCIP_Real* objval, /**< stores the objective value, may be NULL if not needed */
2723 SCIP_Real* primsol, /**< primal solution vector, may be NULL if not needed */
2724 SCIP_Real* dualsol, /**< dual solution vector, may be NULL if not needed */
2725 SCIP_Real* activity, /**< row activity vector, may be NULL if not needed */
2726 SCIP_Real* redcost /**< reduced cost vector, may be NULL if not needed */
2727 )
2728{
2729 assert(lpi != NULL);
2730 assert(lpi->xprslp != NULL);
2731 assert(lpi->solstat >= 0);
2732
2733 SCIPdebugMessage("getting solution\n");
2734
2735#if XPVERSION <= 40
2736 CHECK_ZERO( lpi->messagehdlr, XPRSgetsol(lpi->xprslp, primsol, activity, dualsol, redcost) );
2737#else
2738 CHECK_ZERO( lpi->messagehdlr, XPRSgetlpsol(lpi->xprslp, primsol, activity, dualsol, redcost) );
2739#endif
2740
2741 if( objval != NULL )
2742 {
2743 CHECK_ZERO( lpi->messagehdlr, XPRSgetdblattrib(lpi->xprslp, XPRS_LPOBJVAL, objval) );
2744 }
2745
2746 if( activity != NULL )
2747 {
2748 /* Convert the slack values into activity values. */
2749 int nrows;
2750 int r;
2751
2752 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows) );
2753
2754 SCIP_CALL( ensureSidechgMem(lpi, nrows) );
2755
2756 CHECK_ZERO( lpi->messagehdlr, XPRSgetrhs(lpi->xprslp, lpi->rhsarray, 0, nrows-1) );
2757
2758 for( r = 0; r < nrows; r++ )
2759 activity[r] = lpi->rhsarray[r] - activity[r];
2760 }
2761
2762 return SCIP_OKAY;
2763}
2764
2765/** gets primal ray for unbounded LPs */
2767 SCIP_LPI* lpi, /**< LP interface structure */
2768 SCIP_Real* ray /**< primal ray */
2769 )
2770{
2771 int hasRay;
2772
2773 assert(lpi != NULL);
2774 assert(lpi->xprslp != NULL);
2775 assert(ray != NULL);
2776 assert(lpi->solstat >= 0);
2777
2778 CHECK_ZERO( lpi->messagehdlr, XPRSgetprimalray(lpi->xprslp, ray, &hasRay) );
2779
2780 if( !hasRay )
2781 return SCIP_LPERROR;
2782
2783 return SCIP_OKAY;
2784}
2785
2786/** gets dual Farkas proof for infeasibility */
2788 SCIP_LPI* lpi, /**< LP interface structure */
2789 SCIP_Real* dualfarkas /**< dual Farkas row multipliers */
2790 )
2791{
2792 int hasRay;
2793
2794 assert(lpi != NULL);
2795 assert(lpi->xprslp != NULL);
2796 assert(lpi->solstat >= 0);
2797 assert(dualfarkas != NULL);
2798
2799 /**@note The Farkas proof might be numerically questionable which is indicated by "hasRay" use SCIPlpiHasDualRay() to
2800 * check that!
2801 */
2802 CHECK_ZERO( lpi->messagehdlr, XPRSgetdualray(lpi->xprslp, dualfarkas, &hasRay) );
2803
2804 return SCIP_OKAY;
2805}
2806
2807/** gets the number of LP iterations of the last solve call */
2809 SCIP_LPI* lpi, /**< LP interface structure */
2810 int* iterations /**< pointer to store the number of iterations of the last solve call */
2811 )
2812{
2813 assert(lpi != NULL);
2814 assert(lpi->xprslp != NULL);
2815 assert(iterations != NULL);
2816
2817 *iterations = lpi->iterations;
2818
2819 return SCIP_OKAY;
2820}
2821
2822/** gets information about the quality of an LP solution
2823 *
2824 * Such information is usually only available, if also a (maybe not optimal) solution is available.
2825 * The LPI should return SCIP_INVALID for @p quality, if the requested quantity is not available.
2826 */
2828 SCIP_LPI* lpi, /**< LP interface structure */
2829 SCIP_LPSOLQUALITY qualityindicator, /**< indicates which quality should be returned */
2830 SCIP_Real* quality /**< pointer to store quality number */
2831 )
2832{ /*lint --e{715}*/
2833 assert(lpi != NULL);
2834 assert(quality != NULL);
2835 SCIP_UNUSED(qualityindicator);
2836
2837 *quality = SCIP_INVALID;
2838
2839 return SCIP_OKAY;
2840}
2841
2842/**@} */
2843
2844
2845/**@name LP Basis Methods
2846 *
2847 * @{
2848 */
2849
2850/** gets current basis status for columns and rows; arrays must be large enough to store the basis status */
2852 SCIP_LPI* lpi, /**< LP interface structure */
2853 int* cstat, /**< array to store column basis status, or NULL */
2854 int* rstat /**< array to store row basis status, or NULL (the status is need for the row and not for the slack column) */
2855 )
2856{
2857 int nrows;
2858 int r;
2859
2860 assert(lpi != NULL);
2861 assert(lpi->xprslp != NULL);
2862
2863 /*lint --e{506}*/
2864 assert((int) SCIP_BASESTAT_LOWER == 0);
2865 assert((int) SCIP_BASESTAT_BASIC == 1);
2866 assert((int) SCIP_BASESTAT_UPPER == 2);
2867
2868 SCIPdebugMessage("saving Xpress basis into %p/%p\n", (void*)rstat, (void*)cstat);
2869
2870 /* get the basis status */
2871 CHECK_ZERO( lpi->messagehdlr, XPRSgetbasis(lpi->xprslp, rstat, cstat) );
2872
2873 /* get the number of rows */
2874 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows) );
2875
2876 /* XPRSgetbasis collects the basis status for the column and the slack column, since SCIP request the basis for
2877 * columns and rows we need to convert slack column status to row status
2878 */
2879 for( r = 0; r < nrows; ++r )
2880 {
2881 if (rstat[r] == (int) SCIP_BASESTAT_LOWER)
2882 rstat[r] = (int) SCIP_BASESTAT_UPPER;
2883 else if (rstat[r] == (int) SCIP_BASESTAT_UPPER)
2884 rstat[r] = (int) SCIP_BASESTAT_LOWER;
2885 }
2886
2887 return SCIP_OKAY;
2888}
2889
2890/** sets current basis status for columns and rows */
2892 SCIP_LPI* lpi, /**< LP interface structure */
2893 const int* cstat, /**< array with column basis status */
2894 const int* rstat /**< array with row basis status */
2895 )
2896{
2897 int* slackstats;
2898 int ncols;
2899 int nrows;
2900 int r;
2901
2902 assert(lpi != NULL);
2903 assert(lpi->xprslp != NULL);
2904
2905 /* get the number of rows/columns */
2906 SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
2907 SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
2908
2909 assert(cstat != NULL || ncols == 0);
2910 assert(rstat != NULL || nrows == 0);
2911
2912 /*lint --e{506}*/
2913 assert((int) SCIP_BASESTAT_LOWER == 0);
2914 assert((int) SCIP_BASESTAT_BASIC == 1);
2915 assert((int) SCIP_BASESTAT_UPPER == 2);
2916
2917 SCIPdebugMessage("loading basis %p/%p into Xpress\n", (void*)rstat, (void*)cstat);
2918
2919 invalidateSolution(lpi);
2920
2921 SCIP_ALLOC( BMSallocMemoryArray(&slackstats, nrows) );
2922
2923 /* XPRSloadbasis expects the basis status for the column and the slack column, since SCIP has the basis status for
2924 * columns and rows we need to convert row status to slack column status
2925 */
2926 for( r = 0; r < nrows; ++r )
2927 {
2928 if (rstat[r] == (int) SCIP_BASESTAT_LOWER) /*lint !e613*/
2929 slackstats[r] = (int) SCIP_BASESTAT_UPPER;
2930 else if (rstat[r] == (int) SCIP_BASESTAT_UPPER) /*lint !e613*/
2931 slackstats[r] = (int) SCIP_BASESTAT_LOWER;
2932 else
2933 slackstats[r] = rstat[r]; /*lint !e613*/
2934 }
2935
2936 /* load basis information into Xpress
2937 *
2938 * @note Xpress expects the row status w.r.t. slack columns!
2939 */
2940 CHECK_ZERO( lpi->messagehdlr, XPRSloadbasis(lpi->xprslp, slackstats, cstat) );
2941
2942 BMSfreeMemoryArray(&slackstats);
2943
2944 lpi->clearstate = FALSE;
2945
2946 return SCIP_OKAY;
2947}
2948
2949/** returns the indices of the basic columns and rows; basic column n gives value n, basic row m gives value -1-m */
2951 SCIP_LPI* lpi, /**< LP interface structure */
2952 int* bind /**< pointer to store basis indices ready to keep number of rows entries */
2953 )
2954{
2955 int irspace;
2956 int nrows;
2957 int r;
2958
2959 /* In the basis methods we assume that xprs basis flags coincide with scip, so assert it */
2960 /*lint --e{506}*/
2961 assert((int) SCIP_BASESTAT_LOWER == 0);
2962 assert((int) SCIP_BASESTAT_BASIC == 1);
2963 assert((int) SCIP_BASESTAT_UPPER == 2);
2964 assert((int) SCIP_BASESTAT_ZERO == 3);
2965
2966 assert(lpi != NULL);
2967 assert(lpi->xprslp != NULL);
2968 assert(bind != NULL);
2969
2970 SCIPdebugMessage("getting basis information\n");
2971
2972 CHECK_ZERO( lpi->messagehdlr, XPRSgetpivotorder(lpi->xprslp, bind) );
2973
2974 /* Reindex variables to match those of SCIP. */
2975 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows) );
2976 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_SPAREROWS, &irspace) );
2977 irspace += nrows;
2978
2979 for( r = 0; r < nrows; r++ )
2980 {
2981 if( bind[r] < nrows )
2982 bind[r] = -bind[r]-1;
2983 else
2984 {
2985 assert(bind[r] >= irspace);
2986 bind[r] = bind[r] - irspace;
2987 }
2988 }
2989
2990 return SCIP_OKAY;
2991}
2992
2993/** get row of inverse basis matrix B^-1
2994 *
2995 * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
2996 * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
2997 * see also the explanation in lpi.h.
2998 *
2999 * @todo check that the result is in terms of the LP interface definition
3000 */
3002 SCIP_LPI* lpi, /**< LP interface structure */
3003 int row, /**< row number */
3004 SCIP_Real* coef, /**< pointer to store the coefficients of the row */
3005 int* inds, /**< array to store the non-zero indices, or NULL */
3006 int* ninds /**< pointer to store the number of non-zero indices, or NULL
3007 * (-1: if we do not store sparsity information) */
3008 )
3009{ /*lint --e{715}*/
3010 int nrows;
3011
3012 assert(lpi != NULL);
3013 assert(lpi->xprslp != NULL);
3014 assert(coef != NULL);
3015 SCIP_UNUSED(inds);
3016
3017 SCIPdebugMessage("getting binv-row %d\n", row);
3018
3019 /* can only return dense result */
3020 if ( ninds != NULL )
3021 *ninds = -1;
3022
3023 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows) );
3024 BMSclearMemoryArray(coef, nrows);
3025 coef[row] = 1.0;
3026 CHECK_ZERO( lpi->messagehdlr, XPRSbtran(lpi->xprslp, coef) );
3027
3028 return SCIP_OKAY;
3029}
3030
3031/** get column of inverse basis matrix B^-1
3032 *
3033 * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
3034 * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
3035 * see also the explanation in lpi.h.
3036 *
3037 * @todo check that the result is in terms of the LP interface definition
3038 */
3040 SCIP_LPI* lpi, /**< LP interface structure */
3041 int c, /**< column number of B^-1; this is NOT the number of the column in the LP;
3042 * you have to call SCIPlpiGetBasisInd() to get the array which links the
3043 * B^-1 column numbers to the row and column numbers of the LP!
3044 * c must be between 0 and nrows-1, since the basis has the size
3045 * nrows * nrows */
3046 SCIP_Real* coef, /**< pointer to store the coefficients of the column */
3047 int* inds, /**< array to store the non-zero indices, or NULL */
3048 int* ninds /**< pointer to store the number of non-zero indices, or NULL
3049 * (-1: if we do not store sparsity information) */
3050 )
3051{ /*lint --e{715}*/
3052 int nrows;
3053
3054 assert(lpi != NULL);
3055 assert(lpi->xprslp != NULL);
3056 assert(coef != NULL);
3057 SCIP_UNUSED(inds);
3058
3059 SCIPdebugMessage("getting binv-col %d\n", c);
3060
3061 /* can only return dense result */
3062 if ( ninds != NULL )
3063 *ninds = -1;
3064
3065 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows) );
3066 BMSclearMemoryArray(coef, nrows);
3067 coef[c] = 1.0;
3068 CHECK_ZERO( lpi->messagehdlr, XPRSftran(lpi->xprslp, coef) );
3069
3070 return SCIP_OKAY;
3071}
3072
3073/** get row of inverse basis matrix times constraint matrix B^-1 * A
3074 *
3075 * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
3076 * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
3077 * see also the explanation in lpi.h.
3078 *
3079 * @todo check that the result is in terms of the LP interface definition
3080 */
3082 SCIP_LPI* lpi, /**< LP interface structure */
3083 int r, /**< row number */
3084 const SCIP_Real* binvrow, /**< row in (A_B)^-1 from prior call to SCIPlpiGetBInvRow(), or NULL */
3085 SCIP_Real* coef, /**< vector to return coefficients of the row */
3086 int* inds, /**< array to store the non-zero indices, or NULL */
3087 int* ninds /**< pointer to store the number of non-zero indices, or NULL
3088 * (-1: if we do not store sparsity information) */
3089 )
3090{ /*lint --e{715}*/
3091 SCIP_Real* binv;
3092 SCIP_Real* buffer;
3093 int ncols;
3094 int nrows;
3095 int nnonz;
3096 int c;
3097
3098 assert(lpi != NULL);
3099 assert(lpi->xprslp != NULL);
3100 assert(coef != NULL);
3101
3102 SCIPdebugMessage("getting binva-row %d\n", r);
3103
3104 /* can only return dense result */
3105 if ( ninds != NULL )
3106 *ninds = -1;
3107
3108 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows) );
3109 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_COLS, &ncols) );
3110
3111 buffer = NULL;
3112
3113 /* get (or calculate) the row in B^-1 */
3114 if( binvrow == NULL )
3115 {
3116 SCIP_ALLOC( BMSallocMemoryArray(&buffer, nrows) );
3117 SCIP_CALL( SCIPlpiGetBInvRow(lpi, r, buffer, inds, ninds) );
3118 binv = buffer;
3119 }
3120 else
3121 binv = (double*) binvrow;
3122
3123 /* We need space to extract a single column. */
3124 SCIP_CALL( ensureValMem(lpi, nrows) );
3125
3126 for( c = 0; c < ncols; c++ )
3127 {
3128 int i;
3129
3130 coef[c] = 0;
3131
3132 /* Extract the column. */
3133 CHECK_ZERO( lpi->messagehdlr, XPRSgetcols(lpi->xprslp, NULL, lpi->indarray, lpi->valarray, nrows, &nnonz, c, c) );
3134 assert(nnonz <= nrows);
3135
3136 /* Price out the column. */
3137 for( i = 0; i < nnonz; i++ )
3138 coef[c] += binv[lpi->indarray[i]] * lpi->valarray[i];
3139 }
3140
3141 /* Free allocated memory. */
3142 BMSfreeMemoryArrayNull(&buffer);
3143
3144 return SCIP_OKAY;
3145}
3146
3147/** get column of inverse basis matrix times constraint matrix B^-1 * A
3148 *
3149 * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
3150 * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
3151 * see also the explanation in lpi.h.
3152 *
3153 * @todo check that the result is in terms of the LP interface definition
3154 */
3156 SCIP_LPI* lpi, /**< LP interface structure */
3157 int c, /**< column number */
3158 SCIP_Real* coef, /**< vector to return coefficients of the column */
3159 int* inds, /**< array to store the non-zero indices, or NULL */
3160 int* ninds /**< pointer to store the number of non-zero indices, or NULL
3161 * (-1: if we do not store sparsity information) */
3162 )
3163{ /*lint --e{715}*/
3164 int nrows;
3165 int nnonz;
3166 int i;
3167
3168 /* Ftran */
3169
3170 assert(lpi != NULL);
3171 assert(lpi->xprslp != NULL);
3172 assert(coef != NULL);
3173 SCIP_UNUSED(inds);
3174
3175 SCIPdebugMessage("getting binv-col %d\n", c);
3176
3177 /* can only return dense result */
3178 if ( ninds != NULL )
3179 *ninds = -1;
3180
3181 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows) );
3182
3183 /* We need space to extract the column. */
3184 SCIP_CALL( ensureValMem(lpi, nrows) );
3185
3186 /* Get the column to transform. */
3187 CHECK_ZERO( lpi->messagehdlr, XPRSgetcols(lpi->xprslp, NULL, lpi->indarray, lpi->valarray, nrows, &nnonz, c, c) );
3188 assert(nnonz <= nrows);
3189
3190 /* Transform the column. */
3191 BMSclearMemoryArray(coef, nrows);
3192 for( i = 0; i < nnonz; i++ )
3193 coef[lpi->indarray[i]] = lpi->valarray[i];
3194
3195 CHECK_ZERO( lpi->messagehdlr, XPRSftran(lpi->xprslp, coef) );
3196
3197 return SCIP_OKAY;
3198}
3199
3200/**@} */
3201
3202
3203/**@name LP State Methods
3204 *
3205 * @{
3206 */
3207
3208/** stores LPi state (like basis information) into lpistate object */
3210 SCIP_LPI* lpi, /**< LP interface structure */
3211 BMS_BLKMEM* blkmem, /**< block memory */
3212 SCIP_LPISTATE** lpistate /**< pointer to LPi state information (like basis information) */
3213 )
3214{
3215 int ncols;
3216 int nrows;
3217
3218 assert(blkmem != NULL);
3219 assert(lpi != NULL);
3220 assert(lpi->xprslp != NULL);
3221 assert(lpistate != NULL);
3222
3223 /* if there is no basis information available (e.g. after barrier without crossover), or no state can be saved; if
3224 * SCIPlpiClearState() has been called, do not return the state
3225 */
3226 if( !lpi->solisbasic || lpi->clearstate )
3227 {
3228 *lpistate = NULL;
3229 return SCIP_OKAY;
3230 }
3231
3232 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows) );
3233 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_COLS, &ncols) );
3234 assert(ncols >= 0);
3235 assert(nrows >= 0);
3236
3237 /* allocate lpistate data */
3238 SCIP_CALL( lpistateCreate(lpistate, blkmem, ncols, nrows) );
3239
3240 SCIPdebugMessage("storing Xpress LPI state in %p (%d cols, %d rows)\n", (void*)*lpistate, ncols, nrows);
3241
3242 /* allocate enough memory for storing uncompressed basis information */
3243 SCIP_CALL( ensureCstatMem(lpi, ncols) );
3244 SCIP_CALL( ensureRstatMem(lpi, nrows) );
3245
3246 /* get unpacked basis information from Xpress
3247 *
3248 * @note The row status is w.r.t. slack columns!
3249 */
3250 CHECK_ZERO( lpi->messagehdlr, XPRSgetbasis(lpi->xprslp, lpi->rstat, lpi->cstat) );
3251
3252 /* pack LPi state data */
3253 (*lpistate)->ncols = ncols;
3254 (*lpistate)->nrows = nrows;
3255 lpistatePack(*lpistate, lpi->cstat, lpi->rstat);
3256
3257 return SCIP_OKAY;
3258}
3259
3260/** loads LPi state (like basis information) into solver; note that the LP might have been extended with additional
3261 * columns and rows since the state was stored with SCIPlpiGetState()
3262 */
3264 SCIP_LPI* lpi, /**< LP interface structure */
3265 BMS_BLKMEM* blkmem, /**< block memory */
3266 const SCIP_LPISTATE* lpistate /**< LPi state information (like basis information), or NULL */
3267 )
3268{
3269 int nrows;
3270 int ncols;
3271 int i;
3272
3273 assert(blkmem != NULL);
3274 assert(lpi != NULL);
3275 assert(lpi->xprslp != NULL);
3276
3277 /* if there was no basis information available, the LPI state was not stored */
3278 if( lpistate == NULL )
3279 return SCIP_OKAY;
3280
3281 if( lpistate->ncols == 0 || lpistate->nrows == 0 )
3282 return SCIP_OKAY;
3283
3284 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows) );
3285 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_COLS, &ncols) );
3286
3287 /* the dimension of the lpi state should not be larger than the current problem; it might be that columns and rows
3288 * are added since the saving of the lpi state
3289 */
3290 assert(lpistate->ncols <= ncols);
3291 assert(lpistate->nrows <= nrows);
3292
3293 SCIPdebugMessage("loading LPI state %p (%d cols, %d rows) into Xpress\n", (void*)lpistate, lpistate->ncols, lpistate->nrows);
3294
3295 /* allocate enough memory for storing uncompressed basis information */
3296 SCIP_CALL( ensureCstatMem(lpi, ncols) );
3297 SCIP_CALL( ensureRstatMem(lpi, nrows) );
3298
3299 /* unpack LPi state data
3300 *
3301 * @note The row status is w.r.t. slack column!
3302 */
3303 lpistateUnpack(lpistate, lpi->cstat, lpi->rstat);
3304
3305 /* extend the basis to the current LP beyond the previously existing columns */
3306 for( i = lpistate->ncols; i < ncols; ++i )
3307 {
3308 SCIP_Real bnd;
3309
3310 CHECK_ZERO( lpi->messagehdlr, XPRSgetlb(lpi->xprslp, &bnd, i, i) );
3311
3312 if( SCIPlpiIsInfinity(lpi, REALABS(bnd)) )
3313 {
3314 /* if lower bound is +/- infinity -> try upper bound */
3315 CHECK_ZERO( lpi->messagehdlr, XPRSgetub(lpi->xprslp, &bnd, i, i) );
3316
3317 if( SCIPlpiIsInfinity(lpi, REALABS(bnd)) )
3318 lpi->cstat[i] = (int) SCIP_BASESTAT_ZERO; /* variable is free */
3319 else
3320 lpi->cstat[i] = (int) SCIP_BASESTAT_UPPER; /* use finite upper bound */
3321 }
3322 else
3323 lpi->cstat[i] = (int) SCIP_BASESTAT_LOWER; /* use finite lower bound */
3324 }
3325 for( i = lpistate->nrows; i < nrows; ++i )
3326 lpi->rstat[i] = (int) SCIP_BASESTAT_BASIC;
3327
3328 /* load basis information into Xpress
3329 *
3330 * @note Xpress expects the row status w.r.t. slack columns!
3331 */
3332 CHECK_ZERO( lpi->messagehdlr, XPRSloadbasis(lpi->xprslp, lpi->rstat, lpi->cstat) );
3333
3334 lpi->clearstate = FALSE;
3335
3336 return SCIP_OKAY;
3337}
3338
3339/** clears current LPi state (like basis information) of the solver */
3341 SCIP_LPI* lpi /**< LP interface structure */
3342 )
3343{
3344 assert(lpi != NULL);
3345
3346 /* set KEEPBASIS to 0 for the next solve */
3347 lpi->clearstate = TRUE;
3348
3349 return SCIP_OKAY;
3350}
3351
3352/** frees LPi state information */
3354 SCIP_LPI* lpi, /**< LP interface structure */
3355 BMS_BLKMEM* blkmem, /**< block memory */
3356 SCIP_LPISTATE** lpistate /**< pointer to LPi state information (like basis information) */
3357 )
3358{
3359 assert(lpi != NULL);
3360 assert(lpistate != NULL);
3361 assert(blkmem != NULL);
3362
3363 if( *lpistate != NULL )
3364 {
3365 lpistateFree(lpistate, blkmem);
3366 }
3367
3368 return SCIP_OKAY;
3369}
3370
3371/** checks, whether the given LP state contains simplex basis information */
3373 SCIP_LPI* lpi, /**< LP interface structure */
3374 SCIP_LPISTATE* lpistate /**< LP state information (like basis information), or NULL */
3375 )
3376{ /*lint --e{715}*/
3377 assert(lpi != NULL);
3378 return (lpistate != NULL);
3379}
3380
3381/** reads LP state (like basis information from a file */
3383 SCIP_LPI* lpi, /**< LP interface structure */
3384 const char* fname /**< file name */
3385 )
3386{
3387 assert(lpi != NULL);
3388 assert(lpi->xprslp != NULL);
3389 assert(fname != NULL);
3390
3391 SCIPdebugMessage("reading LP state from file <%s>\n", fname);
3392
3393 CHECK_ZERO( lpi->messagehdlr, XPRSreadbasis(lpi->xprslp, fname, "") );
3394
3395 return SCIP_OKAY;
3396}
3397
3398/** writes LPi state (i.e. basis information) to a file */
3400 SCIP_LPI* lpi, /**< LP interface structure */
3401 const char* fname /**< file name */
3402 )
3403{
3404 assert(lpi != NULL);
3405 assert(lpi->xprslp != NULL);
3406 assert(fname != NULL);
3407
3408 SCIPdebugMessage("writing LP state to file <%s>\n", fname);
3409
3410 CHECK_ZERO( lpi->messagehdlr, XPRSwritebasis(lpi->xprslp, fname, "") );
3411
3412 return SCIP_OKAY;
3413}
3414
3415/**@} */
3416
3417
3418/**@name LP Pricing Norms Methods
3419 *
3420 * @{
3421 */
3422
3423/** stores LPi pricing norms information
3424 * @todo should we store norm information?
3425 */
3427 SCIP_LPI* lpi, /**< LP interface structure */
3428 BMS_BLKMEM* blkmem, /**< block memory */
3429 SCIP_LPINORMS** lpinorms /**< pointer to LPi pricing norms information */
3430 )
3431{ /*lint --e{715}*/
3432 assert(lpi != NULL);
3433 assert(blkmem != NULL);
3434 assert(lpinorms != NULL);
3435
3436 (*lpinorms) = NULL;
3437
3438 return SCIP_OKAY;
3439}
3440
3441/** loads LPi pricing norms into solver; note that the LP might have been extended with additional
3442 * columns and rows since the state was stored with SCIPlpiGetNorms()
3443 */
3445 SCIP_LPI* lpi, /**< LP interface structure */
3446 BMS_BLKMEM* blkmem, /**< block memory */
3447 const SCIP_LPINORMS* lpinorms /**< LPi pricing norms information, or NULL */
3448 )
3449{ /*lint --e{715}*/
3450 assert(lpi != NULL);
3451 assert(lpinorms == NULL);
3452 SCIP_UNUSED(blkmem);
3453
3454 /* no work necessary */
3455 return SCIP_OKAY;
3456}
3457
3458/** frees pricing norms information */
3460 SCIP_LPI* lpi, /**< LP interface structure */
3461 BMS_BLKMEM* blkmem, /**< block memory */
3462 SCIP_LPINORMS** lpinorms /**< pointer to LPi pricing norms information, or NULL */
3463 )
3464{ /*lint --e{715}*/
3465 assert(lpi != NULL);
3466 assert(lpinorms == NULL);
3467 SCIP_UNUSED(blkmem);
3468
3469 /* no work necessary */
3470 return SCIP_OKAY;
3471}
3472
3473/**@} */
3474
3475
3476/**@name Parameter Methods
3477 *
3478 * @{
3479 */
3480
3481/** gets integer parameter of LP */
3483 SCIP_LPI* lpi, /**< LP interface structure */
3484 SCIP_LPPARAM type, /**< parameter number */
3485 int* ival /**< buffer to store the parameter value */
3486 )
3487{
3488 int ictrlval;
3489
3490 assert(lpi != NULL);
3491 assert(lpi->xprslp != NULL);
3492 assert(ival != NULL);
3493
3494 SCIPdebugMessage("getting int parameter %d\n", type);
3495
3496 switch( type )
3497 {
3498 case SCIP_LPPAR_PRICING:
3499 *ival = (int)lpi->pricing;
3500 break;
3502#if 1
3503 *ival = (lpi->notfromscratch == 0);
3504#else
3505 CHECK_ZERO( lpi->messagehdlr, XPRSgetintcontrol(lpi->xprslp, XPRS_KEEPBASIS, &ictrlval) );
3506 *ival = (ictrlval == 0);
3507#endif
3508 break;
3509 case SCIP_LPPAR_SCALING:
3510 CHECK_ZERO( lpi->messagehdlr, XPRSgetintcontrol(lpi->xprslp, XPRS_SCALING, &ictrlval) );
3511 if( ictrlval == 0 )
3512 *ival = 0;
3513 else if( ictrlval == 16 )
3514 *ival = 2;
3515 else
3516 *ival = 1;
3517 break;
3519 *ival = lpi->par_presolve;
3520 break;
3521 case SCIP_LPPAR_LPINFO:
3522 CHECK_ZERO( lpi->messagehdlr, XPRSgetintcontrol(lpi->xprslp, XPRS_OUTPUTLOG, &ictrlval) );
3523 *ival = (ictrlval != 0);
3524 break;
3525 case SCIP_LPPAR_LPITLIM:
3526 CHECK_ZERO( lpi->messagehdlr, XPRSgetintcontrol(lpi->xprslp, XPRS_LPITERLIMIT, &ictrlval) );
3527 *ival = ictrlval;
3528 if( *ival >= XPRS_MAXINT )
3529 *ival = XPRS_MAXINT;
3530 break;
3531 case SCIP_LPPAR_THREADS:
3532 CHECK_ZERO( lpi->messagehdlr, XPRSgetintcontrol(lpi->xprslp, XPRS_THREADS, &ictrlval) );
3533 *ival = ictrlval;
3534 break;
3535 default:
3536 return SCIP_PARAMETERUNKNOWN;
3537 } /*lint !e788*/
3538
3539 return SCIP_OKAY;
3540}
3541
3542/** sets integer parameter of LP */
3544 SCIP_LPI* lpi, /**< LP interface structure */
3545 SCIP_LPPARAM type, /**< parameter number */
3546 int ival /**< parameter value */
3547 )
3548{
3549 assert(lpi != NULL);
3550 assert(lpi->xprslp != NULL);
3551
3552 SCIPdebugMessage("setting int parameter %d to %d\n", type, ival);
3553
3554 switch( type )
3555 {
3556 case SCIP_LPPAR_PRICING:
3557 /* every non-supported pricing strategy is promoted to the default pricing strategy */
3558 lpi->pricing = (SCIP_PRICING)ival; /* store pricing method in LPI struct */
3559 switch( lpi->pricing )
3560 {
3562 CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_PRICINGALG, XPRS_PRICING_PARTIAL) );
3563 break;
3564 case SCIP_PRICING_DEVEX:
3565 CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_PRICINGALG, XPRS_PRICING_DEVEX) );
3566 break;
3567 case SCIP_PRICING_AUTO:
3568 case SCIP_PRICING_FULL:
3570 case SCIP_PRICING_STEEP:
3572 default:
3573 CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_PRICINGALG, XPRS_PRICING_DEFAULT) );
3574 break;
3575 }
3576 break;
3578 assert(ival == TRUE || ival == FALSE);
3579 lpi->notfromscratch = (int)(!ival);
3580 CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_KEEPBASIS, (ival == FALSE) ? 1 : 0) );
3581 break;
3582 case SCIP_LPPAR_SCALING:
3583 assert(ival >= 0 && ival <= 2);
3584 if( ival == 0 )
3585 {
3586 CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_SCALING, 0) );
3587 }
3588 else if( ival == 1 )
3589 {
3590 CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_SCALING, 163) );
3591 }
3592 else
3593 {
3594 CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_SCALING, 16) );
3595 }
3596
3597 break;
3599 assert(ival == TRUE || ival == FALSE);
3600 lpi->par_presolve = ival;
3601 break;
3602 case SCIP_LPPAR_LPINFO:
3603 assert(ival == TRUE || ival == FALSE);
3604 CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_OUTPUTLOG, (ival == TRUE) ? 1 : 0) );
3605 break;
3606 case SCIP_LPPAR_LPITLIM:
3607 assert( ival >= 0 );
3608 /* 0 <= ival, 0 stopping immediately */
3609 ival = MIN(ival, XPRS_MAXINT); /*lint !e685*//*lint !e2650*//*lint !e587*/
3610 CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_LPITERLIMIT, ival) );
3611 break;
3612 case SCIP_LPPAR_THREADS:
3613 CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_THREADS, ival) );
3614 break;
3615 default:
3616 return SCIP_PARAMETERUNKNOWN;
3617 } /*lint !e788*/
3618
3619 return SCIP_OKAY;
3620}
3621
3622/** gets floating point parameter of LP */
3624 SCIP_LPI* lpi, /**< LP interface structure */
3625 SCIP_LPPARAM type, /**< parameter number */
3626 SCIP_Real* dval /**< buffer to store the parameter value */
3627 )
3628{
3629#if XPVERSION <= 40
3630 int ictrlval;
3631#endif
3632 double dctrlval;
3633
3634 assert(lpi != NULL);
3635 assert(lpi->xprslp != NULL);
3636 assert(dval != NULL);
3637
3638 SCIPdebugMessage("getting real parameter %d\n", type);
3639
3640 switch( type )
3641 {
3642 case SCIP_LPPAR_FEASTOL:
3643 CHECK_ZERO( lpi->messagehdlr, XPRSgetdblcontrol(lpi->xprslp, XPRS_FEASTOL, &dctrlval) );
3644 *dval = dctrlval;
3645 break;
3647 CHECK_ZERO( lpi->messagehdlr, XPRSgetdblcontrol(lpi->xprslp, XPRS_OPTIMALITYTOL, &dctrlval) );
3648 *dval = dctrlval;
3649 break;
3651 CHECK_ZERO( lpi->messagehdlr, XPRSgetdblcontrol(lpi->xprslp, XPRS_BARGAPSTOP, &dctrlval) );
3652 *dval = dctrlval;
3653 break;
3654 case SCIP_LPPAR_LPTILIM:
3655#if XPVERSION <= 40
3656 CHECK_ZERO( lpi->messagehdlr, XPRSgetintcontrol(lpi->xprslp, XPRS_MAXTIME, &ictrlval) );
3657 /* ictrlval is the negative of the timelimit (see SCIPlpiSetRealpar) */
3658 *dval = (double) -ictrlval;
3659#else
3660 CHECK_ZERO( lpi->messagehdlr, XPRSgetdblcontrol(lpi->xprslp, XPRS_TIMELIMIT, &dctrlval) );
3661 *dval = dctrlval;
3662#endif
3663 break;
3665 CHECK_ZERO( lpi->messagehdlr, XPRSgetdblcontrol(lpi->xprslp, XPRS_MARKOWITZTOL, &dctrlval) );
3666 *dval = dctrlval;
3667 break;
3668 case SCIP_LPPAR_OBJLIM:
3669 CHECK_ZERO( lpi->messagehdlr, XPRSgetdblcontrol(lpi->xprslp, XPRS_MIPABSCUTOFF, &dctrlval) );
3670 *dval = dctrlval;
3671 break;
3672 default:
3673 return SCIP_PARAMETERUNKNOWN;
3674 } /*lint !e788*/
3675
3676 return SCIP_OKAY;
3677}
3678
3679/** sets floating point parameter of LP */
3681 SCIP_LPI* lpi, /**< LP interface structure */
3682 SCIP_LPPARAM type, /**< parameter number */
3683 SCIP_Real dval /**< parameter value */
3684 )
3685{
3686 assert(lpi != NULL);
3687 assert(lpi->xprslp != NULL);
3688
3689 SCIPdebugMessage("setting real parameter %d to %g\n", type, dval);
3690
3691 switch( type )
3692 {
3693 case SCIP_LPPAR_FEASTOL:
3694 /* Xpress does not pose any restriction on dval, its absolute value is used as tolerance.
3695 * For consistency we assert it to be strictly positive.
3696 */
3697 assert( dval > 0.0 );
3698 CHECK_ZERO( lpi->messagehdlr, XPRSsetdblcontrol(lpi->xprslp, XPRS_FEASTOL, dval) );
3699 break;
3701 /* Xpress does not pose any restriction on dval,
3702 * however for consistency we assert it to be strictly positive.
3703 */
3704 assert( dval > 0.0 );
3705 CHECK_ZERO( lpi->messagehdlr, XPRSsetdblcontrol(lpi->xprslp, XPRS_OPTIMALITYTOL, dval) );
3706 break;
3708 assert( dval >= 0.0 );
3709 /* Xpress poses no restriction on dval
3710 * However for consistency we assert it to be nonnegative.
3711 */
3712 CHECK_ZERO( lpi->messagehdlr, XPRSsetdblcontrol(lpi->xprslp, XPRS_BARGAPSTOP, dval) );
3713 break;
3714 case SCIP_LPPAR_LPTILIM:
3715 {
3716#if XPVERSION <= 40
3717 int ival;
3718
3719 /* From the Xpress documentation:
3720 * dval>0 If an integer solution has been found, stop MIP search after dval seconds,
3721 * otherwise continue until an integer solution is finally found.
3722 * dval<0 Stop in LP or MIP search after dval seconds.
3723 * dval=0 No time limit
3724 */
3725 assert( dval > 0.0 );
3726 if( dval >= INT_MAX )
3727 ival = 0;
3728 else
3729 ival = (int) -floor(dval);
3730
3731 CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_MAXTIME, ival) );
3732#else
3733 CHECK_ZERO( lpi->messagehdlr, XPRSsetdblcontrol(lpi->xprslp, XPRS_TIMELIMIT, dval) );
3734#endif
3735 break;
3736 }
3738 /* no restriction on dval */
3739 CHECK_ZERO( lpi->messagehdlr, XPRSsetdblcontrol(lpi->xprslp, XPRS_MARKOWITZTOL, dval) );
3740 break;
3741 case SCIP_LPPAR_OBJLIM:
3742 /* no restriction on dval */
3743 CHECK_ZERO( lpi->messagehdlr, XPRSsetdblcontrol(lpi->xprslp, XPRS_MIPABSCUTOFF, dval) );
3744 break;
3745 default:
3746 return SCIP_PARAMETERUNKNOWN;
3747 } /*lint !e788*/
3748
3749 return SCIP_OKAY;
3750}
3751
3752/** interrupts the currently ongoing lp solve or disables the interrupt */
3754 SCIP_LPI* lpi, /**< LP interface structure */
3755 SCIP_Bool interrupt /**< TRUE if interrupt should be set, FALSE if it should be disabled */
3756 )
3757{
3758 /*lint --e{715}*/
3759 assert(lpi != NULL);
3760
3761 return SCIP_OKAY;
3762}
3763
3764/**@} */
3765
3766
3767/**@name Numerical Methods
3768 *
3769 * @{
3770 */
3771
3772/** returns value treated as infinity in the LP solver */
3774 SCIP_LPI* lpi /**< LP interface structure */
3775 )
3776{ /*lint --e{715}*/
3777 assert(lpi != NULL);
3778 return XPRS_PLUSINFINITY;
3779}
3780
3781/** checks if given value is treated as infinity in the LP solver */
3783 SCIP_LPI* lpi, /**< LP interface structure */
3784 SCIP_Real val /**< value to be checked for infinity */
3785 )
3786{ /*lint --e{715}*/
3787 assert(lpi != NULL);
3788 return (val >= XPRS_PLUSINFINITY);
3789}
3790
3791/**@} */
3792
3793
3794/**@name File Interface Methods
3795 *
3796 * @{
3797 */
3798
3799/** reads LP from a file
3800 *
3801 * The file extension defines the format. That can be lp or mps. Any given file name needs to have one of these two
3802 * extension. If not nothing is read and a SCIP_READERROR is returned.
3803 */
3805 SCIP_LPI* lpi, /**< LP interface structure */
3806 const char* fname /**< file name */
3807 )
3808{
3809 SCIP_RETCODE retcode = SCIP_OKAY;
3810
3811 char* basename = NULL;
3812 char* compression = NULL;
3813 char* extension = NULL;
3814 char* filename = NULL;
3815 char* path = NULL;
3816 char* xpressfilename = NULL;
3817
3818 int size;
3819
3820 assert(lpi != NULL);
3821 assert(lpi->xprslp != NULL);
3822 assert(fname != NULL);
3823
3824 SCIPdebugMessage("reading LP from file <%s>\n", fname);
3825
3826 /* get the length of the file name */
3827 size = (int)strlen(fname)+1;
3828
3829 /* check that the file name is longer than Xpress can handle */
3830 if (size > XPRS_MAXPROBNAMELENGTH)
3831 return SCIP_WRITEERROR;
3832
3833 /* get char array for the file name we pass to Xpress */
3834 SCIP_ALLOC( BMSallocMemoryArray(&xpressfilename, size) );
3835
3836 /* copy filename to be able to split it into its components */
3837 SCIP_ALLOC( BMSduplicateMemoryArray(&filename, fname, size) );
3838
3839 /* get path, base file name, extension, and compression of the given file name */
3840 SCIPsplitFilename(filename, &path, &basename, &extension, &compression);
3841
3842 /* construct file name without extension */
3843 if (path != NULL)
3844 (void) SCIPsnprintf(xpressfilename, size, "%s/%s", path, basename);
3845 else
3846 (void) SCIPsnprintf(xpressfilename, size, "%s", basename);
3847
3848 /* check that the file name did not has a compression extension, has an lp or mps extension, and actually a base name */
3849 if (compression != NULL || extension == NULL || basename == NULL)
3850 retcode = SCIP_READERROR;
3851 if (strcasecmp(extension, "mps") == 0) {
3852 CHECK_ZERO( lpi->messagehdlr, XPRSreadprob(lpi->xprslp, xpressfilename, "") );
3853 }
3854 else if (strcasecmp(extension, "lp") == 0) {
3855 CHECK_ZERO( lpi->messagehdlr, XPRSreadprob(lpi->xprslp, xpressfilename, "l") );
3856 }
3857 else
3858 retcode = SCIP_READERROR;
3859
3860 /* free array */
3861 BMSfreeMemoryArrayNull(&filename);
3862 BMSfreeMemoryArrayNull(&xpressfilename);
3863
3864 return retcode;
3865}
3866
3867/** writes LP to a file
3868 *
3869 * The file extension defines the format. That can be lp or mps. Any given file name needs to have one of these two
3870 * extension. If not nothing is written and a SCIP_WRITEERROR is returned.
3871 */
3873 SCIP_LPI* lpi, /**< LP interface structure */
3874 const char* fname /**< file name */
3875 )
3876{
3877 SCIP_RETCODE retcode = SCIP_OKAY;
3878
3879 char* basename = NULL;
3880 char* compression = NULL;
3881 char* extension = NULL;
3882 char* filename = NULL;
3883 char* path = NULL;
3884 char* xpressfilename = NULL;
3885
3886 int size;
3887
3888 assert(lpi != NULL);
3889 assert(lpi->xprslp != NULL);
3890 assert(fname != NULL);
3891
3892 SCIPdebugMessage("writing LP to file <%s>\n", fname);
3893
3894 /* get the length of the file name */
3895 size = (int)strlen(fname)+1;
3896
3897 /* check that the file name is longer than Xpress can handle */
3898 if (size > XPRS_MAXPROBNAMELENGTH)
3899 return SCIP_WRITEERROR;
3900
3901 /* get char array for the file name we pass to Xpress */
3902 SCIP_ALLOC( BMSallocMemoryArray(&xpressfilename, size) );
3903
3904 /* copy filename to be able to split it into its components */
3905 SCIP_ALLOC( BMSduplicateMemoryArray(&filename, fname, size) );
3906
3907 /* get path, base file name, extension, and compression of the given file name */
3908 SCIPsplitFilename(filename, &path, &basename, &extension, &compression);
3909
3910 /* construct file name without extension */
3911 if (path != NULL)
3912 (void) SCIPsnprintf(xpressfilename, size, "%s/%s", path, basename);
3913 else
3914 (void) SCIPsnprintf(xpressfilename, size, "%s", basename);
3915
3916 /* check that the file name did not has a compression extension, has an lp or mps extension, and actually a base name */
3917 if (compression != NULL || extension == NULL || basename == NULL)
3918 retcode = SCIP_WRITEERROR;
3919 if (strcasecmp(extension, "mps") == 0) {
3920 CHECK_ZERO( lpi->messagehdlr, XPRSwriteprob(lpi->xprslp, xpressfilename, "p") );
3921 }
3922 else if (strcasecmp(extension, "lp") == 0) {
3923 CHECK_ZERO( lpi->messagehdlr, XPRSwriteprob(lpi->xprslp, xpressfilename, "lp") );
3924 }
3925 else
3926 retcode = SCIP_WRITEERROR;
3927
3928 /* free array */
3929 BMSfreeMemoryArrayNull(&filename);
3930 BMSfreeMemoryArrayNull(&xpressfilename);
3931
3932 return retcode;
3933}
3934
3935/**@} */
void SCIPdecodeDualBit(const SCIP_DUALPACKET *inp, int *out, int count)
Definition: bitencode.c:308
void SCIPencodeDualBit(const int *inp, SCIP_DUALPACKET *out, int count)
Definition: bitencode.c:238
packing single and dual bit values
unsigned int SCIP_DUALPACKET
Definition: bitencode.h:42
SCIP_Real * r
Definition: circlepacking.c:59
#define NULL
Definition: def.h:262
#define SCIP_UNUSED(x)
Definition: def.h:423
#define SCIP_INVALID
Definition: def.h:192
#define SCIP_Bool
Definition: def.h:91
#define MIN(x, y)
Definition: def.h:238
#define SCIP_ALLOC(x)
Definition: def.h:380
#define SCIP_Real
Definition: def.h:172
#define TRUE
Definition: def.h:93
#define FALSE
Definition: def.h:94
#define MAX(x, y)
Definition: def.h:234
#define EPSCEIL(x, eps)
Definition: def.h:206
#define SCIPABORT()
Definition: def.h:341
#define EPSFLOOR(x, eps)
Definition: def.h:205
#define REALABS(x)
Definition: def.h:196
#define SCIP_CALL(x)
Definition: def.h:369
void SCIPsplitFilename(char *filename, char **path, char **name, char **extension, char **compression)
Definition: misc.c:11124
SCIP_RETCODE SCIPlpiChgSides(SCIP_LPI *lpi, int nrows, const int *ind, const SCIP_Real *lhs, const SCIP_Real *rhs)
Definition: lpi_xprs.c:1291
SCIP_RETCODE SCIPlpiSetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, const SCIP_LPISTATE *lpistate)
Definition: lpi_xprs.c:3263
SCIP_RETCODE SCIPlpiGetBInvACol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_xprs.c:3155
SCIP_RETCODE SCIPlpiGetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real *dval)
Definition: lpi_xprs.c:3623
SCIP_Real SCIPlpiInfinity(SCIP_LPI *lpi)
Definition: lpi_xprs.c:3773
SCIP_Bool SCIPlpiIsObjlimExc(SCIP_LPI *lpi)
Definition: lpi_xprs.c:2618
SCIP_RETCODE SCIPlpiChgObjsen(SCIP_LPI *lpi, SCIP_OBJSEN objsense)
Definition: lpi_xprs.c:1344
SCIP_Bool SCIPlpiIsInfinity(SCIP_LPI *lpi, SCIP_Real val)
Definition: lpi_xprs.c:3782
SCIP_RETCODE SCIPlpiClear(SCIP_LPI *lpi)
Definition: lpi_xprs.c:1227
SCIP_RETCODE SCIPlpiClearState(SCIP_LPI *lpi)
Definition: lpi_xprs.c:3340
SCIP_Bool SCIPlpiExistsDualRay(SCIP_LPI *lpi)
Definition: lpi_xprs.c:2465
SCIP_Bool SCIPlpiExistsPrimalRay(SCIP_LPI *lpi)
Definition: lpi_xprs.c:2359
SCIP_RETCODE SCIPlpiGetBase(SCIP_LPI *lpi, int *cstat, int *rstat)
Definition: lpi_xprs.c:2851
SCIP_RETCODE SCIPlpiReadState(SCIP_LPI *lpi, const char *fname)
Definition: lpi_xprs.c:3382
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_xprs.c:1083
SCIP_RETCODE SCIPlpiGetPrimalRay(SCIP_LPI *lpi, SCIP_Real *ray)
Definition: lpi_xprs.c:2766
SCIP_RETCODE SCIPlpiGetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int *ival)
Definition: lpi_xprs.c:3482
SCIP_RETCODE SCIPlpiWriteLP(SCIP_LPI *lpi, const char *fname)
Definition: lpi_xprs.c:3872
SCIP_RETCODE SCIPlpiSetIntegralityInformation(SCIP_LPI *lpi, int ncols, int *intInfo)
Definition: lpi_xprs.c:703
SCIP_Bool SCIPlpiIsDualInfeasible(SCIP_LPI *lpi)
Definition: lpi_xprs.c:2509
SCIP_RETCODE SCIPlpiSetRealpar(SCIP_LPI *lpi, SCIP_LPPARAM type, SCIP_Real dval)
Definition: lpi_xprs.c:3680
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_xprs.c:2224
SCIP_RETCODE SCIPlpiSetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, const SCIP_LPINORMS *lpinorms)
Definition: lpi_xprs.c:3444
SCIP_RETCODE SCIPlpiGetNNonz(SCIP_LPI *lpi, int *nnonz)
Definition: lpi_xprs.c:1551
SCIP_Bool SCIPlpiHasPrimalSolve(void)
Definition: lpi_xprs.c:718
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_xprs.c:2267
SCIP_RETCODE SCIPlpiGetBounds(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *lbs, SCIP_Real *ubs)
Definition: lpi_xprs.c:1768
SCIP_Bool SCIPlpiHasBarrierSolve(void)
Definition: lpi_xprs.c:734
SCIP_RETCODE SCIPlpiGetDualfarkas(SCIP_LPI *lpi, SCIP_Real *dualfarkas)
Definition: lpi_xprs.c:2787
SCIP_RETCODE SCIPlpiGetObjval(SCIP_LPI *lpi, SCIP_Real *objval)
Definition: lpi_xprs.c:2699
SCIP_RETCODE SCIPlpiScaleCol(SCIP_LPI *lpi, int col, SCIP_Real scaleval)
Definition: lpi_xprs.c:1443
int SCIPlpiGetInternalStatus(SCIP_LPI *lpi)
Definition: lpi_xprs.c:2672
SCIP_RETCODE SCIPlpiStartStrongbranch(SCIP_LPI *lpi)
Definition: lpi_xprs.c:2005
SCIP_RETCODE SCIPlpiGetSolFeasibility(SCIP_LPI *lpi, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
Definition: lpi_xprs.c:2337
SCIP_RETCODE SCIPlpiFreeNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition: lpi_xprs.c:3459
SCIP_Bool SCIPlpiIsIterlimExc(SCIP_LPI *lpi)
Definition: lpi_xprs.c:2630
SCIP_RETCODE SCIPlpiChgBounds(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *lb, const SCIP_Real *ub)
Definition: lpi_xprs.c:1247
SCIP_Bool SCIPlpiIsPrimalUnbounded(SCIP_LPI *lpi)
Definition: lpi_xprs.c:2394
SCIP_RETCODE SCIPlpiIgnoreInstability(SCIP_LPI *lpi, SCIP_Bool *success)
Definition: lpi_xprs.c:2683
SCIP_RETCODE SCIPlpiWriteState(SCIP_LPI *lpi, const char *fname)
Definition: lpi_xprs.c:3399
SCIP_RETCODE SCIPlpiFree(SCIP_LPI **lpi)
Definition: lpi_xprs.c:825
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_xprs.c:2245
SCIP_RETCODE SCIPlpiGetCoef(SCIP_LPI *lpi, int row, int col, SCIP_Real *val)
Definition: lpi_xprs.c:1821
SCIP_Bool SCIPlpiIsPrimalFeasible(SCIP_LPI *lpi)
Definition: lpi_xprs.c:2427
SCIP_RETCODE SCIPlpiReadLP(SCIP_LPI *lpi, const char *fname)
Definition: lpi_xprs.c:3804
SCIP_RETCODE SCIPlpiGetRealSolQuality(SCIP_LPI *lpi, SCIP_LPSOLQUALITY qualityindicator, SCIP_Real *quality)
Definition: lpi_xprs.c:2827
SCIP_Bool SCIPlpiIsDualFeasible(SCIP_LPI *lpi)
Definition: lpi_xprs.c:2523
SCIP_RETCODE SCIPlpiGetNorms(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPINORMS **lpinorms)
Definition: lpi_xprs.c:3426
SCIP_Bool SCIPlpiIsTimelimExc(SCIP_LPI *lpi)
Definition: lpi_xprs.c:2651
SCIP_Bool SCIPlpiHasStateBasis(SCIP_LPI *lpi, SCIP_LPISTATE *lpistate)
Definition: lpi_xprs.c:3372
SCIP_RETCODE SCIPlpiSetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int ival)
Definition: lpi_xprs.c:3543
const char * SCIPlpiGetSolverName(void)
Definition: lpi_xprs.c:667
SCIP_RETCODE SCIPlpiSetBase(SCIP_LPI *lpi, const int *cstat, const int *rstat)
Definition: lpi_xprs.c:2891
SCIP_Bool SCIPlpiHasPrimalRay(SCIP_LPI *lpi)
Definition: lpi_xprs.c:2373
SCIP_RETCODE SCIPlpiGetBInvRow(SCIP_LPI *lpi, int row, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_xprs.c:3001
SCIP_RETCODE SCIPlpiDelRows(SCIP_LPI *lpi, int firstrow, int lastrow)
Definition: lpi_xprs.c:1148
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_xprs.c:1571
SCIP_RETCODE SCIPlpiGetBInvCol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_xprs.c:3039
SCIP_RETCODE SCIPlpiGetColNames(SCIP_LPI *lpi, int firstcol, int lastcol, char **colnames, char *namestorage, int namestoragesize, int *storageleft)
Definition: lpi_xprs.c:1680
SCIP_RETCODE SCIPlpiGetBInvARow(SCIP_LPI *lpi, int r, const SCIP_Real *binvrow, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_xprs.c:3081
SCIP_RETCODE SCIPlpiGetRows(SCIP_LPI *lpi, int firstrow, int lastrow, SCIP_Real *lhss, SCIP_Real *rhss, int *nnonz, int *beg, int *ind, SCIP_Real *val)
Definition: lpi_xprs.c:1627
SCIP_Bool SCIPlpiWasSolved(SCIP_LPI *lpi)
Definition: lpi_xprs.c:2318
const char * SCIPlpiGetSolverDesc(void)
Definition: lpi_xprs.c:684
SCIP_RETCODE SCIPlpiSolveBarrier(SCIP_LPI *lpi, SCIP_Bool crossover)
Definition: lpi_xprs.c:1983
SCIP_Bool SCIPlpiIsOptimal(SCIP_LPI *lpi)
Definition: lpi_xprs.c:2559
SCIP_RETCODE SCIPlpiGetRowNames(SCIP_LPI *lpi, int firstrow, int lastrow, char **rownames, char *namestorage, int namestoragesize, int *storageleft)
Definition: lpi_xprs.c:1703
SCIP_Bool SCIPlpiHasDualSolve(void)
Definition: lpi_xprs.c:726
SCIP_RETCODE SCIPlpiEndStrongbranch(SCIP_LPI *lpi)
Definition: lpi_xprs.c:2017
SCIP_RETCODE SCIPlpiGetSides(SCIP_LPI *lpi, int firstrow, int lastrow, SCIP_Real *lhss, SCIP_Real *rhss)
Definition: lpi_xprs.c:1794
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_xprs.c:2288
SCIP_RETCODE SCIPlpiGetSol(SCIP_LPI *lpi, SCIP_Real *objval, SCIP_Real *primsol, SCIP_Real *dualsol, SCIP_Real *activity, SCIP_Real *redcost)
Definition: lpi_xprs.c:2720
SCIP_Bool SCIPlpiHasDualRay(SCIP_LPI *lpi)
Definition: lpi_xprs.c:2479
SCIP_RETCODE SCIPlpiDelColset(SCIP_LPI *lpi, int *dstat)
Definition: lpi_xprs.c:1033
SCIP_RETCODE SCIPlpiGetObj(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *vals)
Definition: lpi_xprs.c:1749
SCIP_RETCODE SCIPlpiFreeState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lpi_xprs.c:3353
SCIP_Bool SCIPlpiIsPrimalInfeasible(SCIP_LPI *lpi)
Definition: lpi_xprs.c:2413
SCIP_RETCODE SCIPlpiSolveDual(SCIP_LPI *lpi)
Definition: lpi_xprs.c:1971
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_xprs.c:937
SCIP_RETCODE SCIPlpiSolvePrimal(SCIP_LPI *lpi)
Definition: lpi_xprs.c:1959
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_xprs.c:865
SCIP_Bool SCIPlpiIsDualUnbounded(SCIP_LPI *lpi)
Definition: lpi_xprs.c:2495
SCIP_RETCODE SCIPlpiGetIterations(SCIP_LPI *lpi, int *iterations)
Definition: lpi_xprs.c:2808
SCIP_RETCODE SCIPlpiGetBasisInd(SCIP_LPI *lpi, int *bind)
Definition: lpi_xprs.c:2950
SCIP_RETCODE SCIPlpiCreate(SCIP_LPI **lpi, SCIP_MESSAGEHDLR *messagehdlr, const char *name, SCIP_OBJSEN objsen)
Definition: lpi_xprs.c:750
void * SCIPlpiGetSolverPointer(SCIP_LPI *lpi)
Definition: lpi_xprs.c:695
SCIP_RETCODE SCIPlpiChgObj(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *obj)
Definition: lpi_xprs.c:1362
SCIP_RETCODE SCIPlpiGetObjsen(SCIP_LPI *lpi, SCIP_OBJSEN *objsen)
Definition: lpi_xprs.c:1726
SCIP_Bool SCIPlpiIsStable(SCIP_LPI *lpi)
Definition: lpi_xprs.c:2577
SCIP_RETCODE SCIPlpiGetNCols(SCIP_LPI *lpi, int *ncols)
Definition: lpi_xprs.c:1534
SCIP_RETCODE SCIPlpiInterrupt(SCIP_LPI *lpi, SCIP_Bool interrupt)
Definition: lpi_xprs.c:3753
SCIP_RETCODE SCIPlpiDelCols(SCIP_LPI *lpi, int firstcol, int lastcol)
Definition: lpi_xprs.c:1002
SCIP_RETCODE SCIPlpiDelRowset(SCIP_LPI *lpi, int *dstat)
Definition: lpi_xprs.c:1178
SCIP_RETCODE SCIPlpiScaleRow(SCIP_LPI *lpi, int row, SCIP_Real scaleval)
Definition: lpi_xprs.c:1384
SCIP_RETCODE SCIPlpiGetNRows(SCIP_LPI *lpi, int *nrows)
Definition: lpi_xprs.c:1517
SCIP_RETCODE SCIPlpiGetState(SCIP_LPI *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
Definition: lpi_xprs.c:3209
SCIP_RETCODE SCIPlpiChgCoef(SCIP_LPI *lpi, int row, int col, SCIP_Real newval)
Definition: lpi_xprs.c:1324
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10878
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 lpiStrongbranches(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_xprs.c:2114
static void reconvertSides(SCIP_LPI *lpi, int nrows, SCIP_Real *lhs, SCIP_Real *rhs)
Definition: lpi_xprs.c:624
static void lpistatePack(SCIP_LPISTATE *lpistate, const int *cstat, const int *rstat)
Definition: lpi_xprs.c:340
static void lpistateUnpack(const SCIP_LPISTATE *lpistate, int *cstat, int *rstat)
Definition: lpi_xprs.c:356
static int rowpacketNum(int nrows)
Definition: lpi_xprs.c:331
static _Thread_local char xprsname[100]
Definition: lpi_xprs.c:662
SCIP_DUALPACKET ROWPACKET
Definition: lpi_xprs.c:83
static SCIP_RETCODE ensureCstatMem(SCIP_LPI *lpi, int num)
Definition: lpi_xprs.c:270
static void reconvertBothSides(SCIP_LPI *lpi, int nrows, SCIP_Real *lhss, SCIP_Real *rhss)
Definition: lpi_xprs.c:485
static SCIP_RETCODE lpiSolve(SCIP_LPI *lpi, const char *method)
Definition: lpi_xprs.c:1847
#define COLS_PER_PACKET
Definition: lpi_xprs.c:82
static void reconvertRhs(SCIP_LPI *lpi, int nrows, SCIP_Real *rhss)
Definition: lpi_xprs.c:579
#define XPRS_LPQUICKPRESOLVE
Definition: lpi_xprs.c:56
static SCIP_RETCODE ensureBoundchgMem(SCIP_LPI *lpi, int num)
Definition: lpi_xprs.c:194
static void debugCheckRowrang(SCIP_LPI *lpi, int firstrow, int lastrow)
Definition: lpi_xprs.c:160
static void lpistateFree(SCIP_LPISTATE **lpistate, BMS_BLKMEM *blkmem)
Definition: lpi_xprs.c:393
SCIP_DUALPACKET COLPACKET
Definition: lpi_xprs.c:81
static int xprsObjsen(SCIP_OBJSEN const objsen)
Definition: lpi_xprs.c:417
#define XPRS_LP_OPTIMAL_SCALEDINFEAS
Definition: lpi_xprs.c:60
#define ABORT_ZERO(messagehdlr, retval, x)
Definition: lpi_xprs.c:71
static SCIP_RETCODE lpiStrongbranch(SCIP_LPI *lpi, int col, SCIP_Real psol, int itlim, SCIP_Real *down, SCIP_Real *up, SCIP_Bool *downvalid, SCIP_Bool *upvalid, int *iter)
Definition: lpi_xprs.c:2030
#define CHECK_ZERO(messagehdlr, x)
Definition: lpi_xprs.c:62
static SCIP_RETCODE ensureRstatMem(SCIP_LPI *lpi, int num)
Definition: lpi_xprs.c:292
static int colpacketNum(int ncols)
Definition: lpi_xprs.c:322
static void debugCheckColrang(SCIP_LPI *lpi, int firstcol, int lastcol)
Definition: lpi_xprs.c:143
static void convertSides(SCIP_LPI *lpi, int nrows, const SCIP_Real *lhss, const SCIP_Real *rhss)
Definition: lpi_xprs.c:436
static SCIP_RETCODE ensureSidechgMem(SCIP_LPI *lpi, int num)
Definition: lpi_xprs.c:223
static void reconvertLhs(SCIP_LPI *lpi, int nrows, SCIP_Real *lhss)
Definition: lpi_xprs.c:534
static SCIP_RETCODE lpistateCreate(SCIP_LPISTATE **lpistate, BMS_BLKMEM *blkmem, int ncols, int nrows)
Definition: lpi_xprs.c:372
#define ROWS_PER_PACKET
Definition: lpi_xprs.c:84
static void invalidateSolution(SCIP_LPI *lpi)
Definition: lpi_xprs.c:644
static SCIP_RETCODE ensureValMem(SCIP_LPI *lpi, int num)
Definition: lpi_xprs.c:247
#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 BMSduplicateMemoryArray(ptr, source, num)
Definition: memory.h:143
#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
public methods for message output
#define SCIPerrorMessage
Definition: pub_message.h:64
#define SCIPdebugMessage
Definition: pub_message.h:96
public data structures and miscellaneous methods
COLPACKET * packcstat
Definition: lpi_clp.cpp:136
ROWPACKET * packrstat
Definition: lpi_clp.cpp:137
int par_presolve
Definition: lpi_xprs.c:120
SCIP_Bool clearstate
Definition: lpi_cpx.c:172
int iterations
Definition: lpi_cpx.c:167
SCIP_Real * valarray
Definition: lpi_cpx.c:157
int valsize
Definition: lpi_cpx.c:164
int par_fastlp
Definition: lpi_xprs.c:119
SCIP_Real par_lobjlim
Definition: lpi_xprs.c:117
char * uarray
Definition: lpi_cpx.c:153
XPRSprob xprslp
Definition: lpi_xprs.c:89
int boundchgsize
Definition: lpi_cpx.c:162
int notfromscratch
Definition: lpi_xprs.c:93
int * indarray
Definition: lpi_cpx.c:161
int * cstat
Definition: lpi_clp.cpp:107
char solmethod
Definition: lpi_xprs.c:95
SCIP_Bool solisbasic
Definition: lpi_cpx.c:169
int solstat
Definition: lpi_cpx.c:149
int rstatsize
Definition: lpi_clp.cpp:110
SCIP_Real * rhsarray
Definition: lpi_cpx.c:155
int * rstat
Definition: lpi_clp.cpp:108
int sidechgsize
Definition: lpi_cpx.c:163
char name[200]
Definition: lpi_xprs.c:90
SCIP_PRICING pricing
Definition: lpi_clp.cpp:112
int cstatsize
Definition: lpi_clp.cpp:109
char * senarray
Definition: lpi_cpx.c:154
SCIP_Real par_uobjlim
Definition: lpi_xprs.c:118
SCIP_MESSAGEHDLR * messagehdlr
Definition: lpi_cpx.c:185
SCIP_Real * rngarray
Definition: lpi_cpx.c:156
char * larray
Definition: lpi_cpx.c:152
@ 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_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_DUALFEASTOL
Definition: type_lpi.h:57
@ SCIP_LPPAR_FROMSCRATCH
Definition: type_lpi.h:50
@ SCIP_LPPAR_MARKOWITZ
Definition: type_lpi.h:62
@ SCIP_LPPAR_FEASTOL
Definition: type_lpi.h:56
@ SCIP_LPPAR_LPITLIM
Definition: type_lpi.h:60
@ SCIP_LPPAR_OBJLIM
Definition: type_lpi.h:59
@ SCIP_BASESTAT_BASIC
Definition: type_lpi.h:92
@ SCIP_BASESTAT_UPPER
Definition: type_lpi.h:93
@ SCIP_BASESTAT_LOWER
Definition: type_lpi.h:91
@ SCIP_BASESTAT_ZERO
Definition: type_lpi.h:94
enum SCIP_LPSolQuality SCIP_LPSOLQUALITY
Definition: type_lpi.h:104
@ SCIP_OBJSEN_MAXIMIZE
Definition: type_lpi.h:42
@ SCIP_OBJSEN_MINIMIZE
Definition: type_lpi.h:43
enum SCIP_ObjSen SCIP_OBJSEN
Definition: type_lpi.h:45
@ SCIP_LPERROR
Definition: type_retcode.h:49
@ SCIP_READERROR
Definition: type_retcode.h:45
@ SCIP_PARAMETERUNKNOWN
Definition: type_retcode.h:55
@ SCIP_WRITEERROR
Definition: type_retcode.h:46
@ SCIP_OKAY
Definition: type_retcode.h:42
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63