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