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