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