Scippy

SCIP

Solving Constraint Integer Programs

lpi_xprs.c
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the program and library */
4/* SCIP --- Solving Constraint Integer Programs */
5/* */
6/* Copyright (c) 2002-2025 Zuse Institute Berlin (ZIB) */
7/* */
8/* Licensed under the Apache License, Version 2.0 (the "License"); */
9/* you may not use this file except in compliance with the License. */
10/* You may obtain a copy of the License at */
11/* */
12/* http://www.apache.org/licenses/LICENSE-2.0 */
13/* */
14/* Unless required by applicable law or agreed to in writing, software */
15/* distributed under the License is distributed on an "AS IS" BASIS, */
16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17/* See the License for the specific language governing permissions and */
18/* limitations under the License. */
19/* */
20/* You should have received a copy of the Apache-2.0 license */
21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
22/* */
23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24
25/**@file lpi_xprs.c
26 * @ingroup LPIS
27 * @brief LP interface for Xpress-MP
28 * @author Tobias Achterberg
29 * @author Michael Perregaard
30 * @author Livio Bertacco
31 * @author Stefan Heinz
32 *
33 * This interface was revised for Xpress 26. Therefore, we removed all legacy code.
34 *
35 * Xpress requires that column and row names are unique. Since column and row names are not needed we ignore all column
36 * and row names to avoid the uniqueness issue.
37 */
38
39/*--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
40
41#include <assert.h>
42#include <string.h>
43#ifdef _MSC_VER
44#define strcasecmp _stricmp
45#else
46#include <strings.h> /*lint --e{766}*/
47#endif
48
49#include "xprs.h"
50#include "scip/bitencode.h"
51#include "scip/pub_misc.h"
52#include "scip/pub_message.h"
53#include "lpi/lpi.h"
54#include "tinycthread/tinycthread.h"
55
56#ifndef XPRS_LPQUICKPRESOLVE
57#define XPRS_LPQUICKPRESOLVE 8207
58#endif
59
60/* For SCIP we need an extra LP status which is optimal with scaled infeasibilities. */
61#define XPRS_LP_OPTIMAL_SCALEDINFEAS 16
62
63#define CHECK_ZERO(messagehdlr, x) { int _restat_; \
64 if( (_restat_ = (x)) != 0 ) \
65 { \
66 SCIPmessagePrintWarning((messagehdlr), "%s:%d: LP Error: Xpress returned %d\n", __FILE__, __LINE__, _restat_); \
67 return SCIP_LPERROR; \
68 } \
69 }
70
71/* this macro is only called in functions returning SCIP_Bool; thus, we return retval if there is an error in optimized mode */
72#define ABORT_ZERO(messagehdlr, retval, x) { int _restat_; \
73 if( (_restat_ = (x)) != 0 ) \
74 { \
75 SCIPmessagePrintWarning((messagehdlr), "LP Error: Xpress returned %d\n", _restat_); \
76 SCIPABORT(); \
77 return retval; \
78 } \
79 }
80
81
82typedef SCIP_DUALPACKET COLPACKET; /* each column needs two bits of information (basic/on_lower/on_upper) */
83#define COLS_PER_PACKET SCIP_DUALPACKETSIZE
84typedef SCIP_DUALPACKET ROWPACKET; /* each row needs two bit of information (basic/on_lower/on_upper) */
85#define ROWS_PER_PACKET SCIP_DUALPACKETSIZE
86
87/** LP interface */
88struct SCIP_LPi
89{
90 XPRSprob xprslp; /**< Xpress LP pointer */
91 char name[200]; /**< problem name */
92
93 SCIP_PRICING pricing; /**< SCIP pricing setting */
94 int notfromscratch; /**< do we not want to solve the lp from scratch */
95 int solstat; /**< solution status of last optimization call */
96 char solmethod; /**< method used to solve the LP */
97
98 char* larray; /**< array with 'L' entries for changing lower bounds */
99 char* uarray; /**< array with 'U' entries for changing upper bounds */
100 char* senarray; /**< array for storing row senses */
101 SCIP_Real* rhsarray; /**< array for storing rhs values */
102 SCIP_Real* rngarray; /**< array for storing range values */
103 SCIP_Real* valarray; /**< array for storing coefficient values */
104 int* cstat; /**< array for storing column basis status */
105 int* rstat; /**< array for storing row basis status (row status w.r.t. slack columns) */
106 int* indarray; /**< array for storing coefficient indices */
107
108 int boundchgsize; /**< size of larray and uarray */
109 int sidechgsize; /**< size of senarray and rngarray */
110 int valsize; /**< size of valarray and indarray */
111 int cstatsize; /**< size of cstat array */
112 int rstatsize; /**< size of rstat array */
113
114 int iterations; /**< number of iterations used in the last solving call */
115 SCIP_Bool solisbasic; /**< is current LP solution a basic solution? */
116 SCIP_Bool clearstate; /**< should the current basis be ignored with the next LP solve */
117
118 SCIP_Real par_lobjlim; /**< objective lower bound */
119 SCIP_Real par_uobjlim; /**< objective upper bound */
120 int par_fastlp; /**< special meta parameter for making LP reoptimize go faster */
121 int par_presolve; /**< need to distinguish between the users setting and the optimizer setting of presolve */
122
123 SCIP_MESSAGEHDLR* messagehdlr; /**< messagehdlr handler to printing messages, or NULL */
124};
125
126/** LPi state stores basis information */
127struct SCIP_LPiState
128{
129 int ncols; /**< number of LP columns */
130 int nrows; /**< number of LP rows */
131 COLPACKET* packcstat; /**< column basis status in compressed form */
132 ROWPACKET* packrstat; /**< row basis status in compressed form (row status w.r.t. slack columns) */
133};
134
135/**@name Debug check methods
136 *
137 * @{
138 */
139
140#ifndef NDEBUG
141
142/** check that the column range fits */
143static
145 SCIP_LPI* lpi, /**< LP interface structure */
146 int firstcol, /**< first column to be deleted */
147 int lastcol /**< last column to be deleted */
148 )
149{
150 int ncols;
151
152 assert(lpi != NULL);
153 assert(firstcol >= 0);
154 assert(firstcol <= lastcol + 1);
155 (void)XPRSgetintattrib(lpi->xprslp, XPRS_COLS, &ncols);
156 assert(lastcol < ncols);
157}
158
159/** check that the row range fits */
160static
162 SCIP_LPI* lpi, /**< LP interface structure */
163 int firstrow, /**< first row to be deleted */
164 int lastrow /**< last row to be deleted */
165 )
166{
167 int nrows;
168
169 assert(lpi != NULL);
170 assert(firstrow >= 0);
171 assert(firstrow <= lastrow + 1);
172 (void)XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows);
173 assert(lastrow < nrows);
174}
175
176#else
177
178/* in optimized mode the checks are replaced with an empty command */
179#define debugCheckColrang(lpi, firstcol, lastcol) /* */
180#define debugCheckRowrang(lpi, firstrow, lastrow) /* */
181#endif
182
183/**@} */
184
185
186/**@name Dynamic memory arrays
187 *
188 * @{
189 */
190
191/** resizes larray and uarray to have at least num entries and fill it with 'L' and 'U' for the lower and upper bound
192 * markers
193 */
194static
196 SCIP_LPI* lpi, /**< LP interface structure */
197 int num /**< minimal number of entries in array */
198 )
199{
200 assert(lpi != NULL);
201
202 if( num > lpi->boundchgsize )
203 {
204 int newsize;
205 int i;
206
207 newsize = MAX(2*lpi->boundchgsize, num);
208 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->larray, newsize) );
209 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->uarray, newsize) );
210 for( i = lpi->boundchgsize; i < newsize; ++i )
211 {
212 lpi->larray[i] = 'L';
213 lpi->uarray[i] = 'U';
214 }
215 lpi->boundchgsize = newsize;
216 }
217 assert(num <= lpi->boundchgsize);
218
219 return SCIP_OKAY;
220}
221
222/** resizes senarray, rngarray, and rhsarray to have at least num entries */
223static
225 SCIP_LPI* lpi, /**< LP interface structure */
226 int num /**< minimal number of entries in array */
227 )
228{
229 assert(lpi != NULL);
230
231 if( num > lpi->sidechgsize )
232 {
233 int newsize;
234
235 newsize = MAX(2*lpi->sidechgsize, num);
236 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->senarray, newsize) );
237 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->rhsarray, newsize) );
238 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->rngarray, newsize) );
239 lpi->sidechgsize = newsize;
240 }
241 assert(num <= lpi->sidechgsize);
242
243 return SCIP_OKAY;
244}
245
246/** resizes valarray and indarray to have at least num entries */
247static
249 SCIP_LPI* lpi, /**< LP interface structure */
250 int num /**< minimal number of entries in array */
251 )
252{
253 assert(lpi != NULL);
254
255 if( num > lpi->valsize )
256 {
257 int newsize;
258
259 newsize = MAX(2*lpi->valsize, num);
260 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->valarray, newsize) );
261 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->indarray, newsize) );
262 lpi->valsize = newsize;
263 }
264 assert(num <= lpi->valsize);
265
266 return SCIP_OKAY;
267}
268
269/** resizes cstat array to have at least num entries */
270static
272 SCIP_LPI* lpi, /**< LP interface structure */
273 int num /**< minimal number of entries in array */
274 )
275{
276 assert(lpi != NULL);
277
278 if( num > lpi->cstatsize )
279 {
280 int newsize;
281
282 newsize = MAX(2*lpi->cstatsize, num);
283 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->cstat, newsize) );
284 lpi->cstatsize = newsize;
285 }
286 assert(num <= lpi->cstatsize);
287
288 return SCIP_OKAY;
289}
290
291/** resizes rstat array to have at least num entries */
292static
294 SCIP_LPI* lpi, /**< LP interface structure */
295 int num /**< minimal number of entries in array */
296 )
297{
298 assert(lpi != NULL);
299
300 if( num > lpi->rstatsize )
301 {
302 int newsize;
303
304 newsize = MAX(2*lpi->rstatsize, num);
305 SCIP_ALLOC( BMSreallocMemoryArray(&lpi->rstat, newsize) );
306 lpi->rstatsize = newsize;
307 }
308 assert(num <= lpi->rstatsize);
309
310 return SCIP_OKAY;
311}
312
313/**@} */
314
315
316/**@name LPi state methods
317 *
318 * @{
319 */
320
321/** returns the number of packets needed to store column packet information */
322static
324 int ncols /**< number of columns to store */
325 )
326{
327 return (ncols+(int)COLS_PER_PACKET-1)/(int)COLS_PER_PACKET;
328}
329
330/** returns the number of packets needed to store row packet information */
331static
333 int nrows /**< number of rows to store */
334 )
335{
336 return (nrows+(int)ROWS_PER_PACKET-1)/(int)ROWS_PER_PACKET;
337}
338
339/** store row and column basis status in a packed LPi state object */
340static
342 SCIP_LPISTATE* lpistate, /**< pointer to LPi state data */
343 const int* cstat, /**< basis status of columns in unpacked format */
344 const int* rstat /**< basis status of rows in unpacked format (row status w.r.t. slack columns) */
345 )
346{
347 assert(lpistate != NULL);
348 assert(lpistate->packcstat != NULL);
349 assert(lpistate->packrstat != NULL);
350
351 SCIPencodeDualBit(cstat, lpistate->packcstat, lpistate->ncols);
352 SCIPencodeDualBit(rstat, lpistate->packrstat, lpistate->nrows);
353}
354
355/** unpacks row and column basis status from a packed LPi state object */
356static
358 const SCIP_LPISTATE* lpistate, /**< pointer to LPi state data */
359 int* cstat, /**< buffer for storing basis status of columns in unpacked format */
360 int* rstat /**< buffer for storing basis status of rows in unpacked format (row status w.r.t. slack columns) */
361 )
362{
363 assert(lpistate != NULL);
364 assert(lpistate->packcstat != NULL);
365 assert(lpistate->packrstat != NULL);
366
367 SCIPdecodeDualBit(lpistate->packcstat, cstat, lpistate->ncols);
368 SCIPdecodeDualBit(lpistate->packrstat, rstat, lpistate->nrows);
369}
370
371/** creates LPi state information object */
372static
374 SCIP_LPISTATE** lpistate, /**< pointer to LPi state */
375 BMS_BLKMEM* blkmem, /**< block memory */
376 int ncols, /**< number of columns to store */
377 int nrows /**< number of rows to store */
378 )
379{
380 assert(lpistate != NULL);
381 assert(blkmem != NULL);
382 assert(ncols >= 0);
383 assert(nrows >= 0);
384
385 SCIP_ALLOC( BMSallocBlockMemory(blkmem, lpistate) );
386 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpistate)->packcstat, colpacketNum(ncols)) );
387 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpistate)->packrstat, rowpacketNum(nrows)) );
388
389 return SCIP_OKAY;
390}
391
392/** frees LPi state information */
393static
395 SCIP_LPISTATE** lpistate, /**< pointer to LPi state information (like basis information) */
396 BMS_BLKMEM* blkmem /**< block memory */
397 )
398{
399 assert(blkmem != NULL);
400 assert(lpistate != NULL);
401 assert(*lpistate != NULL);
402
403 BMSfreeBlockMemoryArray(blkmem, &(*lpistate)->packcstat, colpacketNum((*lpistate)->ncols));
404 BMSfreeBlockMemoryArray(blkmem, &(*lpistate)->packrstat, rowpacketNum((*lpistate)->nrows));
405 BMSfreeBlockMemory(blkmem, lpistate);
406}
407
408/**@} */
409
410
411/**@name Conversion methods
412 *
413 * @{
414 */
415
416/** converts SCIP's objective sense into CPLEX's objective sense */
417static
419 SCIP_OBJSEN const objsen /**< objective sense */
420 )
421{
422 switch( objsen )
423 {
425 return XPRS_OBJ_MAXIMIZE;
427 return XPRS_OBJ_MINIMIZE;
428 default:
429 SCIPerrorMessage("invalid objective sense\n");
430 SCIPABORT();
431 return 0; /*lint !e527*/
432 }
433}
434
435/** converts SCIP's lhs/rhs pairs into Xpress' sen/rhs/rng */
436static
438 SCIP_LPI* lpi, /**< LP interface structure */
439 int nrows, /**< number of rows */
440 const SCIP_Real* lhss, /**< left hand side vector */
441 const SCIP_Real* rhss /**< right hand side vector */
442 )
443{
444 int i;
445
446 assert(lpi != NULL);
447 assert(nrows >= 0);
448 assert(lhss != NULL);
449 assert(rhss != NULL);
450
451 /* convert lhs/rhs into sen/rhs/rng */
452 for( i = 0; i < nrows; ++i )
453 {
454 assert(lhss[i] <= rhss[i]);
455 if( lhss[i] == rhss[i] ) /*lint !e777*/
456 {
457 assert(XPRS_MINUSINFINITY < rhss[i] && rhss[i] < XPRS_PLUSINFINITY);
458 lpi->senarray[i] = 'E';
459 lpi->rhsarray[i] = rhss[i];
460 lpi->rngarray[i] = 0.0;
461 }
462 else if( lhss[i] <= XPRS_MINUSINFINITY )
463 {
464 lpi->senarray[i] = 'L';
465 lpi->rhsarray[i] = rhss[i];
466 lpi->rngarray[i] = XPRS_PLUSINFINITY;
467 }
468 else if( rhss[i] >= XPRS_PLUSINFINITY )
469 {
470 lpi->senarray[i] = 'G';
471 lpi->rhsarray[i] = lhss[i];
472 lpi->rngarray[i] = XPRS_PLUSINFINITY;
473 }
474 else
475 {
476 /* Xpress defines a ranged row to be within rhs-rng and rhs. */
477 lpi->senarray[i] = 'R';
478 lpi->rhsarray[i] = rhss[i];
479 lpi->rngarray[i] = rhss[i] - lhss[i];
480 }
481 }
482}
483
484/** converts Xpress' sen/rhs/rng triplets into SCIP's lhs/rhs pairs */
485static
487 SCIP_LPI* lpi, /**< LP interface structure */
488 int nrows, /**< number of rows */
489 SCIP_Real* lhss, /**< buffer to store the left hand side vector */
490 SCIP_Real* rhss /**< buffer to store the right hand side vector */
491 )
492{
493 int i;
494
495 assert(lpi != NULL);
496 assert(nrows >= 0);
497 assert(lhss != NULL);
498 assert(rhss != NULL);
499
500 for( i = 0; i < nrows; ++i )
501 {
502 switch( lpi->senarray[i] )
503 {
504 case 'E':
505 lhss[i] = lpi->rhsarray[i];
506 rhss[i] = lpi->rhsarray[i];
507 break;
508
509 case 'L':
510 lhss[i] = XPRS_MINUSINFINITY;
511 rhss[i] = lpi->rhsarray[i];
512 break;
513
514 case 'G':
515 lhss[i] = lpi->rhsarray[i];
516 rhss[i] = XPRS_PLUSINFINITY;
517 break;
518
519 case 'R':
520 assert(lpi->rngarray[i] >= 0.0);
521 rhss[i] = lpi->rhsarray[i];
522 lhss[i] = lpi->rhsarray[i] - lpi->rngarray[i];
523 break;
524
525 default:
526 SCIPerrorMessage("invalid row sense\n");
527 SCIPABORT();
528 }
529 assert(lhss[i] <= rhss[i]);
530 }
531}
532
533/** converts Xpress' sen/rhs/rng triplets into SCIP's lhs/rhs pairs, only storing the left hand side */
534static
536 SCIP_LPI* lpi, /**< LP interface structure */
537 int nrows, /**< number of rows */
538 SCIP_Real* lhss /**< buffer to store the left hand side vector */
539 )
540{
541 int i;
542
543 assert(lpi != NULL);
544 assert(nrows >= 0);
545 assert(lhss != NULL);
546
547 for( i = 0; i < nrows; ++i )
548 {
549 switch( lpi->senarray[i] )
550 {
551 case 'E':
552 assert(lpi->rngarray[i] == 0.0);
553 lhss[i] = lpi->rhsarray[i];
554 break;
555
556 case 'L':
557 assert(lpi->rngarray[i] == 0.0);
558 lhss[i] = XPRS_MINUSINFINITY;
559 break;
560
561 case 'G':
562 assert(lpi->rngarray[i] == 0.0);
563 lhss[i] = lpi->rhsarray[i];
564 break;
565
566 case 'R':
567 assert(lpi->rngarray[i] >= 0.0);
568 lhss[i] = lpi->rhsarray[i] - lpi->rngarray[i];
569 break;
570
571 default:
572 SCIPerrorMessage("invalid row sense\n");
573 SCIPABORT();
574 }
575 }
576}
577
578/** converts Xpress' sen/rhs/rng triplets into SCIP's lhs/rhs pairs, only storing the right hand side */
579static
581 SCIP_LPI* lpi, /**< LP interface structure */
582 int nrows, /**< number of rows */
583 SCIP_Real* rhss /**< buffer to store the right hand side vector */
584 )
585{
586 int i;
587
588 assert(lpi != NULL);
589 assert(nrows >= 0);
590 assert(rhss != NULL);
591
592 for( i = 0; i < nrows; ++i )
593 {
594 switch( lpi->senarray[i] )
595 {
596 case 'E':
597 assert(lpi->rngarray[i] == 0.0);
598 rhss[i] = lpi->rhsarray[i];
599 break;
600
601 case 'L':
602 assert(lpi->rngarray[i] == 0.0);
603 rhss[i] = lpi->rhsarray[i];
604 break;
605
606 case 'G':
607 assert(lpi->rngarray[i] == 0.0);
608 rhss[i] = XPRS_PLUSINFINITY;
609 break;
610
611 case 'R':
612 assert(lpi->rngarray[i] >= 0.0);
613 rhss[i] = lpi->rhsarray[i];
614 break;
615
616 default:
617 SCIPerrorMessage("invalid row sense\n");
618 SCIPABORT();
619 }
620 }
621}
622
623/** converts Xpress' sen/rhs/rng triplets into SCIP's lhs/rhs pairs */
624static
626 SCIP_LPI* lpi, /**< LP interface structure */
627 int nrows, /**< number of rows */
628 SCIP_Real* lhs, /**< buffer to store the left hand side vector, or NULL */
629 SCIP_Real* rhs /**< buffer to store the right hand side vector, or NULL */
630 )
631{
632 if( lhs != NULL && rhs != NULL )
633 reconvertBothSides(lpi, nrows, lhs, rhs);
634 else if( lhs != NULL )
635 reconvertLhs(lpi, nrows, lhs);
636 else if( rhs != NULL )
637 reconvertRhs(lpi, nrows, rhs);
638}
639
640/**@} */
641
642
643/** marks the current LP to be unsolved */
644static
646 SCIP_LPI* lpi
647 )
648{
649 assert(lpi != NULL);
650 lpi->solstat = -1;
651}
652
653/*
654 * LP Interface Methods
655 */
656
657/**@name Miscellaneous Methods
658 *
659 * @{
660 */
661
662#ifdef _Thread_local
663static _Thread_local char xprsname[100];
664#else
665static char xprsname[] = {'X', 'p', 'r', 'e', 's', 's', ' ', '0' + XPVERSION / 10, '0' + XPVERSION % 10, '\0'};
666#endif
667/** gets name and version of LP solver */
669 void
670 )
671{
672#ifdef _Thread_local
673 char version[16];
674
675 /* get version of Xpress */
676 if( XPRSgetversion(version) == 0 )
677 (void) sprintf(xprsname, "Xpress %s", version);
678 else
679 (void) sprintf(xprsname, "Xpress %d", XPVERSION);
680#endif
681 return xprsname;
682}
683
684/** gets description of LP solver (developer, webpage, ...) */
686 void
687 )
688{
689 return "Linear Programming Solver developed by FICO (www.fico.com/en/products/fico-xpress-optimization)";
690}
691
692/** gets pointer for LP solver - use only with great care
693 *
694 * Here we return the pointer to the LP environment.
695 */
697 SCIP_LPI* lpi /**< pointer to an LP interface structure */
698 )
699{ /*lint --e{715}*/
700 return (void*) lpi->xprslp;
701}
702
703/** pass integrality information to LP solver */
705 SCIP_LPI* lpi, /**< pointer to an LP interface structure */
706 int ncols, /**< length of integrality array */
707 int* intInfo /**< integrality array (0: continuous, 1: integer). May be NULL iff ncols is 0. */
708 )
709{ /*lint --e{715}*/
710 assert(lpi != NULL);
711 assert(ncols >= 0);
712 assert(ncols == 0 || intInfo != NULL);
713
714 SCIPerrorMessage("SCIPlpiSetIntegralityInformation() has not been implemented yet.\n");
715 return SCIP_LPERROR;
716}
717
718/** informs about availability of a primal simplex solving method */
720 void
721 )
722{
723 return TRUE;
724}
725
726/** informs about availability of a dual simplex solving method */
728 void
729 )
730{
731 return TRUE;
732}
733
734/** informs about availability of a barrier solving method */
736 void
737 )
738{
739 return TRUE;
740}
741
742/**@} */
743
744
745/**@name LPI Creation and Destruction Methods
746 *
747 * @{
748 */
749
750/** creates an LP problem object */
752 SCIP_LPI** lpi, /**< pointer to an LP interface structure */
753 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler to use for printing messages, or NULL */
754 const char* name, /**< problem name */
755 SCIP_OBJSEN objsen /**< objective sense */
756 )
757{
758 int zero = 0;
759
760 assert(sizeof(SCIP_Real) == sizeof(double)); /*lint !e506*/ /* Xpress only works with doubles as floating points */
761 assert(sizeof(SCIP_Bool) == sizeof(int)); /*lint !e506*/ /* Xpress only works with ints as bools */
762 assert(lpi != NULL);
763 assert(name != NULL);
764
765 SCIPdebugMessage("SCIPlpiCreate()\n");
766
767 /* the interface is revised for Xpress 26 or higher */
768 if( XPVERSION < 26 ) /*lint !e506 !e774*/
769 {
770 SCIPmessagePrintWarning(messagehdlr, "Please use Xpress version 26 or higher, you are using %d\n", XPVERSION);
771 return SCIP_LPERROR;
772 }
773
774 /* initialize the Xpress library (licensing) */
775 CHECK_ZERO( messagehdlr, XPRSinit(NULL) );
776
777 /* create LPi data structure */
779
780 /* copy the problem name */
781 (void)strncpy((*lpi)->name, name, 199);
782 (*lpi)->name[199] = '\0';
783
784 (*lpi)->larray = NULL;
785 (*lpi)->uarray = NULL;
786 (*lpi)->senarray = NULL;
787 (*lpi)->rhsarray = NULL;
788 (*lpi)->rngarray = NULL;
789 (*lpi)->indarray = NULL;
790 (*lpi)->valarray = NULL;
791 (*lpi)->cstat = NULL;
792 (*lpi)->rstat = NULL;
793 (*lpi)->boundchgsize = 0;
794 (*lpi)->sidechgsize = 0;
795 (*lpi)->valsize = 0;
796 (*lpi)->cstatsize = 0;
797 (*lpi)->rstatsize = 0;
798 (*lpi)->iterations = 0;
799 (*lpi)->solisbasic = TRUE;
800 (*lpi)->clearstate = FALSE;
801 (*lpi)->solmethod = ' ';
802 (*lpi)->par_lobjlim = -1e+40;
803 (*lpi)->par_uobjlim = +1e+40;
804 (*lpi)->par_fastlp = 0;
805 (*lpi)->par_presolve = 0;
806 (*lpi)->messagehdlr = messagehdlr;
807
808 CHECK_ZERO( messagehdlr, XPRScreateprob(&(*lpi)->xprslp) );
809 invalidateSolution(*lpi);
810
811 /* turn logging off until the user explicitly turns it on; this should prevent any unwanted Xpress output from
812 * appearing in the SCIP log.
813 */
814 CHECK_ZERO( messagehdlr, XPRSsetintcontrol((*lpi)->xprslp, XPRS_OUTPUTLOG, 0) );
815
816 /* we need to create an empty LP in this prob since SCIP might attempt to add rows or columns to it */
817 CHECK_ZERO( messagehdlr, XPRSloadlp((*lpi)->xprslp, (*lpi)->name, 0, 0, NULL, NULL, NULL, NULL, &zero, NULL, NULL, NULL, NULL, NULL) );
818
819 /* set objective sense */
820 SCIP_CALL( SCIPlpiChgObjsen(*lpi, objsen) );
821
822 return SCIP_OKAY;
823}
824
825/** deletes an LP problem object */
827 SCIP_LPI** lpi /**< pointer to an LP interface structure */
828 )
829{
830 assert(lpi != NULL);
831 assert(*lpi != NULL);
832 assert((*lpi)->xprslp != NULL);
833
834 SCIPdebugMessage("SCIPlpiFree()\n");
835
836 /* free LP */
837 CHECK_ZERO( (*lpi)->messagehdlr, XPRSdestroyprob(((*lpi)->xprslp)) );
838
839 /* free environment */
840 CHECK_ZERO( (*lpi)->messagehdlr, XPRSfree() );
841
842 /* free memory */
843 BMSfreeMemoryArrayNull(&(*lpi)->larray);
844 BMSfreeMemoryArrayNull(&(*lpi)->uarray);
845 BMSfreeMemoryArrayNull(&(*lpi)->senarray);
846 BMSfreeMemoryArrayNull(&(*lpi)->rhsarray);
847 BMSfreeMemoryArrayNull(&(*lpi)->rngarray);
848 BMSfreeMemoryArrayNull(&(*lpi)->indarray);
849 BMSfreeMemoryArrayNull(&(*lpi)->valarray);
850 BMSfreeMemoryArrayNull(&(*lpi)->cstat);
851 BMSfreeMemoryArrayNull(&(*lpi)->rstat);
852 BMSfreeMemory(lpi);
853
854 return SCIP_OKAY;
855}
856
857/**@} */
858
859
860/**@name Modification Methods
861 *
862 * @{
863 */
864
865/** copies LP data with column matrix into LP solver */
867 SCIP_LPI* lpi, /**< LP interface structure */
868 SCIP_OBJSEN objsen, /**< objective sense */
869 int ncols, /**< number of columns */
870 const SCIP_Real* obj, /**< objective function values of columns */
871 const SCIP_Real* lb, /**< lower bounds of columns */
872 const SCIP_Real* ub, /**< upper bounds of columns */
873 char** colnames, /**< column names, or NULL */
874 int nrows, /**< number of rows */
875 const SCIP_Real* lhs, /**< left hand sides of rows */
876 const SCIP_Real* rhs, /**< right hand sides of rows */
877 char** rownames, /**< row names, or NULL */
878 int nnonz, /**< number of nonzero elements in the constraint matrix */
879 const int* beg, /**< start index of each column in ind- and val-array */
880 const int* ind, /**< row indices of constraint matrix entries */
881 const SCIP_Real* val /**< values of constraint matrix entries */
882 )
883{ /*lint --e{715}*/
884 int c;
885
886#ifndef NDEBUG
887 {
888 int j;
889 for( j = 0; j < nnonz; j++ )
890 assert( val[j] != 0 );
891 }
892#endif
893
894 assert(lpi != NULL);
895 assert(lpi->xprslp != NULL);
896 assert(obj != NULL);
897 assert(lb != NULL);
898 assert(ub != NULL);
899 assert(beg != NULL);
900 assert(ind != NULL);
901 assert(val != NULL);
902 SCIP_UNUSED(colnames);
903 SCIP_UNUSED(rownames);
904
905 SCIPdebugMessage("loading LP in column format into Xpress: %d cols, %d rows\n", ncols, nrows);
906
908
909 /* ensure that the temporary arrays for the side conversion are long enough */
910 SCIP_CALL( ensureSidechgMem(lpi, nrows) );
911
912 /* convert lhs/rhs into sen/rhs/range tuples the sen/rhs/range are stored in the temporary arrays in lpi structure */
913 convertSides(lpi, nrows, lhs, rhs);
914
915 /* ensure that the temporary arrays are large enough */
916 SCIP_CALL( ensureValMem(lpi, ncols) );
917
918 /* calculate column lengths */
919 for( c = 0; c < ncols-1; ++c )
920 {
921 lpi->indarray[c] = beg[c+1] - beg[c];
922 assert(lpi->indarray[c] >= 0);
923 }
924 lpi->indarray[ncols-1] = nnonz - beg[ncols-1];
925 assert(lpi->indarray[ncols-1] >= 0);
926
927 /* copy data into Xpress */
928 CHECK_ZERO( lpi->messagehdlr, XPRSloadlp(lpi->xprslp, lpi->name, ncols, nrows, lpi->senarray, lpi->rhsarray,
929 lpi->rngarray, obj, beg, lpi->indarray, ind, val, lb, ub) );
930
931 /* set objective sense */
932 SCIP_CALL( SCIPlpiChgObjsen(lpi, objsen) );
933
934 return SCIP_OKAY;
935}
936
937/** adds columns to the LP */
939 SCIP_LPI* lpi, /**< LP interface structure */
940 int ncols, /**< number of columns to be added */
941 const SCIP_Real* obj, /**< objective function values of new columns */
942 const SCIP_Real* lb, /**< lower bounds of new columns */
943 const SCIP_Real* ub, /**< upper bounds of new columns */
944 char** colnames, /**< column names, or NULL */
945 int nnonz, /**< number of nonzero elements to be added to the constraint matrix */
946 const int* beg, /**< start index of each column in ind- and val-array, or NULL if nnonz == 0 */
947 const int* ind, /**< row indices of constraint matrix entries, or NULL if nnonz == 0 */
948 const SCIP_Real* val /**< values of constraint matrix entries, or NULL if nnonz == 0 */
949 )
950{ /*lint --e{715}*/
951 int c;
952
953 assert(lpi != NULL);
954 assert(lpi->xprslp != NULL);
955 assert(ncols > 0);
956 assert(obj != NULL);
957 assert(lb != NULL);
958 assert(ub != NULL);
959 assert(nnonz >= 0);
960 assert(nnonz == 0 || beg != NULL);
961 assert(nnonz == 0 || ind != NULL);
962 assert(nnonz == 0 || val != NULL);
963 SCIP_UNUSED(colnames);
964
965 SCIPdebugMessage("adding %d columns with %d nonzeros to Xpress\n", ncols, nnonz);
966
968
969 /* ensure that the temporary arrays are large enough */
970 SCIP_CALL( ensureValMem(lpi, ncols+1) );
971
972#ifndef NDEBUG
973 {
974 /* perform check that no new rows are added - this is forbidden */
975 int nrows;
976 int j;
977
978 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows) );
979 for (j = 0; j < nnonz; ++j)
980 {
981 assert( val[j] != 0.0 );
982 assert( 0 <= ind[j] && ind[j] < nrows );
983 }
984 }
985#endif
986
987 /* only collect the start array if we have at least one non-zero */
988 if( nnonz > 0 )
989 {
990 /* we need ncol+1 entries in the start array for Xpress */
991 for( c = 0; c < ncols; c++ )
992 lpi->indarray[c] = beg[c];
993 lpi->indarray[ncols] = nnonz;
994 }
995
996 /* add the columns with (potential) non-zeros to the Xpress */
997 CHECK_ZERO( lpi->messagehdlr, XPRSaddcols(lpi->xprslp, ncols, nnonz, obj, lpi->indarray, ind, val, lb, ub) );
998
999 return SCIP_OKAY;
1000}
1001
1002/** deletes all columns in the given range from LP */
1004 SCIP_LPI* lpi, /**< LP interface structure */
1005 int firstcol, /**< first column to be deleted */
1006 int lastcol /**< last column to be deleted */
1007 )
1008{
1009 int c;
1010
1011 debugCheckColrang(lpi, firstcol, lastcol);
1012
1013 SCIPdebugMessage("deleting %d columns from Xpress\n", lastcol - firstcol + 1);
1014
1015 /* handle empty range */
1016 if( firstcol > lastcol )
1017 return SCIP_OKAY;
1018
1019 invalidateSolution(lpi);
1020
1021 /* ensure that the temporary arrays are large enough */
1022 SCIP_CALL( ensureValMem(lpi, lastcol-firstcol+1) );
1023
1024 /* collect the columns indices to be deleted */
1025 for( c = firstcol; c <= lastcol; c++ )
1026 lpi->indarray[c-firstcol] = c;
1027
1028 CHECK_ZERO( lpi->messagehdlr, XPRSdelcols(lpi->xprslp, lastcol-firstcol+1, lpi->indarray) );
1029
1030 return SCIP_OKAY;
1031}
1032
1033/** deletes columns from SCIP_LP; the new position of a column must not be greater that its old position */
1035 SCIP_LPI* lpi, /**< LP interface structure */
1036 int* dstat /**< deletion status of columns
1037 * input: 1 if column should be deleted, 0 if not
1038 * output: new position of column, -1 if column was deleted */
1039 )
1040{
1041 int nkeptcols;
1042 int ndelcols;
1043 int ncols;
1044 int c;
1045
1046 assert(lpi != NULL);
1047 assert(lpi->xprslp != NULL);
1048 assert(dstat != NULL);
1049
1050 SCIPdebugMessage("deleting a column set from Xpress\n");
1051
1052 invalidateSolution(lpi);
1053
1054 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_COLS, &ncols) );
1055
1056 nkeptcols = 0;
1057 ndelcols = 0;
1058
1059 /* ensure that the temporary arrays are large enough */
1060 SCIP_CALL( ensureValMem(lpi, ncols) );
1061
1062 /* collect the column indecies which should be deleted and create a the new column ordering */
1063 for( c = 0; c < ncols; c++ )
1064 {
1065 if( dstat[c] == 1 )
1066 {
1067 dstat[c] = -1;
1068 lpi->indarray[ndelcols] = c;
1069 ndelcols++;
1070 }
1071 else
1072 {
1073 dstat[c] = nkeptcols;
1074 nkeptcols++;
1075 }
1076 }
1077
1078 CHECK_ZERO( lpi->messagehdlr, XPRSdelcols(lpi->xprslp, ndelcols, lpi->indarray) );
1079
1080 return SCIP_OKAY;
1081}
1082
1083/** adds rows to the LP */
1085 SCIP_LPI* lpi, /**< LP interface structure */
1086 int nrows, /**< number of rows to be added */
1087 const SCIP_Real* lhs, /**< left hand sides of new rows */
1088 const SCIP_Real* rhs, /**< right hand sides of new rows */
1089 char** rownames, /**< row names, or NULL */
1090 int nnonz, /**< number of nonzero elements to be added to the constraint matrix */
1091 const int* beg, /**< start index of each row in ind- and val-array, or NULL if nnonz == 0 */
1092 const int* ind, /**< column indices of constraint matrix entries, or NULL if nnonz == 0 */
1093 const SCIP_Real* val /**< values of constraint matrix entries, or NULL if nnonz == 0 */
1094 )
1095{ /*lint --e{715}*/
1096 int r;
1097
1098 assert(lpi != NULL);
1099 assert(lpi->xprslp != NULL);
1100 assert(nrows >= 0);
1101 assert(lhs != NULL);
1102 assert(rhs != NULL);
1103 assert(nnonz >= 0);
1104 assert(nnonz == 0 || beg != NULL);
1105 assert(nnonz == 0 || ind != NULL);
1106 assert(nnonz == 0 || val != NULL);
1107 SCIP_UNUSED(rownames);
1108
1109 SCIPdebugMessage("adding %d rows with %d nonzeros to Xpress\n", nrows, nnonz);
1110
1111 invalidateSolution(lpi);
1112
1113#ifndef NDEBUG
1114 {
1115 /* perform check that no new cols are added - this is forbidden */
1116 int ncols;
1117 int j;
1118
1119 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_COLS, &ncols) );
1120 for (j = 0; j < nnonz; ++j)
1121 {
1122 assert( val[j] != 0.0 );
1123 assert( 0 <= ind[j] && ind[j] < ncols );
1124 }
1125 }
1126#endif
1127
1128 /* ensure that the temporary arrays are large enough */
1129 SCIP_CALL( ensureSidechgMem(lpi, nrows) );
1130 SCIP_CALL( ensureValMem(lpi, nrows+1) );
1131
1132 /* convert lhs/rhs into sen/rhs/range tuples */
1133 convertSides(lpi, nrows, lhs, rhs);
1134
1135 /* only collect the start array if we have at least one non-zero */
1136 if( nnonz > 0 )
1137 {
1138 for( r = 0; r < nrows; r++ )
1139 lpi->indarray[r] = beg[r];
1140 lpi->indarray[nrows] = nnonz;
1141 }
1142
1143 CHECK_ZERO( lpi->messagehdlr, XPRSaddrows(lpi->xprslp, nrows, nnonz, lpi->senarray, lpi->rhsarray, lpi->rngarray, lpi->indarray, ind, val) );
1144
1145 return SCIP_OKAY;
1146}
1147
1148/** deletes all rows in the given range from LP */
1150 SCIP_LPI* lpi, /**< LP interface structure */
1151 int firstrow, /**< first row to be deleted */
1152 int lastrow /**< last row to be deleted */
1153 )
1154{
1155 int r;
1156
1157 debugCheckRowrang(lpi, firstrow, lastrow);
1158
1159 SCIPdebugMessage("deleting %d rows from Xpress\n", lastrow - firstrow + 1);
1160
1161 /* handle empty range */
1162 if( firstrow > lastrow )
1163 return SCIP_OKAY;
1164
1165 invalidateSolution(lpi);
1166
1167 /* ensure that the temporary arrays are large enough */
1168 SCIP_CALL( ensureValMem(lpi, lastrow-firstrow+1) );
1169
1170 for( r = firstrow; r <= lastrow; r++ )
1171 lpi->indarray[r-firstrow] = r;
1172
1173 CHECK_ZERO( lpi->messagehdlr, XPRSdelrows(lpi->xprslp, lastrow-firstrow+1, lpi->indarray) );
1174
1175 return SCIP_OKAY;
1176}
1177
1178/** deletes rows from SCIP_LP; the new position of a row must not be greater that its old position */
1180 SCIP_LPI* lpi, /**< LP interface structure */
1181 int* dstat /**< deletion status of rows
1182 * input: 1 if row should be deleted, 0 if not
1183 * output: new position of row, -1 if row was deleted */
1184 )
1185{
1186 int nkeptrows;
1187 int ndelrows;
1188 int nrows;
1189 int r;
1190
1191 assert(lpi != NULL);
1192 assert(lpi->xprslp != NULL);
1193
1194 SCIPdebugMessage("deleting a row set from Xpress\n");
1195
1196 invalidateSolution(lpi);
1197
1198 nkeptrows = 0;
1199 ndelrows = 0;
1200
1201 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows) );
1202
1203 /* ensure that the temporary arrays are large enough */
1204 SCIP_CALL( ensureValMem(lpi, nrows) );
1205
1206 /* collect the row indecies which should be deleted and create a the new row ordering */
1207 for( r = 0; r < nrows; r++ )
1208 {
1209 if( dstat[r] == 1 )
1210 {
1211 dstat[r] = -1;
1212 lpi->indarray[ndelrows] = r;
1213 ndelrows++;
1214 }
1215 else
1216 {
1217 dstat[r] = nkeptrows;
1218 nkeptrows++;
1219 }
1220 }
1221
1222 CHECK_ZERO( lpi->messagehdlr, XPRSdelrows(lpi->xprslp, ndelrows, lpi->indarray) );
1223
1224 return SCIP_OKAY;
1225}
1226
1227/** clears the whole LP */
1229 SCIP_LPI* lpi /**< LP interface structure */
1230 )
1231{
1232 int zero = 0;
1233
1234 assert(lpi != NULL);
1235 assert(lpi->xprslp != NULL);
1236
1237 SCIPdebugMessage("clearing Xpress LP\n");
1238
1239 invalidateSolution(lpi);
1240
1241 /* create an empty LP in this */
1242 CHECK_ZERO( lpi->messagehdlr, XPRSloadlp(lpi->xprslp, lpi->name, 0, 0, NULL, NULL, NULL, NULL, &zero, NULL, NULL, NULL, NULL, NULL) );
1243
1244 return SCIP_OKAY;
1245}
1246
1247/** changes lower and upper bounds of columns */
1249 SCIP_LPI* lpi, /**< LP interface structure */
1250 int ncols, /**< number of columns to change bounds for */
1251 const int* ind, /**< column indices or NULL if ncols is zero */
1252 const SCIP_Real* lb, /**< values for the new lower bounds or NULL if ncols is zero */
1253 const SCIP_Real* ub /**< values for the new upper bounds or NULL if ncols is zero */
1254 )
1255{
1256 int j;
1257
1258 assert(lpi != NULL);
1259 assert(lpi->xprslp != NULL);
1260 assert(ncols == 0 || (ind != NULL && lb != NULL && ub != NULL));
1261
1262 SCIPdebugMessage("changing %d bounds in Xpress\n", ncols);
1263 if( ncols <= 0 )
1264 return SCIP_OKAY;
1265
1266 invalidateSolution(lpi);
1267
1268 for (j = 0; j < ncols; ++j)
1269 {
1270 if ( SCIPlpiIsInfinity(lpi, lb[j]) )
1271 {
1272 SCIPerrorMessage("LP Error: fixing lower bound for variable %d to infinity.\n", ind[j]);
1273 return SCIP_LPERROR;
1274 }
1275 if ( SCIPlpiIsInfinity(lpi, -ub[j]) )
1276 {
1277 SCIPerrorMessage("LP Error: fixing upper bound for variable %d to -infinity.\n", ind[j]);
1278 return SCIP_LPERROR;
1279 }
1280 }
1281
1282 /* ensure that the temporary arrays are large enough */
1283 SCIP_CALL( ensureBoundchgMem(lpi, ncols) );
1284
1285 CHECK_ZERO( lpi->messagehdlr, XPRSchgbounds(lpi->xprslp, ncols, ind, lpi->larray, (SCIP_Real*)lb) );
1286 CHECK_ZERO( lpi->messagehdlr, XPRSchgbounds(lpi->xprslp, ncols, ind, lpi->uarray, (SCIP_Real*)ub) );
1287
1288 return SCIP_OKAY;
1289}
1290
1291/** changes left and right hand sides of rows */
1293 SCIP_LPI* lpi, /**< LP interface structure */
1294 int nrows, /**< number of rows to change sides for */
1295 const int* ind, /**< row indices */
1296 const SCIP_Real* lhs, /**< new values for left hand sides */
1297 const SCIP_Real* rhs /**< new values for right hand sides */
1298 )
1299{
1300 assert(lpi != NULL);
1301 assert(lpi->xprslp != NULL);
1302 assert(ind != NULL);
1303
1304 SCIPdebugMessage("changing %d sides in Xpress\n", nrows);
1305 if( nrows <= 0 )
1306 return SCIP_OKAY;
1307
1308 invalidateSolution(lpi);
1309
1310 /* ensure that the temporary arrays are large enough */
1311 SCIP_CALL( ensureSidechgMem(lpi, nrows) );
1312
1313 /* convert lhs/rhs into sen/rhs/range tuples */
1314 convertSides(lpi, nrows, lhs, rhs);
1315
1316 /* change row sides */
1317 CHECK_ZERO( lpi->messagehdlr, XPRSchgrowtype(lpi->xprslp, nrows, ind, lpi->senarray) );
1318 CHECK_ZERO( lpi->messagehdlr, XPRSchgrhs(lpi->xprslp, nrows, ind, lpi->rhsarray) );
1319 CHECK_ZERO( lpi->messagehdlr, XPRSchgrhsrange(lpi->xprslp, nrows, ind, lpi->rngarray) );
1320
1321 return SCIP_OKAY;
1322}
1323
1324/** changes a single coefficient */
1326 SCIP_LPI* lpi, /**< LP interface structure */
1327 int row, /**< row number of coefficient to change */
1328 int col, /**< column number of coefficient to change */
1329 SCIP_Real newval /**< new value of coefficient */
1330 )
1331{
1332 assert(lpi != NULL);
1333 assert(lpi->xprslp != NULL);
1334
1335 SCIPdebugMessage("changing coefficient row %d, column %d in Xpress to %g\n", row, col, newval);
1336
1337 invalidateSolution(lpi);
1338
1339 CHECK_ZERO( lpi->messagehdlr, XPRSchgcoef(lpi->xprslp, row, col, newval) );
1340
1341 return SCIP_OKAY;
1342}
1343
1344/** changes the objective sense */
1346 SCIP_LPI* lpi, /**< LP interface structure */
1347 SCIP_OBJSEN objsense /**< new objective sense */
1348 )
1349{
1350 assert(lpi != NULL);
1351 assert(lpi->xprslp != NULL);
1352
1353 SCIPdebugMessage("changing objective sense in Xpress to %d\n", objsense);
1354
1355 invalidateSolution(lpi);
1356
1357 CHECK_ZERO( lpi->messagehdlr, XPRSchgobjsense(lpi->xprslp, xprsObjsen(objsense)) );
1358
1359 return SCIP_OKAY;
1360}
1361
1362/** changes objective values of columns in the LP */
1364 SCIP_LPI* lpi, /**< LP interface structure */
1365 int ncols, /**< number of columns to change objective value for */
1366 const int* ind, /**< column indices to change objective value for */
1367 const SCIP_Real* obj /**< new objective values for columns */
1368 )
1369{
1370 assert(lpi != NULL);
1371 assert(lpi->xprslp != NULL);
1372 assert(ind != NULL);
1373 assert(obj != NULL);
1374
1375 SCIPdebugMessage("changing %d objective values in Xpress\n", ncols);
1376
1377 invalidateSolution(lpi);
1378
1379 CHECK_ZERO( lpi->messagehdlr, XPRSchgobj(lpi->xprslp, ncols, ind, obj) );
1380
1381 return SCIP_OKAY;
1382}
1383
1384/** multiplies a row with a non-zero scalar; for negative scalars, the row's sense is switched accordingly */
1386 SCIP_LPI* lpi, /**< LP interface structure */
1387 int row, /**< row number to scale */
1388 SCIP_Real scaleval /**< scaling multiplier */
1389 )
1390{
1391 SCIP_Real lhs;
1392 SCIP_Real rhs;
1393 int nnonz;
1394 int ncols;
1395 int i;
1396
1397 assert(lpi != NULL);
1398 assert(lpi->xprslp != NULL);
1399 assert(scaleval != 0.0);
1400
1401 SCIPdebugMessage("scaling row %d with factor %g in Xpress\n", row, scaleval);
1402
1403 invalidateSolution(lpi);
1404
1405 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_COLS, &ncols) );
1406 SCIP_CALL( ensureValMem(lpi, ncols) );
1407
1408 /* get the row */
1409 SCIP_CALL( SCIPlpiGetSides(lpi, row, row, &lhs, &rhs) );
1410 CHECK_ZERO( lpi->messagehdlr, XPRSgetrows(lpi->xprslp, NULL, lpi->indarray, lpi->valarray, ncols, &nnonz, row, row) );
1411 assert(nnonz <= ncols);
1412
1413 /* scale row coefficients */
1414 for( i = 0; i < nnonz; ++i )
1415 {
1416 SCIP_CALL( SCIPlpiChgCoef(lpi, row, lpi->indarray[i], lpi->valarray[i] * scaleval) );
1417 }
1418
1419 /* scale row sides */
1420 if( lhs > XPRS_MINUSINFINITY )
1421 lhs *= scaleval;
1422 else if( scaleval < 0.0 )
1423 lhs = XPRS_PLUSINFINITY;
1424 if( rhs < XPRS_PLUSINFINITY )
1425 rhs *= scaleval;
1426 else if( scaleval < 0.0 )
1427 rhs = XPRS_MINUSINFINITY;
1428
1429 if( scaleval > 0.0 )
1430 {
1431 SCIP_CALL( SCIPlpiChgSides(lpi, 1, &row, &lhs, &rhs) );
1432 }
1433 else
1434 {
1435 SCIP_CALL( SCIPlpiChgSides(lpi, 1, &row, &rhs, &lhs) );
1436 }
1437
1438 return SCIP_OKAY;
1439}
1440
1441/** multiplies a column with a non-zero scalar; the objective value is multiplied with the scalar, and the bounds
1442 * are divided by the scalar; for negative scalars, the column's bounds are switched
1443 */
1445 SCIP_LPI* lpi, /**< LP interface structure */
1446 int col, /**< column number to scale */
1447 SCIP_Real scaleval /**< scaling multiplier */
1448 )
1449{
1450 SCIP_Real lb;
1451 SCIP_Real ub;
1452 SCIP_Real obj;
1453 int nnonz;
1454 int nrows;
1455 int i;
1456
1457 assert(lpi != NULL);
1458 assert(lpi->xprslp != NULL);
1459 assert(scaleval != 0.0);
1460
1461 SCIPdebugMessage("scaling column %d with factor %g in Xpress\n", col, scaleval);
1462
1463 invalidateSolution(lpi);
1464
1465 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows) );
1466 SCIP_CALL( ensureValMem(lpi, nrows) );
1467
1468 /* get the column */
1469 CHECK_ZERO( lpi->messagehdlr, XPRSgetlb(lpi->xprslp, &lb, col, col) );
1470 CHECK_ZERO( lpi->messagehdlr, XPRSgetub(lpi->xprslp, &ub, col, col) );
1471 CHECK_ZERO( lpi->messagehdlr, XPRSgetcols(lpi->xprslp, NULL, lpi->indarray, lpi->valarray, nrows, &nnonz, col, col) );
1472 assert(nnonz <= nrows);
1473
1474 /* get objective coefficient */
1475 SCIP_CALL( SCIPlpiGetObj(lpi, col, col, &obj) );
1476
1477 /* scale column coefficients */
1478 for( i = 0; i < nnonz; ++i )
1479 {
1480 SCIP_CALL( SCIPlpiChgCoef(lpi, lpi->indarray[i], col, lpi->valarray[i] * scaleval) );
1481 }
1482
1483 /* scale objective value */
1484 obj *= scaleval;
1485 SCIP_CALL( SCIPlpiChgObj(lpi, 1, &col, &obj) );
1486
1487 /* scale column bounds */
1488 if( lb > XPRS_MINUSINFINITY )
1489 lb /= scaleval;
1490 else if( scaleval < 0.0 )
1491 lb = XPRS_PLUSINFINITY;
1492 if( ub < XPRS_PLUSINFINITY )
1493 ub /= scaleval;
1494 else if( scaleval < 0.0 )
1495 ub = XPRS_MINUSINFINITY;
1496
1497 if( scaleval > 0.0 )
1498 {
1499 SCIP_CALL( SCIPlpiChgBounds(lpi, 1, &col, &lb, &ub) );
1500 }
1501 else
1502 {
1503 SCIP_CALL( SCIPlpiChgBounds(lpi, 1, &col, &ub, &lb) );
1504 }
1505
1506 return SCIP_OKAY;
1507}
1508
1509/**@} */
1510
1511
1512/**@name Data Accessing Methods
1513 *
1514 * @{
1515 */
1516
1517/** gets the number of rows in the LP */
1519 SCIP_LPI* lpi, /**< LP interface structure */
1520 int* nrows /**< pointer to store the number of rows */
1521 )
1522{
1523 assert(lpi != NULL);
1524 assert(lpi->xprslp != NULL);
1525 assert(nrows != NULL);
1526
1527 SCIPdebugMessage("getting number of rows\n");
1528
1529 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, nrows) );
1530
1531 return SCIP_OKAY;
1532}
1533
1534/** gets the number of columns in the LP */
1536 SCIP_LPI* lpi, /**< LP interface structure */
1537 int* ncols /**< pointer to store the number of cols */
1538 )
1539{
1540 assert(lpi != NULL);
1541 assert(lpi->xprslp != NULL);
1542 assert(ncols != NULL);
1543
1544 SCIPdebugMessage("getting number of columns\n");
1545
1546 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_COLS, ncols) );
1547
1548 return SCIP_OKAY;
1549}
1550
1551/** gets the number of nonzero elements in the LP constraint matrix */
1553 SCIP_LPI* lpi, /**< LP interface structure */
1554 int* nnonz /**< pointer to store the number of nonzeros */
1555 )
1556{
1557 assert(lpi != NULL);
1558 assert(lpi->xprslp != NULL);
1559 assert(nnonz != NULL);
1560
1561 SCIPdebugMessage("getting number of non-zeros\n");
1562
1563 CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ELEMS, nnonz) );
1564
1565 return SCIP_OKAY;
1566}
1567
1568/** gets columns from LP problem object; the arrays have to be large enough to store all values
1569 * Either both, lb and ub, have to be NULL, or both have to be non-NULL,
1570 * either nnonz, beg, ind, and val have to be NULL, or all of them have to be non-NULL.
1571 */
1573 SCIP_LPI* lpi, /**< LP interface structure */
1574 int firstcol, /**< first column to get from LP */
1575 int lastcol, /**< last column to get from LP */
1576 SCIP_Real* lb, /**< buffer to store the lower bound vector, or NULL */
1577 SCIP_Real* ub, /**< buffer to store the upper bound vector, or NULL */
1578 int* nnonz, /**< pointer to store the number of nonzero elements returned, or NULL */
1579 int* beg, /**< buffer to store start index of each column in ind- and val-array, or NULL */
1580 int* ind, /**< buffer to store row indices of constraint matrix entries, or NULL */
1581 SCIP_Real* val /**< buffer to store values of constraint matrix entries, or NULL */
1582 )
1583{
1584 assert((lb != NULL && ub != NULL) || (lb == NULL && ub == NULL));
1585 assert((nnonz != NULL && beg != NULL && ind != NULL && val != NULL) || (nnonz == NULL && beg == NULL && ind == NULL && val == NULL));
1586
1587 debugCheckColrang(lpi, firstcol, lastcol);
1588
1589 SCIPdebugMessage("getting columns %d to %d\n", firstcol, lastcol);
1590
1591 if( lb != NULL )
1592 {
1593 CHECK_ZERO( lpi->messagehdlr, XPRSgetlb(lpi->xprslp, lb, firstcol, lastcol) );
1594 CHECK_ZERO( lpi->messagehdlr, XPRSgetub(lpi->xprslp, ub, firstcol, lastcol) );
1595 }
1596
1597 if( nnonz != NULL )
1598 {
1599 int ntotalnonz;
1600 int c;
1601
1602 /* ensure that the temporary buffer array is large enough */
1603 SCIP_CALL( ensureValMem(lpi, lastcol-firstcol+2) );
1604
1605 /* get number of nonzero in the whole problem; needed to pass a proper size to XPRSgetcols() function call
1606 *
1607 * @note We are assuming that the arrays given by SCIP are large enough. Otherwise we are getting invalid writes
1608 */
1609 SCIP_CALL( SCIPlpiGetNNonz(lpi, &ntotalnonz) );
1610
1611 /* get matrix entries */
1612 CHECK_ZERO( lpi->messagehdlr, XPRSgetcols(lpi->xprslp, lpi->indarray, ind, val, ntotalnonz, nnonz, firstcol, lastcol) );
1613 assert(*nnonz <= ntotalnonz);
1614 assert(lpi->indarray[lastcol-firstcol+1] == *nnonz);
1615
1616 assert(beg != NULL); /* for lint */
1617 for( c = 0; c < lastcol-firstcol+1; c++ )
1618 beg[c] = lpi->indarray[c];
1619 }
1620
1621 return SCIP_OKAY;
1622}
1623
1624/** gets rows from LP problem object; the arrays have to be large enough to store all values.
1625 * Either both, lhs and rhs, have to be NULL, or both have to be non-NULL,
1626 * either nnonz, beg, ind, and val have to be NULL, or all of them have to be non-NULL.
1627 */
1629 SCIP_LPI* lpi, /**< LP interface structure */
1630 int firstrow, /**< first row to get from LP */
1631 int lastrow, /**< last row to get from LP */
1632 SCIP_Real* lhss, /**< buffer to store left hand side vector, or NULL */
1633 SCIP_Real* rhss, /**< buffer to store right hand side vector, or NULL */
1634 int* nnonz, /**< pointer to store the number of nonzero elements returned, or NULL */
1635 int* beg, /**< buffer to store start index of each row in ind- and val-array, or NULL */
1636 int* ind, /**< buffer to store column indices of constraint matrix entries, or NULL */
1637 SCIP_Real* val /**< buffer to store values of constraint matrix entries, or NULL */
1638 )
1639{
1640 assert((lhss != NULL && rhss != NULL) || (lhss == NULL && rhss == NULL));
1641 assert((nnonz != NULL && beg != NULL && ind != NULL && val != NULL) || (nnonz == NULL && beg == NULL && ind == NULL && val == NULL));
1642
1643 debugCheckRowrang(lpi, firstrow, lastrow);
1644
1645 SCIPdebugMessage("getting rows %d to %d\n", firstrow, lastrow);
1646
1647 if( lhss != NULL )
1648 {
1649 /* get left and right sides */
1650 SCIP_CALL( SCIPlpiGetSides(lpi, firstrow, lastrow, lhss, rhss) );
1651 }
1652
1653 if( nnonz != NULL )
1654 {
1655 int ntotalnonz;
1656 int r;
1657
1658 /* ensure that the temporary buffer array is large enough */
1659 SCIP_CALL( ensureValMem(lpi, lastrow-firstrow+2) );
1660
1661 /* get number of nonzero in the whole problem; needed to pass a proper size to XPRSgetrows() function call
1662 *
1663 * @note We are assuming that the arrays given by SCIP are large enough. Otherwise we are getting invalid writes
1664 */
1665 SCIP_CALL( SCIPlpiGetNNonz(lpi, &ntotalnonz) );
1666
1667 /* get matrix entries */
1668 CHECK_ZERO( lpi->messagehdlr, XPRSgetrows(lpi->xprslp, lpi->indarray, ind, val, ntotalnonz, nnonz, firstrow, lastrow) );
1669 assert(*nnonz <= ntotalnonz);
1670 assert(lpi->indarray[lastrow-firstrow+1] == *nnonz);
1671
1672 assert(beg != NULL); /* for lint */
1673 for( r = 0; r < lastrow-firstrow+1; r++ )
1674 beg[r] = lpi->indarray[r];
1675 }
1676
1677 return SCIP_OKAY;
1678}
1679
1680/** gets column names */
1682 SCIP_LPI* lpi, /**< LP interface structure */
1683 int firstcol, /**< first column to get name from LP */
1684 int lastcol, /**< last column to get name from LP */
1685 char** colnames, /**< pointers to column names (of size at least lastcol-firstcol+1) or NULL if namestoragesize is zero */
1686 char* namestorage, /**< storage for col names or NULL if namestoragesize is zero */
1687 int namestoragesize, /**< size of namestorage (if 0, storageleft returns the storage needed) */
1688 int* storageleft /**< amount of storage left (if < 0 the namestorage was not big enough) or NULL if namestoragesize is zero */
1689 )
1690{ /*lint --e{715}*/
1691 assert(colnames != NULL || namestoragesize == 0);
1692 assert(namestorage != NULL || namestoragesize == 0);
1693 assert(namestoragesize >= 0);
1694 assert(storageleft != NULL);
1695
1696 debugCheckColrang(lpi, firstcol, lastcol);
1697
1698 SCIPerrorMessage("SCIPlpiGetColNames() has not been implemented yet.\n");
1699
1700 return SCIP_LPERROR;
1701}
1702
1703/** gets row names */
1705 SCIP_LPI* lpi, /**< LP interface structure */
1706 int firstrow, /**< first row to get name from LP */
1707 int lastrow, /**< last row to get name from LP */
1708 char** rownames, /**< pointers to row names (of size at least lastrow-firstrow+1) or NULL if namestoragesize is zero */
1709 char* namestorage, /**< storage for row names or NULL if namestoragesize is zero */
1710 int namestoragesize, /**< size of namestorage (if 0, -storageleft returns the storage needed) */
1711 int* storageleft /**< amount of storage left (if < 0 the namestorage was not big enough) or NULL if namestoragesize is zero */
1712 )
1713{ /*lint --e{715}*/
1714 assert(rownames != NULL || namestoragesize == 0);
1715 assert(namestorage != NULL || namestoragesize == 0);
1716 assert(namestoragesize >= 0);
1717 assert(storageleft != NULL);
1718
1719 debugCheckRowrang(lpi, firstrow, lastrow);
1720
1721 SCIPerrorMessage("SCIPlpiGetRowNames() has not been implemented yet.\n");
1722
1723 return SCIP_LPERROR;
1724}
1725
1726/** gets the objective sense of the LP */
1728 SCIP_LPI* lpi, /**< LP interface structure */
1729 SCIP_OBJSEN* objsen /**< pointer to store objective sense */
1730 )
1731{
1732 double xprsobjsen;
1733 assert(lpi != NULL);
1734 assert(lpi->xprslp != NULL);
1735 assert(objsen != NULL);
1736
1737 /* check the objective sense attribute for the current objective sense set in Xpress */
1738 CHECK_ZERO( lpi->messagehdlr, XPRSgetdblattrib(lpi->xprslp, XPRS_OBJSENSE, &xprsobjsen) );
1739
1740 /* convert the Xpress objective sense attribute to a SCIP objective sense */
1741 if( xprsobjsen < 0.0 )
1742 (*objsen) = SCIP_OBJSEN_MAXIMIZE;
1743 else
1744 (*objsen) = SCIP_OBJSEN_MINIMIZE;
1745
1746 return SCIP_OKAY;
1747}
1748
1749/** gets objective coefficients from LP problem object */
1751 SCIP_LPI* lpi, /**< LP interface structure */
1752 int firstcol, /**< first column to get objective coefficient for */
1753 int lastcol, /**< last column to get objective coefficient for */
1754 SCIP_Real* vals /**< array to store objective coefficients */
1755 )
1756{
1757 assert(vals != NULL);
1758
1759 debugCheckColrang(lpi, firstcol, lastcol);
1760
1761 SCIPdebugMessage("getting objective values %d to %d\n", firstcol, lastcol);
1762
1763 CHECK_ZERO( lpi->messagehdlr, XPRSgetobj(lpi->xprslp, vals, firstcol, lastcol) );
1764
1765 return SCIP_OKAY;
1766}
1767
1768/** gets current bounds from LP problem object */
1770 SCIP_LPI* lpi, /**< LP interface structure */
1771 int firstcol, /**< first column to get bounds for */
1772 int lastcol, /**< last column to get bounds for */
1773 SCIP_Real* lbs, /**< array to store lower bound values, or NULL */
1774 SCIP_Real* ubs /**< array to store upper bound values, or NULL */
1775 )
1776{
1777 debugCheckColrang(lpi, firstcol, lastcol);
1778
1779 SCIPdebugMessage("getting bounds %d to %d\n", firstcol, lastcol);
1780
1781 if( lbs != NULL )
1782 {
1783 CHECK_ZERO( lpi->messagehdlr, XPRSgetlb(lpi->xprslp, lbs, firstcol, lastcol) );
1784 }
1785
1786 if( ubs != NULL )
1787 {
1788 CHECK_ZERO( lpi->messagehdlr, XPRSgetub(lpi->xprslp, ubs, firstcol, lastcol) );
1789 }
1790
1791 return SCIP_OKAY;
1792}
1793
1794/** gets current row sides from LP problem object */
1796 SCIP_LPI* lpi, /**< LP interface structure */
1797 int firstrow, /**< first row to get sides for */
1798 int lastrow, /**< last row to get sides for */
1799 SCIP_Real* lhss, /**< array to store left hand side values, or NULL */
1800 SCIP_Real* rhss /**< array to store right hand side values, or NULL */
1801 )
1802{
1803 debugCheckRowrang(lpi, 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:248
#define SCIP_UNUSED(x)
Definition: def.h:409
#define SCIP_INVALID
Definition: def.h:178
#define SCIP_Bool
Definition: def.h:91
#define MIN(x, y)
Definition: def.h:224
#define SCIP_ALLOC(x)
Definition: def.h:366
#define SCIP_Real
Definition: def.h:156
#define TRUE
Definition: def.h:93
#define FALSE
Definition: def.h:94
#define MAX(x, y)
Definition: def.h:220
#define EPSCEIL(x, eps)
Definition: def.h:192
#define SCIPABORT()
Definition: def.h:327
#define EPSFLOOR(x, eps)
Definition: def.h:191
#define REALABS(x)
Definition: def.h:182
#define SCIP_CALL(x)
Definition: def.h:355
void SCIPsplitFilename(char *filename, char **path, char **name, char **extension, char **compression)
Definition: misc.c:11073
SCIP_RETCODE SCIPlpiChgSides(SCIP_LPI *lpi, int nrows, const int *ind, const SCIP_Real *lhs, const SCIP_Real *rhs)
Definition: lpi_xprs.c:1292
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:1345
SCIP_Bool SCIPlpiIsInfinity(SCIP_LPI *lpi, SCIP_Real val)
Definition: lpi_xprs.c:3783
SCIP_RETCODE SCIPlpiClear(SCIP_LPI *lpi)
Definition: lpi_xprs.c:1228
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:1084
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:704
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:1552
SCIP_Bool SCIPlpiHasPrimalSolve(void)
Definition: lpi_xprs.c:719
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:1769
SCIP_Bool SCIPlpiHasBarrierSolve(void)
Definition: lpi_xprs.c:735
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:1444
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:1248
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:826
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:668
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:1149
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:1572
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:1681
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:1628
SCIP_Bool SCIPlpiWasSolved(SCIP_LPI *lpi)
Definition: lpi_xprs.c:2319
const char * SCIPlpiGetSolverDesc(void)
Definition: lpi_xprs.c:685
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:1704
SCIP_Bool SCIPlpiHasDualSolve(void)
Definition: lpi_xprs.c:727
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:1795
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:1034
SCIP_RETCODE SCIPlpiGetObj(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *vals)
Definition: lpi_xprs.c:1750
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:938
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:866
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:751
void * SCIPlpiGetSolverPointer(SCIP_LPI *lpi)
Definition: lpi_xprs.c:696
SCIP_RETCODE SCIPlpiChgObj(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *obj)
Definition: lpi_xprs.c:1363
SCIP_RETCODE SCIPlpiGetObjsen(SCIP_LPI *lpi, SCIP_OBJSEN *objsen)
Definition: lpi_xprs.c:1727
SCIP_Bool SCIPlpiIsStable(SCIP_LPI *lpi)
Definition: lpi_xprs.c:2578
SCIP_RETCODE SCIPlpiGetNCols(SCIP_LPI *lpi, int *ncols)
Definition: lpi_xprs.c:1535
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:1003
SCIP_RETCODE SCIPlpiDelRowset(SCIP_LPI *lpi, int *dstat)
Definition: lpi_xprs.c:1179
SCIP_RETCODE SCIPlpiScaleRow(SCIP_LPI *lpi, int row, SCIP_Real scaleval)
Definition: lpi_xprs.c:1385
SCIP_RETCODE SCIPlpiGetNRows(SCIP_LPI *lpi, int *nrows)
Definition: lpi_xprs.c:1518
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:1325
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10827
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:625
static void lpistatePack(SCIP_LPISTATE *lpistate, const int *cstat, const int *rstat)
Definition: lpi_xprs.c:341
static void lpistateUnpack(const SCIP_LPISTATE *lpistate, int *cstat, int *rstat)
Definition: lpi_xprs.c:357
static int rowpacketNum(int nrows)
Definition: lpi_xprs.c:332
static _Thread_local char xprsname[100]
Definition: lpi_xprs.c:663
SCIP_DUALPACKET ROWPACKET
Definition: lpi_xprs.c:84
static SCIP_RETCODE ensureCstatMem(SCIP_LPI *lpi, int num)
Definition: lpi_xprs.c:271
static void reconvertBothSides(SCIP_LPI *lpi, int nrows, SCIP_Real *lhss, SCIP_Real *rhss)
Definition: lpi_xprs.c:486
static SCIP_RETCODE lpiSolve(SCIP_LPI *lpi, const char *method)
Definition: lpi_xprs.c:1848
#define COLS_PER_PACKET
Definition: lpi_xprs.c:83
static void reconvertRhs(SCIP_LPI *lpi, int nrows, SCIP_Real *rhss)
Definition: lpi_xprs.c:580
#define XPRS_LPQUICKPRESOLVE
Definition: lpi_xprs.c:57
static SCIP_RETCODE ensureBoundchgMem(SCIP_LPI *lpi, int num)
Definition: lpi_xprs.c:195
static void debugCheckRowrang(SCIP_LPI *lpi, int firstrow, int lastrow)
Definition: lpi_xprs.c:161
static void lpistateFree(SCIP_LPISTATE **lpistate, BMS_BLKMEM *blkmem)
Definition: lpi_xprs.c:394
SCIP_DUALPACKET COLPACKET
Definition: lpi_xprs.c:82
static int xprsObjsen(SCIP_OBJSEN const objsen)
Definition: lpi_xprs.c:418
#define XPRS_LP_OPTIMAL_SCALEDINFEAS
Definition: lpi_xprs.c:61
#define ABORT_ZERO(messagehdlr, retval, x)
Definition: lpi_xprs.c:72
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:63
static SCIP_RETCODE ensureRstatMem(SCIP_LPI *lpi, int num)
Definition: lpi_xprs.c:293
static int colpacketNum(int ncols)
Definition: lpi_xprs.c:323
static void debugCheckColrang(SCIP_LPI *lpi, int firstcol, int lastcol)
Definition: lpi_xprs.c:144
static void convertSides(SCIP_LPI *lpi, int nrows, const SCIP_Real *lhss, const SCIP_Real *rhss)
Definition: lpi_xprs.c:437
static SCIP_RETCODE ensureSidechgMem(SCIP_LPI *lpi, int num)
Definition: lpi_xprs.c:224
static void reconvertLhs(SCIP_LPI *lpi, int nrows, SCIP_Real *lhss)
Definition: lpi_xprs.c:535
static SCIP_RETCODE lpistateCreate(SCIP_LPISTATE **lpistate, BMS_BLKMEM *blkmem, int ncols, int nrows)
Definition: lpi_xprs.c:373
#define ROWS_PER_PACKET
Definition: lpi_xprs.c:85
static void invalidateSolution(SCIP_LPI *lpi)
Definition: lpi_xprs.c:645
static SCIP_RETCODE ensureValMem(SCIP_LPI *lpi, int num)
Definition: lpi_xprs.c:248
#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:121
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:120
SCIP_Real par_lobjlim
Definition: lpi_xprs.c:118
char * uarray
Definition: lpi_cpx.c:153
XPRSprob xprslp
Definition: lpi_xprs.c:90
int boundchgsize
Definition: lpi_cpx.c:162
int notfromscratch
Definition: lpi_xprs.c:94
int * indarray
Definition: lpi_cpx.c:161
int * cstat
Definition: lpi_clp.cpp:107
char solmethod
Definition: lpi_xprs.c:96
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:91
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:119
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