Scippy

SCIP

Solving Constraint Integer Programs

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