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