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