SCIP Doxygen Documentation
Loading...
Searching...
No Matches
lpiexact_qsoex.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-2026 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 lpiexact_qsoex.c
26 * @ingroup LPIEXACTS
27 * @brief exact LP interface for QSopt_ex version >= 2.5.4 (r239)
28 * @author Leon Eifler
29 * @author Daniel Espinoza
30 * @author Marc Pfetsch
31 * @author Kati Wolter
32*/
33
34/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
35/* #define VERIFY_OUT */ /* uncomment to get info of QSopt_ex about verifying dual feasibility of the basis */
36
37/* #define USEOBJLIM */ /* uncomment to pass objlimit to exact lp solver; same as in cons_exactlinear.c; warning: QSopt_ex allows objlimits but the support is buggy; if the limit is reached, QSopt_ex does not stop but increasess the precision */
38
39#include "scip/def.h"
40
41#if defined(SCIP_WITH_GMP) && defined(SCIP_WITH_EGLIB)
42#include "EGlib.h"
43#include "QSopt_ex.h"
44#endif
45
46#include <string.h>
47
48#include "scip/bitencode.h"
49#include "scip/scip_mem.h"
51#include "lpiexact/lpiexact.h"
52#include "scip/pub_message.h"
53#include "scip/rationalgmp.h"
54
55
56/** solver name */
57static char __qsstr[1024];
58static char __egstr[1024];
59
60#ifdef SCIP_WITH_GMP
61
62typedef SCIP_DUALPACKET COLPACKET; /* each column needs two bits of information (basic/on_lower/on_upper) */
63#define COLS_PER_PACKET SCIP_DUALPACKETSIZE
64typedef SCIP_DUALPACKET ROWPACKET; /* each row needs two bit of information (basic/on_lower/on_upper) */
65#define ROWS_PER_PACKET SCIP_DUALPACKETSIZE
66
67/** LP interface */
68struct SCIP_LPiExact
69{
70#if defined(SCIP_WITH_GMP) && defined(SCIP_WITH_EGLIB)
71 mpq_QSprob prob; /**< LP struct pointer */
72 mpq_factor_work* factor; /**< factorized matrix */
73 int solstat; /**< solution status of last optimization call */
74 int previt; /**< previous number of simplex iterations performed */
75 int pricing; /**< SCIP pricing option */
76#endif
77 int rowspace; /**< current size of internal row-related arrays */
78 char* isen; /**< array of length rowspace */
79 mpq_t* irhs; /**< array of rhs rowspace */
80 mpq_t* irng; /**< array of range rowspace */
81 int* ircnt; /**< array of count rowspace */
82 int* irbeg; /**< array of begining index rowspace */
83 int colspace; /**< current size of internal column-related arrays */
84 int* iccnt; /**< array of length colspace */
85 char* iccha; /**< array of type colspace */
86 int tbsz; /**< current size of tableau-related arrays */
87 mpq_t* itab; /**< array of length tbsz */
88 char* ibas; /**< array of length tbsz */
89};
90
91
92
93/*
94 * local defines
95 */
96
97/*lint --e{750} */
98/** print location of the calling line */
99#define __QS_PRINTLOC__ fprintf(stderr,", in (%s:%d)\n", __FILE__, __LINE__);
100
101/** This macro is to print error messages and jump to the given point in the code, it also print the
102 * file and line where this happend */
103#define QS_TESTG(A,B,...) do { { \
104 if (A){ \
105 fprintf(stderr,__VA_ARGS__); \
106 __QS_PRINTLOC__; \
107 goto B; } } } while(0)
108
109/** This macro is to print error messages and to exit with SCIP_LPERROR */
110#define QS_ERROR(A,...) do { { \
111 if (A){ \
112 fprintf(stderr,__VA_ARGS__); \
113 __QS_PRINTLOC__; \
114 return SCIP_LPERROR; } } } while(0)
115
116/** return value macro, if the value is non-zero, write to standard error the returning code and
117 * where this happened, and return SCIP_ERROR, otherwise return normal SCIP_OKAY termination code. */
118#define QS_RETURN(A) do { \
119 const int __RVAL__ = (A); \
120 if (__RVAL__){ \
121 fprintf(stderr,"LP Error: QSopt_ex returned %d",__RVAL__); \
122 __QS_PRINTLOC__; \
123 return SCIP_ERROR; } \
124 return SCIP_OKAY; } while(0)
125
126/** return value macro, if the value is non-zero, write to standard error the returning code and
127 * where this happened, and return SCIP_ERROR, otherwise do nothing. */
128#define QS_CONDRET(A) do { \
129 const int __RVAL__ = (A); \
130 if (__RVAL__){ \
131 fprintf(stderr,"LP Error: QSopt_ex returned %d",__RVAL__); \
132 __QS_PRINTLOC__; \
133 return SCIP_LPERROR; } \
134 } while(0)
135
136
137
138/*
139 * LPi state methods
140 */
141
142
143/** LPi state stores basis information */
144struct SCIP_LPiState
145{
146 int ncols; /**< number of LP columns */
147 int nrows; /**< number of LP rows */
148 COLPACKET* packcstat; /**< column basis status in compressed form */
149 ROWPACKET* packrstat; /**< row basis status in compressed form */
150};
151
152static
153void printGMP(
154 const mpq_t val
155 )
156{
157 char* buffer;
158 buffer = (char*) malloc(mpz_sizeinbase(mpq_numref(val), 10) + mpz_sizeinbase(mpq_denref(val), 10) + 3);
159 if( buffer != NULL )
160 {
161 (void)mpq_get_str(buffer, 10, val);
162 printf("%s \n", buffer);
163 free(buffer);
164 }
165}
166
167/** returns the number of packets needed to store column packet information */
168static
169int colpacketNum(
170 int ncols /**< number of columns to store */
171 )
172{
173 return (ncols + (int)COLS_PER_PACKET-1)/(int)COLS_PER_PACKET;
174}
175
176/** returns the number of packets needed to store row packet information */
177static
178int rowpacketNum(
179 int nrows /**< number of rows to store */
180 )
181{
182 return (nrows + (int)ROWS_PER_PACKET-1)/(int)ROWS_PER_PACKET;
183}
184
185/** store row and column basis status in a packed LPi state object */
186static
187void lpistatePack(
188 SCIP_LPISTATE* lpistate, /**< pointer to LPi state data */
189 const int* cstat, /**< basis status of columns in unpacked format */
190 const int* rstat /**< basis status of rows in unpacked format */
191 )
192{
193 assert(lpistate != NULL);
194 assert(lpistate->packcstat != NULL);
195 assert(lpistate->packrstat != NULL);
196
197 SCIPencodeDualBit(cstat, lpistate->packcstat, lpistate->ncols);
198 SCIPencodeDualBit(rstat, lpistate->packrstat, lpistate->nrows);
199}
200
201/** unpacks row and column basis status from a packed LPi state object */
202static
203void lpistateUnpack(
204 const SCIP_LPISTATE* lpistate, /**< pointer to LPi state data */
205 int* cstat, /**< buffer for storing basis status of columns in unpacked format */
206 int* rstat /**< buffer for storing basis status of rows in unpacked format */
207 )
208{
209 assert(lpistate != NULL);
210 assert(lpistate->packcstat != NULL);
211 assert(lpistate->packrstat != NULL);
212
213 SCIPdecodeDualBit(lpistate->packcstat, cstat, lpistate->ncols);
214 SCIPdecodeDualBit(lpistate->packrstat, rstat, lpistate->nrows);
215}
216
217/** creates LPi state information object */
218static
220 SCIP_LPISTATE** lpistate, /**< pointer to LPi state */
221 BMS_BLKMEM* blkmem, /**< block memory */
222 int ncols, /**< number of columns to store */
223 int nrows /**< number of rows to store */
224 )
225{
226 assert(lpistate != NULL);
227 assert(blkmem != NULL);
228 assert(ncols >= 0);
229 assert(nrows >= 0);
230
231 SCIP_ALLOC( BMSallocBlockMemory(blkmem, lpistate) );
232 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpistate)->packcstat, colpacketNum(ncols)) );
233 SCIP_ALLOC( BMSallocBlockMemoryArray(blkmem, &(*lpistate)->packrstat, rowpacketNum(nrows)) );
234
235 return SCIP_OKAY;
236}
237
238/** frees LPi state information */
239static
240void lpistateFree(
241 SCIP_LPISTATE** lpistate, /**< pointer to LPi state information (like basis information) */
242 BMS_BLKMEM* blkmem /**< block memory */
243 )
244{
245 assert(blkmem != NULL);
246 assert(lpistate != NULL);
247 assert(*lpistate != NULL);
248
249 BMSfreeBlockMemoryArray(blkmem, &(*lpistate)->packcstat, colpacketNum((*lpistate)->ncols));
250 BMSfreeBlockMemoryArray(blkmem, &(*lpistate)->packrstat, rowpacketNum((*lpistate)->nrows));
251 BMSfreeBlockMemory(blkmem, lpistate);
252}
253
254
255/*
256 * local functions
257 */
258
259/** ensure size of column-related arrays */
260static inline
262 SCIP_LPIEXACT* lpi,
263 int const sz
264 )
265{ /*lint --e{647}*/
266 register int i;
267 if( lpi->tbsz < sz )
268 {
269 SCIP_ALLOC( BMSreallocMemoryArray(&(lpi->itab), sz*2) );
270 SCIP_ALLOC( BMSreallocMemoryArray(&(lpi->ibas), sz*2) );
271 for( i = lpi->tbsz ; i < sz * 2 ; i++ )
272 mpq_init(lpi->itab[i]);
273 lpi->tbsz = sz*2;
274 }
275 return SCIP_OKAY;
276}
277
278/** ensure size of column-related arrays */
279static inline
281 SCIP_LPIEXACT* lpi,
282 int const ncols
283 )
284{
285 if( lpi->colspace < ncols )
286 {
287 lpi->colspace = ncols * 2;
288 SCIP_ALLOC( BMSreallocMemoryArray(&(lpi->iccnt), lpi->colspace) );
289 SCIP_ALLOC( BMSreallocMemoryArray(&(lpi->iccha), lpi->colspace) );
290 }
291 return SCIP_OKAY;
292}
293
294/** ensure size of row-related arrays */
295static inline
297 SCIP_LPIEXACT* lpi,
298 int const nrows
299 )
300{ /*lint --e{647}*/
301 register int i;
302 if( lpi->rowspace < nrows )
303 {
304 SCIP_ALLOC( BMSreallocMemoryArray(&(lpi->isen), nrows * 2) );
305 SCIP_ALLOC( BMSreallocMemoryArray(&(lpi->irhs), nrows * 2) );
306 SCIP_ALLOC( BMSreallocMemoryArray(&(lpi->irng), nrows * 2) );
307 SCIP_ALLOC( BMSreallocMemoryArray(&(lpi->ircnt), nrows * 2) );
308 SCIP_ALLOC( BMSreallocMemoryArray(&(lpi->irbeg), nrows * 2) );
309 for (i = lpi->rowspace ; i < nrows * 2; i++)
310 {
311 mpq_init(lpi->irhs[i]);
312 mpq_init(lpi->irng[i]);
313 }
314 lpi->rowspace = nrows * 2;
315 }
316 return SCIP_OKAY;
317}
318
319/** transform lhs/rhs into qsopt format */
320static inline
322 SCIP_LPIEXACT* const lpi,
323 int const nrows,
324 SCIP_RATIONAL** lhs,
325 SCIP_RATIONAL** rhs
326 )
327{ /*lint --e{663, 550, 438, 528}*/
328 int state;
329 register int i;
330
331 for( i = 0; i < nrows; ++i )
332 {
333 mpq_t* lhsg;
334 mpq_t* rhsg;
335 int state1;
336 int state2;
337
338 lhsg = SCIPrationalGetGMP(lhs[i]);
339 rhsg = SCIPrationalGetGMP(rhs[i]);
340#if defined(SCIP_WITH_GMP) && defined(SCIP_WITH_EGLIB)
341 state1 = ((mpq_cmp(*lhsg, mpq_ILL_MINDOUBLE) <= 0) ? 1U : 0U);
342 state2 = ((mpq_cmp(*rhsg, mpq_ILL_MAXDOUBLE) >= 0) ? 2U : 0U);
343 state = state1 | state2;
344#else
345 state1 = 0;
346 state2 = 0;
347 state = 0;
348#endif
349 /* state = (((mpq_cmp(*lhsg, mpq_ILL_MINDOUBLE) <= 0) ? 1U : 0U) | ((mpq_cmp(*rhsg, mpq_ILL_MAXDOUBLE) >= 0) ? 2U : 0U)); */
350 lpi->ircnt[i] = 0;
351 lpi->irbeg[i] = 0;
352 switch( state )
353 {
354 case 0:
355 if( SCIPrationalIsEQ(lhs[i], rhs[i]) )
356 {
357 lpi->isen[i] = 'E';
358 mpq_set(lpi->irhs[i], *lhsg);
359 mpq_set_ui(lpi->irng[i], 0UL, 1UL);
360 }
361 else
362 {
363 lpi->isen[i] = 'R';
364 mpq_set(lpi->irhs[i], *lhsg);
365 mpq_sub(lpi->irng[i], *rhsg, *lhsg);
366 assert( mpq_sgn(lpi->irng[i]) >=0 );
367 }
368 break;
369 case 1:
370 lpi->isen[i] = 'L';
371 mpq_set(lpi->irhs[i], *rhsg);
372 mpq_set_ui(lpi->irng[i], 0UL, 1UL);
373 break;
374 case 2:
375 lpi->isen[i] = 'G';
376 mpq_set(lpi->irhs[i], *lhsg);
377 mpq_set_ui(lpi->irng[i], 0UL, 1UL);
378 break;
379 default:
380 SCIPerrorMessage("Error, constraint %d has no bounds!",i);
381 SCIPABORT();
382 }
383 }
384 return SCIP_OKAY;
385 } /*lint --e{528}*/
386
387
388/*
389 * Miscellaneous Methods
390 */
391
392/**@name Miscellaneous Methods */
393/**@{ */
394
395
396#endif
397/** gets name and version of LP solver */
399 void
400 )
401{
402#if defined(SCIP_WITH_GMP) && defined(SCIP_WITH_EGLIB)
403 sprintf(__qsstr, "QSopt_ex %s", string_QSopt_ex);
404#else
405 sprintf(__qsstr, "QSopt_ex");
406#endif
407
408 return __qsstr;
409}
410
411/** gets description of LP solver (developer, webpage, ...) */
413 void
414 )
415{
416 return "Exact Linear Programming Solver by D. Espinoza, W. Cook, S. Dash, and D. Applegate (dii.uchile.cl/~daespino/QSoptExact_doc/main.html)";
417}
418
419/** gets name and version of external package required for LP solver */
421 void
422 )
423{
424#if defined(SCIP_WITH_GMP) && defined(SCIP_WITH_EGLIB)
425 sprintf(__egstr, "EGlib %s", string_EGlib);
426#else
427 sprintf(__egstr, "EGlib");
428#endif
429
430 return __egstr;
431}
432
433/** gets description of external package required for LP solver (developer, webpage, ...) */
435 void
436 )
437{
438 return "Library for basic structures and utilities by D. Espinoza and M. Goycoolea (dii.uchile.cl/~daespino/EGlib_doc/main.html)";
439}
440
441#if defined(SCIP_WITH_GMP) && defined(SCIP_WITH_EGLIB)
442
443/** gets pointer for LP solver - use only with great care */
445 SCIP_LPIEXACT* lpi /**< pointer to an LP interface structure */
446 )
447{
448 return (void*) lpi->prob;
449}
450
451/**@} */
452
453
454/*
455 * LPI Creation and Destruction Methods
456 */
457
458/**@name LPI Creation and Destruction Methods */
459/**@{ */
460
461/** calls initializator of LP solver (if this did not already happen); this is mainly needed for defining constants in extended and rational precision */
463 void
464 )
465{
466 if( !__QSexact_setup )
467 QSexactStart();
468}
469
470/** calls deinitializator of LP solver; this is needed for freeing all internal data of the solver, like constants in
471 * extended and rational precision
472 */
473void SCIPlpiExactEnd(
474 void
475 )
476{
477 if( __QSexact_setup )
478 QSexactClear();
479}
480
481/** creates an LP problem object
482 *
483 * @return \ref SCIP_OKAY is returned if everything worked. Otherwise a suitable error code is passed. See \ref
484 * SCIP_Retcode "SCIP_RETCODE" for a complete list of error codes.
485 */
487 SCIP_LPIEXACT** lpi, /**< pointer to an LP interface structure */
488 SCIP_MESSAGEHDLR* messagehdlr, /**< message handler to use for printing messages, or NULL */
489 const char* name, /**< problem name */
490 SCIP_OBJSEN objsen /**< objective sense */
491 )
492{
493 register int i;
494
495 /* QSopt_ex only works with bools as integers */
496 assert(sizeof (SCIP_Bool) == sizeof (int));
497 assert(lpi != NULL);
498
499 SCIPdebugMessage("SCIPlpiExactCreate()\n");
500
501 /* create LP */
504 memset(*lpi, 0, sizeof(struct SCIP_LPiExact));
505
506 /* factor work is NULL unless used */
507 (*lpi)->factor = (mpq_factor_work*) NULL;
508
509 (*lpi)->prob = mpq_QScreate_prob(name, (int) objsen);
510 if( (*lpi)->prob == NULL )
511 {
512 SCIPerrorMessage("No memory\n");
513 return SCIP_LPERROR;
514 }
515
516 (*lpi)->rowspace = 1024;
517 SCIP_ALLOC( BMSallocMemoryArray(&((*lpi)->isen), 1024) );
518 SCIP_ALLOC( BMSallocMemoryArray(&((*lpi)->irhs), 1024) );
519 SCIP_ALLOC( BMSallocMemoryArray(&((*lpi)->irng), 1024) );
520 SCIP_ALLOC( BMSallocMemoryArray(&((*lpi)->irbeg), 1024) );
521 SCIP_ALLOC( BMSallocMemoryArray(&((*lpi)->ircnt), 1024) );
522
523 (*lpi)->colspace = 1024;
524 SCIP_ALLOC( BMSallocMemoryArray(&((*lpi)->iccnt), 1024) );
525 SCIP_ALLOC( BMSallocMemoryArray(&((*lpi)->iccha), 1024) );
526
527 (*lpi)->tbsz = 1024;
528 SCIP_ALLOC( BMSallocMemoryArray(&((*lpi)->itab), 1024) );
529 SCIP_ALLOC( BMSallocMemoryArray(&((*lpi)->ibas), 1024) );
530 for( i = 0; i < 1024; i++ )
531 {
532 mpq_init((*lpi)->irhs[i]);
533 mpq_init((*lpi)->irng[i]);
534 mpq_init((*lpi)->itab[i]);
535 }
536
537 return SCIP_OKAY;
538}
539
540/** deletes an LP problem object */
542 SCIP_LPIEXACT** lpi /**< pointer to an LP interface structure */
543 )
544{
545 register int i;
546
547 assert(lpi != NULL);
548 assert(*lpi != NULL);
549
550 SCIPdebugMessage("SCIPlpiExactFree()\n");
551
552 /* free factor work */
553 if( (*lpi)->factor != NULL )
554 {
555 mpq_ILLfactor_free_factor_work((*lpi)->factor);
556 BMSfreeMemoryArray( &((*lpi)->factor) );
557 }
558
559 /* free LP */
560 mpq_QSfree_prob((*lpi)->prob);
561 for( i = 0; i < (*lpi)->tbsz; ++i )
562 mpq_clear((*lpi)->itab[i]);
563 for( i = 0; i < (*lpi)->rowspace; ++i )
564 {
565 mpq_clear((*lpi)->irng[i]);
566 mpq_clear((*lpi)->irhs[i]);
567 }
568 BMSfreeMemoryArray(&((*lpi)->isen));
569 BMSfreeMemoryArray(&((*lpi)->irhs));
570 BMSfreeMemoryArray(&((*lpi)->irng));
571 BMSfreeMemoryArray(&((*lpi)->ircnt));
572 BMSfreeMemoryArray(&((*lpi)->irbeg));
573 BMSfreeMemoryArray(&((*lpi)->iccnt));
574 BMSfreeMemoryArray(&((*lpi)->iccha));
575 BMSfreeMemoryArray(&((*lpi)->itab));
576 BMSfreeMemoryArray(&((*lpi)->ibas));
577
578 /* free memory */
579 BMSfreeMemory(lpi);
580
581 return SCIP_OKAY;
582}
583/**@} */
584
585
586/*
587 * Modification Methods
588 */
589
590/**@name Modification Methods */
591/**@{ */
592
593
594/** copies LP data with column matrix into LP solver */
596 SCIP_LPIEXACT* lpi, /**< LP interface structure */
597 SCIP_OBJSEN objsen, /**< objective sense */
598 int ncols, /**< number of columns */
599 SCIP_RATIONAL** obj, /**< objective function values of columns */
600 SCIP_RATIONAL** lb, /**< lower bounds of columns */
601 SCIP_RATIONAL** ub, /**< upper bounds of columns */
602 char** colnames, /**< column names, or NULL */
603 int nrows, /**< number of rows */
604 SCIP_RATIONAL** lhs, /**< left hand sides of rows */
605 SCIP_RATIONAL** rhs, /**< right hand sides of rows */
606 char** rownames, /**< row names, or NULL */
607 int nnonz, /**< number of nonzero elements in the constraint matrix */
608 int* beg, /**< start index of each column in ind- and val-array */
609 int* ind, /**< row indices of constraint matrix entries */
610 SCIP_RATIONAL** val /**< values of constraint matrix entries */
611 )
612{
613 int rval = 0;
614
615 assert(lpi != NULL);
616 assert(lpi->prob != NULL);
617
618 lpi->solstat = 0;
619 SCIPdebugMessage("loading LP in column format into QSopt_ex: %d cols, %d rows\n", ncols, nrows);
620
621 /* delete old LP */
623
624 /* set sense */
625 if( objsen == SCIP_OBJSEN_MAXIMIZE )
626 {
627 rval = mpq_QSchange_objsense(lpi->prob, QS_MAX);
628 QS_CONDRET(rval);
629 }
630 else
631 {
632 rval = mpq_QSchange_objsense(lpi->prob, QS_MIN);
633 QS_CONDRET(rval);
634 }
635
636 /* add rows with no matrix, and then the columns, first ensure space */
637 SCIP_CALL( ensureRowMem(lpi, nrows) );
638
639 /* convert lhs/rhs into sen/rhs/range tuples */
640 SCIP_CALL( convertSides(lpi, nrows, lhs, rhs) );
641
642 /* now we add the rows */
643 rval = mpq_QSadd_ranged_rows(lpi->prob, nrows, lpi->ircnt, lpi->irbeg, 0, (const mpq_t*) 0, (const mpq_t*) lpi->irhs,
644 lpi->isen, (const mpq_t*) lpi->irng, (const char**)rownames);
645 QS_CONDRET(rval);
646
647 SCIPlpiExactAddCols(lpi, ncols, obj, lb, ub, colnames, nnonz, beg, ind, val);
648
649 QS_RETURN(rval);
650}
651
652/** adds columns to the LP */
654 SCIP_LPIEXACT* lpi, /**< LP interface structure */
655 int ncols, /**< number of columns to be added */
656 SCIP_RATIONAL** obj, /**< objective function values of new columns */
657 SCIP_RATIONAL** lb, /**< lower bounds of new columns */
658 SCIP_RATIONAL** ub, /**< upper bounds of new columns */
659 char** colnames, /**< column names, or NULL */
660 int nnonz, /**< number of nonzero elements to be added to the constraint matrix */
661 int* beg, /**< start index of each column in ind- and val-array, or NULL if nnonz == 0 */
662 int* ind, /**< row indices of constraint matrix entries, or NULL if nnonz == 0 */
663 SCIP_RATIONAL** val /**< values of constraint matrix entries, or NULL if nnonz == 0 */
664 )
665{
666 mpq_t* valgmp;
667 int rval = 0;
668 register int i;
669
670 assert(lpi != NULL);
671 assert(lpi->prob != NULL);
672
673 SCIPdebugMessage("adding %d columns with %d nonzeros to QSopt_ex\n", ncols, nnonz);
674
675 lpi->solstat = 0;
676
677 /* ensure column size */
678 SCIP_CALL( ensureColMem(lpi, ncols) );
679
680 if( nnonz > 0 )
681 {
682 /* compute column lengths */
683 for( i = 0; i < ncols - 1; ++i )
684 {
685 lpi->iccnt[i] = beg[i+1] - beg[i];
686 assert(lpi->iccnt[i] >= 0);
687 }
688 if( ncols > 0 )
689 {
690 lpi->iccnt[ncols-1] = nnonz - beg[ncols-1];
691 assert( lpi->iccnt[ncols-1] >= 0 );
692 }
693
694 SCIP_ALLOC( BMSallocMemoryArray(&valgmp, nnonz) );
695 SCIPrationalSetGMPArray(valgmp, val, nnonz);
696
697 /* and add the columns */
698 for( i = 0; i < ncols; ++i )
699 {
700 mpq_QSadd_col(lpi->prob, lpi->iccnt[i], &ind[beg[i]], &(valgmp[beg[i]]),
701 *SCIPrationalGetGMP(obj[i]), *SCIPrationalGetGMP(lb[i]), *SCIPrationalGetGMP(ub[i]), (const char*) colnames[i]);
702 }
703
704 SCIPrationalClearArrayGMP(valgmp, nnonz);
705 BMSfreeMemoryArray(&valgmp);
706 }
707 else
708 {
709 for( i = 0; i < ncols; ++i )
710 {
711 rval = mpq_QSnew_col(lpi->prob, *SCIPrationalGetGMP(obj[i]), *SCIPrationalGetGMP(lb[i]), *SCIPrationalGetGMP(ub[i]), (const char*) colnames[i]);
712 }
713 }
714
715 QS_RETURN(rval);
716}
717
718/** deletes all columns in the given range from LP */
720 SCIP_LPIEXACT* lpi, /**< LP interface structure */
721 int firstcol, /**< first column to be deleted */
722 int lastcol /**< last column to be deleted */
723 )
724{
725 const int len = lastcol - firstcol +1;
726 int rval = 0;
727 register int i;
728
729 assert(lpi != NULL);
730 assert(lpi->prob != NULL);
731
732 lpi->solstat = 0;
733 assert(0 <= firstcol && len > 0 && lastcol < mpq_QSget_colcount (lpi->prob));
734
735 SCIPdebugMessage("deleting %d columns from QSopt_ex\n", len);
736
737 SCIP_CALL( ensureColMem(lpi, len) );
738 for( i = firstcol ; i <= lastcol ; i++ )
739 lpi->iccnt[i-firstcol] = i;
740
741 rval = mpq_QSdelete_cols(lpi->prob, len, lpi->iccnt);
742
743 QS_RETURN(rval);
744}
745
746/** deletes columns from SCIP_LP; the new position of a column must not be greater that its old position */
748 SCIP_LPIEXACT* lpi, /**< LP interface structure */
749 int* dstat /**< deletion status of columns
750 * input: 1 if column should be deleted, 0 if not
751 * output: new position of column, -1 if column was deleted */
752 )
753{
754 int rval = 0, ncols, ccnt;
755 register int i;
756
757 assert(lpi != NULL);
758 assert(lpi->prob != NULL);
759
760 ncols = mpq_QSget_colcount(lpi->prob);
761 lpi->solstat = 0;
762
763 SCIPdebugMessage("deleting a column set from QSopt_ex\n");
764
765 rval = mpq_QSdelete_setcols(lpi->prob,dstat);
766 QS_CONDRET(rval);
767
768 for( i = 0, ccnt = 0; i < ncols; i++ )
769 {
770 if( dstat[i] )
771 dstat[i] = -1;
772 else
773 dstat[i] = ccnt++;
774 }
775 return SCIP_OKAY;
776}
777
778/** adds rows to the LP */
779SCIP_EXPORT
781 SCIP_LPIEXACT* lpi, /**< LP interface structure */
782 int nrows, /**< number of rows to be added */
783 SCIP_RATIONAL** lhs, /**< left hand sides of new rows */
784 SCIP_RATIONAL** rhs, /**< right hand sides of new rows */
785 char** rownames, /**< row names, or NULL */
786 int nnonz, /**< number of nonzero elements to be added to the constraint matrix */
787 int* beg, /**< start index of each row in ind- and val-array, or NULL if nnonz == 0 */
788 int* ind, /**< column indices of constraint matrix entries, or NULL if nnonz == 0 */
789 SCIP_RATIONAL** val /**< values of constraint matrix entries, or NULL if nnonz == 0 */
790 )
791{
792 register int i;
793 int rval = 0;
794 mpq_t* valgmp;
795
796 assert(lpi != NULL);
797 assert(lpi->prob != NULL);
798
799 lpi->solstat = 0;
800 SCIPdebugMessage("adding %d rows with %d nonzeros to QSopt_ex\n", nrows, nnonz);
801
802 /* add rows with no matrix, and then the columns, first ensure space */
803 SCIP_CALL( ensureRowMem (lpi, nrows) );
804
805 /* convert lhs/rhs into sen/rhs/range tuples */
806 SCIP_CALL( convertSides(lpi, nrows, lhs, rhs) );
807
808 /* compute row count */
809 for( i = 0; i < nrows - 1; i++ )
810 {
811 lpi->ircnt[i] = beg[i + 1] - beg[i];
812 assert(lpi->ircnt[i] >= 0);
813 }
814 if( nrows > 0 )
815 {
816 lpi->ircnt[nrows - 1] = nnonz - beg[nrows - 1];
817 assert(lpi->ircnt[nrows - 1] >= 0);
818 }
819
820 SCIP_ALLOC( BMSallocMemoryArray(&valgmp, nnonz) );
821 SCIPrationalSetGMPArray(valgmp, val, nnonz);
822
823 rval = mpq_QSadd_ranged_rows(lpi->prob, nrows, lpi->ircnt, beg, ind, (const mpq_t*) valgmp, (const mpq_t*) lpi->irhs,
824 lpi->isen, (const mpq_t*) lpi->irng, (const char**) rownames);
825 QS_CONDRET(rval);
826
827 SCIPrationalClearArrayGMP(valgmp, nnonz);
828 BMSfreeMemoryArray(&valgmp);
829
830 return SCIP_OKAY;
831}
832
833
834/** deletes all rows in the given range from LP */
836 SCIP_LPIEXACT* lpi, /**< LP interface structure */
837 int firstrow, /**< first row to be deleted */
838 int lastrow /**< last row to be deleted */
839 )
840{
841 const int len = lastrow - firstrow +1;
842 int rval = 0;
843 register int i;
844
845 assert(lpi != NULL);
846 assert(lpi->prob != NULL);
847
848 lpi->solstat = 0;
849 assert(0 <= firstrow && len > 0 && lastrow < mpq_QSget_rowcount (lpi->prob));
850
851 SCIPdebugMessage("deleting %d rows from QSopt_ex\n", len);
852
853 SCIP_CALL( ensureRowMem(lpi, len) );
854 for( i = firstrow; i <= lastrow; i++ )
855 lpi->ircnt[i - firstrow] = i;
856 rval = mpq_QSdelete_rows(lpi->prob, len, lpi->ircnt);
857
858 QS_RETURN(rval);
859}
860
861
862/** deletes rows from SCIP_LP; the new position of a row must not be greater that its old position */
864 SCIP_LPIEXACT* lpi, /**< LP interface structure */
865 int* dstat /**< deletion status of rows
866 * input: 1 if row should be deleted, 0 if not
867 * output: new position of row, -1 if row was deleted */
868 )
869{
870 int rval = 0, nrows, ccnt, ndel=0;
871 register int i;
872
873 assert(lpi != NULL);
874 assert(lpi->prob != NULL);
875
876 nrows = mpq_QSget_rowcount(lpi->prob);
877 lpi->solstat = 0;
878
879 for( i = 0; i < nrows; ++i )
880 {
881 if( dstat[i] == 1 )
882 ndel++;
883 }
884
885 SCIPdebugMessage("deleting a row set from QSopt_ex (%d)\n",ndel);
886
887 rval = mpq_QSdelete_setrows(lpi->prob,dstat);
888 QS_CONDRET(rval);
889
890 for( i = 0, ccnt = 0; i < nrows; ++i )
891 {
892 if( dstat[i] )
893 dstat[i] = -1;
894 else
895 dstat[i] = ccnt++;
896 }
897 return SCIP_OKAY;
898}
899
900/** clears the whole LP */
902 SCIP_LPIEXACT* lpi /**< LP interface structure */
903 )
904{
905 register int i;
906 int ncols, nrows, rval = 0;
907
908 assert(lpi != NULL);
909 assert(lpi->prob != NULL);
910
911 SCIPdebugMessage("clearing QSopt_ex LP\n");
912 lpi->solstat = 0;
913
914 ncols = mpq_QSget_colcount(lpi->prob);
915 nrows = mpq_QSget_rowcount(lpi->prob);
916 if( ncols >= 1 )
917 {
918 SCIP_CALL( ensureColMem(lpi,ncols) );
919 for (i = 0; i < ncols; ++i)
920 lpi->iccnt[i] = i;
921 rval = mpq_QSdelete_cols(lpi->prob, ncols, lpi->iccnt);
922 QS_CONDRET(rval);
923 }
924
925 if( nrows >= 1 )
926 {
927 SCIP_CALL( ensureRowMem(lpi, nrows) );
928 for (i = 0; i < nrows; ++i)
929 lpi->ircnt[i] = i;
930 rval = mpq_QSdelete_rows(lpi->prob, nrows, lpi->ircnt);
931 QS_CONDRET(rval);
932 }
933 QS_RETURN(rval);
934}
935
936
937/** changes lower and upper bounds of columns */
939 SCIP_LPIEXACT* lpi, /**< LP interface structure */
940 int ncols, /**< number of columns to change bounds for */
941 int* ind, /**< column indices */
942 SCIP_RATIONAL** lb, /**< values for the new lower bounds, or NULL */
943 SCIP_RATIONAL** ub /**< values for the new upper bounds, or NULL */
944 )
945{
946 register int i;
947 int rval = 0;
948
949 assert(lpi != NULL);
950 assert(lpi->prob != NULL);
951 assert(lb != NULL || ub != NULL);
952
953 lpi->solstat = 0;
954
955 SCIPdebugMessage("changing %d bounds in QSopt_ex\n", ncols);
956#ifdef SCIP_DEBUG
957 {
958 int j;
959 char s[SCIP_MAXSTRLEN];
960
961 for( j = 0; j < ncols; ++j )
962 {
963 if( lb == NULL)
964 gmp_snprintf(s, SCIP_MAXSTRLEN, " col %d: [--,%Qd]\n", ind[j], *SCIPrationalGetGMP(ub[j]));
965 else if( ub == NULL )
966 gmp_snprintf(s, SCIP_MAXSTRLEN, " col %d: [%Qd,--]\n", ind[j], *SCIPrationalGetGMP(lb[j]));
967 else
968 gmp_snprintf(s, SCIP_MAXSTRLEN, " col %d: [%Qd,%Qd]\n", ind[j], *SCIPrationalGetGMP(lb[j]), *SCIPrationalGetGMP(ub[j]));
970 }
971 }
972#endif
973
974 SCIP_CALL( ensureColMem(lpi, ncols) );
975
976 if( lb != NULL )
977 {
978 for( i = 0; i < ncols; i++ )
979 {
980 lpi->iccha[i] = 'L';
981 rval = mpq_QSchange_bound(lpi->prob, ind[i], lpi->iccha[i], *SCIPrationalGetGMP(lb[i]));
982 QS_CONDRET(rval);
983 }
984 }
985
986 if( ub != NULL )
987 {
988 for( i = 0; i < ncols; i++ )
989 {
990 lpi->iccha[i] = 'U';
991 rval = mpq_QSchange_bound(lpi->prob, ind[i], lpi->iccha[i], *SCIPrationalGetGMP(ub[i]));
992 QS_CONDRET(rval);
993 }
994 }
995 QS_RETURN(rval);
996}
997
998/** changes left and right hand sides of rows */
1000 SCIP_LPIEXACT* lpi, /**< LP interface structure */
1001 int nrows, /**< number of rows to change sides for */
1002 int* ind, /**< row indices */
1003 SCIP_RATIONAL** lhs, /**< new values for left hand sides */
1004 SCIP_RATIONAL** rhs /**< new values for right hand sides */
1005 )
1006{
1007 register int i;
1008 int rval = 0;
1009
1010 assert(lpi != NULL);
1011 assert(lpi->prob != NULL);
1012
1013 lpi->solstat = 0;
1014 SCIPdebugMessage("changing %d sides in QSopt_ex\n", nrows);
1015
1016 SCIP_CALL( ensureRowMem(lpi, nrows) );
1017
1018 /* convert lhs/rhs into sen/rhs/range tuples */
1019 SCIP_CALL( convertSides(lpi, nrows, lhs, rhs) );
1020
1021 /* now we change all rows */
1022 for( i = 0; i < nrows; ++i )
1023 {
1024 rval = mpq_QSchange_sense(lpi->prob, ind[i], lpi->isen[i]);
1025 QS_CONDRET(rval);
1026
1027 rval = mpq_QSchange_rhscoef(lpi->prob, ind[i], lpi->irhs[i]);
1028 QS_CONDRET(rval);
1029
1030 if (lpi->isen[i] == 'R')
1031 {
1032 rval = mpq_QSchange_range(lpi->prob, ind[i], lpi->irng[i]);
1033 QS_CONDRET(rval);
1034 }
1035 }
1036
1037 QS_RETURN(rval);
1038}
1039
1040/** changes a single coefficient */
1042 SCIP_LPIEXACT* lpi, /**< LP interface structure */
1043 int row, /**< row number of coefficient to change */
1044 int col, /**< column number of coefficient to change */
1045 SCIP_RATIONAL* newval /**< new value of coefficient */
1046 )
1047{
1048 int rval = 0;
1049
1050 assert(lpi != NULL);
1051 assert(lpi->prob != NULL);
1052
1053 lpi->solstat = 0;
1054
1055 SCIPdebugMessage("changing coefficient row %d, column %d in QSopt_ex to %g\n", row, col, SCIPrationalGetReal(newval));
1056
1057 rval = mpq_QSchange_coef(lpi->prob, row, col, *SCIPrationalGetGMP(newval));
1058
1059 QS_RETURN(rval);
1060}
1061
1062/** changes the objective sense */
1064 SCIP_LPIEXACT* lpi, /**< LP interface structure */
1065 SCIP_OBJSEN objsen /**< new objective sense */
1066 )
1067{
1068 int rval = 0;
1069
1070 assert(lpi != NULL);
1071 assert(lpi->prob != NULL);
1072
1073 lpi->solstat = 0;
1074 SCIPdebugMessage("changing objective sense in QSopt_ex to %d\n", objsen);
1075
1076 /* set sense */
1077 if( objsen == SCIP_OBJSEN_MAXIMIZE )
1078 {
1079 rval = mpq_QSchange_objsense(lpi->prob, QS_MAX);
1080 QS_CONDRET(rval);
1081 }
1082 else
1083 {
1084 rval = mpq_QSchange_objsense(lpi->prob, QS_MIN);
1085 QS_CONDRET(rval);
1086 }
1087
1088 QS_RETURN(rval);
1089}
1090
1091/** changes objective values of columns in the LP */
1093 SCIP_LPIEXACT* lpi, /**< LP interface structure */
1094 int ncols, /**< number of columns to change objective value for */
1095 int* ind, /**< column indices to change objective value for */
1096 SCIP_RATIONAL** obj /**< new objective values for columns */
1097 )
1098{
1099 register int i;
1100 int rval = 0;
1101
1102 assert(lpi != NULL);
1103 assert(lpi->prob != NULL);
1104
1105 lpi->solstat = 0;
1106 SCIPdebugMessage("changing %d objective values in QSopt_ex\n", ncols);
1107
1108 for( i = 0; i < ncols; ++i )
1109 {
1110 rval = mpq_QSchange_objcoef(lpi->prob, ind[i], *SCIPrationalGetGMP(obj[i]));
1111 QS_CONDRET(rval);
1112 }
1113 QS_RETURN(rval);
1114}
1115
1116/** multiplies a row with a non-zero scalar; for negative scalars, the row's sense is switched accordingly */
1118 SCIP_LPIEXACT* lpi, /**< LP interface structure */
1119 int row, /**< row number to scale */
1120 SCIP_RATIONAL* scaleval /**< scaling multiplier */
1121 )
1122{
1123 register int i;
1124 int rowlist[1];
1125 int* rowcnt = NULL, *rowbeg = NULL, *rowind = NULL;
1126 mpq_t* rowval = NULL, *rhs = NULL, *range = NULL;
1127 char* sense = NULL;
1128 int rval = 0;
1129 mpq_t svl;
1130
1131 assert(lpi != NULL);
1132 assert(lpi->prob != NULL);
1133
1134 mpq_init(svl);
1135 lpi->solstat = 0;
1136 SCIPrationalDebugMessage("scaling row %d with factor %g in QSopt_ex\n", row, scaleval);
1137
1138 rowlist[0] = row;
1139 /* get row */
1140 rval = mpq_QSget_ranged_rows_list(lpi->prob, 1, rowlist, &rowcnt, &rowbeg, &rowind, &rowval, &rhs, &sense, &range, 0);
1141 QS_TESTG(rval, CLEANUP, " ");
1142
1143 /* change all coefficients in the constraint */
1144 for( i = 0; i < rowcnt[0]; ++i )
1145 {
1146 mpq_mul(svl, rowval[i], *SCIPrationalGetGMP(scaleval));
1147 rval = mpq_QSchange_coef(lpi->prob, row, rowind[i], svl);
1148 QS_TESTG(rval, CLEANUP, " ");
1149 }
1150
1151 /* if we have a positive scalar, we just scale rhs and range */
1152 if( SCIPrationalGetSign(scaleval) >= 0 )
1153 {
1154 mpq_mul(svl, *SCIPrationalGetGMP(scaleval), rhs[0]);
1155 rval = mpq_QSchange_rhscoef(lpi->prob, row, svl);
1156 QS_TESTG(rval, CLEANUP, " ");
1157 if (sense[0] == 'R')
1158 {
1159 mpq_mul(svl, range[0], *SCIPrationalGetGMP(scaleval));
1160 rval = mpq_QSchange_range(lpi->prob, row, svl);
1161 QS_TESTG(rval, CLEANUP, " ");
1162 }
1163 }
1164 /* otherwise, we must change everything */
1165 else
1166 {
1167 switch( sense[0] )
1168 {
1169 case 'E':
1170 mpq_mul(svl, rhs[0], *SCIPrationalGetGMP(scaleval));
1171 rval = mpq_QSchange_rhscoef(lpi->prob, row, svl);
1172 QS_TESTG(rval, CLEANUP, " ");
1173 break;
1174 case 'L':
1175 mpq_mul(svl, rhs[0], *SCIPrationalGetGMP(scaleval));
1176 rval = mpq_QSchange_rhscoef(lpi->prob, row, svl);
1177 QS_TESTG(rval, CLEANUP, " ");
1178 rval = mpq_QSchange_sense(lpi->prob, row, 'G');
1179 QS_TESTG(rval, CLEANUP, " ");
1180 break;
1181 case 'G':
1182 mpq_mul(svl, rhs[0], *SCIPrationalGetGMP(scaleval));
1183 rval = mpq_QSchange_rhscoef(lpi->prob, row, svl);
1184 QS_TESTG(rval, CLEANUP, " ");
1185 rval = mpq_QSchange_sense(lpi->prob, row, 'L');
1186 QS_TESTG(rval, CLEANUP, " ");
1187 break;
1188 case 'R':
1189 mpq_add(svl, rhs[0], range[0]);
1190 mpq_mul(svl, svl, *SCIPrationalGetGMP(scaleval));
1191 rval = mpq_QSchange_rhscoef(lpi->prob, row, svl);
1192 QS_TESTG(rval, CLEANUP, " ");
1193 mpq_abs(svl,*SCIPrationalGetGMP(scaleval));
1194 mpq_mul(svl, svl, range[0]);
1195 rval = mpq_QSchange_range(lpi->prob, row, svl);
1196 QS_TESTG(rval, CLEANUP, " ");
1197 break;
1198 default:
1199 SCIPerrorMessage("Imposible! received sense %c (not E L G R)", sense[0]);
1200 rval = 1;
1201 goto CLEANUP;
1202 }
1203 }
1204 /* now we must free all received arrays */
1205 /* ending */
1206 CLEANUP:
1207 if (rowcnt) mpq_QSfree(rowcnt);
1208 if (rowbeg) mpq_QSfree(rowbeg);
1209 if (rowind) mpq_QSfree(rowind);
1210 if (rowval) mpq_EGlpNumFreeArray(rowval);
1211 if (rhs) mpq_EGlpNumFreeArray(rhs);
1212 if (sense) mpq_QSfree(sense);
1213 if (range) mpq_EGlpNumFreeArray(range);
1214 mpq_clear(svl);
1215
1216 QS_RETURN(rval);
1217}
1218
1219/** multiplies a column with a non-zero scalar; the objective value is multiplied with the scalar, and the bounds
1220 * are divided by the scalar; for negative scalars, the column's bounds are switched
1221 */
1223 SCIP_LPIEXACT* lpi, /**< LP interface structure */
1224 int col, /**< column number to scale */
1225 SCIP_RATIONAL* scaleval /**< scaling multiplier */
1226 )
1227{
1228 register int i;
1229 int collist[1];
1230 int* colcnt=0, *colbeg=0, *colind=0;
1231 mpq_t* colval=0, *lb=0, *ub=0, *obj=0;
1232 int rval = 0;
1233 mpq_t svl;
1234
1235 assert(lpi != NULL);
1236 assert(lpi->prob != NULL);
1237
1238 mpq_init(svl);
1239 lpi->solstat = 0;
1240 SCIPdebugMessage("scaling column %d with factor %g in QSopt_ex\n",
1241 col, SCIPrationalGetReal(scaleval));
1242
1243 /* get the column */
1244 collist[0] = col;
1245 rval = mpq_QSget_columns_list(lpi->prob, 1, collist, &colcnt, &colbeg, &colind, &colval, &obj, &lb, &ub, 0);
1246 QS_TESTG(rval,CLEANUP," ");
1247
1248 /* scale column coefficients */
1249 for( i = 0; i < colcnt[0]; ++i )
1250 {
1251 mpq_mul(svl, colval[i], *SCIPrationalGetGMP(scaleval));
1252 rval = mpq_QSchange_coef(lpi->prob, colind[i], col, svl);
1253 QS_TESTG(rval,CLEANUP," ");
1254 }
1255
1256 /* scale objective value */
1257 mpq_mul(svl, obj[0], *SCIPrationalGetGMP(scaleval));
1258 rval = mpq_QSchange_objcoef(lpi->prob, col, svl);
1259 QS_TESTG(rval,CLEANUP," ");
1260
1261 /* scale column bounds */
1262 if( mpq_sgn(*SCIPrationalGetGMP(scaleval)) < 0 )
1263 {
1264 mpq_set(obj[0], lb[0]);
1265 mpq_neg(lb[0], ub[0]);
1266 mpq_neg(ub[0], obj[0]);
1267 }
1268 if( mpq_cmp(lb[0],mpq_ILL_MINDOUBLE) > 0 )
1269 {
1270 mpq_abs(svl,*SCIPrationalGetGMP(scaleval));
1271 mpq_mul(lb[0], lb[0], svl);
1272 }
1273 if( mpq_cmp(ub[0], mpq_ILL_MAXDOUBLE) < 0 )
1274 {
1275 mpq_abs(svl, *SCIPrationalGetGMP(scaleval));
1276 mpq_mul(ub[0], ub[0], svl);
1277 }
1278
1279 if( mpq_cmp(lb[0], mpq_ILL_MINDOUBLE) < 0 )
1280 mpq_set(lb[0], mpq_ILL_MINDOUBLE);
1281 if( mpq_cmp(ub[0], mpq_ILL_MAXDOUBLE) > 0 )
1282 mpq_set(ub[0], mpq_ILL_MAXDOUBLE);
1283
1284 rval = mpq_QSchange_bound(lpi->prob, col, 'L', lb[0]);
1285 QS_TESTG(rval, CLEANUP, " ");
1286 rval = mpq_QSchange_bound(lpi->prob, col, 'U', ub[0]);
1287 QS_TESTG(rval, CLEANUP, " ");
1288
1289 /* ending */
1290 CLEANUP:
1291 if (colcnt) mpq_QSfree(colcnt);
1292 if (colbeg) mpq_QSfree(colbeg);
1293 if (colind) mpq_QSfree(colind);
1294 if (colval) mpq_EGlpNumFreeArray(colval);
1295 if (obj) mpq_EGlpNumFreeArray(obj);
1296 if (lb) mpq_EGlpNumFreeArray(lb);
1297 if (ub) mpq_EGlpNumFreeArray(ub);
1298 mpq_clear(svl);
1299
1300 QS_RETURN(rval);
1301}
1302/**@} */
1303
1304/*
1305 * Data Accessing Methods
1306 */
1307
1308/**@name Data Accessing Methods */
1309/**@{ */
1310
1311/** gets the number of rows in the LP */
1313 SCIP_LPIEXACT* lpi, /**< LP interface structure */
1314 int* nrows /**< pointer to store the number of rows */
1315 )
1316{
1317 assert(lpi != NULL);
1318 assert(lpi->prob != NULL);
1319 assert(nrows != NULL);
1320
1321 SCIPdebugMessage("getting number of rows\n");
1322
1323 *nrows = mpq_QSget_rowcount(lpi->prob);
1324
1325 return SCIP_OKAY;
1326}
1327
1328/** gets the number of columns in the LP */
1330 SCIP_LPIEXACT* lpi, /**< LP interface structure */
1331 int* ncols /**< pointer to store the number of cols */
1332 )
1333{
1334 assert(lpi != NULL);
1335 assert(lpi->prob != NULL);
1336 assert(ncols != NULL);
1337
1338 SCIPdebugMessage("getting number of columns\n");
1339
1340 *ncols = mpq_QSget_colcount(lpi->prob);
1341
1342 return SCIP_OKAY;
1343}
1344
1345/** gets the number of nonzero elements in the LP constraint matrix */
1347 SCIP_LPIEXACT* lpi, /**< LP interface structure */
1348 int* nnonz /**< pointer to store the number of nonzeros */
1349 )
1350{
1351 assert(lpi != NULL);
1352 assert(lpi->prob != NULL);
1353
1354 SCIPdebugMessage("getting number of columns\n");
1355
1356 *nnonz = mpq_QSget_nzcount(lpi->prob);
1357
1358 return SCIP_OKAY;
1359}
1360
1361/** gets columns from LP problem object; the arrays have to be large enough to store all values
1362 * Either both, lb and ub, have to be NULL, or both have to be non-NULL,
1363 * either nnonz, beg, ind, and val have to be NULL, or all of them have to be non-NULL.
1364 */
1366 SCIP_LPIEXACT* lpi, /**< LP interface structure */
1367 int firstcol, /**< first column to get from LP */
1368 int lastcol, /**< last column to get from LP */
1369 SCIP_RATIONAL** lb, /**< buffer to store the lower bound vector, or NULL */
1370 SCIP_RATIONAL** ub, /**< buffer to store the upper bound vector, or NULL */
1371 int* nnonz, /**< pointer to store the number of nonzero elements returned, or NULL */
1372 int* beg, /**< buffer to store start index of each column in ind- and val-array, or NULL */
1373 int* ind, /**< buffer to store column indices of constraint matrix entries, or NULL */
1374 SCIP_RATIONAL** val /**< buffer to store values of constraint matrix entries, or NULL */
1375 )
1376{
1377 int len;
1378 register int i;
1379 mpq_t* lval = NULL;
1380 mpq_t* llb = NULL;
1381 mpq_t* lub = NULL;
1382 int rval = 0;
1383 int* lcnt = NULL;
1384 int* lbeg = NULL;
1385 int* lind = NULL;
1386
1387 assert(lpi != NULL);
1388 assert(lpi->prob != NULL);
1389 assert( 0 <= firstcol && firstcol <= lastcol && lastcol < mpq_QSget_colcount (lpi->prob) );
1390 assert( (lb == 0 && ub == 0) || (lb != 0 && ub != 0));
1391 assert( (nnonz != 0 && beg != 0 && ind != 0 && val != 0) || (nnonz == 0 && beg == 0 && ind == 0 && val == 0) );
1392
1393 SCIPdebugMessage("getting columns %d to %d\n", firstcol, lastcol);
1394
1395 /* build col-list */
1396 len = lastcol - firstcol + 1;
1397 SCIP_CALL( ensureColMem(lpi,len) );
1398 for( i = 0; i < len; ++i )
1399 lpi->iccnt[i] = i + firstcol;
1400
1401 /* get data from qsopt */
1402 rval = mpq_QSget_columns_list(lpi->prob, len, lpi->iccnt, nnonz ? (&lcnt) : 0, nnonz ? (&lbeg) : 0, nnonz ? (&lind) : 0,
1403 nnonz ? (&lval) : 0, 0, lb ? (&llb) : 0, lb ? (&lub) : 0, 0);
1404
1405 QS_TESTG(rval, CLEANUP, " ");
1406
1407 /* store in the user-provided data */
1408 if( nnonz )
1409 {
1410 assert( lbeg != NULL );
1411 assert( lcnt != NULL );
1412 assert( lind != NULL );
1413 assert( lval != NULL );
1414
1415 *nnonz = lbeg[len-1] + lcnt[len-1];
1416 for( i = 0 ; i < len ; i++ )
1417 beg[i] = lbeg[i]; /*lint !e613*/
1418 for( i = 0; i < *nnonz; ++i )
1419 {
1420 ind[i] = lind[i]; /*lint !e613*/
1421 SCIPrationalSetGMP(val[i], lval[i]);
1422 }
1423 }
1424 if( lb )
1425 {
1426 assert(llb != NULL);
1427 assert(lub != NULL);
1428
1429 for( i = 0; i < len; ++i )
1430 {
1431 SCIPrationalSetGMP(lb[i], llb[i]);
1432 SCIPrationalSetGMP(ub[i], lub[i]); /*lint !e613*/
1433 }
1434 }
1435
1436 CLEANUP:
1437 if (lval) mpq_EGlpNumFreeArray(lval);
1438 if (lub) mpq_EGlpNumFreeArray(lub);
1439 if (llb) mpq_EGlpNumFreeArray(llb);
1440 if (lind) mpq_QSfree(lind);
1441 if (lbeg) mpq_QSfree(lbeg);
1442 if (lcnt) mpq_QSfree(lcnt);
1443
1444 QS_RETURN(rval);
1445}
1446
1447/** gets rows from LP problem object; the arrays have to be large enough to store all values.
1448 * Either both, lhs and rhs, have to be NULL, or both have to be non-NULL,
1449 * either nnonz, beg, ind, and val have to be NULL, or all of them have to be non-NULL.
1450 */
1452 SCIP_LPIEXACT* lpi, /**< LP interface structure */
1453 int firstrow, /**< first row to get from LP */
1454 int lastrow, /**< last row to get from LP */
1455 SCIP_RATIONAL** lhs, /**< buffer to store left hand side vector, or NULL */
1456 SCIP_RATIONAL** rhs, /**< buffer to store right hand side vector, or NULL */
1457 int* nnonz, /**< pointer to store the number of nonzero elements returned, or NULL */
1458 int* beg, /**< buffer to store start index of each row in ind- and val-array, or NULL */
1459 int* ind, /**< buffer to store row indices of constraint matrix entries, or NULL */
1460 SCIP_RATIONAL** val /**< buffer to store values of constraint matrix entries, or NULL */
1461 )
1462{
1463 const int len = lastrow - firstrow + 1;
1464 register int i;
1465 mpq_t* lval = NULL;
1466 mpq_t* lrhs = NULL;
1467 mpq_t* lrng = NULL;
1468 int rval = 0;
1469 int* lcnt = NULL;
1470 int* lbeg = NULL;
1471 int* lind = NULL;
1472 char* lsense = NULL;
1473
1474 assert(lpi != NULL);
1475 assert(lpi->prob != NULL);
1476 assert(0 <= firstrow && firstrow <= lastrow && lastrow < mpq_QSget_rowcount (lpi->prob));
1477 assert( (lhs == 0 && rhs == 0) || (rhs != 0 && lhs != 0));
1478 assert( (nnonz != 0 && beg != 0 && ind != 0 && val != 0) || (nnonz == 0 && beg == 0 && ind == 0 && val == 0));
1479
1480 SCIPdebugMessage("getting rows %d to %d\n", firstrow, lastrow);
1481
1482 /* build row-list */
1483 SCIP_CALL( ensureRowMem(lpi, len) );
1484 for( i = 0; i < len; ++i )
1485 lpi->ircnt[i] = i + firstrow;
1486
1487 /* get data from qsopt */
1488 rval = mpq_QSget_ranged_rows_list(lpi->prob, len, lpi->ircnt, nnonz ? (&lcnt) : 0, nnonz ? (&lbeg) : 0, nnonz ? (&lind) : 0,
1489 nnonz ? (&lval) : 0, rhs ? (&lrhs) : 0, rhs ? (&lsense) : 0, rhs ? (&lrng) : 0, 0);
1490 QS_TESTG(rval, CLEANUP, " ");
1491
1492 /* store in the user-provided data */
1493 if( nnonz )
1494 {
1495 assert(lbeg != NULL);
1496 assert(lcnt != NULL);
1497 assert(lind != NULL);
1498 assert(lval != NULL);
1499
1500 *nnonz = lbeg[len-1] + lcnt[len-1];
1501 for( i = 0; i < len; i++ )
1502 beg[i] = lbeg[i]; /*lint !e613*/
1503 for( i = 0; i < *nnonz; ++i )
1504 {
1505 ind[i] = lind[i]; /*lint !e613*/
1506 SCIPrationalSetGMP(val[i], lval[i]); /*lint !e613*/
1507 }
1508 }
1509 if( rhs )
1510 {
1511 assert(lrhs != NULL);
1512 assert(lrng != NULL);
1513 assert(lsense != NULL);
1514
1515 for( i = 0; i < len; ++i )
1516 {
1517 switch( lsense[i] )
1518 {
1519 case 'R':
1520 SCIPrationalSetGMP(lhs[i], lrhs[i]);
1521 SCIPrationalSetGMP(rhs[i], lrng[i]);
1522 SCIPrationalAdd(rhs[i], rhs[i], lhs[i]);
1523 break;
1524 case 'E':
1525 SCIPrationalSetGMP(lhs[i], lrhs[i]);
1526 SCIPrationalSetGMP(rhs[i], lrhs[i]);
1527 break;
1528 case 'L':
1529 SCIPrationalSetGMP(rhs[i], lrhs[i]);
1530 SCIPrationalSetGMP(lhs[i], mpq_ILL_MINDOUBLE); /*lint !e613*/
1531 break;
1532 case 'G':
1533 SCIPrationalSetGMP(lhs[i], lrhs[i]);
1534 SCIPrationalSetGMP(rhs[i], mpq_ILL_MAXDOUBLE);
1535 break;
1536 default:
1537 SCIPerrorMessage("Unknown sense %c from QSopt_ex", lsense[i]);
1538 SCIPABORT();
1539 }
1540 }
1541 }
1542
1543 CLEANUP:
1544 if (lsense) mpq_QSfree(lsense);
1545 if (lrng) mpq_EGlpNumFreeArray(lrng);
1546 if (lrhs) mpq_EGlpNumFreeArray(lrhs);
1547 if (lval) mpq_EGlpNumFreeArray(lval);
1548 if (lind) mpq_QSfree(lind);
1549 if (lbeg) mpq_QSfree(lbeg);
1550 if (lcnt) mpq_QSfree(lcnt);
1551
1552 QS_RETURN(rval);
1553}
1554
1555/** gets objective coefficients from LP problem object */
1557 SCIP_LPIEXACT* lpi, /**< LP interface structure */
1558 int firstcol, /**< first column to get objective coefficient for */
1559 int lastcol, /**< last column to get objective coefficient for */
1560 SCIP_RATIONAL** vals /**< array to store objective coefficients */
1561 )
1562{
1563 const int len = lastcol - firstcol + 1;
1564 int rval = 0;
1565 register int i;
1566 mpq_t* valgmp;
1567
1568 assert(lpi != NULL);
1569 assert(lpi->prob != NULL);
1570 assert(0 <= firstcol && firstcol <= lastcol && lastcol < mpq_QSget_colcount (lpi->prob));
1571
1572 SCIPdebugMessage("getting objective values %d to %d\n", firstcol, lastcol);
1573
1574 /* build col-list */
1575 SCIP_CALL( ensureColMem(lpi,len) );
1576 for( i = 0; i < len; ++i )
1577 lpi->iccnt[i] = i + firstcol;
1578
1579 SCIP_ALLOC( BMSallocMemoryArray(&valgmp, len) );
1580 SCIPrationalSetGMPArray(valgmp, vals, len);
1581 /* get data from qsopt */
1582 rval = mpq_QSget_obj_list(lpi->prob, len, lpi->iccnt, valgmp);
1583 SCIPrationalSetArrayGMP(vals, valgmp, len);
1584
1585 SCIPrationalClearArrayGMP(valgmp, len);
1586 BMSfreeMemoryArray(&valgmp);
1587
1588 QS_RETURN(rval);
1589}
1590
1591/** gets current bounds from LP problem object */
1593 SCIP_LPIEXACT* lpi, /**< LP interface structure */
1594 int firstcol, /**< first column to get objective value for */
1595 int lastcol, /**< last column to get objective value for */
1596 SCIP_RATIONAL** lbs, /**< array to store lower bound values, or NULL */
1597 SCIP_RATIONAL** ubs /**< array to store upper bound values, or NULL */
1598 )
1599{
1600 const int len = lastcol - firstcol + 1;
1601 int rval = 0;
1602 register int i;
1603
1604 assert(lpi != NULL);
1605 assert(lpi->prob != NULL);
1606 assert(0 <= firstcol && firstcol <= lastcol&& lastcol < mpq_QSget_colcount (lpi->prob));
1607
1608 SCIPdebugMessage("getting bound values %d to %d\n", firstcol, lastcol);
1609
1610 /* build col-list */
1611 SCIP_CALL( ensureColMem(lpi,len) );
1612 for( i = 0; i < len; ++i )
1613 {
1614 if( lbs != NULL )
1615 {
1616 QS_CONDRET( mpq_QSget_bound(lpi->prob, i + firstcol, 'L', SCIPrationalGetGMP(lbs[i])) );
1619 }
1620 if( ubs != NULL )
1621 {
1622 QS_CONDRET( mpq_QSget_bound(lpi->prob, i + firstcol, 'U', SCIPrationalGetGMP(ubs[i])) );
1625 }
1626 }
1627
1628 QS_RETURN(rval);
1629}
1630
1631/** gets current row sides from LP problem object */
1633 SCIP_LPIEXACT* lpi, /**< LP interface structure */
1634 int firstrow, /**< first row to get sides for */
1635 int lastrow, /**< last row to get sides for */
1636 SCIP_RATIONAL** lhss, /**< array to store left hand side values, or NULL */
1637 SCIP_RATIONAL** rhss /**< array to store right hand side values, or NULL */
1638 )
1639{
1640 const int len = lastrow - firstrow + 1;
1641 register int i;
1642 mpq_t* lrhs = 0;
1643 mpq_t* lrng = 0;
1644 int rval = 0;
1645 char* lsense=0;
1646
1647 assert(lpi != NULL);
1648 assert(lpi->prob != NULL);
1649 assert(0 <= firstrow && firstrow <= lastrow && lastrow < mpq_QSget_rowcount (lpi->prob));
1650 assert(rhss != 0 && lhss != 0);
1651
1652 SCIPdebugMessage("getting row sides %d to %d\n", firstrow, lastrow);
1653
1654 /* build row-list */
1655 SCIP_CALL( ensureRowMem(lpi, len) );
1656 for( i = 0; i < len; ++i )
1657 lpi->ircnt[i] = i + firstrow;
1658
1659 /* get data from qsopt */
1660 rval = mpq_QSget_ranged_rows_list(lpi->prob, len, lpi->ircnt, 0, 0, 0, 0, &lrhs, &lsense, &lrng, 0);
1661 QS_TESTG(rval, CLEANUP, " ");
1662
1663 /* store in the user-provided data */
1664 for( i = 0; i < len; ++i )
1665 {
1666 switch (lsense[i])
1667 {
1668 case 'R':
1669 SCIPrationalSetGMP(lhss[i], lrhs[i]);
1670 SCIPrationalSetGMP(rhss[i], lrng[i]);
1671 SCIPrationalAdd(rhss[i], rhss[i], lhss[i]);
1672 break;
1673 case 'E':
1674 SCIPrationalSetGMP(lhss[i], lrhs[i]);
1675 SCIPrationalSetGMP(rhss[i], lrhs[i]);
1676 break;
1677 case 'L':
1678 SCIPrationalSetGMP(rhss[i], lrhs[i]);
1679 SCIPrationalSetGMP(lhss[i], mpq_ILL_MINDOUBLE);
1680 break;
1681 case 'G':
1682 SCIPrationalSetGMP(lhss[i], lrhs[i]);
1683 SCIPrationalSetGMP(rhss[i], mpq_ILL_MAXDOUBLE);
1684 break;
1685 default:
1686 SCIPerrorMessage("Unknown sense %c from QSopt_ex", lsense[i]);
1687 SCIPABORT();
1688 }
1689 }
1690
1691 CLEANUP:
1692 if (lsense)
1693 mpq_QSfree(lsense);
1694 if (lrng)
1695 mpq_EGlpNumFreeArray(lrng);
1696 if (lrhs)
1697 mpq_EGlpNumFreeArray(lrhs);
1698
1699 QS_RETURN(rval);
1700}
1701
1702/** gets a single coefficient */
1704 SCIP_LPIEXACT* lpi, /**< LP interface structure */
1705 int row, /**< row number of coefficient */
1706 int col, /**< column number of coefficient */
1707 SCIP_RATIONAL* val /**< pointer to store the value of the coefficient */
1708 )
1709{
1710 int rval = 0;
1711
1712 assert(lpi != NULL);
1713 assert(lpi->prob != NULL);
1714
1715 SCIPdebugMessage("getting coefficient of row %d col %d\n", row, col);
1716
1717 rval = mpq_QSget_coef(lpi->prob, row, col, SCIPrationalGetGMP(val));
1720
1721 QS_RETURN(rval);
1722}
1723
1724/**@} */
1725
1726/*
1727 * Solving Methods
1728 */
1729
1730/**@name Solving Methods */
1731/**@{ */
1732
1733/** calls primal simplex to solve the LP */
1735 SCIP_LPIEXACT* lpi /**< LP interface structure */
1736 )
1737{
1738 int rval = 0;
1739 QSbasis* B;
1740
1741 assert(lpi != NULL);
1742 assert(lpi->prob != NULL);
1743
1744 SCIPdebugMessage("calling QSopt_ex primal simplex: %d cols, %d rows, %d nz\n", mpq_QSget_colcount(lpi->prob),
1745 mpq_QSget_rowcount(lpi->prob), mpq_QSget_nzcount(lpi->prob));
1746
1747 B = mpq_QSget_basis(lpi->prob);
1748 rval = QSexact_solver(lpi->prob, 0, 0, B, PRIMAL_SIMPLEX, &(lpi->solstat));
1749 if( B )
1750 mpq_QSfree_basis(B);
1751
1752 QS_RETURN(rval);
1753}
1754
1755/** calls dual simplex to solve the LP */
1757 SCIP_LPIEXACT* lpi /**< LP interface structure */
1758 )
1759{
1760 int rval = 0;
1761 QSbasis* B;
1762
1763 assert(lpi != NULL);
1764 assert(lpi->prob != NULL);
1765
1766 SCIPdebugMessage("calling QSopt_ex dual simplex: %d cols, %d rows, %d nz\n", mpq_QSget_colcount(lpi->prob),
1767 mpq_QSget_rowcount(lpi->prob), mpq_QSget_nzcount(lpi->prob));
1768
1769 B = mpq_QSget_basis(lpi->prob);
1770 rval = QSexact_solver(lpi->prob, 0, 0, B, DUAL_SIMPLEX, &(lpi->solstat));
1771 if( B )
1772 mpq_QSfree_basis(B);
1773
1774 QS_RETURN(rval);
1775}
1776
1777/** calls barrier or interior point algorithm to solve the LP with crossover to simplex basis */
1779 SCIP_LPIEXACT* lpi, /**< LP interface structure */
1780 SCIP_Bool crossover /**< perform crossover */
1781 )
1782{ /*lint --e{715}*/
1783 return SCIPlpiExactSolveDual(lpi);
1784}
1785
1786/**@} */
1787
1788/*
1789 * Solution Information Methods
1790 */
1791
1792/**@name Solution Information Methods */
1793/**@{ */
1794
1795/** returns whether a solve method was called after the last modification of the LP */
1797 SCIP_LPIEXACT* lpi /**< LP interface structure */
1798 )
1799{
1800 assert(lpi!=NULL);
1801 assert(lpi->prob!=NULL);
1802
1803 return (lpi->solstat != 0 && lpi->solstat != QS_LP_MODIFIED && lpi->solstat != QS_LP_CHANGE_PREC);
1804}
1805
1806/** gets information about primal and dual feasibility of the current LP solution */
1808 SCIP_LPIEXACT* lpi, /**< LP interface structure */
1809 SCIP_Bool* primalfeasible, /**< stores primal feasibility status */
1810 SCIP_Bool* dualfeasible /**< stores dual feasibility status */
1811 )
1812{
1813 assert(lpi != NULL);
1814 assert(lpi->prob != NULL);
1815
1816 SCIPdebugMessage("getting solution feasibility\n");
1817
1818 *primalfeasible = FALSE;
1819 *dualfeasible = FALSE;
1820
1821 if( lpi->solstat == QS_LP_OPTIMAL || lpi->solstat == QS_LP_UNBOUNDED )
1822 *primalfeasible = TRUE;
1823
1824 /* @todo: check why we can conclude dual feasibility from primal infeasibility. in theory, the LP could be primal and
1825 * dual infeasible as well; see also SCIPlpiExactIsDualFeasible() and SCIPlpiExactIsDualInfeasible()
1826 */
1827#ifdef USEOBJLIM
1828 if( lpi->solstat == QS_LP_OPTIMAL || lpi->solstat == QS_LP_INFEASIBLE || lpi->solstat == QS_LP_OBJ_LIMIT )
1829#else
1830 if( lpi->solstat == QS_LP_OPTIMAL || lpi->solstat == QS_LP_INFEASIBLE )
1831#endif
1832 *dualfeasible = TRUE;
1833
1834 return SCIP_OKAY;
1835}
1836
1837/** returns TRUE iff LP is proven to have a primal unbounded ray (but not necessary a primal feasible point);
1838 * this does not necessarily mean, that the solver knows and can return the primal ray
1839 */
1841 SCIP_LPIEXACT* lpi /**< LP interface structure */
1842 )
1843{
1844 assert(lpi != NULL);
1845 assert(lpi->prob != NULL);
1846
1847 SCIPdebugMessage("checking primal ray existance\n");
1848
1849 return (lpi->solstat == QS_LP_UNBOUNDED);
1850}
1851
1852/** returns TRUE iff LP is proven to have a primal unbounded ray (but not necessary a primal feasible point),
1853 * and the solver knows and can return the primal ray
1854 */
1856 SCIP_LPIEXACT* lpi /**< LP interface structure */
1857 )
1858{
1859 assert(lpi != NULL);
1860 assert(lpi->prob != NULL);
1861
1862 SCIPdebugMessage("checking for primal ray\n");
1863
1864 /* the current version of QSopt_ex can not give a primal certificate of unboundness */
1865 return FALSE;
1866}
1867
1868/** returns TRUE iff LP is proven to be primal unbounded */
1870 SCIP_LPIEXACT* lpi /**< LP interface structure */
1871 )
1872{
1873 assert(lpi != NULL);
1874 assert(lpi->prob != NULL);
1875
1876 SCIPdebugMessage("checking for primal unboundness\n");
1877
1878 return (lpi->solstat == QS_LP_UNBOUNDED);
1879}
1880
1881/** returns TRUE iff LP is proven to be primal infeasible */
1883 SCIP_LPIEXACT* lpi /**< LP interface structure */
1884 )
1885{
1886 assert(lpi != NULL);
1887 assert(lpi->prob != NULL);
1888
1889 SCIPdebugMessage("checking for primal infeasibility\n");
1890
1891 return (lpi->solstat == QS_LP_INFEASIBLE);
1892}
1893
1894/** returns TRUE iff LP is proven to be primal feasible */
1896 SCIP_LPIEXACT* lpi /**< LP interface structure */
1897 )
1898{
1899 assert(lpi != NULL);
1900 assert(lpi->prob != NULL);
1901
1902 SCIPdebugMessage("checking for primal feasibility\n");
1903
1904 return (lpi->solstat == QS_LP_OPTIMAL || lpi->solstat == QS_LP_UNBOUNDED);
1905}
1906
1907/** returns TRUE iff LP is proven to have a dual unbounded ray (but not necessary a dual feasible point);
1908 * this does not necessarily mean, that the solver knows and can return the dual ray
1909 */
1911 SCIP_LPIEXACT* lpi /**< LP interface structure */
1912 )
1913{
1914 assert(lpi != NULL);
1915 assert(lpi->prob != NULL);
1916
1917 SCIPdebugMessage("checking for dual ray availability\n");
1918
1919 return (lpi->solstat == QS_LP_INFEASIBLE);
1920}
1921
1922/** returns TRUE iff LP is proven to have a dual unbounded ray (but not necessary a dual feasible point),
1923 * and the solver knows and can return the dual ray
1924 */
1926 SCIP_LPIEXACT* lpi /**< LP interface structure */
1927 )
1928{
1929 assert(lpi != NULL);
1930 assert(lpi->prob != NULL);
1931
1932 SCIPdebugMessage("checking for dual ray availability\n");
1933
1934 return (lpi->solstat == QS_LP_INFEASIBLE);
1935}
1936
1937/** returns TRUE iff LP is dual unbounded */
1939 SCIP_LPIEXACT* lpi /**< LP interface structure */
1940 )
1941{
1942 assert(lpi != NULL);
1943 assert(lpi->prob != NULL);
1944
1945 SCIPdebugMessage("checking for dual unboundness\n");
1946
1947 return (lpi->solstat == QS_LP_INFEASIBLE);
1948}
1949
1950/** returns TRUE iff LP is dual infeasible */
1952 SCIP_LPIEXACT* lpi /**< LP interface structure */
1953 )
1954{
1955 assert(lpi != NULL);
1956 assert(lpi->prob != NULL);
1957
1958 SCIPdebugMessage("checking for dual infeasibility\n");
1959
1960 return (lpi->solstat == QS_LP_UNBOUNDED);
1961}
1962
1963/** returns TRUE iff LP is proven to be dual feasible */
1965 SCIP_LPIEXACT* lpi /**< LP interface structure */
1966 )
1967{
1968 assert(lpi != NULL);
1969 assert(lpi->prob != NULL);
1970
1971 SCIPdebugMessage("checking for dual feasibility\n");
1972
1973#ifdef USEOBJLIM
1974 return (lpi->solstat == QS_LP_OPTIMAL || lpi->solstat == QS_LP_OBJ_LIMIT );
1975#else
1976 return (lpi->solstat == QS_LP_OPTIMAL);
1977#endif
1978}
1979
1980/** returns TRUE iff LP was solved to optimality */
1982 SCIP_LPIEXACT* lpi /**< LP interface structure */
1983 )
1984{
1985 assert(lpi != NULL);
1986 assert(lpi->prob != NULL);
1987
1988 SCIPdebugMessage("checking for optimality\n");
1989
1990 return (lpi->solstat == QS_LP_OPTIMAL);
1991}
1992
1993/** returns TRUE iff current LP basis is stable */
1995 SCIP_LPIEXACT* lpi /**< LP interface structure */
1996 )
1997{
1998 assert(lpi != NULL);
1999 assert(lpi->prob != NULL);
2000
2001 SCIPdebugMessage("checking for numerical stability\n");
2002
2003 return (lpi->solstat != QS_LP_NUMERR);
2004}
2005
2006/** returns TRUE iff the objective limit was reached */
2008 SCIP_LPIEXACT* lpi /**< LP interface structure */
2009 )
2010{
2011 assert(lpi != NULL);
2012 assert(lpi->prob != NULL);
2013
2014 SCIPdebugMessage("checking for objective limit exceeded\n");
2015
2016#ifdef USEOBJLIM
2017 return (lpi->solstat == QS_LP_OBJ_LIMIT);
2018#else
2019 return FALSE;
2020#endif
2021}
2022
2023/** returns TRUE iff the iteration limit was reached */
2025 SCIP_LPIEXACT* lpi /**< LP interface structure */
2026 )
2027{
2028 assert(lpi != NULL);
2029 assert(lpi->prob != NULL);
2030
2031 SCIPdebugMessage("checking for iteration limit exceeded\n");
2032
2033 return (lpi->solstat == QS_LP_ITER_LIMIT);
2034}
2035
2036/** returns TRUE iff the time limit was reached */
2038 SCIP_LPIEXACT* lpi /**< LP interface structure */
2039 )
2040{
2041 assert(lpi != NULL);
2042 assert(lpi->prob != NULL);
2043
2044 SCIPdebugMessage("checking for time limit exceeded\n");
2045
2046 return (lpi->solstat == QS_LP_TIME_LIMIT);
2047}
2048
2049/** returns the internal solution status of the solver */
2051 SCIP_LPIEXACT* lpi /**< LP interface structure */
2052 )
2053{
2054 assert(lpi != NULL);
2055 assert(lpi->prob != NULL);
2056
2057 SCIPdebugMessage("getting internal solution status\n");
2058
2059 return lpi->solstat;
2060}
2061
2062/** tries to reset the internal status of the LP solver in order to ignore an instability of the last solving call */
2064 SCIP_LPIEXACT* lpi, /**< LP interface structure */
2065 SCIP_Bool* success /**< pointer to store, whether the instability could be ignored */
2066 )
2067{
2068 assert(lpi != NULL);
2069 assert(lpi->prob != NULL);
2070
2071 SCIPdebugMessage("ignore instability (will fail)\n");
2072
2073 /* it seems that in QSopt_ex this does not make much sense */
2074 *success = FALSE;
2075
2076 return SCIP_OKAY;
2077}
2078
2079/** gets objective value of solution */
2081 SCIP_LPIEXACT* lpi, /**< LP interface structure */
2082 SCIP_RATIONAL* objval /**< stores the objective value */
2083 )
2084{
2085 int rval = 0;
2086
2087 assert(lpi != NULL);
2088 assert(lpi->prob != NULL);
2089
2090 SCIPdebugMessage("getting solution's objective value\n");
2091
2092 rval = mpq_QSget_objval(lpi->prob, SCIPrationalGetGMP(objval));
2095
2096 QS_RETURN(rval);
2097}
2098
2099/** gets primal and dual solution vectors */
2101 SCIP_LPIEXACT* lpi, /**< LP interface structure */
2102 SCIP_RATIONAL* objval, /**< stores the objective value, may be NULL if not needed */
2103 SCIP_RATIONAL** primsol, /**< primal solution vector, may be NULL if not needed */
2104 SCIP_RATIONAL** dualsol, /**< dual solution vector, may be NULL if not needed */
2105 SCIP_RATIONAL** activity, /**< row activity vector, may be NULL if not needed */
2106 SCIP_RATIONAL** redcost /**< reduced cost vector, may be NULL if not needed */
2107 )
2108{
2109 int rval = 0, nrows, ncols;
2110 register int i;
2111 mpq_t* primsolgmp, *dualsolgmp, *redcostgmp, *objvalgmp;
2112
2113 assert(lpi != NULL);
2114 assert(lpi->prob != NULL);
2115
2116 SCIPdebugMessage("getting solution\n");
2117
2118 nrows = mpq_QSget_rowcount(lpi->prob);
2119 ncols = mpq_QSget_colcount(lpi->prob);
2120 SCIP_CALL( ensureRowMem(lpi, nrows) );
2121
2122 if( primsol == NULL )
2123 primsolgmp = NULL;
2124 else
2125 {
2126 SCIP_ALLOC( BMSallocMemoryArray(&primsolgmp, ncols) );
2127 SCIPrationalSetGMPArray(primsolgmp, primsol, ncols);
2128 }
2129 if( redcost == NULL )
2130 redcostgmp = NULL;
2131 else
2132 {
2133 SCIP_ALLOC( BMSallocMemoryArray(&redcostgmp, ncols) );
2134 SCIPrationalSetGMPArray(redcostgmp, redcost, ncols);
2135 }
2136 if( dualsol == NULL )
2137 dualsolgmp = NULL;
2138 else
2139 {
2140 SCIP_ALLOC( BMSallocMemoryArray(&dualsolgmp, nrows) );
2141 SCIPrationalSetGMPArray(dualsolgmp, dualsol, nrows);
2142 }
2143 if( objval != NULL )
2144 {
2145 objvalgmp = SCIPrationalGetGMP(objval);
2147 }
2148 else
2149 objvalgmp = NULL;
2150
2151 rval = mpq_QSget_solution(lpi->prob, objvalgmp, primsolgmp, dualsolgmp, lpi->irng, redcostgmp);
2152
2153 if( objval != NULL )
2155
2156 if( redcost != NULL )
2157 {
2158 SCIPrationalSetArrayGMP(redcost, redcostgmp, ncols);
2159 SCIPrationalClearArrayGMP(redcostgmp, ncols);
2160 BMSfreeMemoryArray(&redcostgmp);
2161 }
2162 if( primsol != NULL )
2163 {
2164 SCIPrationalSetArrayGMP(primsol, primsolgmp, ncols);
2165 SCIPrationalClearArrayGMP(primsolgmp, ncols);
2166 BMSfreeMemoryArray(&primsolgmp);
2167 }
2168 if( dualsol != NULL )
2169 {
2170 SCIPrationalSetArrayGMP(dualsol, dualsolgmp, nrows);
2171 SCIPrationalClearArrayGMP(dualsolgmp, nrows);
2172 BMSfreeMemoryArray(&dualsolgmp);
2173 }
2174
2175 QS_CONDRET(rval);
2176
2177 rval = mpq_QSget_rhs(lpi->prob, lpi->irhs);
2178 QS_CONDRET(rval);
2179 rval = mpq_QSget_senses(lpi->prob, lpi->isen);
2180 QS_CONDRET(rval);
2181
2182 /* build back the activity */
2183 if( activity != NULL )
2184 {
2185 for( i = 0; i < nrows; ++i )
2186 {
2187 switch (lpi->isen[i])
2188 {
2189 case 'R':
2190 case 'E':
2191 case 'G':
2192 mpq_add(*SCIPrationalGetGMP(activity[i]), lpi->irhs[i], lpi->irng[i]);
2194 SCIPrationalCheckInfByValue(activity[i]);
2195 break;
2196 case 'L':
2197 mpq_sub(*SCIPrationalGetGMP(activity[i]), lpi->irhs[i], lpi->irng[i]);
2199 SCIPrationalCheckInfByValue(activity[i]);
2200 break;
2201 default:
2202 SCIPerrorMessage("unknown sense %c\n", lpi->isen[i]);
2203 SCIPABORT();
2204 }
2205 }
2206 }
2207
2208 return SCIP_OKAY;
2209}
2210
2211/** gets primal ray for unbounded LPs */
2213 SCIP_LPIEXACT* lpi, /**< LP interface structure */
2214 SCIP_RATIONAL** ray /**< primal ray */
2215 )
2216{ /*lint --e{715}*/
2217 assert(lpi != NULL);
2218 assert(lpi->prob != NULL);
2219
2220 SCIPerrorMessage("SCIPlpiExactGetPrimalRay() not supported by QSopt_ex.\n");
2221
2222 return SCIP_ERROR;
2223}
2224
2225/** gets dual farkas proof for infeasibility */
2227 SCIP_LPIEXACT* lpi, /**< LP interface structure */
2228 SCIP_RATIONAL** dualfarkas /**< dual farkas row multipliers */
2229 )
2230{
2231 int rval = 0;
2232 int nrows;
2233 mpq_t* dualfarkasgmp;
2234
2235 assert(lpi != NULL);
2236 assert(lpi->prob != NULL);
2237 assert(dualfarkas != NULL);
2238
2239 SCIPdebugMessage("calling QSopt_ex dual farkas: %d cols, %d rows, %d non zeros\n", mpq_QSget_colcount (lpi->prob),
2240 mpq_QSget_rowcount(lpi->prob), mpq_QSget_nzcount(lpi->prob));
2241
2242 nrows = mpq_QSget_rowcount(lpi->prob);\
2243 SCIP_ALLOC( BMSallocMemoryArray(&dualfarkasgmp, nrows) );
2244 SCIPrationalSetGMPArray(dualfarkasgmp, dualfarkas, nrows);
2245
2246 rval = mpq_QSget_infeas_array(lpi->prob, dualfarkasgmp);
2247
2248 SCIPrationalSetArrayGMP(dualfarkas, dualfarkasgmp, nrows);
2249 SCIPrationalClearArrayGMP(dualfarkasgmp, nrows);
2250 BMSfreeMemoryArray(&dualfarkasgmp);
2251
2252 QS_RETURN(rval);
2253}
2254
2255/** gets the number of LP iterations of the last solve call */
2257 SCIP_LPIEXACT* lpi, /**< LP interface structure */
2258 int* iterations /**< pointer to store the number of iterations of the last solve call */
2259 )
2260{
2261 int rval = 0, nit;
2262
2263 assert(lpi != NULL);
2264 assert(lpi->prob != NULL);
2265
2266 rval = mpq_QSget_itcnt(lpi->prob, 0, 0, 0, 0, &nit);
2267 QS_CONDRET(rval);
2268
2269 *iterations = nit - lpi->previt;
2270 lpi->previt = nit;
2271
2272 QS_RETURN(rval);
2273}
2274
2275/**@} */
2276
2277/*
2278 * LP Basis Methods
2279 */
2280
2281/**@name LP Basis Methods */
2282/**@{ */
2283
2284/** gets current basis status for columns and rows; arrays must be large enough to store the basis status */
2286 SCIP_LPIEXACT* lpi, /**< LP interface structure */
2287 int* cstat, /**< array to store column basis status, or NULL */
2288 int* rstat /**< array to store row basis status, or NULL */
2289 )
2290{
2291 int rval = 0, ncols, nrows;
2292 char* icstat = NULL;
2293 char* irstat = NULL;
2294 register int i;
2295
2296 assert(lpi != NULL);
2297 assert(lpi->prob != NULL);
2298
2299 SCIPdebugMessage("saving QSopt_ex basis into %p/%p\n", (void *) cstat, (void *) rstat);
2300
2301 ncols = mpq_QSget_colcount(lpi->prob);
2302 nrows = mpq_QSget_rowcount(lpi->prob);
2303
2304 SCIP_CALL( ensureTabMem(lpi, nrows + ncols) );
2305
2306 icstat = lpi->ibas;
2307 irstat = lpi->ibas+ncols;
2308 rval = mpq_QSget_basis_array(lpi->prob, icstat, irstat);
2309 QS_CONDRET(rval);
2310
2311 /* now we must transform QSopt_ex codes into SCIP codes */
2312 for( i = 0; i < nrows; ++i )
2313 {
2314 switch (irstat[i])
2315 {
2316 case QS_ROW_BSTAT_LOWER:
2317 rstat[i] = SCIP_BASESTAT_LOWER; /*lint !e641*/
2318 break;
2319 case QS_ROW_BSTAT_BASIC:
2320 rstat[i] = SCIP_BASESTAT_BASIC; /*lint !e641*/
2321 break;
2322 case QS_ROW_BSTAT_UPPER:
2323 rstat[i] = SCIP_BASESTAT_UPPER; /*lint !e641*/
2324 break;
2325 default:
2326 SCIPerrorMessage("Unknown row basic status %c", rstat[i]);
2327 SCIPABORT();
2328 }
2329 }
2330 for( i = 0; i < ncols; ++i )
2331 {
2332 switch(icstat[i])
2333 {
2334 case QS_COL_BSTAT_LOWER:
2335 cstat[i] = SCIP_BASESTAT_LOWER; /*lint !e641*/
2336 break;
2337 case QS_COL_BSTAT_BASIC:
2338 cstat[i] = SCIP_BASESTAT_BASIC; /*lint !e641*/
2339 break;
2340 case QS_COL_BSTAT_UPPER:
2341 cstat[i] = SCIP_BASESTAT_UPPER; /*lint !e641*/
2342 break;
2343 case QS_COL_BSTAT_FREE:
2344 cstat[i] = SCIP_BASESTAT_ZERO; /*lint !e641*/
2345 break;
2346 default:
2347 SCIPerrorMessage("Unknown column basic status %c", cstat[i]);
2348 SCIPABORT();
2349 }
2350 }
2351 QS_RETURN(rval);
2352}
2353
2354/** sets current basis status for columns and rows */
2356 SCIP_LPIEXACT* lpi, /**< LP interface structure */
2357 int* cstat, /**< array with column basis status */
2358 int* rstat /**< array with row basis status */
2359 )
2360{
2361 int rval = 0, ncols, nrows;
2362 register int i;
2363 char* icstat=0, *irstat = 0;
2364
2365 assert(lpi != NULL);
2366 assert(lpi->prob != NULL);
2367
2368 SCIPdebugMessage("loading basis %p/%p into QSopt_ex\n", (void *) cstat, (void *) rstat);
2369
2370 ncols = mpq_QSget_colcount(lpi->prob);
2371 nrows = mpq_QSget_rowcount(lpi->prob);
2372
2373 /* allocate enough memory for storing uncompressed basis information */
2374 SCIP_CALL( ensureColMem(lpi, ncols) );
2375 SCIP_CALL( ensureRowMem(lpi, nrows) );
2376 SCIP_CALL( ensureTabMem(lpi, nrows+ncols) );
2377
2378 icstat = lpi->ibas;
2379 irstat = lpi->ibas + ncols;
2380
2381 /* now we must transform QSopt_ex codes into SCIP codes */
2382 for( i = 0; i < nrows; ++i )
2383 {
2384 switch(rstat[i])
2385 {
2387 irstat[i] = QS_ROW_BSTAT_LOWER; /*lint !e641*/
2388 break;
2390 irstat[i] = QS_ROW_BSTAT_BASIC; /*lint !e641*/
2391 break;
2393 /* sense of inexact LP row is R (ranged row) since this is the only case where the basis status of the
2394 * slack variable is allowed to be UPPER
2395 */
2396 if( lpi->isen[i] == 'R' )
2397 /* sense of LPEX row is R, too */
2398 irstat[i] = QS_ROW_BSTAT_UPPER; /*lint !e641*/
2399 else
2400 /* sense of LPEX row is L, G or E, thus, basis status must be LOWER/BASIC. we use non-basic status LOWER
2401 * instead of non-basic status UPPER for slack variable in LPEX. this might happen when the inexact LP
2402 * is an FP relaxation of the exact LP
2403 */
2404 irstat[i] = QS_ROW_BSTAT_LOWER;
2405 break;
2406 default:
2407 SCIPerrorMessage("Unknown row basic status %d", rstat[i]);
2408 SCIPABORT();
2409 }
2410 }
2411 for( i = 0; i < ncols; ++i )
2412 {
2413 switch(cstat[i])
2414 {
2416 icstat[i] = QS_COL_BSTAT_LOWER; /*lint !e641*/
2417 break;
2419 icstat[i] = QS_COL_BSTAT_BASIC; /*lint !e641*/
2420 break;
2422 icstat[i] = QS_COL_BSTAT_UPPER; /*lint !e641*/
2423 break;
2424 case SCIP_BASESTAT_ZERO:
2425 icstat[i] = QS_COL_BSTAT_FREE; /*lint !e641*/
2426 break;
2427 default:
2428 SCIPerrorMessage("Unknown column basic status %d", cstat[i]);
2429 SCIPABORT();
2430 }
2431 }
2432
2433 /* set the basis */
2434 rval = mpq_QSload_basis_array(lpi->prob, icstat, irstat);
2435 QS_RETURN(rval);
2436}
2437
2438/** returns the indices of the basic columns and rows */
2440 SCIP_LPIEXACT* lpi, /**< LP interface structure */
2441 int* bind /**< basic column n gives value n, basic row m gives value -1-m */
2442 )
2443{
2444 int rval = 0, nrows, ncols;
2445 register int i;
2446
2447 assert(lpi!=NULL);
2448 assert(lpi->prob!=NULL);
2449
2450 SCIPdebugMessage("getting basis information\n");
2451
2452 nrows = mpq_QSget_rowcount(lpi->prob);
2453 ncols = mpq_QSget_colcount(lpi->prob);
2454 rval = mpq_QSget_basis_order(lpi->prob, bind);
2455 QS_CONDRET(rval);
2456
2457 /* transform QSopt_ex basis header into SCIP format */
2458 for( i = 0; i < nrows; ++i )
2459 {
2460 if( bind[i] >= ncols )
2461 bind[i] = -(bind[i] - ncols - 1);
2462 }
2463
2464 return SCIP_OKAY;
2465}
2466
2467/**@} */
2468
2469/*
2470 * LP State Methods
2471 */
2472
2473/**@name LP State Methods */
2474/**@{ */
2475
2476/** stores LPi state (like basis information) into lpistate object */
2478 SCIP_LPIEXACT* lpi, /**< LP interface structure */
2479 BMS_BLKMEM* blkmem, /**< block memory */
2480 SCIP_LPISTATE** lpistate /**< pointer to LPi state information (like basis information) */
2481 )
2482{
2483 int ncols;
2484 int nrows;
2485
2486 assert(lpi != NULL);
2487 assert(lpi->prob != NULL);
2488 assert(blkmem != NULL);
2489 assert(lpistate != NULL);
2490
2491 ncols = mpq_QSget_colcount(lpi->prob);
2492 nrows = mpq_QSget_rowcount(lpi->prob);
2493
2494 assert(ncols >= 0);
2495 assert(nrows >= 0);
2496
2497 /* allocate lpistate data */
2498 SCIP_CALL( lpistateCreate(lpistate, blkmem, ncols, nrows));
2499 SCIPdebugMessage("storing QSopt_ex LPI state in %p (%d cols, %d rows)\n", (void *) *lpistate, ncols, nrows);
2500
2501 /* get unpacked basis information from QSopt_ex */
2502 SCIP_CALL( ensureColMem(lpi, ncols) );
2503 SCIP_CALL( ensureRowMem(lpi, nrows) );
2504 SCIP_CALL( SCIPlpiExactGetBase(lpi, lpi->iccnt, lpi->ircnt) );
2505
2506 /* pack LPi state data */
2507 (*lpistate)->ncols = ncols;
2508 (*lpistate)->nrows = nrows;
2509 lpistatePack(*lpistate, lpi->iccnt, lpi->ircnt);
2510
2511 return SCIP_OKAY;
2512}
2513
2514/** loads LPi state (like basis information) into solver; note that the LP might have been extended with additional
2515 * columns and rows since the state was stored with SCIPlpiExactGetState()
2516 */
2518 SCIP_LPIEXACT* lpi, /**< LP interface structure */
2519 BMS_BLKMEM* blkmem, /**< block memory */
2520 SCIP_LPISTATE* lpistate /**< LPi state information (like basis information) */
2521 )
2522{ /*lint --e{715} */
2523 register int i;
2524 int rval = 0;
2525 int ncols;
2526 int nrows;
2527 char* icstat = 0;
2528 char* irstat = 0;
2529
2530 assert(lpi != NULL);
2531 assert(lpi->prob != NULL);
2532
2533 /* if there was no basis information available, LPI state was not stored */
2534 if (lpistate == NULL)
2535 QS_RETURN(rval);
2536
2537 /* continue test */
2538 ncols = mpq_QSget_colcount(lpi->prob);
2539 nrows = mpq_QSget_rowcount(lpi->prob);
2540
2541 assert(ncols >= 0);
2542 assert(nrows >= 0);
2543 assert(lpistate->ncols <= ncols);
2544 assert(lpistate->nrows <= nrows);
2545
2546 SCIPdebugMessage("loading LPI state %p (%d cols, %d rows) into QSopt_ex LP (%d cols and %d rows)\n", (void*) lpistate,
2547 lpistate->ncols, lpistate->nrows, ncols, nrows);
2548
2549 if( lpistate->ncols == 0 || lpistate->nrows == 0 )
2550 QS_RETURN(rval);
2551
2552 /* allocate enough memory for storing uncompressed basis information */
2553 SCIP_CALL( ensureColMem(lpi, ncols) );
2554 SCIP_CALL( ensureRowMem(lpi, nrows) );
2555 SCIP_CALL( ensureTabMem(lpi, nrows+ncols) );
2556
2557 icstat = lpi->ibas;
2558 irstat = lpi->ibas + ncols;
2559
2560 /* unpack LPi state data */
2561 lpistateUnpack(lpistate, lpi->iccnt, lpi->ircnt);
2562
2563 /* extend the basis to the current LP */
2564 for( i = lpistate->ncols; i < ncols; ++i )
2565 lpi->iccnt[i] = SCIP_BASESTAT_LOWER; /*lint !e641*/ /**@todo this has to be corrected for lb = -infinity */
2566 for( i = lpistate->nrows; i < nrows; ++i )
2567 lpi->ircnt[i] = SCIP_BASESTAT_BASIC; /*lint !e641*/
2568
2569 /* convert the loaded basis into QSopt_ex format */
2570 SCIPdebugMessage("basis status of SCIP lpistate rows (nrows=%d):\n", lpistate->nrows);
2571 for( i = 0; i < nrows; ++i )
2572 {
2573 SCIPdebugMessage("row_%d: %d (%s)\n", i, lpi->ircnt[i],
2574 lpi->ircnt[i] == SCIP_BASESTAT_LOWER ? "lower" : lpi->ircnt[i] == SCIP_BASESTAT_BASIC ? "basic" : "upper");
2575
2576 switch( lpi->ircnt[i] )
2577 {
2579 irstat[i] = QS_ROW_BSTAT_LOWER;
2580 break;
2582 irstat[i] = QS_ROW_BSTAT_BASIC;
2583 break;
2585 /* sense of inexact LP row is R (ranged row) since this is the only case where the basis status of the
2586 * slack variable is allowed to be UPPER
2587 */
2588 if( lpi->isen[i] == 'R' )
2589 /* sense of LPEX row is R, too */
2590 irstat[i] = QS_ROW_BSTAT_UPPER;
2591 else
2592 /* sense of LPEX row is L, G or E, thus, basis status must be LOWER/BASIC. we use non-basic status LOWER
2593 * instead of non-basic status UPPER for slack variable in LPEX. this might happen when the inexact LP
2594 * is an FP relaxation of the exact LP
2595 */
2596 irstat[i] = QS_ROW_BSTAT_LOWER;
2597 break;
2598 default:
2599 SCIPerrorMessage("Unknown row basic status %d", lpi->ircnt[i]);
2600 SCIPABORT();
2601 break;
2602 }
2603 }
2604 for( i = 0; i < ncols; ++i )
2605 {
2606 switch(lpi->iccnt[i])
2607 {
2609 icstat[i] = QS_COL_BSTAT_LOWER;
2610 break;
2612 icstat[i] = QS_COL_BSTAT_BASIC;
2613 break;
2615 icstat[i] = QS_COL_BSTAT_UPPER;
2616 break;
2617 case SCIP_BASESTAT_ZERO:
2618 icstat[i] = QS_COL_BSTAT_FREE;
2619 break;
2620 default:
2621 SCIPerrorMessage("Unknown column basic status %d", lpi->iccnt[i]);
2622 SCIPABORT();
2623 break;
2624 }
2625 }
2626
2627 /* set the basis */
2628 rval = mpq_QSload_basis_array(lpi->prob, icstat, irstat);
2629 QS_RETURN(rval);
2630}
2631
2632/** frees LPi state information */
2634 SCIP_LPIEXACT* lpi, /**< LP interface structure */
2635 BMS_BLKMEM* blkmem, /**< block memory */
2636 SCIP_LPISTATE** lpistate /**< pointer to LPi state information (like basis information) */
2637 )
2638{
2639 assert(lpi != NULL);
2640 assert(lpistate != NULL);
2641
2642 if( *lpistate != NULL )
2643 lpistateFree(lpistate, blkmem);
2644
2645 return SCIP_OKAY;
2646}
2647
2648/** checks, whether the given LP state contains simplex basis information */
2650 SCIP_LPIEXACT* lpi, /**< LP interface structure */
2651 SCIP_LPISTATE* lpistate /**< LP state information (like basis information) */
2652 )
2653{ /*lint --e{715} */
2654 return (lpistate != NULL);
2655}
2656
2657/** reads LP state (like basis information from a file */
2659 SCIP_LPIEXACT* lpi, /**< LP interface structure */
2660 const char* fname /**< file name */
2661 )
2662{
2663 int rval = 0;
2664
2665 assert(lpi != NULL);
2666 assert(lpi->prob != NULL);
2667
2668 SCIPdebugMessage("reading QSopt_ex LP state from file <%s>\n", fname);
2669
2670 rval = mpq_QSread_and_load_basis(lpi->prob, fname);
2671 if( rval )
2672 {
2673 SCIPerrorMessage("Error while loading basis from file <%s>.\n", fname);
2674 return SCIP_READERROR;
2675 }
2676
2677 return SCIP_OKAY;
2678}
2679
2680/** writes LP state (like basis information) to a file */
2682 SCIP_LPIEXACT* lpi, /**< LP interface structure */
2683 const char* fname /**< file name */
2684 )
2685{
2686 QSbasis* bas = 0;
2687 int rval = 0;
2688
2689 assert(lpi != NULL);
2690 assert(lpi->prob != NULL);
2691
2692 SCIPdebugMessage("writing QSopt_ex LP state to file <%s>\n", fname);
2693
2694 bas = mpq_QSget_basis(lpi->prob);
2695 QS_ERROR(bas == 0, "Could not get basis from problem."); /*lint !e820*/
2696 assert( bas );
2697
2698 rval = mpq_QSwrite_basis(lpi->prob, bas, fname);
2699 mpq_QSfree(bas);
2700 if( rval )
2701 {
2702 SCIPerrorMessage("Could not write basis to file <%s>.\n", fname);
2703 return SCIP_WRITEERROR;
2704 }
2705
2706 return SCIP_OKAY;
2707}
2708
2709#ifdef SCIP_DISABLED_CODE
2710/** checks whether LPi state (i.e. basis information) is dual feasible and returns corresponding dual objective value.
2711 * if wanted it will first directly test the corresponding approximate dual and primal solution
2712 * (corrected via dual variables for bounds and primal variables for slacks if possible) for optimality
2713 * before performing the dual feasibility test on the more expensive exact basic solution.
2714 */
2716 SCIP_LPIEXACT* lpi, /**< LP interface structure */
2717 BMS_BLKMEM* blkmem, /**< block memory */
2718 SCIP_LPISTATE* lpistate, /**< LPi state information (like basis information) */
2719 SCIP_Bool useprestep, /**< should approximate primal and dual solution first */
2720 SCIP_Real* primalsol, /**< approximate primal solution; or NULL to compute by exact LP solver */
2721 SCIP_Real* dualsol, /**< approximate dual solution; or NULL to compute by exact LP solver */
2722 SCIP_Bool* result, /**< pointer to store whether given LPi state is dual feasible */
2723 mpq_t* dualobjval /**< pointer to store dual objective value in case of dual feasibility */
2724 )
2725{ /*lint --e{715} */
2726 int rval = 0;
2727 QSbasis* B;
2728
2729 *result = FALSE;
2730
2731 /* loads LPi state (like basis information) into solver */
2732 SCIP_CALL( SCIPlpiExactSetState(lpi, blkmem, lpistate) );
2733
2734 /* checks whether basis just loaded into the solver is dual feasible */
2735 B = mpq_QSget_basis(lpi->prob);
2736
2737#ifdef VERIFY_OUT
2738 rval = QSexact_verify(lpi->prob, B, (int) useprestep, primalsol, dualsol, (char*) result, dualobjval, 0);
2739#else
2740 rval = QSexact_verify(lpi->prob, B, (int) useprestep, primalsol, dualsol, (char*) result, dualobjval, 1);
2741#endif
2742
2743 if( B )
2744 mpq_QSfree_basis(B);
2745
2746 QS_RETURN(rval);
2747}
2748#endif
2749
2750/**@} */
2751
2752/*
2753 * Parameter Methods
2754 */
2755
2756/**@name Parameter Methods */
2757/**@{ */
2758
2759/** gets integer parameter of LP */
2761 SCIP_LPIEXACT* lpi, /**< LP interface structure */
2762 SCIP_LPPARAM type, /**< parameter number */
2763 int* ival /**< buffer to store the parameter value */
2764 )
2765{
2766 int rval = 0;
2767
2768 assert(lpi != NULL);
2769 assert(lpi->prob != NULL);
2770 assert(ival != NULL);
2771
2772 SCIPdebugMessage("getting int parameter %d\n", type);
2773
2774 switch( type )
2775 {
2777 case SCIP_LPPAR_FASTMIP:
2779 return SCIP_PARAMETERUNKNOWN;
2780 case SCIP_LPPAR_SCALING:
2781 rval = mpq_QSget_param(lpi->prob, QS_PARAM_SIMPLEX_SCALING, ival);
2782 if( *ival )
2783 *ival = TRUE;
2784 else
2785 *ival = FALSE;
2786 break;
2787 case SCIP_LPPAR_PRICING:
2788 *ival = lpi->pricing;
2789 break;
2790 case SCIP_LPPAR_LPINFO:
2791 rval = mpq_QSget_param(lpi->prob, QS_PARAM_SIMPLEX_DISPLAY, ival);
2792 if( *ival )
2793 *ival = TRUE;
2794 else
2795 *ival = FALSE;
2796 break;
2797 case SCIP_LPPAR_LPITLIM:
2798 rval = mpq_QSget_param(lpi->prob, QS_PARAM_SIMPLEX_MAX_ITERATIONS, ival);
2799 break;
2800 default:
2801 return SCIP_PARAMETERUNKNOWN;
2802 } /*lint !e788*/
2803
2804 QS_RETURN(rval);
2805}
2806
2807/** sets integer parameter of LP */
2809 SCIP_LPIEXACT* lpi, /**< LP interface structure */
2810 SCIP_LPPARAM type, /**< parameter number */
2811 int ival /**< parameter value */
2812 )
2813{
2814 int rval = 0;
2815
2816 assert(lpi != NULL);
2817 assert(lpi->prob != NULL);
2818
2819 SCIPdebugMessage("setting int parameter %d to %d\n", type, ival);
2820
2821 switch (type)
2822 {
2823 case SCIP_LPPAR_SCALING:
2824 if( ival == TRUE )
2825 rval = mpq_QSset_param(lpi->prob, QS_PARAM_SIMPLEX_SCALING, 1);
2826 else
2827 rval = mpq_QSset_param(lpi->prob, QS_PARAM_SIMPLEX_SCALING, 0);
2828 break;
2829 case SCIP_LPPAR_PRICING:
2830 lpi->pricing = ival;
2831 switch( ival )
2832 {
2833 case SCIP_PRICING_AUTO:
2835 case SCIP_PRICING_FULL:
2836 case SCIP_PRICING_STEEP:
2838 rval = mpq_QSset_param(lpi->prob, QS_PARAM_PRIMAL_PRICING, QS_PRICE_PSTEEP);
2839 rval += mpq_QSset_param(lpi->prob, QS_PARAM_DUAL_PRICING, QS_PRICE_DSTEEP);
2840 break;
2842 rval = mpq_QSset_param(lpi->prob,QS_PARAM_PRIMAL_PRICING,QS_PRICE_PMULTPARTIAL);
2843 rval += mpq_QSset_param(lpi->prob,QS_PARAM_DUAL_PRICING,QS_PRICE_DMULTPARTIAL);
2844 break;
2845 case SCIP_PRICING_DEVEX:
2846 rval = mpq_QSset_param(lpi->prob,QS_PARAM_PRIMAL_PRICING,QS_PRICE_PDEVEX);
2847 rval += mpq_QSset_param(lpi->prob,QS_PARAM_DUAL_PRICING,QS_PRICE_DDEVEX);
2848 break;
2849 default:
2850 return SCIP_LPERROR;
2851 }
2852 break;
2853 case SCIP_LPPAR_LPINFO:
2854 if( ival == TRUE )
2855 rval = mpq_QSset_param(lpi->prob, QS_PARAM_SIMPLEX_DISPLAY, 1);
2856 else
2857 rval = mpq_QSset_param(lpi->prob, QS_PARAM_SIMPLEX_DISPLAY, 0);
2858 break;
2859 case SCIP_LPPAR_LPITLIM:
2860 rval = mpq_QSset_param(lpi->prob, QS_PARAM_SIMPLEX_MAX_ITERATIONS, ival);
2861 break;
2862 default:
2863 return SCIP_PARAMETERUNKNOWN;
2864 } /*lint !e788*/
2865
2866 QS_RETURN(rval);
2867}
2868
2869/** gets floating point parameter of LP */
2871 SCIP_LPIEXACT* lpi, /**< LP interface structure */
2872 SCIP_LPPARAM type, /**< parameter number */
2873 SCIP_Real* dval /**< buffer to store the parameter value */
2874 )
2875{
2876 int rval = 0;
2877 mpq_t tmpval;
2878 mpq_init(tmpval);
2879
2880 assert(lpi != NULL);
2881 assert(lpi->prob != NULL);
2882 assert(dval != NULL);
2883
2884 SCIPdebugMessage("getting real parameter %d\n", type);
2885
2886 switch( type )
2887 {
2888 case SCIP_LPPAR_OBJLIM:
2889 rval = mpq_QSget_param_EGlpNum(lpi->prob, QS_PARAM_OBJLLIM, &tmpval);
2890 break;
2891 case SCIP_LPPAR_LPTILIM:
2892 rval = mpq_QSget_param_EGlpNum(lpi->prob, QS_PARAM_SIMPLEX_MAX_TIME, &tmpval);
2893 break;
2894 default:
2898 case SCIP_LPPAR_FEASTOL:
2899 return SCIP_PARAMETERUNKNOWN;
2900 } /*lint !e788*/
2901
2902 *dval = mpq_get_d(tmpval);
2903 mpq_clear(tmpval);
2904
2905 QS_RETURN(rval);
2906}
2907
2908/** sets floating point parameter of LP */
2910 SCIP_LPIEXACT* lpi, /**< LP interface structure */
2911 SCIP_LPPARAM type, /**< parameter number */
2912 SCIP_Real dval /**< parameter value */
2913 )
2914{
2915 int rval = 0;
2916 mpq_t tmpval;
2917 mpq_init(tmpval);
2918 mpq_set_d(tmpval, dval);
2919
2920 assert(lpi != NULL);
2921 assert(lpi->prob != NULL);
2922
2923 SCIPdebugMessage("setting real parameter %d to %g\n", type, dval);
2924
2925 switch( type )
2926 {
2927 case SCIP_LPPAR_LPTILIM:
2928 rval = mpq_QSset_param_EGlpNum(lpi->prob, QS_PARAM_SIMPLEX_MAX_TIME, tmpval);
2929 break;
2930 case SCIP_LPPAR_OBJLIM:
2931 rval = mpq_QSset_param_EGlpNum(lpi->prob, QS_PARAM_OBJLLIM, tmpval);
2932 break;
2933 case SCIP_LPPAR_FEASTOL:
2937 default:
2938 return SCIP_PARAMETERUNKNOWN;
2939 } /*lint !e788*/
2940
2941 mpq_clear(tmpval);
2942
2943 QS_RETURN(rval);
2944}
2945
2946/**@} */
2947
2948/*
2949 * Numerical Methods
2950 */
2951
2952/**@name Numerical Methods */
2953/**@{ */
2954
2955/** returns value treated as positive infinity in the LP solver */
2957 SCIP_LPIEXACT* lpi, /**< LP interface structure */
2958 SCIP_RATIONAL* infval /**< pointer to store positive infinity value of LP solver */
2959 )
2960{
2961 assert(infval != NULL);
2962
2963 SCIPrationalSetGMP(infval, mpq_ILL_MAXDOUBLE);
2964}
2965
2966/** checks if given value is treated as positive infinity in the LP solver */
2968 SCIP_LPIEXACT* lpi, /**< LP interface structure */
2969 SCIP_RATIONAL* val /**< given value */
2970 )
2971{ /*lint --e{715} */
2972 return (mpq_cmp(*SCIPrationalGetGMP(val), mpq_ILL_MAXDOUBLE) >= 0);
2973}
2974
2975/** returns value treated as negative infinity in the LP solver */
2977 SCIP_LPIEXACT* lpi, /**< LP interface structure */
2978 SCIP_RATIONAL* infval /**< pointer to store negative infinity value of LP solver */
2979 )
2980{ /*lint --e{715} */
2981 assert(infval != NULL);
2982
2983 SCIPrationalSetGMP(infval, mpq_ILL_MINDOUBLE);
2984}
2985
2986/** checks if given value is treated as negative infinity in the LP solver */
2988 SCIP_LPIEXACT* lpi, /**< LP interface structure */
2989 SCIP_RATIONAL* val /**< given value */
2990 )
2991{ /*lint --e{715} */
2992 return (mpq_cmp(*SCIPrationalGetGMP(val), mpq_ILL_MINDOUBLE) <= 0);
2993}
2994
2995/** returns value treated as negative infinity in the LP solver */
2997 SCIP_LPIEXACT* lpi /**< LP interface structure */
2998 )
2999{ /*lint --e{715} */
3000 assert(lpi != NULL);
3001
3002 return mpq_get_d(mpq_ILL_MAXDOUBLE);
3003}
3004
3005/** checks if given value is treated as negative infinity in the LP solver */
3007 SCIP_LPIEXACT* lpi, /**< LP interface structure */
3008 SCIP_Real val /**< given value */
3009 )
3010{ /*lint --e{715} */
3011 return val >= mpq_get_d(mpq_ILL_MAXDOUBLE);
3012}
3013
3014/**@} */
3015
3016/*
3017 * File Interface Methods
3018 */
3019
3020/**@name File Interface Methods */
3021/**@{ */
3022
3023/** reads LP from a file */
3025 SCIP_LPIEXACT* lpi, /**< LP interface structure */
3026 const char* fname /**< file name */
3027 )
3028{
3029 int j;
3030
3031 assert(lpi != NULL);
3032 assert(lpi->prob != NULL);
3033
3034 SCIPdebugMessage("reading LP from file <%s>\n", fname);
3035
3036 if( lpi->prob )
3037 mpq_QSfree_prob(lpi->prob);
3038
3039 lpi->solstat = 0;
3040 lpi->previt = 0;
3041
3042 /* try to extract file type */
3043 j = strlen(fname)-1;
3044 while( j >= 0 && fname[j] != '.' )
3045 --j;
3046 if( fname[j] == '.' )
3047 ++j;
3048
3049 /* load problem */
3050 lpi->prob = mpq_QSread_prob(fname, &(fname[j]));
3051 if( lpi->prob == 0 )
3052 return SCIP_READERROR;
3053
3054 return SCIP_OKAY;
3055}
3056
3057/** writes LP to a file */
3059 SCIP_LPIEXACT* lpi, /**< LP interface structure */
3060 const char* fname /**< file name */
3061 )
3062{
3063 int j;
3064
3065 assert(lpi != NULL);
3066 assert(lpi->prob != NULL);
3067
3068 SCIPdebugMessage("writing LP to file <%s>\n", fname);
3069
3070 /* try to extract file type */
3071 j = strlen(fname) - 1;
3072 while( j >= 0 && fname[j] != '.' )
3073 --j;
3074 if( fname[j] == '.' )
3075 ++j;
3076
3077 /* write problem */
3078 if( mpq_QSwrite_prob(lpi->prob, fname, &(fname[j])) )
3079 return SCIP_WRITEERROR;
3080
3081 return SCIP_OKAY;
3082}
3083
3084/** prints additional lpiex internal info */
3086 SCIP_LPIEXACT* lpi /**< pointer to an LP interface structure */
3087 )
3088{
3089 mpq_lpinfo* lp;
3090 lp = lpi->prob->lp;
3091 SCIPerrorMessage("solstat= %d\n (solstat values: QS_LP_OPTIMAL=1, QS_LP_INFEASIBLE=2, QS_LP_UNBOUNDED=3, QS_LP_ITER_LIMIT=4, QS_LP_TIME_LIMIT=5, QS_LP_UNSOLVED=6, QS_LP_ABORTED=7, QS_LP_NUMERR=8, QS_LP_OBJ_LIMIT=9, QS_MODIFIED=100)\n", lpi->solstat );
3092 SCIPerrorMessage("probstat.optimal= %d\n", lp->probstat.optimal );
3093 SCIPerrorMessage("probstat.primal_feasible= %d\n", lp->probstat.primal_feasible );
3094 SCIPerrorMessage("probstat.primal_infeasible= %d\n", lp->probstat.primal_infeasible );
3095 SCIPerrorMessage("probstat.primal_unbounded= %d\n", lp->probstat.primal_unbounded );
3096 SCIPerrorMessage("probstat.dual_feasible= %d\n", lp->probstat.dual_feasible );
3097 SCIPerrorMessage("probstat.dual_infeasible= %d\n", lp->probstat.dual_infeasible );
3098 SCIPerrorMessage("probstat.dual_unbounded= %d\n", lp->probstat.dual_unbounded );
3099 SCIPerrorMessage("basisstat.primal_feasible= %d\n", lp->basisstat.primal_feasible );
3100 SCIPerrorMessage("basisstat.primal_infeasible= %d\n", lp->basisstat.primal_infeasible );
3101 SCIPerrorMessage("basisstat.dual_feasible= %d\n", lp->basisstat.dual_feasible );
3102 SCIPerrorMessage("basisstat.dual_infeasible= %d\n", lp->basisstat.dual_infeasible );
3103}
3104/**@} */
3105#endif
void SCIPdecodeDualBit(const SCIP_DUALPACKET *inp, int *out, int count)
Definition bitencode.c:308
void SCIPencodeDualBit(const int *inp, SCIP_DUALPACKET *out, int count)
Definition bitencode.c:238
packing single and dual bit values
unsigned int SCIP_DUALPACKET
Definition bitencode.h:42
common defines and data types used in all packages of SCIP
#define NULL
Definition def.h:255
#define SCIP_MAXSTRLEN
Definition def.h:276
#define SCIP_Bool
Definition def.h:98
#define SCIP_ALLOC(x)
Definition def.h:373
#define SCIP_Real
Definition def.h:163
#define TRUE
Definition def.h:100
#define FALSE
Definition def.h:101
#define SCIPABORT()
Definition def.h:334
#define SCIP_CALL(x)
Definition def.h:362
void * SCIPlpiExactGetSolverPointer(SCIP_LPIEXACT *lpi)
SCIP_Bool SCIPlpiExactHasDualRay(SCIP_LPIEXACT *lpi)
SCIP_RETCODE SCIPlpiExactSetRealpar(SCIP_LPIEXACT *lpi, SCIP_LPPARAM type, SCIP_Real dval)
SCIP_RETCODE SCIPlpiExactSetBase(SCIP_LPIEXACT *lpi, int *cstat, int *rstat)
SCIP_RETCODE SCIPlpiExactReadState(SCIP_LPIEXACT *lpi, const char *fname)
SCIP_Bool SCIPlpiExactHasStateBasis(SCIP_LPIEXACT *lpi, SCIP_LPISTATE *lpistate)
SCIP_RETCODE SCIPlpiExactGetObj(SCIP_LPIEXACT *lpi, int firstcol, int lastcol, SCIP_RATIONAL **vals)
SCIP_RETCODE SCIPlpiExactIgnoreInstability(SCIP_LPIEXACT *lpi, SCIP_Bool *success)
SCIP_RETCODE SCIPlpiExactGetObjval(SCIP_LPIEXACT *lpi, SCIP_RATIONAL *objval)
void SCIPlpiExactEnd(void)
SCIP_RETCODE SCIPlpiExactScaleRow(SCIP_LPIEXACT *lpi, int row, SCIP_RATIONAL *scaleval)
const char * SCIPlpiExactGetExternalCodeDesc(void)
SCIP_Bool SCIPlpiExactIsPosInfinity(SCIP_LPIEXACT *lpi, SCIP_RATIONAL *val)
SCIP_Bool SCIPlpiExactIsDualUnbounded(SCIP_LPIEXACT *lpi)
void SCIPlpiExactPrintInfo(SCIP_LPIEXACT *lpi)
SCIP_RETCODE SCIPlpiExactWriteLP(SCIP_LPIEXACT *lpi, const char *fname)
SCIP_Bool SCIPlpiExactHasPrimalRay(SCIP_LPIEXACT *lpi)
SCIP_Bool SCIPlpiExactExistsDualRay(SCIP_LPIEXACT *lpi)
SCIP_Bool SCIPlpiExactIsStable(SCIP_LPIEXACT *lpi)
SCIP_RETCODE SCIPlpiExactGetDualfarkas(SCIP_LPIEXACT *lpi, SCIP_RATIONAL **dualfarkas)
SCIP_RETCODE SCIPlpiExactSolveDual(SCIP_LPIEXACT *lpi)
const char * SCIPlpiExactGetSolverDesc(void)
SCIP_RETCODE SCIPlpiExactChgObjsen(SCIP_LPIEXACT *lpi, SCIP_OBJSEN objsen)
SCIP_RETCODE SCIPlpiExactSetIntpar(SCIP_LPIEXACT *lpi, SCIP_LPPARAM type, int ival)
SCIP_RETCODE SCIPlpiExactWriteState(SCIP_LPIEXACT *lpi, const char *fname)
SCIP_RETCODE SCIPlpiExactScaleCol(SCIP_LPIEXACT *lpi, int col, SCIP_RATIONAL *scaleval)
SCIP_RETCODE SCIPlpiExactChgCoef(SCIP_LPIEXACT *lpi, int row, int col, SCIP_RATIONAL *newval)
SCIP_Bool SCIPlpiExactWasSolved(SCIP_LPIEXACT *lpi)
SCIP_Bool SCIPlpiExactIsPrimalUnbounded(SCIP_LPIEXACT *lpi)
SCIP_RETCODE SCIPlpiExactGetSides(SCIP_LPIEXACT *lpi, int firstrow, int lastrow, SCIP_RATIONAL **lhss, SCIP_RATIONAL **rhss)
const char * SCIPlpiExactGetSolverName(void)
SCIP_RETCODE SCIPlpiExactGetCols(SCIP_LPIEXACT *lpi, int firstcol, int lastcol, SCIP_RATIONAL **lb, SCIP_RATIONAL **ub, int *nnonz, int *beg, int *ind, SCIP_RATIONAL **val)
SCIP_Bool SCIPlpiExactIsPrimalInfeasible(SCIP_LPIEXACT *lpi)
SCIP_Real SCIPlpiExactInfinity(SCIP_LPIEXACT *lpi)
SCIP_RETCODE SCIPlpiExactGetRows(SCIP_LPIEXACT *lpi, int firstrow, int lastrow, SCIP_RATIONAL **lhs, SCIP_RATIONAL **rhs, int *nnonz, int *beg, int *ind, SCIP_RATIONAL **val)
SCIP_RETCODE SCIPlpiExactGetSolFeasibility(SCIP_LPIEXACT *lpi, SCIP_Bool *primalfeasible, SCIP_Bool *dualfeasible)
SCIP_Bool SCIPlpiExactExistsPrimalRay(SCIP_LPIEXACT *lpi)
SCIP_Bool SCIPlpiExactIsInfinity(SCIP_LPIEXACT *lpi, SCIP_Real val)
SCIP_RETCODE SCIPlpiExactAddRows(SCIP_LPIEXACT *lpi, int nrows, SCIP_RATIONAL **lhs, SCIP_RATIONAL **rhs, char **rownames, int nnonz, int *beg, int *ind, SCIP_RATIONAL **val)
SCIP_RETCODE SCIPlpiExactCreate(SCIP_LPIEXACT **lpi, SCIP_MESSAGEHDLR *messagehdlr, const char *name, SCIP_OBJSEN objsen)
SCIP_Bool SCIPlpiExactIsIterlimExc(SCIP_LPIEXACT *lpi)
SCIP_RETCODE SCIPlpiExactLoadColLP(SCIP_LPIEXACT *lpi, SCIP_OBJSEN objsen, int ncols, SCIP_RATIONAL **obj, SCIP_RATIONAL **lb, SCIP_RATIONAL **ub, char **colnames, int nrows, SCIP_RATIONAL **lhs, SCIP_RATIONAL **rhs, char **rownames, int nnonz, int *beg, int *ind, SCIP_RATIONAL **val)
SCIP_Bool SCIPlpiExactIsPrimalFeasible(SCIP_LPIEXACT *lpi)
SCIP_Bool SCIPlpiExactIsNegInfinity(SCIP_LPIEXACT *lpi, SCIP_RATIONAL *val)
SCIP_Bool SCIPlpiExactIsDualFeasible(SCIP_LPIEXACT *lpi)
SCIP_RETCODE SCIPlpiExactReadLP(SCIP_LPIEXACT *lpi, const char *fname)
SCIP_RETCODE SCIPlpiExactGetBasisInd(SCIP_LPIEXACT *lpi, int *bind)
SCIP_Bool SCIPlpiExactIsOptimal(SCIP_LPIEXACT *lpi)
SCIP_RETCODE SCIPlpiExactAddCols(SCIP_LPIEXACT *lpi, int ncols, SCIP_RATIONAL **obj, SCIP_RATIONAL **lb, SCIP_RATIONAL **ub, char **colnames, int nnonz, int *beg, int *ind, SCIP_RATIONAL **val)
void SCIPlpiExactStart(void)
SCIP_RETCODE SCIPlpiExactGetBase(SCIP_LPIEXACT *lpi, int *cstat, int *rstat)
SCIP_RETCODE SCIPlpiExactDelColset(SCIP_LPIEXACT *lpi, int *dstat)
SCIP_RETCODE SCIPlpiExactDelCols(SCIP_LPIEXACT *lpi, int firstcol, int lastcol)
SCIP_RETCODE SCIPlpiExactChgObj(SCIP_LPIEXACT *lpi, int ncols, int *ind, SCIP_RATIONAL **obj)
SCIP_RETCODE SCIPlpiExactGetPrimalRay(SCIP_LPIEXACT *lpi, SCIP_RATIONAL **ray)
SCIP_RETCODE SCIPlpiExactGetBounds(SCIP_LPIEXACT *lpi, int firstcol, int lastcol, SCIP_RATIONAL **lbs, SCIP_RATIONAL **ubs)
int SCIPlpiExactGetInternalStatus(SCIP_LPIEXACT *lpi)
const char * SCIPlpiExactGetExternalCodeName(void)
void SCIPlpiExactPosInfinity(SCIP_LPIEXACT *lpi, SCIP_RATIONAL *infval)
SCIP_RETCODE SCIPlpiExactGetCoef(SCIP_LPIEXACT *lpi, int row, int col, SCIP_RATIONAL *val)
SCIP_RETCODE SCIPlpiExactClear(SCIP_LPIEXACT *lpi)
SCIP_RETCODE SCIPlpiExactGetNNonz(SCIP_LPIEXACT *lpi, int *nnonz)
SCIP_RETCODE SCIPlpiExactFree(SCIP_LPIEXACT **lpi)
SCIP_Bool SCIPlpiExactIsDualInfeasible(SCIP_LPIEXACT *lpi)
SCIP_Bool SCIPlpiExactIsObjlimExc(SCIP_LPIEXACT *lpi)
SCIP_RETCODE SCIPlpiExactGetNCols(SCIP_LPIEXACT *lpi, int *ncols)
SCIP_RETCODE SCIPlpiExactSolveBarrier(SCIP_LPIEXACT *lpi, SCIP_Bool crossover)
void SCIPlpiExactNegInfinity(SCIP_LPIEXACT *lpi, SCIP_RATIONAL *infval)
SCIP_RETCODE SCIPlpiExactChgSides(SCIP_LPIEXACT *lpi, int nrows, int *ind, SCIP_RATIONAL **lhs, SCIP_RATIONAL **rhs)
SCIP_RETCODE SCIPlpiExactGetState(SCIP_LPIEXACT *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
SCIP_RETCODE SCIPlpiExactDelRows(SCIP_LPIEXACT *lpi, int firstrow, int lastrow)
SCIP_RETCODE SCIPlpiExactGetNRows(SCIP_LPIEXACT *lpi, int *nrows)
SCIP_Bool SCIPlpiExactIsTimelimExc(SCIP_LPIEXACT *lpi)
SCIP_RETCODE SCIPlpiExactGetRealpar(SCIP_LPIEXACT *lpi, SCIP_LPPARAM type, SCIP_Real *dval)
SCIP_RETCODE SCIPlpiExactChgBounds(SCIP_LPIEXACT *lpi, int ncols, int *ind, SCIP_RATIONAL **lb, SCIP_RATIONAL **ub)
SCIP_RETCODE SCIPlpiExactStateDualFeasible(SCIP_LPIEXACT *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE *lpistate, SCIP_Bool useprestep, SCIP_Real *primalsol, SCIP_Real *dualsol, SCIP_Bool *result, SCIP_RATIONAL **dualobjval)
SCIP_RETCODE SCIPlpiExactFreeState(SCIP_LPIEXACT *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE **lpistate)
SCIP_RETCODE SCIPlpiExactDelRowset(SCIP_LPIEXACT *lpi, int *dstat)
SCIP_RETCODE SCIPlpiExactGetSol(SCIP_LPIEXACT *lpi, SCIP_RATIONAL *objval, SCIP_RATIONAL **primsol, SCIP_RATIONAL **dualsol, SCIP_RATIONAL **activity, SCIP_RATIONAL **redcost)
SCIP_RETCODE SCIPlpiExactSolvePrimal(SCIP_LPIEXACT *lpi)
SCIP_RETCODE SCIPlpiExactGetIntpar(SCIP_LPIEXACT *lpi, SCIP_LPPARAM type, int *ival)
SCIP_RETCODE SCIPlpiExactSetState(SCIP_LPIEXACT *lpi, BMS_BLKMEM *blkmem, SCIP_LPISTATE *lpistate)
SCIP_RETCODE SCIPlpiExactGetIterations(SCIP_LPIEXACT *lpi, int *iterations)
void SCIPrationalAdd(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
Definition rational.cpp:936
SCIP_Real SCIPrationalGetReal(SCIP_RATIONAL *rational)
void SCIPrationalResetFloatingPointRepresentable(SCIP_RATIONAL *rat)
Definition rational.cpp:643
#define SCIPrationalDebugMessage
Definition rational.h:641
void SCIPrationalCheckInfByValue(SCIP_RATIONAL *rational)
Definition rational.cpp:553
int SCIPrationalGetSign(const SCIP_RATIONAL *rational)
SCIP_Bool SCIPrationalIsEQ(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
return SCIP_OKAY
SCIP_Real objval
SCIP_Real obj
assert(minobj< SCIPgetCutoffbound(scip))
SCIP_Real primsol
static void lpistatePack(SCIP_LPISTATE *lpistate, const int *cstat, const int *rstat)
Definition lpi_clp.cpp:218
static void lpistateUnpack(const SCIP_LPISTATE *lpistate, int *cstat, int *rstat)
Definition lpi_clp.cpp:234
static int rowpacketNum(int nrows)
Definition lpi_clp.cpp:209
SCIP_DUALPACKET ROWPACKET
Definition lpi_clp.cpp:128
#define COLS_PER_PACKET
Definition lpi_clp.cpp:127
static void lpistateFree(SCIP_LPISTATE **lpistate, BMS_BLKMEM *blkmem)
Definition lpi_clp.cpp:271
SCIP_DUALPACKET COLPACKET
Definition lpi_clp.cpp:126
static int colpacketNum(int ncols)
Definition lpi_clp.cpp:200
static SCIP_RETCODE lpistateCreate(SCIP_LPISTATE **lpistate, BMS_BLKMEM *blkmem, int ncols, int nrows)
Definition lpi_clp.cpp:250
#define ROWS_PER_PACKET
Definition lpi_clp.cpp:129
static void convertSides(SCIP_LPI *lpi, int nrows, const SCIP_Real *lhs, const SCIP_Real *rhs, int indoffset, int *rngcount)
Definition lpi_cpx.c:740
static SCIP_RETCODE ensureTabMem(SCIP_LPI *const lpi, int sz)
Definition lpi_qso.c:253
#define QS_TESTG(A, B, C)
Definition lpi_qso.c:109
#define QS_CONDRET(A)
Definition lpi_qso.c:134
static SCIP_RETCODE ensureRowMem(SCIP_LPI *const lpi, int nrows)
Definition lpi_qso.c:287
#define QS_RETURN(A)
Definition lpi_qso.c:124
static SCIP_RETCODE ensureColMem(SCIP_LPI *const lpi, int ncols)
Definition lpi_qso.c:270
#define QS_ERROR(A,...)
Definition lpi_qso.c:116
interface methods for specific exact LP solvers
#define BMSfreeMemory(ptr)
Definition memory.h:145
#define BMSfreeBlockMemory(mem, ptr)
Definition memory.h:465
#define BMSallocBlockMemory(mem, ptr)
Definition memory.h:451
#define BMSreallocMemoryArray(ptr, num)
Definition memory.h:127
#define BMSallocMemoryArray(ptr, num)
Definition memory.h:123
#define BMSfreeMemoryArray(ptr)
Definition memory.h:147
#define BMSallocBlockMemoryArray(mem, ptr, num)
Definition memory.h:454
#define BMSfreeBlockMemoryArray(mem, ptr, num)
Definition memory.h:467
struct BMS_BlkMem BMS_BLKMEM
Definition memory.h:437
#define BMSallocMemory(ptr)
Definition memory.h:118
public methods for message output
#define SCIPerrorMessage
Definition pub_message.h:64
#define SCIPdebugMessage
Definition pub_message.h:96
#define SCIPdebugPrintf
Definition pub_message.h:99
wrapper for rational number arithmetic that interacts with GMP
public methods for memory management
SCIP_PRICING pricing
COLPACKET * packcstat
Definition lpi_clp.cpp:136
ROWPACKET * packrstat
Definition lpi_clp.cpp:137
@ SCIP_PRICING_STEEPQSTART
Definition type_lpi.h:83
@ SCIP_PRICING_AUTO
Definition type_lpi.h:79
@ SCIP_PRICING_DEVEX
Definition type_lpi.h:84
@ SCIP_PRICING_STEEP
Definition type_lpi.h:82
@ SCIP_PRICING_FULL
Definition type_lpi.h:80
@ SCIP_PRICING_LPIDEFAULT
Definition type_lpi.h:78
@ SCIP_PRICING_PARTIAL
Definition type_lpi.h:81
enum SCIP_LPParam SCIP_LPPARAM
Definition type_lpi.h:73
struct SCIP_LPiState SCIP_LPISTATE
Definition type_lpi.h:107
@ SCIP_LPPAR_PRICING
Definition type_lpi.h:54
@ SCIP_LPPAR_LPINFO
Definition type_lpi.h:55
@ SCIP_LPPAR_SCALING
Definition type_lpi.h:52
@ SCIP_LPPAR_LPTILIM
Definition type_lpi.h:61
@ SCIP_LPPAR_BARRIERCONVTOL
Definition type_lpi.h:58
@ SCIP_LPPAR_PRESOLVING
Definition type_lpi.h:53
@ SCIP_LPPAR_FASTMIP
Definition type_lpi.h:51
@ SCIP_LPPAR_DUALFEASTOL
Definition type_lpi.h:57
@ SCIP_LPPAR_FROMSCRATCH
Definition type_lpi.h:50
@ SCIP_LPPAR_MARKOWITZ
Definition type_lpi.h:62
@ SCIP_LPPAR_FEASTOL
Definition type_lpi.h:56
@ SCIP_LPPAR_LPITLIM
Definition type_lpi.h:60
@ SCIP_LPPAR_OBJLIM
Definition type_lpi.h:59
@ SCIP_BASESTAT_BASIC
Definition type_lpi.h:92
@ SCIP_BASESTAT_UPPER
Definition type_lpi.h:93
@ SCIP_BASESTAT_LOWER
Definition type_lpi.h:91
@ SCIP_BASESTAT_ZERO
Definition type_lpi.h:94
@ SCIP_OBJSEN_MAXIMIZE
Definition type_lpi.h:42
enum SCIP_ObjSen SCIP_OBJSEN
Definition type_lpi.h:45
type definitions for specific exact LP solvers interface
struct SCIP_LPiExact SCIP_LPIEXACT
struct SCIP_Messagehdlr SCIP_MESSAGEHDLR
struct SCIP_Rational SCIP_RATIONAL
@ SCIP_LPERROR
@ SCIP_READERROR
@ SCIP_PARAMETERUNKNOWN
@ SCIP_WRITEERROR
@ SCIP_ERROR
enum SCIP_Retcode SCIP_RETCODE