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