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