Scippy

SCIP

Solving Constraint Integer Programs

lpi_xprs.c
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the program and library */
4 /* SCIP --- Solving Constraint Integer Programs */
5 /* */
6 /* Copyright (c) 2002-2024 Zuse Institute Berlin (ZIB) */
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/en/products/fico-xpress-optimization)";
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 #if XPVERSION <= 40
2737  CHECK_ZERO( lpi->messagehdlr, XPRSgetsol(lpi->xprslp, primsol, activity, dualsol, redcost) );
2738 #else
2739  CHECK_ZERO( lpi->messagehdlr, XPRSgetlpsol(lpi->xprslp, primsol, activity, dualsol, redcost) );
2740 #endif
2741 
2742  if( objval != NULL )
2743  {
2744  CHECK_ZERO( lpi->messagehdlr, XPRSgetdblattrib(lpi->xprslp, XPRS_LPOBJVAL, objval) );
2745  }
2746 
2747  if( activity != NULL )
2748  {
2749  /* Convert the slack values into activity values. */
2750  int nrows;
2751  int r;
2752 
2753  CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows) );
2754 
2755  SCIP_CALL( ensureSidechgMem(lpi, nrows) );
2756 
2757  CHECK_ZERO( lpi->messagehdlr, XPRSgetrhs(lpi->xprslp, lpi->rhsarray, 0, nrows-1) );
2758 
2759  for( r = 0; r < nrows; r++ )
2760  activity[r] = lpi->rhsarray[r] - activity[r];
2761  }
2762 
2763  return SCIP_OKAY;
2764 }
2765 
2766 /** gets primal ray for unbounded LPs */
2768  SCIP_LPI* lpi, /**< LP interface structure */
2769  SCIP_Real* ray /**< primal ray */
2770  )
2771 {
2772  int hasRay;
2773 
2774  assert(lpi != NULL);
2775  assert(lpi->xprslp != NULL);
2776  assert(ray != NULL);
2777  assert(lpi->solstat >= 0);
2778 
2779  CHECK_ZERO( lpi->messagehdlr, XPRSgetprimalray(lpi->xprslp, ray, &hasRay) );
2780 
2781  if( !hasRay )
2782  return SCIP_LPERROR;
2783 
2784  return SCIP_OKAY;
2785 }
2786 
2787 /** gets dual Farkas proof for infeasibility */
2789  SCIP_LPI* lpi, /**< LP interface structure */
2790  SCIP_Real* dualfarkas /**< dual Farkas row multipliers */
2791  )
2792 {
2793  int hasRay;
2794 
2795  assert(lpi != NULL);
2796  assert(lpi->xprslp != NULL);
2797  assert(lpi->solstat >= 0);
2798  assert(dualfarkas != NULL);
2799 
2800  /**@note The Farkas proof might be numerically questionable which is indicated by "hasRay" use SCIPlpiHasDualRay() to
2801  * check that!
2802  */
2803  CHECK_ZERO( lpi->messagehdlr, XPRSgetdualray(lpi->xprslp, dualfarkas, &hasRay) );
2804 
2805  return SCIP_OKAY;
2806 }
2807 
2808 /** gets the number of LP iterations of the last solve call */
2810  SCIP_LPI* lpi, /**< LP interface structure */
2811  int* iterations /**< pointer to store the number of iterations of the last solve call */
2812  )
2813 {
2814  assert(lpi != NULL);
2815  assert(lpi->xprslp != NULL);
2816  assert(iterations != NULL);
2817 
2818  *iterations = lpi->iterations;
2819 
2820  return SCIP_OKAY;
2821 }
2822 
2823 /** gets information about the quality of an LP solution
2824  *
2825  * Such information is usually only available, if also a (maybe not optimal) solution is available.
2826  * The LPI should return SCIP_INVALID for @p quality, if the requested quantity is not available.
2827  */
2829  SCIP_LPI* lpi, /**< LP interface structure */
2830  SCIP_LPSOLQUALITY qualityindicator, /**< indicates which quality should be returned */
2831  SCIP_Real* quality /**< pointer to store quality number */
2832  )
2833 { /*lint --e{715}*/
2834  assert(lpi != NULL);
2835  assert(quality != NULL);
2836  SCIP_UNUSED(qualityindicator);
2837 
2838  *quality = SCIP_INVALID;
2839 
2840  return SCIP_OKAY;
2841 }
2842 
2843 /**@} */
2844 
2845 
2846 /**@name LP Basis Methods
2847  *
2848  * @{
2849  */
2850 
2851 /** gets current basis status for columns and rows; arrays must be large enough to store the basis status */
2853  SCIP_LPI* lpi, /**< LP interface structure */
2854  int* cstat, /**< array to store column basis status, or NULL */
2855  int* rstat /**< array to store row basis status, or NULL (the status is need for the row and not for the slack column) */
2856  )
2857 {
2858  int nrows;
2859  int r;
2860 
2861  assert(lpi != NULL);
2862  assert(lpi->xprslp != NULL);
2863 
2864  /*lint --e{506}*/
2865  assert((int) SCIP_BASESTAT_LOWER == 0);
2866  assert((int) SCIP_BASESTAT_BASIC == 1);
2867  assert((int) SCIP_BASESTAT_UPPER == 2);
2868 
2869  SCIPdebugMessage("saving Xpress basis into %p/%p\n", (void*)rstat, (void*)cstat);
2870 
2871  /* get the basis status */
2872  CHECK_ZERO( lpi->messagehdlr, XPRSgetbasis(lpi->xprslp, rstat, cstat) );
2873 
2874  /* get the number of rows */
2875  CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows) );
2876 
2877  /* XPRSgetbasis collects the basis status for the column and the slack column, since SCIP request the basis for
2878  * columns and rows we need to convert slack column status to row status
2879  */
2880  for( r = 0; r < nrows; ++r )
2881  {
2882  if (rstat[r] == (int) SCIP_BASESTAT_LOWER)
2883  rstat[r] = (int) SCIP_BASESTAT_UPPER;
2884  else if (rstat[r] == (int) SCIP_BASESTAT_UPPER)
2885  rstat[r] = (int) SCIP_BASESTAT_LOWER;
2886  }
2887 
2888  return SCIP_OKAY;
2889 }
2890 
2891 /** sets current basis status for columns and rows */
2893  SCIP_LPI* lpi, /**< LP interface structure */
2894  const int* cstat, /**< array with column basis status */
2895  const int* rstat /**< array with row basis status */
2896  )
2897 {
2898  int* slackstats;
2899  int ncols;
2900  int nrows;
2901  int r;
2902 
2903  assert(lpi != NULL);
2904  assert(lpi->xprslp != NULL);
2905 
2906  /* get the number of rows/columns */
2907  SCIP_CALL( SCIPlpiGetNRows(lpi, &nrows) );
2908  SCIP_CALL( SCIPlpiGetNCols(lpi, &ncols) );
2909 
2910  assert(cstat != NULL || ncols == 0);
2911  assert(rstat != NULL || nrows == 0);
2912 
2913  /*lint --e{506}*/
2914  assert((int) SCIP_BASESTAT_LOWER == 0);
2915  assert((int) SCIP_BASESTAT_BASIC == 1);
2916  assert((int) SCIP_BASESTAT_UPPER == 2);
2917 
2918  SCIPdebugMessage("loading basis %p/%p into Xpress\n", (void*)rstat, (void*)cstat);
2919 
2920  invalidateSolution(lpi);
2921 
2922  SCIP_ALLOC( BMSallocMemoryArray(&slackstats, nrows) );
2923 
2924  /* XPRSloadbasis expects the basis status for the column and the slack column, since SCIP has the basis status for
2925  * columns and rows we need to convert row status to slack column status
2926  */
2927  for( r = 0; r < nrows; ++r )
2928  {
2929  if (rstat[r] == (int) SCIP_BASESTAT_LOWER) /*lint !e613*/
2930  slackstats[r] = (int) SCIP_BASESTAT_UPPER;
2931  else if (rstat[r] == (int) SCIP_BASESTAT_UPPER) /*lint !e613*/
2932  slackstats[r] = (int) SCIP_BASESTAT_LOWER;
2933  else
2934  slackstats[r] = rstat[r]; /*lint !e613*/
2935  }
2936 
2937  /* load basis information into Xpress
2938  *
2939  * @note Xpress expects the row status w.r.t. slack columns!
2940  */
2941  CHECK_ZERO( lpi->messagehdlr, XPRSloadbasis(lpi->xprslp, slackstats, cstat) );
2942 
2943  BMSfreeMemoryArray(&slackstats);
2944 
2945  lpi->clearstate = FALSE;
2946 
2947  return SCIP_OKAY;
2948 }
2949 
2950 /** returns the indices of the basic columns and rows; basic column n gives value n, basic row m gives value -1-m */
2952  SCIP_LPI* lpi, /**< LP interface structure */
2953  int* bind /**< pointer to store basis indices ready to keep number of rows entries */
2954  )
2955 {
2956  int irspace;
2957  int nrows;
2958  int r;
2959 
2960  /* In the basis methods we assume that xprs basis flags coincide with scip, so assert it */
2961  /*lint --e{506}*/
2962  assert((int) SCIP_BASESTAT_LOWER == 0);
2963  assert((int) SCIP_BASESTAT_BASIC == 1);
2964  assert((int) SCIP_BASESTAT_UPPER == 2);
2965  assert((int) SCIP_BASESTAT_ZERO == 3);
2966 
2967  assert(lpi != NULL);
2968  assert(lpi->xprslp != NULL);
2969  assert(bind != NULL);
2970 
2971  SCIPdebugMessage("getting basis information\n");
2972 
2973  CHECK_ZERO( lpi->messagehdlr, XPRSgetpivotorder(lpi->xprslp, bind) );
2974 
2975  /* Reindex variables to match those of SCIP. */
2976  CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows) );
2977  CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_SPAREROWS, &irspace) );
2978  irspace += nrows;
2979 
2980  for( r = 0; r < nrows; r++ )
2981  {
2982  if( bind[r] < nrows )
2983  bind[r] = -bind[r]-1;
2984  else
2985  {
2986  assert(bind[r] >= irspace);
2987  bind[r] = bind[r] - irspace;
2988  }
2989  }
2990 
2991  return SCIP_OKAY;
2992 }
2993 
2994 /** get row of inverse basis matrix B^-1
2995  *
2996  * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
2997  * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
2998  * see also the explanation in lpi.h.
2999  *
3000  * @todo check that the result is in terms of the LP interface definition
3001  */
3003  SCIP_LPI* lpi, /**< LP interface structure */
3004  int row, /**< row number */
3005  SCIP_Real* coef, /**< pointer to store the coefficients of the row */
3006  int* inds, /**< array to store the non-zero indices, or NULL */
3007  int* ninds /**< pointer to store the number of non-zero indices, or NULL
3008  * (-1: if we do not store sparsity information) */
3009  )
3010 { /*lint --e{715}*/
3011  int nrows;
3012 
3013  assert(lpi != NULL);
3014  assert(lpi->xprslp != NULL);
3015  assert(coef != NULL);
3016  SCIP_UNUSED(inds);
3017 
3018  SCIPdebugMessage("getting binv-row %d\n", row);
3019 
3020  /* can only return dense result */
3021  if ( ninds != NULL )
3022  *ninds = -1;
3023 
3024  CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows) );
3025  BMSclearMemoryArray(coef, nrows);
3026  coef[row] = 1.0;
3027  CHECK_ZERO( lpi->messagehdlr, XPRSbtran(lpi->xprslp, coef) );
3028 
3029  return SCIP_OKAY;
3030 }
3031 
3032 /** get column of inverse basis matrix B^-1
3033  *
3034  * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
3035  * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
3036  * see also the explanation in lpi.h.
3037  *
3038  * @todo check that the result is in terms of the LP interface definition
3039  */
3041  SCIP_LPI* lpi, /**< LP interface structure */
3042  int c, /**< column number of B^-1; this is NOT the number of the column in the LP;
3043  * you have to call SCIPlpiGetBasisInd() to get the array which links the
3044  * B^-1 column numbers to the row and column numbers of the LP!
3045  * c must be between 0 and nrows-1, since the basis has the size
3046  * nrows * nrows */
3047  SCIP_Real* coef, /**< pointer to store the coefficients of the column */
3048  int* inds, /**< array to store the non-zero indices, or NULL */
3049  int* ninds /**< pointer to store the number of non-zero indices, or NULL
3050  * (-1: if we do not store sparsity information) */
3051  )
3052 { /*lint --e{715}*/
3053  int nrows;
3054 
3055  assert(lpi != NULL);
3056  assert(lpi->xprslp != NULL);
3057  assert(coef != NULL);
3058  SCIP_UNUSED(inds);
3059 
3060  SCIPdebugMessage("getting binv-col %d\n", c);
3061 
3062  /* can only return dense result */
3063  if ( ninds != NULL )
3064  *ninds = -1;
3065 
3066  CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows) );
3067  BMSclearMemoryArray(coef, nrows);
3068  coef[c] = 1.0;
3069  CHECK_ZERO( lpi->messagehdlr, XPRSftran(lpi->xprslp, coef) );
3070 
3071  return SCIP_OKAY;
3072 }
3073 
3074 /** get row of inverse basis matrix times constraint matrix B^-1 * A
3075  *
3076  * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
3077  * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
3078  * see also the explanation in lpi.h.
3079  *
3080  * @todo check that the result is in terms of the LP interface definition
3081  */
3083  SCIP_LPI* lpi, /**< LP interface structure */
3084  int r, /**< row number */
3085  const SCIP_Real* binvrow, /**< row in (A_B)^-1 from prior call to SCIPlpiGetBInvRow(), or NULL */
3086  SCIP_Real* coef, /**< vector to return coefficients of the row */
3087  int* inds, /**< array to store the non-zero indices, or NULL */
3088  int* ninds /**< pointer to store the number of non-zero indices, or NULL
3089  * (-1: if we do not store sparsity information) */
3090  )
3091 { /*lint --e{715}*/
3092  SCIP_Real* binv;
3093  SCIP_Real* buffer;
3094  int ncols;
3095  int nrows;
3096  int nnonz;
3097  int c;
3098 
3099  assert(lpi != NULL);
3100  assert(lpi->xprslp != NULL);
3101  assert(coef != NULL);
3102 
3103  SCIPdebugMessage("getting binva-row %d\n", r);
3104 
3105  /* can only return dense result */
3106  if ( ninds != NULL )
3107  *ninds = -1;
3108 
3109  CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows) );
3110  CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_COLS, &ncols) );
3111 
3112  buffer = NULL;
3113 
3114  /* get (or calculate) the row in B^-1 */
3115  if( binvrow == NULL )
3116  {
3117  SCIP_ALLOC( BMSallocMemoryArray(&buffer, nrows) );
3118  SCIP_CALL( SCIPlpiGetBInvRow(lpi, r, buffer, inds, ninds) );
3119  binv = buffer;
3120  }
3121  else
3122  binv = (double*) binvrow;
3123 
3124  /* We need space to extract a single column. */
3125  SCIP_CALL( ensureValMem(lpi, nrows) );
3126 
3127  for( c = 0; c < ncols; c++ )
3128  {
3129  int i;
3130 
3131  coef[c] = 0;
3132 
3133  /* Extract the column. */
3134  CHECK_ZERO( lpi->messagehdlr, XPRSgetcols(lpi->xprslp, NULL, lpi->indarray, lpi->valarray, nrows, &nnonz, c, c) );
3135  assert(nnonz <= nrows);
3136 
3137  /* Price out the column. */
3138  for( i = 0; i < nnonz; i++ )
3139  coef[c] += binv[lpi->indarray[i]] * lpi->valarray[i];
3140  }
3141 
3142  /* Free allocated memory. */
3143  BMSfreeMemoryArrayNull(&buffer);
3144 
3145  return SCIP_OKAY;
3146 }
3147 
3148 /** get column of inverse basis matrix times constraint matrix B^-1 * A
3149  *
3150  * @note The LP interface defines slack variables to have coefficient +1. This means that if, internally, the LP solver
3151  * uses a -1 coefficient, then rows associated with slacks variables whose coefficient is -1, should be negated;
3152  * see also the explanation in lpi.h.
3153  *
3154  * @todo check that the result is in terms of the LP interface definition
3155  */
3157  SCIP_LPI* lpi, /**< LP interface structure */
3158  int c, /**< column number */
3159  SCIP_Real* coef, /**< vector to return coefficients of the column */
3160  int* inds, /**< array to store the non-zero indices, or NULL */
3161  int* ninds /**< pointer to store the number of non-zero indices, or NULL
3162  * (-1: if we do not store sparsity information) */
3163  )
3164 { /*lint --e{715}*/
3165  int nrows;
3166  int nnonz;
3167  int i;
3168 
3169  /* Ftran */
3170 
3171  assert(lpi != NULL);
3172  assert(lpi->xprslp != NULL);
3173  assert(coef != NULL);
3174  SCIP_UNUSED(inds);
3175 
3176  SCIPdebugMessage("getting binv-col %d\n", c);
3177 
3178  /* can only return dense result */
3179  if ( ninds != NULL )
3180  *ninds = -1;
3181 
3182  CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows) );
3183 
3184  /* We need space to extract the column. */
3185  SCIP_CALL( ensureValMem(lpi, nrows) );
3186 
3187  /* Get the column to transform. */
3188  CHECK_ZERO( lpi->messagehdlr, XPRSgetcols(lpi->xprslp, NULL, lpi->indarray, lpi->valarray, nrows, &nnonz, c, c) );
3189  assert(nnonz <= nrows);
3190 
3191  /* Transform the column. */
3192  BMSclearMemoryArray(coef, nrows);
3193  for( i = 0; i < nnonz; i++ )
3194  coef[lpi->indarray[i]] = lpi->valarray[i];
3195 
3196  CHECK_ZERO( lpi->messagehdlr, XPRSftran(lpi->xprslp, coef) );
3197 
3198  return SCIP_OKAY;
3199 }
3200 
3201 /**@} */
3202 
3203 
3204 /**@name LP State Methods
3205  *
3206  * @{
3207  */
3208 
3209 /** stores LPi state (like basis information) into lpistate object */
3211  SCIP_LPI* lpi, /**< LP interface structure */
3212  BMS_BLKMEM* blkmem, /**< block memory */
3213  SCIP_LPISTATE** lpistate /**< pointer to LPi state information (like basis information) */
3214  )
3215 {
3216  int ncols;
3217  int nrows;
3218 
3219  assert(blkmem != NULL);
3220  assert(lpi != NULL);
3221  assert(lpi->xprslp != NULL);
3222  assert(lpistate != NULL);
3223 
3224  /* if there is no basis information available (e.g. after barrier without crossover), or no state can be saved; if
3225  * SCIPlpiClearState() has been called, do not return the state
3226  */
3227  if( !lpi->solisbasic || lpi->clearstate )
3228  {
3229  *lpistate = NULL;
3230  return SCIP_OKAY;
3231  }
3232 
3233  CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows) );
3234  CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_COLS, &ncols) );
3235  assert(ncols >= 0);
3236  assert(nrows >= 0);
3237 
3238  /* allocate lpistate data */
3239  SCIP_CALL( lpistateCreate(lpistate, blkmem, ncols, nrows) );
3240 
3241  SCIPdebugMessage("storing Xpress LPI state in %p (%d cols, %d rows)\n", (void*)*lpistate, ncols, nrows);
3242 
3243  /* allocate enough memory for storing uncompressed basis information */
3244  SCIP_CALL( ensureCstatMem(lpi, ncols) );
3245  SCIP_CALL( ensureRstatMem(lpi, nrows) );
3246 
3247  /* get unpacked basis information from Xpress
3248  *
3249  * @note The row status is w.r.t. slack columns!
3250  */
3251  CHECK_ZERO( lpi->messagehdlr, XPRSgetbasis(lpi->xprslp, lpi->rstat, lpi->cstat) );
3252 
3253  /* pack LPi state data */
3254  (*lpistate)->ncols = ncols;
3255  (*lpistate)->nrows = nrows;
3256  lpistatePack(*lpistate, lpi->cstat, lpi->rstat);
3257 
3258  return SCIP_OKAY;
3259 }
3260 
3261 /** loads LPi state (like basis information) into solver; note that the LP might have been extended with additional
3262  * columns and rows since the state was stored with SCIPlpiGetState()
3263  */
3265  SCIP_LPI* lpi, /**< LP interface structure */
3266  BMS_BLKMEM* blkmem, /**< block memory */
3267  const SCIP_LPISTATE* lpistate /**< LPi state information (like basis information), or NULL */
3268  )
3269 {
3270  int nrows;
3271  int ncols;
3272  int i;
3273 
3274  assert(blkmem != NULL);
3275  assert(lpi != NULL);
3276  assert(lpi->xprslp != NULL);
3277 
3278  /* if there was no basis information available, the LPI state was not stored */
3279  if( lpistate == NULL )
3280  return SCIP_OKAY;
3281 
3282  if( lpistate->ncols == 0 || lpistate->nrows == 0 )
3283  return SCIP_OKAY;
3284 
3285  CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_ROWS, &nrows) );
3286  CHECK_ZERO( lpi->messagehdlr, XPRSgetintattrib(lpi->xprslp, XPRS_COLS, &ncols) );
3287 
3288  /* the dimension of the lpi state should not be larger than the current problem; it might be that columns and rows
3289  * are added since the saving of the lpi state
3290  */
3291  assert(lpistate->ncols <= ncols);
3292  assert(lpistate->nrows <= nrows);
3293 
3294  SCIPdebugMessage("loading LPI state %p (%d cols, %d rows) into Xpress\n", (void*)lpistate, lpistate->ncols, lpistate->nrows);
3295 
3296  /* allocate enough memory for storing uncompressed basis information */
3297  SCIP_CALL( ensureCstatMem(lpi, ncols) );
3298  SCIP_CALL( ensureRstatMem(lpi, nrows) );
3299 
3300  /* unpack LPi state data
3301  *
3302  * @note The row status is w.r.t. slack column!
3303  */
3304  lpistateUnpack(lpistate, lpi->cstat, lpi->rstat);
3305 
3306  /* extend the basis to the current LP beyond the previously existing columns */
3307  for( i = lpistate->ncols; i < ncols; ++i )
3308  {
3309  SCIP_Real bnd;
3310 
3311  CHECK_ZERO( lpi->messagehdlr, XPRSgetlb(lpi->xprslp, &bnd, i, i) );
3312 
3313  if( SCIPlpiIsInfinity(lpi, REALABS(bnd)) )
3314  {
3315  /* if lower bound is +/- infinity -> try upper bound */
3316  CHECK_ZERO( lpi->messagehdlr, XPRSgetub(lpi->xprslp, &bnd, i, i) );
3317 
3318  if( SCIPlpiIsInfinity(lpi, REALABS(bnd)) )
3319  lpi->cstat[i] = (int) SCIP_BASESTAT_ZERO; /* variable is free */
3320  else
3321  lpi->cstat[i] = (int) SCIP_BASESTAT_UPPER; /* use finite upper bound */
3322  }
3323  else
3324  lpi->cstat[i] = (int) SCIP_BASESTAT_LOWER; /* use finite lower bound */
3325  }
3326  for( i = lpistate->nrows; i < nrows; ++i )
3327  lpi->rstat[i] = (int) SCIP_BASESTAT_BASIC;
3328 
3329  /* load basis information into Xpress
3330  *
3331  * @note Xpress expects the row status w.r.t. slack columns!
3332  */
3333  CHECK_ZERO( lpi->messagehdlr, XPRSloadbasis(lpi->xprslp, lpi->rstat, lpi->cstat) );
3334 
3335  lpi->clearstate = FALSE;
3336 
3337  return SCIP_OKAY;
3338 }
3339 
3340 /** clears current LPi state (like basis information) of the solver */
3342  SCIP_LPI* lpi /**< LP interface structure */
3343  )
3344 {
3345  assert(lpi != NULL);
3346 
3347  /* set KEEPBASIS to 0 for the next solve */
3348  lpi->clearstate = TRUE;
3349 
3350  return SCIP_OKAY;
3351 }
3352 
3353 /** frees LPi state information */
3355  SCIP_LPI* lpi, /**< LP interface structure */
3356  BMS_BLKMEM* blkmem, /**< block memory */
3357  SCIP_LPISTATE** lpistate /**< pointer to LPi state information (like basis information) */
3358  )
3359 {
3360  assert(lpi != NULL);
3361  assert(lpistate != NULL);
3362  assert(blkmem != NULL);
3363 
3364  if( *lpistate != NULL )
3365  {
3366  lpistateFree(lpistate, blkmem);
3367  }
3368 
3369  return SCIP_OKAY;
3370 }
3371 
3372 /** checks, whether the given LP state contains simplex basis information */
3374  SCIP_LPI* lpi, /**< LP interface structure */
3375  SCIP_LPISTATE* lpistate /**< LP state information (like basis information), or NULL */
3376  )
3377 { /*lint --e{715}*/
3378  assert(lpi != NULL);
3379  return (lpistate != NULL);
3380 }
3381 
3382 /** reads LP state (like basis information from a file */
3384  SCIP_LPI* lpi, /**< LP interface structure */
3385  const char* fname /**< file name */
3386  )
3387 {
3388  assert(lpi != NULL);
3389  assert(lpi->xprslp != NULL);
3390  assert(fname != NULL);
3391 
3392  SCIPdebugMessage("reading LP state from file <%s>\n", fname);
3393 
3394  CHECK_ZERO( lpi->messagehdlr, XPRSreadbasis(lpi->xprslp, fname, "") );
3395 
3396  return SCIP_OKAY;
3397 }
3398 
3399 /** writes LPi state (i.e. basis information) to a file */
3401  SCIP_LPI* lpi, /**< LP interface structure */
3402  const char* fname /**< file name */
3403  )
3404 {
3405  assert(lpi != NULL);
3406  assert(lpi->xprslp != NULL);
3407  assert(fname != NULL);
3408 
3409  SCIPdebugMessage("writing LP state to file <%s>\n", fname);
3410 
3411  CHECK_ZERO( lpi->messagehdlr, XPRSwritebasis(lpi->xprslp, fname, "") );
3412 
3413  return SCIP_OKAY;
3414 }
3415 
3416 /**@} */
3417 
3418 
3419 /**@name LP Pricing Norms Methods
3420  *
3421  * @{
3422  */
3423 
3424 /** stores LPi pricing norms information
3425  * @todo should we store norm information?
3426  */
3428  SCIP_LPI* lpi, /**< LP interface structure */
3429  BMS_BLKMEM* blkmem, /**< block memory */
3430  SCIP_LPINORMS** lpinorms /**< pointer to LPi pricing norms information */
3431  )
3432 { /*lint --e{715}*/
3433  assert(lpi != NULL);
3434  assert(blkmem != NULL);
3435  assert(lpinorms != NULL);
3436 
3437  (*lpinorms) = NULL;
3438 
3439  return SCIP_OKAY;
3440 }
3441 
3442 /** loads LPi pricing norms into solver; note that the LP might have been extended with additional
3443  * columns and rows since the state was stored with SCIPlpiGetNorms()
3444  */
3446  SCIP_LPI* lpi, /**< LP interface structure */
3447  BMS_BLKMEM* blkmem, /**< block memory */
3448  const SCIP_LPINORMS* lpinorms /**< LPi pricing norms information, or NULL */
3449  )
3450 { /*lint --e{715}*/
3451  assert(lpi != NULL);
3452  assert(lpinorms == NULL);
3453  SCIP_UNUSED(blkmem);
3454 
3455  /* no work necessary */
3456  return SCIP_OKAY;
3457 }
3458 
3459 /** frees pricing norms information */
3461  SCIP_LPI* lpi, /**< LP interface structure */
3462  BMS_BLKMEM* blkmem, /**< block memory */
3463  SCIP_LPINORMS** lpinorms /**< pointer to LPi pricing norms information, or NULL */
3464  )
3465 { /*lint --e{715}*/
3466  assert(lpi != NULL);
3467  assert(lpinorms == NULL);
3468  SCIP_UNUSED(blkmem);
3469 
3470  /* no work necessary */
3471  return SCIP_OKAY;
3472 }
3473 
3474 /**@} */
3475 
3476 
3477 /**@name Parameter Methods
3478  *
3479  * @{
3480  */
3481 
3482 /** gets integer parameter of LP */
3484  SCIP_LPI* lpi, /**< LP interface structure */
3485  SCIP_LPPARAM type, /**< parameter number */
3486  int* ival /**< buffer to store the parameter value */
3487  )
3488 {
3489  int ictrlval;
3490 
3491  assert(lpi != NULL);
3492  assert(lpi->xprslp != NULL);
3493  assert(ival != NULL);
3494 
3495  SCIPdebugMessage("getting int parameter %d\n", type);
3496 
3497  switch( type )
3498  {
3499  case SCIP_LPPAR_PRICING:
3500  *ival = (int)lpi->pricing;
3501  break;
3503 #if 1
3504  *ival = (lpi->notfromscratch == 0);
3505 #else
3506  CHECK_ZERO( lpi->messagehdlr, XPRSgetintcontrol(lpi->xprslp, XPRS_KEEPBASIS, &ictrlval) );
3507  *ival = (ictrlval == 0);
3508 #endif
3509  break;
3510  case SCIP_LPPAR_SCALING:
3511  CHECK_ZERO( lpi->messagehdlr, XPRSgetintcontrol(lpi->xprslp, XPRS_SCALING, &ictrlval) );
3512  if( ictrlval == 0 )
3513  *ival = 0;
3514  else if( ictrlval == 16 )
3515  *ival = 2;
3516  else
3517  *ival = 1;
3518  break;
3519  case SCIP_LPPAR_PRESOLVING:
3520  *ival = lpi->par_presolve;
3521  break;
3522  case SCIP_LPPAR_LPINFO:
3523  CHECK_ZERO( lpi->messagehdlr, XPRSgetintcontrol(lpi->xprslp, XPRS_OUTPUTLOG, &ictrlval) );
3524  *ival = (ictrlval != 0);
3525  break;
3526  case SCIP_LPPAR_LPITLIM:
3527  CHECK_ZERO( lpi->messagehdlr, XPRSgetintcontrol(lpi->xprslp, XPRS_LPITERLIMIT, &ictrlval) );
3528  *ival = ictrlval;
3529  if( *ival >= XPRS_MAXINT )
3530  *ival = XPRS_MAXINT;
3531  break;
3532  case SCIP_LPPAR_THREADS:
3533  CHECK_ZERO( lpi->messagehdlr, XPRSgetintcontrol(lpi->xprslp, XPRS_THREADS, &ictrlval) );
3534  *ival = ictrlval;
3535  break;
3536  default:
3537  return SCIP_PARAMETERUNKNOWN;
3538  } /*lint !e788*/
3539 
3540  return SCIP_OKAY;
3541 }
3542 
3543 /** sets integer parameter of LP */
3545  SCIP_LPI* lpi, /**< LP interface structure */
3546  SCIP_LPPARAM type, /**< parameter number */
3547  int ival /**< parameter value */
3548  )
3549 {
3550  assert(lpi != NULL);
3551  assert(lpi->xprslp != NULL);
3552 
3553  SCIPdebugMessage("setting int parameter %d to %d\n", type, ival);
3554 
3555  switch( type )
3556  {
3557  case SCIP_LPPAR_PRICING:
3558  /* every non-supported pricing strategy is promoted to the default pricing strategy */
3559  lpi->pricing = (SCIP_PRICING)ival; /* store pricing method in LPI struct */
3560  switch( lpi->pricing )
3561  {
3562  case SCIP_PRICING_PARTIAL:
3563  CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_PRICINGALG, XPRS_PRICING_PARTIAL) );
3564  break;
3565  case SCIP_PRICING_DEVEX:
3566  CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_PRICINGALG, XPRS_PRICING_DEVEX) );
3567  break;
3568  case SCIP_PRICING_AUTO:
3569  case SCIP_PRICING_FULL:
3571  case SCIP_PRICING_STEEP:
3573  default:
3574  CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_PRICINGALG, XPRS_PRICING_DEFAULT) );
3575  break;
3576  }
3577  break;
3579  assert(ival == TRUE || ival == FALSE);
3580  lpi->notfromscratch = (int)(!ival);
3581  CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_KEEPBASIS, (ival == FALSE) ? 1 : 0) );
3582  break;
3583  case SCIP_LPPAR_SCALING:
3584  assert(ival >= 0 && ival <= 2);
3585  if( ival == 0 )
3586  {
3587  CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_SCALING, 0) );
3588  }
3589  else if( ival == 1 )
3590  {
3591  CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_SCALING, 163) );
3592  }
3593  else
3594  {
3595  CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_SCALING, 16) );
3596  }
3597 
3598  break;
3599  case SCIP_LPPAR_PRESOLVING:
3600  assert(ival == TRUE || ival == FALSE);
3601  lpi->par_presolve = ival;
3602  break;
3603  case SCIP_LPPAR_LPINFO:
3604  assert(ival == TRUE || ival == FALSE);
3605  CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_OUTPUTLOG, (ival == TRUE) ? 1 : 0) );
3606  break;
3607  case SCIP_LPPAR_LPITLIM:
3608  assert( ival >= 0 );
3609  /* 0 <= ival, 0 stopping immediately */
3610  ival = MIN(ival, XPRS_MAXINT); /*lint !e685*//*lint !e2650*//*lint !e587*/
3611  CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_LPITERLIMIT, ival) );
3612  break;
3613  case SCIP_LPPAR_THREADS:
3614  CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_THREADS, ival) );
3615  break;
3616  default:
3617  return SCIP_PARAMETERUNKNOWN;
3618  } /*lint !e788*/
3619 
3620  return SCIP_OKAY;
3621 }
3622 
3623 /** gets floating point parameter of LP */
3625  SCIP_LPI* lpi, /**< LP interface structure */
3626  SCIP_LPPARAM type, /**< parameter number */
3627  SCIP_Real* dval /**< buffer to store the parameter value */
3628  )
3629 {
3630 #if XPVERSION <= 40
3631  int ictrlval;
3632 #endif
3633  double dctrlval;
3634 
3635  assert(lpi != NULL);
3636  assert(lpi->xprslp != NULL);
3637  assert(dval != NULL);
3638 
3639  SCIPdebugMessage("getting real parameter %d\n", type);
3640 
3641  switch( type )
3642  {
3643  case SCIP_LPPAR_FEASTOL:
3644  CHECK_ZERO( lpi->messagehdlr, XPRSgetdblcontrol(lpi->xprslp, XPRS_FEASTOL, &dctrlval) );
3645  *dval = dctrlval;
3646  break;
3648  CHECK_ZERO( lpi->messagehdlr, XPRSgetdblcontrol(lpi->xprslp, XPRS_OPTIMALITYTOL, &dctrlval) );
3649  *dval = dctrlval;
3650  break;
3652  CHECK_ZERO( lpi->messagehdlr, XPRSgetdblcontrol(lpi->xprslp, XPRS_BARGAPSTOP, &dctrlval) );
3653  *dval = dctrlval;
3654  break;
3655  case SCIP_LPPAR_LPTILIM:
3656 #if XPVERSION <= 40
3657  CHECK_ZERO( lpi->messagehdlr, XPRSgetintcontrol(lpi->xprslp, XPRS_MAXTIME, &ictrlval) );
3658  /* ictrlval is the negative of the timelimit (see SCIPlpiSetRealpar) */
3659  *dval = (double) -ictrlval;
3660 #else
3661  CHECK_ZERO( lpi->messagehdlr, XPRSgetdblcontrol(lpi->xprslp, XPRS_TIMELIMIT, &dctrlval) );
3662  *dval = dctrlval;
3663 #endif
3664  break;
3665  case SCIP_LPPAR_MARKOWITZ:
3666  CHECK_ZERO( lpi->messagehdlr, XPRSgetdblcontrol(lpi->xprslp, XPRS_MARKOWITZTOL, &dctrlval) );
3667  *dval = dctrlval;
3668  break;
3669  case SCIP_LPPAR_OBJLIM:
3670  CHECK_ZERO( lpi->messagehdlr, XPRSgetdblcontrol(lpi->xprslp, XPRS_MIPABSCUTOFF, &dctrlval) );
3671  *dval = dctrlval;
3672  break;
3673  default:
3674  return SCIP_PARAMETERUNKNOWN;
3675  } /*lint !e788*/
3676 
3677  return SCIP_OKAY;
3678 }
3679 
3680 /** sets floating point parameter of LP */
3682  SCIP_LPI* lpi, /**< LP interface structure */
3683  SCIP_LPPARAM type, /**< parameter number */
3684  SCIP_Real dval /**< parameter value */
3685  )
3686 {
3687  assert(lpi != NULL);
3688  assert(lpi->xprslp != NULL);
3689 
3690  SCIPdebugMessage("setting real parameter %d to %g\n", type, dval);
3691 
3692  switch( type )
3693  {
3694  case SCIP_LPPAR_FEASTOL:
3695  /* Xpress does not pose any restriction on dval, its absolute value is used as tolerance.
3696  * For consistency we assert it to be strictly positive.
3697  */
3698  assert( dval > 0.0 );
3699  CHECK_ZERO( lpi->messagehdlr, XPRSsetdblcontrol(lpi->xprslp, XPRS_FEASTOL, dval) );
3700  break;
3702  /* Xpress does not pose any restriction on dval,
3703  * however for consistency we assert it to be strictly positive.
3704  */
3705  assert( dval > 0.0 );
3706  CHECK_ZERO( lpi->messagehdlr, XPRSsetdblcontrol(lpi->xprslp, XPRS_OPTIMALITYTOL, dval) );
3707  break;
3709  assert( dval >= 0.0 );
3710  /* Xpress poses no restriction on dval
3711  * However for consistency we assert it to be nonnegative.
3712  */
3713  CHECK_ZERO( lpi->messagehdlr, XPRSsetdblcontrol(lpi->xprslp, XPRS_BARGAPSTOP, dval) );
3714  break;
3715  case SCIP_LPPAR_LPTILIM:
3716  {
3717 #if XPVERSION <= 40
3718  int ival;
3719 
3720  /* From the Xpress documentation:
3721  * dval>0 If an integer solution has been found, stop MIP search after dval seconds,
3722  * otherwise continue until an integer solution is finally found.
3723  * dval<0 Stop in LP or MIP search after dval seconds.
3724  * dval=0 No time limit
3725  */
3726  assert( dval > 0.0 );
3727  if( dval >= INT_MAX )
3728  ival = 0;
3729  else
3730  ival = (int) -floor(dval);
3731 
3732  CHECK_ZERO( lpi->messagehdlr, XPRSsetintcontrol(lpi->xprslp, XPRS_MAXTIME, ival) );
3733 #else
3734  CHECK_ZERO( lpi->messagehdlr, XPRSsetdblcontrol(lpi->xprslp, XPRS_TIMELIMIT, dval) );
3735 #endif
3736  break;
3737  }
3738  case SCIP_LPPAR_MARKOWITZ:
3739  /* no restriction on dval */
3740  CHECK_ZERO( lpi->messagehdlr, XPRSsetdblcontrol(lpi->xprslp, XPRS_MARKOWITZTOL, dval) );
3741  break;
3742  case SCIP_LPPAR_OBJLIM:
3743  /* no restriction on dval */
3744  CHECK_ZERO( lpi->messagehdlr, XPRSsetdblcontrol(lpi->xprslp, XPRS_MIPABSCUTOFF, dval) );
3745  break;
3746  default:
3747  return SCIP_PARAMETERUNKNOWN;
3748  } /*lint !e788*/
3749 
3750  return SCIP_OKAY;
3751 }
3752 
3753 /** interrupts the currently ongoing lp solve or disables the interrupt */
3755  SCIP_LPI* lpi, /**< LP interface structure */
3756  SCIP_Bool interrupt /**< TRUE if interrupt should be set, FALSE if it should be disabled */
3757  )
3758 {
3759  /*lint --e{715}*/
3760  assert(lpi != NULL);
3761 
3762  return SCIP_OKAY;
3763 }
3764 
3765 /**@} */
3766 
3767 
3768 /**@name Numerical Methods
3769  *
3770  * @{
3771  */
3772 
3773 /** returns value treated as infinity in the LP solver */
3775  SCIP_LPI* lpi /**< LP interface structure */
3776  )
3777 { /*lint --e{715}*/
3778  assert(lpi != NULL);
3779  return XPRS_PLUSINFINITY;
3780 }
3781 
3782 /** checks if given value is treated as infinity in the LP solver */
3784  SCIP_LPI* lpi, /**< LP interface structure */
3785  SCIP_Real val /**< value to be checked for infinity */
3786  )
3787 { /*lint --e{715}*/
3788  assert(lpi != NULL);
3789  return (val >= XPRS_PLUSINFINITY);
3790 }
3791 
3792 /**@} */
3793 
3794 
3795 /**@name File Interface Methods
3796  *
3797  * @{
3798  */
3799 
3800 /** reads LP from a file
3801  *
3802  * The file extension defines the format. That can be lp or mps. Any given file name needs to have one of these two
3803  * extension. If not nothing is read and a SCIP_READERROR is returned.
3804  */
3806  SCIP_LPI* lpi, /**< LP interface structure */
3807  const char* fname /**< file name */
3808  )
3809 {
3810  SCIP_RETCODE retcode = SCIP_OKAY;
3811 
3812  char* basename = NULL;
3813  char* compression = NULL;
3814  char* extension = NULL;
3815  char* filename = NULL;
3816  char* path = NULL;
3817  char* xpressfilename = NULL;
3818 
3819  int size;
3820 
3821  assert(lpi != NULL);
3822  assert(lpi->xprslp != NULL);
3823  assert(fname != NULL);
3824 
3825  SCIPdebugMessage("reading LP from file <%s>\n", fname);
3826 
3827  /* get the length of the file name */
3828  size = (int)strlen(fname)+1;
3829 
3830  /* check that the file name is longer than Xpress can handle */
3831  if (size > XPRS_MAXPROBNAMELENGTH)
3832  return SCIP_WRITEERROR;
3833 
3834  /* get char array for the file name we pass to Xpress */
3835  SCIP_ALLOC( BMSallocMemoryArray(&xpressfilename, size) );
3836 
3837  /* copy filename to be able to split it into its components */
3838  SCIP_ALLOC( BMSduplicateMemoryArray(&filename, fname, size) );
3839 
3840  /* get path, base file name, extension, and compression of the given file name */
3841  SCIPsplitFilename(filename, &path, &basename, &extension, &compression);
3842 
3843  /* construct file name without extension */
3844  if (path != NULL)
3845  (void) SCIPsnprintf(xpressfilename, size, "%s/%s", path, basename);
3846  else
3847  (void) SCIPsnprintf(xpressfilename, size, "%s", basename);
3848 
3849  /* check that the file name did not has a compression extension, has an lp or mps extension, and actually a base name */
3850  if (compression != NULL || extension == NULL || basename == NULL)
3851  retcode = SCIP_READERROR;
3852  if (strcasecmp(extension, "mps") == 0) {
3853  CHECK_ZERO( lpi->messagehdlr, XPRSreadprob(lpi->xprslp, xpressfilename, "") );
3854  }
3855  else if (strcasecmp(extension, "lp") == 0) {
3856  CHECK_ZERO( lpi->messagehdlr, XPRSreadprob(lpi->xprslp, xpressfilename, "l") );
3857  }
3858  else
3859  retcode = SCIP_READERROR;
3860 
3861  /* free array */
3862  BMSfreeMemoryArrayNull(&filename);
3863  BMSfreeMemoryArrayNull(&xpressfilename);
3864 
3865  return retcode;
3866 }
3867 
3868 /** writes LP to a file
3869  *
3870  * The file extension defines the format. That can be lp or mps. Any given file name needs to have one of these two
3871  * extension. If not nothing is written and a SCIP_WRITEERROR is returned.
3872  */
3874  SCIP_LPI* lpi, /**< LP interface structure */
3875  const char* fname /**< file name */
3876  )
3877 {
3878  SCIP_RETCODE retcode = SCIP_OKAY;
3879 
3880  char* basename = NULL;
3881  char* compression = NULL;
3882  char* extension = NULL;
3883  char* filename = NULL;
3884  char* path = NULL;
3885  char* xpressfilename = NULL;
3886 
3887  int size;
3888 
3889  assert(lpi != NULL);
3890  assert(lpi->xprslp != NULL);
3891  assert(fname != NULL);
3892 
3893  SCIPdebugMessage("writing LP to file <%s>\n", fname);
3894 
3895  /* get the length of the file name */
3896  size = (int)strlen(fname)+1;
3897 
3898  /* check that the file name is longer than Xpress can handle */
3899  if (size > XPRS_MAXPROBNAMELENGTH)
3900  return SCIP_WRITEERROR;
3901 
3902  /* get char array for the file name we pass to Xpress */
3903  SCIP_ALLOC( BMSallocMemoryArray(&xpressfilename, size) );
3904 
3905  /* copy filename to be able to split it into its components */
3906  SCIP_ALLOC( BMSduplicateMemoryArray(&filename, fname, size) );
3907 
3908  /* get path, base file name, extension, and compression of the given file name */
3909  SCIPsplitFilename(filename, &path, &basename, &extension, &compression);
3910 
3911  /* construct file name without extension */
3912  if (path != NULL)
3913  (void) SCIPsnprintf(xpressfilename, size, "%s/%s", path, basename);
3914  else
3915  (void) SCIPsnprintf(xpressfilename, size, "%s", basename);
3916 
3917  /* check that the file name did not has a compression extension, has an lp or mps extension, and actually a base name */
3918  if (compression != NULL || extension == NULL || basename == NULL)
3919  retcode = SCIP_WRITEERROR;
3920  if (strcasecmp(extension, "mps") == 0) {
3921  CHECK_ZERO( lpi->messagehdlr, XPRSwriteprob(lpi->xprslp, xpressfilename, "p") );
3922  }
3923  else if (strcasecmp(extension, "lp") == 0) {
3924  CHECK_ZERO( lpi->messagehdlr, XPRSwriteprob(lpi->xprslp, xpressfilename, "lp") );
3925  }
3926  else
3927  retcode = SCIP_WRITEERROR;
3928 
3929  /* free array */
3930  BMSfreeMemoryArrayNull(&filename);
3931  BMSfreeMemoryArrayNull(&xpressfilename);
3932 
3933  return retcode;
3934 }
3935 
3936 /**@} */
SCIP_RETCODE SCIPlpiGetBInvCol(SCIP_LPI *lpi, int c, SCIP_Real *coef, int *inds, int *ninds)
Definition: lpi_xprs.c:3040
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
#define NULL
Definition: def.h:267
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:3264
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:3783
#define BMSfreeMemoryArrayNull(ptr)
Definition: memory.h:148
#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:3445
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:2788
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:3544
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:2852
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:11095
SCIP_RETCODE SCIPlpiGetIntpar(SCIP_LPI *lpi, SCIP_LPPARAM type, int *ival)
Definition: lpi_xprs.c:3483
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:2809
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:94
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:10877
#define TRUE
Definition: def.h:93
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:3681
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:3427
SCIP_Real * rhsarray
Definition: lpi_cpx.c:154
#define SCIP_UNUSED(x)
Definition: def.h:434
#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:123
SCIP_RETCODE SCIPlpiReadState(SCIP_LPI *lpi, const char *fname)
Definition: lpi_xprs.c:3383
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:2828
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:145
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:3341
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:3082
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:3873
static _Thread_local char xprsname[100]
Definition: lpi_xprs.c:656
packing single and dual bit values
#define BMSfreeMemoryArray(ptr)
Definition: memory.h:147
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:2951
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:3354
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
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:197
const char * SCIPlpiGetSolverDesc(void)
Definition: lpi_xprs.c:678
int cstatsize
Definition: lpi_clp.cpp:109
#define SCIP_CALL(x)
Definition: def.h:380
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:3460
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:3805
#define EPSCEIL(x, eps)
Definition: def.h:207
int * indarray
Definition: lpi_cpx.c:160
#define BMSduplicateMemoryArray(ptr, source, num)
Definition: memory.h:143
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:465
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:91
int solstat
Definition: lpi_cpx.c:149
SCIP_Bool SCIPlpiHasStateBasis(SCIP_LPI *lpi, SCIP_LPISTATE *lpistate)
Definition: lpi_xprs.c:3373
SCIP_RETCODE SCIPlpiDelCols(SCIP_LPI *lpi, int firstcol, int lastcol)
Definition: lpi_xprs.c:996
#define BMSallocBlockMemoryArray(mem, ptr, num)
Definition: memory.h:454
SCIP_RETCODE SCIPlpiWriteState(SCIP_LPI *lpi, const char *fname)
Definition: lpi_xprs.c:3400
SCIP_Real SCIPlpiInfinity(SCIP_LPI *lpi)
Definition: lpi_xprs.c:3774
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:3210
SCIP_Bool SCIPlpiIsDualInfeasible(SCIP_LPI *lpi)
Definition: lpi_xprs.c:2510
#define BMSfreeBlockMemoryArray(mem, ptr, num)
Definition: memory.h:467
SCIP_RETCODE SCIPlpiGetRowNames(SCIP_LPI *lpi, int firstrow, int lastrow, char **rownames, char *namestorage, int namestoragesize, int *storageleft)
Definition: lpi_xprs.c:1699
#define MIN(x, y)
Definition: def.h:243
SCIP_RETCODE SCIPlpiSetBase(SCIP_LPI *lpi, const int *cstat, const int *rstat)
Definition: lpi_xprs.c:2892
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
#define MAX(x, y)
Definition: def.h:239
SCIP_Real * valarray
Definition: lpi_cpx.c:156
SCIP_RETCODE SCIPlpiGetPrimalRay(SCIP_LPI *lpi, SCIP_Real *ray)
Definition: lpi_xprs.c:2767
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:3156
#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:173
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:118
#define SCIP_INVALID
Definition: def.h:193
#define BMSreallocMemoryArray(ptr, num)
Definition: memory.h:127
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:451
SCIP_RETCODE SCIPlpiInterrupt(SCIP_LPI *lpi, SCIP_Bool interrupt)
Definition: lpi_xprs.c:3754
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:206
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:130
struct BMS_BlkMem BMS_BLKMEM
Definition: memory.h:437
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:3002
#define SCIP_ALLOC(x)
Definition: def.h:391
#define SCIPABORT()
Definition: def.h:352
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:3624
SCIP_RETCODE SCIPlpiDelColset(SCIP_LPI *lpi, int *dstat)
Definition: lpi_xprs.c:1026