Scippy

SCIP

Solving Constraint Integer Programs

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