Scippy

SoPlex

Sequential object-oriented simPlex

spxlpbase.h
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the class library */
4/* SoPlex --- the Sequential object-oriented simPlex. */
5/* */
6/* Copyright (c) 1996-2024 Zuse Institute Berlin (ZIB) */
7/* */
8/* Licensed under the Apache License, Version 2.0 (the "License"); */
9/* you may not use this file except in compliance with the License. */
10/* You may obtain a copy of the License at */
11/* */
12/* http://www.apache.org/licenses/LICENSE-2.0 */
13/* */
14/* Unless required by applicable law or agreed to in writing, software */
15/* distributed under the License is distributed on an "AS IS" BASIS, */
16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17/* See the License for the specific language governing permissions and */
18/* limitations under the License. */
19/* */
20/* You should have received a copy of the Apache-2.0 license */
21/* along with SoPlex; see the file LICENSE. If not email to soplex@zib.de. */
22/* */
23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24
25/**@file spxlpbase.h
26 * @brief Saving LPs in a form suitable for SoPlex.
27 */
28#ifndef _SPXLPBASE_H_
29#define _SPXLPBASE_H_
30
31/* undefine SOPLEX_DEBUG flag from including files; if SOPLEX_DEBUG should be defined in this file, do so below */
32#ifdef SOPLEX_DEBUG
33#define SOPLEX_DEBUG_SPXLPBASE
34#undef SOPLEX_DEBUG
35#endif
36
37#include <assert.h>
38#include <iostream>
39#include <iomanip>
40#include <typeinfo>
41
42#include "soplex/spxdefines.h"
43#include "soplex/basevectors.h"
44#include "soplex/dataarray.h"
45#include "soplex/datakey.h"
46#include "soplex/spxid.h"
47#include "soplex/lprowbase.h"
48#include "soplex/lpcolbase.h"
49#include "soplex/lprowsetbase.h"
50#include "soplex/lpcolsetbase.h"
51#include "soplex/nameset.h"
52#include "soplex/didxset.h"
53#include "soplex/spxfileio.h"
54#include "soplex/spxscaler.h"
55#include "soplex/rational.h"
56
57namespace soplex
58{
59// Declarations to fix errors of the form "SPxMainSM is not a type"
60template <class R>
61class SPxSolverBase;
62template <class R>
63class SPxMainSM;
64template <class R>
65class SPxLPBase;
66template <class R>
67class SPxBasisBase;
68
69template <class R>
70class SPxEquiliSC;
71template <class R>
72class SPxLeastSqSC;
73template <class R>
74class SPxGeometSC;
75template <class R>
76class SPxMainSM;
77
78
79/**@brief Saving LPs in a form suitable for SoPlex.
80 * @ingroup Algo
81 *
82 * Class SPxLPBase provides the data structures required for saving a linear program in the form
83 * \f[
84 * \begin{array}{rl}
85 * \hbox{max} & c^T x \\
86 * \hbox{s.t.} & l_r \le Ax \le u_r \\
87 * & l_c \le x \le u_c
88 * \end{array}
89 * \f]
90 * suitable for solving with SoPlex. This includes:
91 * - SVSetBase%s for both columns and rows
92 * - objective Vector
93 * - upper and lower bound Vectors for variables (\f$l_c\f$ and \f$u_c\f$)
94 * - upper and lower bound Vectors for inequalities (\f$l_r\f$ and \f$u_r\f$)
95 *
96 * Note, that the optimization sense is not saved directly. Instead, the objective function are multiplied by -1 to
97 * transform the LP to our standard form maximizing the objective function. However, the sense of the loaded LP can be
98 * retrieved with method #spxSense().
99 *
100 * Further, equality constraints are modeled by \f$l_r = u_r\f$. Analogously, fixed variables have \f$l_c = u_c\f$.
101 *
102 * #SPxLPBase%s are saved as an SVSet, both for columns and rows. Note that this is redundant but eases the access.
103 */
104
105
106template <class R>
107class SPxLPBase : protected LPRowSetBase<R>, protected LPColSetBase<R>
108{
109 template <class S> friend class SPxLPBase;
116
117public:
118
119 // ------------------------------------------------------------------------------------------------------------------
120 /**@name Types */
121 ///@{
122
123 /// Optimization sense.
125 {
127 MINIMIZE = -1
128 };
129
130 ///@}
131
132private:
133
134 // ------------------------------------------------------------------------------------------------------------------
135 /**@name Data */
136 ///@{
137
138 SPxSense thesense; ///< optimization sense.
139 R offset; ///< offset computed, e.g., in simplification step
140 bool _isScaled; ///< true, if scaling has been performed
142 lp_scaler; ///< points to the scaler if the lp has been scaled, to nullptr otherwise
143
144 ///@}
145
146public:
147
148 // message handler
150
151public:
152
153 void setOutstream(SPxOut& newOutstream)
154 {
155 spxout = &newOutstream;
156 }
157
158 // ------------------------------------------------------------------------------------------------------------------
159
160 /// unscales the lp and clears basis
161 void unscaleLP();
162
163 /**@name Inquiry */
164 ///@{
165
166 /// returns current tolerances
167 const std::shared_ptr<Tolerances> tolerances() const
168 {
169 return _tolerances;
170 }
171
172 /// set tolerances
173 virtual void setTolerances(std::shared_ptr<Tolerances> tolerances)
174 {
175 this->_tolerances = tolerances;
176 }
177
178 /// Returns true if and only if the LP is scaled
179 bool isScaled() const
180 {
181 return _isScaled;
182 }
183
184 /// set whether the LP is scaled or not
185 void setScalingInfo(bool scaled)
186 {
187 _isScaled = scaled;
188 }
189
190 /// Returns number of rows in LP.
191 int nRows() const
192 {
193 return LPRowSetBase<R>::num();
194 }
195
196 /// Returns number of columns in LP.
197 int nCols() const
198 {
199 return LPColSetBase<R>::num();
200 }
201
202 /// Returns number of nonzeros in LP.
203 int nNzos() const
204 {
205
206 int n = 0;
207
208 for(int i = 0; i < nCols(); ++i)
209 n += colVector(i).size();
210
211 return n;
212 }
213
214 /// Absolute smallest non-zero element in (possibly scaled) LP.
215 virtual R minAbsNzo(bool unscaled = true) const;
216
217 /// Absolute biggest non-zero element in (in rational case possibly scaled) LP.
218 virtual R maxAbsNzo(bool unscaled = true) const;
219
220 /// Gets \p i 'th row.
221 void getRow(int i, LPRowBase<R>& row) const
222 {
223 row.setLhs(lhs(i));
224 row.setRhs(rhs(i));
225 row.setObj(rowObj(i));
227 }
228
229 /// Gets row with identifier \p id.
230 void getRow(const SPxRowId& id, LPRowBase<R>& row) const
231 {
232 getRow(number(id), row);
233 }
234
235 /// Gets rows \p start, ... \p end.
236 void getRows(int start, int end, LPRowSetBase<R>& set) const
237 {
238 set.clear();
239
240 for(int i = start; i <= end; i++)
241 set.add(lhs(i), rowVector(i), rhs(i), rowObj(i));
242 }
243
244 /// Gets row vector of row \p i.
245 const SVectorBase<R>& rowVector(int i) const
246 {
248 }
249
250 /// Gets row vector of row with identifier \p id.
251 const SVectorBase<R>& rowVector(const SPxRowId& id) const
252 {
254 }
255
256 /// Gets unscaled row vector of row \p i.
257 void getRowVectorUnscaled(int i, DSVectorBase<R>& vec) const;
258
259 /// Returns right hand side vector.
260 const VectorBase<R>& rhs() const
261 {
262 return LPRowSetBase<R>::rhs();
263 }
264
265 /// Returns right hand side of row number \p i.
266 const R& rhs(int i) const
267 {
268 return LPRowSetBase<R>::rhs(i);
269 }
270
271
272 /// Returns right hand side of row with identifier \p id.
273 const R& rhs(const SPxRowId& id) const
274 {
275 return LPRowSetBase<R>::rhs(id);
276 }
277
278 /// Gets (internal and possibly scaled) right hand side vector.
279 void getRhs(VectorBase<R>& vec) const
280 {
281 vec = LPRowSetBase<R>::rhs();
282 }
283
284 /// Gets unscaled right hand side vector.
286
287 /// Returns unscaled right hand side of row number \p i.
288 R rhsUnscaled(int i) const;
289
290 /// Returns unscaled right hand side of row with identifier \p id.
291 R rhsUnscaled(const SPxRowId& id) const;
292
293 /// Returns left hand side vector.
294 const VectorBase<R>& lhs() const
295 {
296 return LPRowSetBase<R>::lhs();
297 }
298
299 /// Returns left hand side of row number \p i.
300 const R& lhs(int i) const
301 {
302 return LPRowSetBase<R>::lhs(i);
303 }
304
305 /// Returns left hand side of row with identifier \p id.
306 const R& lhs(const SPxRowId& id) const
307 {
308 return LPRowSetBase<R>::lhs(id);
309 }
310
311 /// Gets row objective function vector.
312 void getRowObj(VectorBase<R>& prowobj) const
313 {
314 prowobj = LPRowSetBase<R>::obj();
315
316 if(spxSense() == MINIMIZE)
317 prowobj *= -1.0;
318 }
319
320 ///
321 R rowObj(int i) const
322 {
323 if(spxSense() == MINIMIZE)
324 return -maxRowObj(i);
325 else
326 return maxRowObj(i);
327 }
328
329 /// Returns row objective function value of row with identifier \p id.
330 R rowObj(const SPxRowId& id) const
331 {
332 if(spxSense() == MINIMIZE)
333 return -maxRowObj(id);
334 else
335 return maxRowObj(id);
336 }
337
338 ///
340 {
341 return LPRowSetBase<R>::obj();
342 }
343
344 ///
345 const R& maxRowObj(int i) const
346 {
347 return LPRowSetBase<R>::obj(i);
348 }
349
350 /// Returns row objective function value of row with identifier \p id.
351 const R& maxRowObj(const SPxRowId& id) const
352 {
353 return LPRowSetBase<R>::obj(id);
354 }
355
356 /// Returns unscaled left hand side vector.
358
359 /// Returns unscaled left hand side of row number \p i.
360 R lhsUnscaled(int i) const;
361
362 /// Returns left hand side of row with identifier \p id.
363 R lhsUnscaled(const SPxRowId& id) const;
364
365 /// Returns the inequality type of the \p i'th LPRow.
366 typename LPRowBase<R>::Type rowType(int i) const
367 {
368 return LPRowSetBase<R>::type(i);
369 }
370
371 /// Returns the inequality type of the row with identifier \p key.
372 typename LPRowBase<R>::Type rowType(const SPxRowId& id) const
373 {
374 return LPRowSetBase<R>::type(id);
375 }
376
377 /// Gets \p i 'th column.
378 void getCol(int i, LPColBase<R>& col) const
379 {
380 col.setUpper(upper(i));
381 col.setLower(lower(i));
382 col.setObj(obj(i));
383 col.setColVector(colVector(i));
384 }
385
386 /// Gets column with identifier \p id.
387 void getCol(const SPxColId& id, LPColBase<R>& col) const
388 {
389 getCol(number(id), col);
390 }
391
392 /// Gets columns \p start, ..., \p end.
393 void getCols(int start, int end, LPColSetBase<R>& set) const
394 {
395 if(_isScaled)
396 {
397 LPColBase<R> lpcol;
398
399 for(int i = start; i <= end; i++)
400 {
401 getCol(i, lpcol);
402 set.add(lpcol);
403 }
404
405 }
406 else
407 {
408 set.clear();
409
410 for(int i = start; i <= end; i++)
411 set.add(obj(i), lower(i), colVector(i), upper(i));
412 }
413 }
414
415 /// Returns column vector of column \p i.
416 const SVectorBase<R>& colVector(int i) const
417 {
419 }
420
421 /// Returns column vector of column with identifier \p id.
422 const SVectorBase<R>& colVector(const SPxColId& id) const
423 {
425 }
426
427 /// Gets column vector of column \p i.
428 void getColVectorUnscaled(int i, DSVectorBase<R>& vec) const;
429
430 /// Gets column vector of column with identifier \p id.
431 void getColVectorUnscaled(const SPxColId& id, DSVectorBase<R>& vec) const;
432
433 /// Gets unscaled objective vector.
434 void getObjUnscaled(VectorBase<R>& pobj) const;
435
436 /// Gets objective vector.
437 void getObj(VectorBase<R>& pobj) const
438 {
440
441 if(spxSense() == MINIMIZE)
442 pobj *= -1.0;
443 }
444
445 /// Returns objective value of column \p i.
446 R obj(int i) const
447 {
448 R res = maxObj(i);
449
450 if(spxSense() == MINIMIZE)
451 res *= -1;
452
453 return res;
454 }
455
456 /// Returns objective value of column with identifier \p id.
457 R obj(const SPxColId& id) const
458 {
459 return obj(number(id));
460 }
461
462 /// Returns unscaled objective value of column \p i.
463 R objUnscaled(int i) const;
464
465 /// Returns unscaled objective value of column with identifier \p id.
466 R objUnscaled(const SPxColId& id) const;
467
468 /// Returns objective vector for maximization problem.
469 /** Methods #maxObj() return the objective vector or its elements, after transformation to a maximization
470 * problem. Since this is how SPxLPBase internally stores any LP these methods are generally faster. The following
471 * condition holds: #obj() = #spxSense() * maxObj().
472 */
473 const VectorBase<R>& maxObj() const
474 {
476 }
477
478 /// Returns objective value of column \p i for maximization problem.
479 const R& maxObj(int i) const
480 {
481 return LPColSetBase<R>::maxObj(i);
482 }
483
484 /// Returns objective value of column with identifier \p id for maximization problem.
485 const R& maxObj(const SPxColId& id) const
486 {
487 return maxObj(number(id));
488 }
489
490 /// Returns unscaled objective vector for maximization problem.
492
493 /// Returns unscaled objective value of column \p i for maximization problem.
494 R maxObjUnscaled(int i) const;
495
496 /// Returns unscaled objective value of column with identifier \p id for maximization problem.
497 R maxObjUnscaled(const SPxColId& id) const;
498
499 /// Returns upper bound vector.
500 const VectorBase<R>& upper() const
501 {
502 return LPColSetBase<R>::upper();
503 }
504
505 /// Returns upper bound of column \p i.
506 const R& upper(int i) const
507 {
508 return LPColSetBase<R>::upper(i);
509 }
510
511 /// Returns upper bound of column with identifier \p id.
512 const R& upper(const SPxColId& id) const
513 {
514 return LPColSetBase<R>::upper(id);
515 }
516
517 /// Gets unscaled upper bound vector
519
520 /// Returns unscaled upper bound of column \p i.
521 R upperUnscaled(int i) const;
522
523 /// Returns unscaled upper bound of column with identifier \p id.
524 R upperUnscaled(const SPxColId& id) const;
525
526 /// Returns (internal and possibly scaled) lower bound vector.
527 const VectorBase<R>& lower() const
528 {
529 return LPColSetBase<R>::lower();
530 }
531
532 /// Returns (internal and possibly scaled) lower bound of column \p i.
533 const R& lower(int i) const
534 {
535 return LPColSetBase<R>::lower(i);
536 }
537
538 /// Returns (internal and possibly scaled) lower bound of column with identifier \p id.
539 const R& lower(const SPxColId& id) const
540 {
541 return LPColSetBase<R>::lower(id);
542 }
543
544 /// Gets unscaled lower bound vector.
546
547 /// Returns unscaled lower bound of column \p i.
548 R lowerUnscaled(int i) const;
549
550 /// Returns unscaled lower bound of column with identifier \p id.
551 R lowerUnscaled(const SPxColId& id) const;
552
553 /// Returns the optimization sense.
555 {
556 return thesense;
557 }
558
559 /// Returns the objective function value offset
560 const R& objOffset() const
561 {
562 return offset;
563 }
564
565 /// Returns the row number of the row with identifier \p id.
566 int number(const SPxRowId& id) const
567 {
568 return LPRowSetBase<R>::number(id);
569 }
570
571 /// Returns the column number of the column with identifier \p id.
572 int number(const SPxColId& id) const
573 {
574 return LPColSetBase<R>::number(id);
575 }
576
577 /// Returns the row or column number for identifier \p id.
578 int number(const SPxId& id) const
579 {
580 return (id.type() == SPxId::COL_ID)
583 }
584
585 /// Returns the row number of the row with identifier \p id.
586 bool has(const SPxRowId& id) const
587 {
588 return LPRowSetBase<R>::has(id);
589 }
590
591 /// Returns the column number of the column with identifier \p id.
592 bool has(const SPxColId& id) const
593 {
594 return LPColSetBase<R>::has(id);
595 }
596
597 /// Returns the row or column number for identifier \p id.
598 bool has(const SPxId& id) const
599 {
600 return (id.type() == SPxId::COL_ID)
603 }
604
605 /// Returns the row identifier for row \p n.
606 SPxRowId rId(int n) const
607 {
609 }
610
611 /// Returns the column identifier for column \p n.
612 SPxColId cId(int n) const
613 {
615 }
616
617 ///@}
618
619 // ------------------------------------------------------------------------------------------------------------------
620 /**@name Extension */
621 ///@{
622
623 ///
624 virtual void addRow(const LPRowBase<R>& row, bool scale = false)
625 {
626 doAddRow(row, scale);
627 }
628
629 ///
630 virtual void addRow(const R& lhsValue, const SVectorBase<R>& rowVec, const R& rhsValue,
631 bool scale = false)
632 {
633 doAddRow(lhsValue, rowVec, rhsValue, scale);
634 }
635
636 ///
637 template < class S >
638 void addRow(const S* lhsValue, const S* rowValues, const int* rowIndices, int rowSize,
639 const S* rhsValue)
640 {
641 assert(lhsValue != nullptr);
642 assert(rowSize <= 0 || rowValues != nullptr);
643 assert(rowSize <= 0 || rowIndices != nullptr);
644 assert(rhsValue != nullptr);
645
646 int idx = nRows();
647 int oldColNumber = nCols();
648
649 LPRowSetBase<R>::add(lhsValue, rowValues, rowIndices, rowSize, rhsValue);
650
651 // now insert nonzeros to column file also
652 for(int j = rowSize - 1; j >= 0; --j)
653 {
654 const S& val = rowValues[j];
655 int i = rowIndices[j];
656
657 // create new columns if required
658 if(i >= nCols())
659 {
660 LPColBase<R> empty;
661
662 for(int k = nCols(); k <= i; ++k)
664 }
665
666 assert(i < nCols());
667 LPColSetBase<R>::add2(i, 1, &idx, &val);
668 }
669
670 addedRows(1);
671 addedCols(nCols() - oldColNumber);
672 }
673
674 /// Adds \p row to LPRowSetBase.
675 virtual void addRow(SPxRowId& id, const LPRowBase<R>& row, bool scale = false)
676 {
677 addRow(row, scale);
678 id = rId(nRows() - 1);
679 }
680
681 ///
682 virtual void addRows(const LPRowSetBase<R>& pset, bool scale = false)
683 {
684 doAddRows(pset, scale);
685 }
686
687 ///
688 template < class S >
689 void addRows(const S* lhsValues, const S* rowValues, const int* rowIndices, const int* rowStarts,
690 const int* rowLengths, const int numRows, const int numValues, const S* rhsValues)
691 {
692 assert(lhsValues != nullptr);
693 assert(numValues <= 0 || rowValues != nullptr);
694 assert(numValues <= 0 || rowIndices != nullptr);
695 assert(numValues <= 0 || rowStarts != nullptr);
696 assert(numValues <= 0 || rowLengths != nullptr);
697 assert(rhsValues != nullptr);
698
699 int i, j, k, idx;
700 SVectorBase<R>* col;
701 DataArray < int > newCols(nCols());
702 int oldRowNumber = nRows();
703 int oldColNumber = nCols();
704
705 LPRowSetBase<R>::memRemax(oldRowNumber + numRows);
706
707 for(i = 0; i < numRows; i++)
708 {
709 assert(numValues <= 0 || rowStarts[i] + rowLengths[i] <= numValues);
710
711 if(numValues <= 0)
712 LPRowSetBase<R>::add(&(lhsValues[i]), (S*)0, (int*)nullptr, 0, &(rhsValues[i]));
713 else
714 LPRowSetBase<R>::add(&(lhsValues[i]), &(rowValues[rowStarts[i]]), &(rowIndices[rowStarts[i]]),
715 rowLengths[i], &(rhsValues[i]));
716 }
717
720
721 // count additional nonzeros per column
722 for(i = nCols() - 1; i >= 0; --i)
723 newCols[i] = 0;
724
725 if(numValues > 0)
726 {
727 for(i = 0; i < numRows; i++)
728 {
729 for(j = rowStarts[i]; j < rowStarts[i] + rowLengths[i]; j++)
730 {
731 ///@todo implement the addition of new columns as in doAddRows()
732 assert(rowIndices[j] >= 0);
733 assert(rowIndices[j] < oldColNumber);
734 newCols[rowIndices[j]]++;
735 }
736 }
737 }
738
739 // extend columns as required (backward because of memory efficiency reasons)
740 for(i = nCols() - 1; i >= 0; --i)
741 {
742 if(newCols[i] > 0)
743 {
744 int len = newCols[i] + colVector(i).size();
746
747 /* preset the sizes: beware that this can irritate a consistency check call from xtend(). We need to set the
748 * sizes here, because a possible garbage collection called from xtend might destroy the sizes again. */
749 colVector_w(i).set_size(len);
750 }
751 }
752
753 // insert new elements to column file
754 for(i = nRows() - 1; i >= oldRowNumber; --i)
755 {
756 const SVectorBase<R>& vec = rowVector(i);
757
758 for(j = vec.size() - 1; j >= 0; --j)
759 {
760 k = vec.index(j);
761 col = &colVector_w(k);
762 idx = col->size() - newCols[k];
763 assert(newCols[k] > 0);
764 assert(idx >= 0);
765 newCols[k]--;
766 col->index(idx) = i;
767 col->value(idx) = vec.value(j);
768 }
769 }
770
771#ifndef NDEBUG
772
773 for(i = 0; i < nCols(); ++i)
774 assert(newCols[i] == 0);
775
776#endif
777
779
780 assert(numRows == nRows() - oldRowNumber);
781 addedRows(nRows() - oldRowNumber);
782 addedCols(nCols() - oldColNumber);
783 }
784
785 /// adds all LPRowBase%s of \p pset to LPRowSetBase.
786 virtual void addRows(SPxRowId id[], const LPRowSetBase<R>& set, bool scale = false)
787 {
788 int i = nRows();
789 addRows(set, scale);
790
791 for(int j = 0; i < nRows(); ++i, ++j)
792 id[j] = rId(i);
793 }
794
795 ///
796 virtual void addCol(const LPColBase<R>& col, bool scale = false)
797 {
798 doAddCol(col, scale);
799 }
800
801 ///
802 virtual void addCol(const R& objValue, const R& lowerValue, const SVectorBase<R>& colVec,
803 const R& upperValue, bool scale = false)
804 {
805 doAddCol(objValue, lowerValue, colVec, upperValue, scale);
806 }
807
808 ///
809 template < class S >
810 void addCol(const S* objValue, const S* lowerValue, const S* colValues, const int* colIndices,
811 int colSize, const S* upperValue)
812 {
813 int idx = nCols();
814 int oldRowNumber = nRows();
815
816 LPColSetBase<R>::add(objValue, lowerValue, colValues, colIndices, colSize, upperValue);
817
818 if(thesense != MAXIMIZE)
819 LPColSetBase<R>::maxObj_w(idx) *= -1;
820
821 // now insert nonzeros to column file also
822 for(int j = colSize - 1; j >= 0; --j)
823 {
824 const S& val = colValues[j];
825 int i = colIndices[j];
826
827 // create new rows if required
828 if(i >= nRows())
829 {
830 LPRowBase<R> empty;
831
832 for(int k = nRows(); k <= i; ++k)
834 }
835
836 assert(i < nRows());
837 LPRowSetBase<R>::add2(i, 1, &idx, &val);
838 }
839
840 addedCols(1);
841 addedRows(nRows() - oldRowNumber);
842 }
843
844 /// Adds \p col to LPColSetVBase.
845 virtual void addCol(SPxColId& id, const LPColBase<R>& col, bool scale = false)
846 {
847 addCol(col, scale);
848 id = cId(nCols() - 1);
849 }
850
851 ///
852 virtual void addCols(const LPColSetBase<R>& pset, bool scale = false)
853 {
854 doAddCols(pset, scale);
855 }
856
857 ///
858 template < class S >
859 void addCols(const S* objValue, const S* lowerValues, const S* colValues, const int* colIndices,
860 const int* colStarts, const int* colLengths, const int numCols, const int numValues,
861 const S* upperValues)
862 {
863 assert(lowerValues != nullptr);
864 assert(numValues <= 0 || colValues != nullptr);
865 assert(numValues <= 0 || colIndices != nullptr);
866 assert(numValues <= 0 || colStarts != nullptr);
867 assert(numValues <= 0 || colLengths != nullptr);
868 assert(upperValues != nullptr);
869
870 int i, j, k, idx;
871 SVectorBase<R>* row;
872 DataArray < int > newRows(nRows());
873 int oldColNumber = nCols();
874 int oldRowNumber = nRows();
875 idx = nCols();
876
877 LPColSetBase<R>::memRemax(oldColNumber + numCols);
878
879 for(i = 0; i < numCols; i++)
880 {
881 assert(numValues <= 0 || colStarts[i] + colLengths[i] <= numValues);
882
883 if(numValues <= 0)
884 LPColSetBase<R>::add(&(objValue[i]), &(lowerValues[i]), (S*)0, (int*)nullptr, 0, &(upperValues[i]));
885 else
886 LPColSetBase<R>::add(&(objValue[i]), &(lowerValues[i]), &(colValues[colStarts[i]]),
887 &(colIndices[colStarts[i]]), colLengths[i], &(upperValues[i]));
888
889 if(thesense != MAXIMIZE)
890 LPColSetBase<R>::maxObj_w(idx + i) *= -1;
891 }
892
895
896 // count additional nonzeros per rows
897 for(i = nRows() - 1; i >= 0; --i)
898 newRows[i] = 0;
899
900 for(i = numValues - 1; i >= 0; --i)
901 {
902 ///@todo implement the addition of new rows as in doAddCols()
903 assert(colIndices[i] >= 0);
904 assert(colIndices[i] < oldRowNumber);
905 newRows[colIndices[i]]++;
906 }
907
908 // extend rows as required (backward because of memory efficiency reasons)
909 for(i = nRows() - 1; i >= 0; --i)
910 {
911 if(newRows[i] > 0)
912 {
913 int len = newRows[i] + rowVector(i).size();
915
916 /* preset the sizes: beware that this can irritate a consistency check call from xtend(). We need to set the
917 * sizes here, because a possible garbage collection called from xtend might destroy the sizes again. */
918 rowVector_w(i).set_size(len);
919 }
920 }
921
922 // insert new elements to row file
923 for(i = nCols() - 1; i >= oldColNumber; --i)
924 {
925 const SVectorBase<R>& vec = colVector(i);
926
927 for(j = vec.size() - 1; j >= 0; --j)
928 {
929 k = vec.index(j);
930 row = &rowVector_w(k);
931 idx = row->size() - newRows[k];
932 assert(newRows[k] > 0);
933 assert(idx >= 0);
934 newRows[k]--;
935 row->index(idx) = i;
936 row->value(idx) = vec.value(j);
937 }
938 }
939
940#ifndef NDEBUG
941
942 for(i = 0; i < nRows(); ++i)
943 assert(newRows[i] == 0);
944
945#endif
946
948
949 assert(numCols == nCols() - oldColNumber);
950 addedCols(nCols() - oldColNumber);
951 addedRows(nRows() - oldRowNumber);
952 }
953
954 /// Adds all LPColBase%s of \p set to LPColSetBase.
955 virtual void addCols(SPxColId id[], const LPColSetBase<R>& set, bool scale = false)
956 {
957
958 int i = nCols();
959 addCols(set, scale);
960
961 for(int j = 0; i < nCols(); ++i, ++j)
962 id[j] = cId(i);
963 }
964
965 ///@}
966
967 // ------------------------------------------------------------------------------------------------------------------
968 /**@name Shrinking */
969 ///@{
970
971 /// Removes \p i 'th row.
972 virtual void removeRow(int i)
973 {
974 if(i < 0)
975 return;
976
977 doRemoveRow(i);
978 }
979
980 /// Removes row with identifier \p id.
981 virtual void removeRow(SPxRowId id)
982 {
983 removeRow(number(id));
984 }
985
986 /// Removes multiple rows.
987 /** This method removes all LPRowBase%s from the SPxLPBase with an index \p i such that \p perm[i] < 0. Upon
988 * completion, \p perm[i] >= 0 indicates the new index where the \p i'th LPRowBase<R> has been moved to due to this
989 * removal. Note that \p perm must point to an array of at least #nRows() ints.
990 */
991 virtual void removeRows(int perm[])
992 {
993 doRemoveRows(perm);
994 }
995
996 ///
997 virtual void removeRows(SPxRowId id[], int n, int perm[] = nullptr)
998 {
999
1000 if(perm == nullptr)
1001 {
1003 removeRows(id, n, p.get_ptr());
1004 return;
1005 }
1006
1007 for(int i = nRows() - 1; i >= 0; --i)
1008 perm[i] = i;
1009
1010 while(n--)
1011 perm[number(id[n])] = -1;
1012
1013 removeRows(perm);
1014 }
1015
1016 /// Removes \p n LPRowBase%s.
1017 /** Removing multiple rows with one method invocation is available in two flavours. An array \p perm can be passed as
1018 * third argument or not. If given, \p perm must be an array at least of size #nRows(). It is used to return the
1019 * permutations resulting from this removal: \p perm[i] < 0 indicates, that the element to index \p i has been
1020 * removed. Otherwise, \p perm[i] is the new index of the element with index \p i before the removal.
1021 */
1022 virtual void removeRows(int nums[], int n, int perm[] = nullptr)
1023 {
1024
1025 if(perm == nullptr)
1026 {
1028 removeRows(nums, n, p.get_ptr());
1029 return;
1030 }
1031
1032 for(int i = nRows() - 1; i >= 0; --i)
1033 perm[i] = i;
1034
1035 while(n--)
1036 perm[nums[n]] = -1;
1037
1038 removeRows(perm);
1039 }
1040
1041 /// Removes rows from \p start to \p end (including both).
1042 virtual void removeRowRange(int start, int end, int perm[] = nullptr)
1043 {
1044
1045 if(perm == nullptr)
1046 {
1047 int i = end - start + 1;
1048 DataArray < int > p(i);
1049
1050 while(--i >= 0)
1051 p[i] = start + i;
1052
1053 removeRows(p.get_ptr(), end - start + 1);
1054 return;
1055 }
1056
1057 int i;
1058
1059 for(i = 0; i < start; ++i)
1060 perm[i] = i;
1061
1062 for(; i <= end; ++i)
1063 perm[i] = -1;
1064
1065 for(; i < nRows(); ++i)
1066 perm[i] = i;
1067
1068 removeRows(perm);
1069 }
1070
1071 /// Removes \p i 'th column.
1072 virtual void removeCol(int i)
1073 {
1074 if(i < 0)
1075 return;
1076
1077 doRemoveCol(i);
1078 }
1079
1080 /// Removes column with identifier \p id.
1081 virtual void removeCol(SPxColId id)
1082 {
1083 removeCol(number(id));
1084 }
1085
1086 /// Removes multiple columns.
1087 /** This method removes all LPColBase%s from the SPxLPBase with an index \p i such that \p perm[i] < 0. Upon
1088 * completion, \p perm[i] >= 0 indicates the new index where the \p i 'th LPColBase has been moved to due to this
1089 * removal. Note, that \p perm must point to an array of at least #nCols() ints.
1090 */
1091 virtual void removeCols(int perm[])
1092 {
1093 doRemoveCols(perm);
1094 }
1095
1096 ///
1097 virtual void removeCols(SPxColId id[], int n, int perm[] = nullptr)
1098 {
1099
1100 if(perm == nullptr)
1101 {
1103 removeCols(id, n, p.get_ptr());
1104 return;
1105 }
1106
1107 for(int i = nCols() - 1; i >= 0; --i)
1108 perm[i] = i;
1109
1110 while(n--)
1111 perm[number(id[n])] = -1;
1112
1113 removeCols(perm);
1114 }
1115
1116 /// Removes \p n LPCols.
1117 /** Removing multiple columns with one method invocation is available in two flavours. An array \p perm can be passed
1118 * as third argument or not. If given, \p perm must be an array at least of size #nCols(). It is used to return the
1119 * permutations resulting from this removal: \p perm[i] < 0 indicates, that the element to index \p i has been
1120 * removed. Otherwise, \p perm[i] is the new index of the element with index \p i before the removal.
1121 */
1122 virtual void removeCols(int nums[], int n, int perm[] = nullptr)
1123 {
1124
1125 if(perm == nullptr)
1126 {
1128 removeCols(nums, n, p.get_ptr());
1129 return;
1130 }
1131
1132 for(int i = nCols() - 1; i >= 0; --i)
1133 perm[i] = i;
1134
1135 while(n--)
1136 perm[nums[n]] = -1;
1137
1138 removeCols(perm);
1139 }
1140
1141 /// Removes columns from \p start to \p end (including both).
1142 virtual void removeColRange(int start, int end, int perm[] = nullptr)
1143 {
1144
1145 if(perm == nullptr)
1146 {
1147 int i = end - start + 1;
1148 DataArray < int > p(i);
1149
1150 while(--i >= 0)
1151 p[i] = start + i;
1152
1153 removeCols(p.get_ptr(), end - start + 1);
1154 return;
1155 }
1156
1157 int i;
1158
1159 for(i = 0; i < start; ++i)
1160 perm[i] = i;
1161
1162 for(; i <= end; ++i)
1163 perm[i] = -1;
1164
1165 for(; i < nCols(); ++i)
1166 perm[i] = i;
1167
1168 removeCols(perm);
1169 }
1170
1171 /// clears the LP.
1172 virtual void clear()
1173 {
1174
1178 offset = 0;
1179 _isScaled = false;
1180 lp_scaler = nullptr;
1183 }
1184
1185 ///@}
1186
1187 // ------------------------------------------------------------------------------------------------------------------
1188 /**@name IO */
1189 ///@{
1190
1191 /// Reads LP in LP format from input stream \p in.
1192 virtual bool readLPF(std::istream& in, NameSet* rowNames = nullptr, NameSet* colNames = nullptr,
1193 DIdxSet* intVars = nullptr);
1194
1195 /// Reads an LP in MPS format from input stream \p in.
1196 virtual bool readMPS(std::istream& in, NameSet* rowNames = nullptr, NameSet* colNames = nullptr,
1197 DIdxSet* intVars = nullptr);
1198
1199 /// Reads LP in LP or MPS format from input stream \p in.
1200 /**@param in input stream.
1201 * @param rowNames contains after the call the names of the constraints (rows) in the same order as the rows in the
1202 * LP. Constraints without a name (only possible with LPF files) are automatically assigned a name.
1203 * Maybe 0 if the names are not needed.
1204 * @param colNames contains after the call the names of the variables (columns) in the same order as the columns in
1205 * the LP. Maybe 0 if the names are not needed.
1206 * @param intVars contains after the call the indices of those variables that where marked as beeing integer in the
1207 * file. Maybe 0 if the information is not needed.
1208 * @todo Make sure the Id's in the NameSet%s are the same as in the LP.
1209 */
1210 virtual bool read(std::istream& in, NameSet* rowNames = nullptr, NameSet* colNames = nullptr,
1211 DIdxSet* intVars = nullptr)
1212 {
1213 bool ok;
1214 char c;
1215
1216 in.get(c);
1217 in.putback(c);
1218
1219 /* MPS starts either with a comment mark '*' or with the keyword 'NAME' at the first column. LPF starts either
1220 * with blanks, a comment mark '\' or with the keyword "MAX" or "MIN" in upper or lower case. There is no
1221 * possible valid LPF file starting with a '*' or 'N'.
1222 */
1223 ok = ((c == '*') || (c == 'N'))
1224 ? readMPS(in, rowNames, colNames, intVars)
1225 : readLPF(in, rowNames, colNames, intVars);
1226
1227 return ok;
1228 }
1229
1230 /// Reads LP from a file.
1231 virtual bool readFile(const char* filename, NameSet* rowNames = nullptr,
1232 NameSet* colNames = nullptr,
1233 DIdxSet* intVars = nullptr)
1234 {
1235
1236 spxifstream file(filename);
1237
1238 if(!file)
1239 return false;
1240
1241 return read(file, rowNames, colNames, intVars);
1242 }
1243
1244 /** Writes a file in LP format to \p out. If \p rowNames and \p colNames are \c NULL, default names are used for the
1245 * constraints and variables. If \p intVars is not \c NULL, the variables contained in it are marked as integer in
1246 * the output.
1247 */
1248 virtual void writeLPF(std::ostream& out, const NameSet* rowNames, const NameSet* colNames,
1249 const DIdxSet* p_intvars = nullptr,
1250 const bool writeZeroObjective = false) const;
1251
1252 /// Writes a file in MPS format to \p out.
1253 virtual void writeMPS(std::ostream& out, const NameSet* rowNames, const NameSet* colNames,
1254 const DIdxSet* p_intvars = nullptr,
1255 const bool writeZeroObjective = false) const;
1256
1257 /// Write loaded LP to \p filename.
1258 virtual void writeFileLPBase(const char* filename, const NameSet* rowNames = nullptr,
1259 const NameSet* colNames = nullptr, const DIdxSet* p_intvars = nullptr,
1260 const bool writeZeroObjective = false) const
1261 {
1262
1263 std::ofstream tmp(filename);
1264 size_t len_f = strlen(filename);
1265
1266 if(len_f > 4 && filename[len_f - 1] == 's' && filename[len_f - 2] == 'p'
1267 && filename[len_f - 3] == 'm' && filename[len_f - 4] == '.')
1268 {
1269 writeMPS(tmp, rowNames, colNames, p_intvars, writeZeroObjective);
1270 }
1271 else
1272 {
1273 writeLPF(tmp, rowNames, colNames, p_intvars, writeZeroObjective);
1274 }
1275 }
1276
1277 /** prints problem statistics */
1278 void printProblemStatistics(std::ostream& os)
1279 {
1280 int countLower = 0;
1281 int countUpper = 0;
1282 int countBoxed = 0;
1283 int countFreeCol = 0;
1284
1285 int countEqual = 0;
1286 int countLhs = 0;
1287 int countRhs = 0;
1288 int countRanged = 0;
1289 int countFreeRow = 0;
1290
1291 for(int i = 0; i < nCols(); i++)
1292 {
1293 bool hasLower = false;
1294 bool hasUpper = false;
1295
1296 if(lower(i) > R(-infinity))
1297 {
1298 countLower++;
1299 hasLower = true;
1300 }
1301
1302 if(upper(i) < R(infinity))
1303 {
1304 countUpper++;
1305 hasUpper = true;
1306 }
1307
1308 if(hasUpper && hasLower)
1309 {
1310 countBoxed++;
1311 countLower--;
1312 countUpper--;
1313 }
1314
1315 if(!hasUpper && !hasLower)
1316 countFreeCol++;
1317 }
1318
1319 for(int i = 0; i < nRows(); i++)
1320 {
1321 bool hasRhs = false;
1322 bool hasLhs = false;
1323
1324 if(lhs(i) > R(-infinity))
1325 {
1326 countLhs++;
1327 hasLhs = true;
1328 }
1329
1330 if(rhs(i) < R(infinity))
1331 {
1332 countRhs++;
1333 hasRhs = true;
1334 }
1335
1336 if(hasRhs && hasLhs)
1337 {
1338 if(EQ(lhs(i), rhs(i), this->tolerances()->epsilon()))
1339 countEqual++;
1340 else
1341 countRanged++;
1342
1343 countLhs--;
1344 countRhs--;
1345 }
1346
1347 if(!hasRhs && !hasLhs)
1348 countFreeRow++;
1349 }
1350
1351 SPxOut::setFixed(os);
1352 os << " Columns : " << nCols() << "\n"
1353 << " boxed : " << countBoxed << "\n"
1354 << " lower bound : " << countLower << "\n"
1355 << " upper bound : " << countUpper << "\n"
1356 << " free : " << countFreeCol << "\n"
1357 << " Rows : " << nRows() << "\n"
1358 << " equal : " << countEqual << "\n"
1359 << " ranged : " << countRanged << "\n"
1360 << " lhs : " << countLhs << "\n"
1361 << " rhs : " << countRhs << "\n"
1362 << " free : " << countFreeRow << "\n"
1363 << " Nonzeros : " << nNzos() << "\n"
1364 << " per column : " << R(nNzos()) / R(nCols()) << "\n"
1365 << " per row : " << R(nNzos()) / R(nRows()) << "\n"
1366 << " sparsity : " << R(nNzos()) / R(nCols()) / R(nRows()) << "\n"
1367 << " min. abs. value : " << R(minAbsNzo()) << "\n"
1368 << " max. abs. value : " << R(maxAbsNzo()) << "\n";
1369 }
1370
1371 ///@}
1372
1373 // ------------------------------------------------------------------------------------------------------------------
1374 /**@name Manipulation */
1375 ///@{
1376
1377 /// Changes objective vector to \p newObj. \p scale determines whether the new data should be scaled
1378 virtual void changeObj(const VectorBase<R>& newObj, bool scale = false)
1379 {
1380 changeMaxObj(newObj, scale);
1381
1382 if(spxSense() == MINIMIZE)
1384 }
1385
1386 /// changes \p i 'th objective vector element to \p newVal. \p scale determines whether the new data should be scaled
1387 virtual void changeObj(int i, const R& newVal, bool scale = false)
1388 {
1389 changeMaxObj(i, newVal, scale);
1390
1391 if(spxSense() == MINIMIZE)
1393 }
1394
1395 /// changes \p i 'th objective vector element to \p newVal.
1396 template < class S >
1397 void changeObj(int i, const S* newVal)
1398 {
1399 LPColSetBase<R>::maxObj_w(i) = *newVal;
1400
1401 if(spxSense() == MINIMIZE)
1403
1404 assert(isConsistent());
1405 }
1406
1407 /// Changes objective value of column with identifier \p id to \p newVal. \p scale determines whether the new data should be scaled
1408 virtual void changeObj(SPxColId id, const R& newVal, bool scale = false)
1409 {
1410 this->changeObj(number(id), newVal, scale);
1411 }
1412
1413 /// Changes objective vector to \p newObj. \p scale determines whether the new data should be scaled
1414 virtual void changeMaxObj(const VectorBase<R>& newObj, bool scale = false)
1415 {
1416 assert(maxObj().dim() == newObj.dim());
1417
1418 if(scale)
1419 {
1420 assert(_isScaled);
1421 assert(lp_scaler);
1422
1423 for(int i = 0; i < maxObj().dim(); i++)
1424 LPColSetBase<R>::maxObj_w(i) = lp_scaler->scaleObj(*this, i, newObj[i]);
1425 }
1426 else
1427 LPColSetBase<R>::maxObj_w() = newObj;
1428
1429 assert(isConsistent());
1430 }
1431
1432 /// changes \p i 'th objective vector element to \p newVal. \p scale determines whether the new data should be scaled
1433 virtual void changeMaxObj(int i, const R& newVal, bool scale = false)
1434 {
1435 if(scale)
1436 {
1437 assert(_isScaled);
1438 assert(lp_scaler);
1439 LPColSetBase<R>::maxObj_w(i) = lp_scaler->scaleObj(*this, i, newVal);
1440 }
1441 else
1442 LPColSetBase<R>::maxObj_w(i) = newVal;
1443
1444 assert(isConsistent());
1445 }
1446
1447 /// changes \p i 'th objective vector element to \p newVal.
1448 template < class S >
1449 void changeMaxObj(int i, const S* newVal)
1450 {
1451 LPColSetBase<R>::maxObj_w(i) = *newVal;
1452 assert(isConsistent());
1453 }
1454
1455 /// Changes objective value of column with identifier \p id to \p newVal. \p scale determines whether the new data should be scaled
1456 virtual void changeMaxObj(SPxColId id, const R& newVal, bool scale = false)
1457 {
1458 changeMaxObj(number(id), newVal, scale);
1459 }
1460
1461 /// Changes vector of lower bounds to \p newLower. \p scale determines whether the new data should be scaled
1462 virtual void changeLower(const VectorBase<R>& newLower, bool scale = false)
1463 {
1464 assert(lower().dim() == newLower.dim());
1465
1466 if(scale)
1467 {
1468 assert(_isScaled);
1469 assert(lp_scaler);
1470
1471 for(int i = 0; i < lower().dim(); i++)
1472 LPColSetBase<R>::lower_w(i) = lp_scaler->scaleLower(*this, i, newLower[i]);
1473 }
1474 else
1475 LPColSetBase<R>::lower_w() = newLower;
1476
1477 assert(isConsistent());
1478 }
1479
1480 /// changes \p i 'th lower bound to \p newLower. \p scale determines whether the new data should be scaled
1481 virtual void changeLower(int i, const R& newLower, bool scale = false)
1482 {
1483 if(scale && newLower > R(-infinity))
1484 {
1485 assert(_isScaled);
1486 assert(lp_scaler);
1487 LPColSetBase<R>::lower_w(i) = lp_scaler->scaleLower(*this, i, newLower);
1488 }
1489 else
1490 LPColSetBase<R>::lower_w(i) = newLower;
1491
1492 assert(isConsistent());
1493 }
1494
1495 /// changes \p i 'th lower bound to \p newLower.
1496 template < class S >
1497 void changeLower(int i, const S* newLower)
1498 {
1499 LPColSetBase<R>::lower_w(i) = *newLower;
1500 assert(isConsistent());
1501 }
1502
1503 /// changes lower bound of column with identifier \p id to \p newLower. \p scale determines whether the new data should be scaled
1504 virtual void changeLower(SPxColId id, const R& newLower, bool scale = false)
1505 {
1506 changeLower(number(id), newLower, scale);
1507 }
1508
1509 /// Changes vector of upper bounds to \p newUpper. \p scale determines whether the new data should be scaled
1510 virtual void changeUpper(const VectorBase<R>& newUpper, bool scale = false)
1511 {
1512 assert(upper().dim() == newUpper.dim());
1513
1514 if(scale)
1515 {
1516 assert(_isScaled);
1517 assert(lp_scaler);
1518
1519 for(int i = 0; i < upper().dim(); i++)
1520 LPColSetBase<R>::upper_w(i) = lp_scaler->scaleUpper(*this, i, newUpper[i]);
1521 }
1522 else
1523 LPColSetBase<R>::upper_w() = newUpper;
1524
1525 assert(isConsistent());
1526 }
1527
1528 /// Changes \p i 'th upper bound to \p newUpper. \p scale determines whether the new data should be scaled
1529 virtual void changeUpper(int i, const R& newUpper, bool scale = false)
1530 {
1531 if(scale && newUpper < R(infinity))
1532 {
1533 assert(_isScaled);
1534 assert(lp_scaler);
1535 LPColSetBase<R>::upper_w(i) = lp_scaler->scaleUpper(*this, i, newUpper);
1536 }
1537 else
1538 LPColSetBase<R>::upper_w(i) = newUpper;
1539
1540 assert(isConsistent());
1541 }
1542
1543 /// Changes \p i 'th upper bound to \p newUpper.
1544 template < class S >
1545 void changeUpper(int i, const S* newUpper)
1546 {
1547 LPColSetBase<R>::upper_w(i) = *newUpper;
1548 assert(isConsistent());
1549 }
1550
1551 /// Changes upper bound of column with identifier \p id to \p newLower. \p scale determines whether the new data should be scaled
1552 virtual void changeUpper(SPxColId id, const R& newUpper, bool scale = false)
1553 {
1554 changeUpper(number(id), newUpper, scale);
1555 }
1556
1557 /// Changes variable bounds to \p newLower and \p newUpper. \p scale determines whether the new data should be scaled
1558 virtual void changeBounds(const VectorBase<R>& newLower, const VectorBase<R>& newUpper,
1559 bool scale = false)
1560 {
1561 changeLower(newLower, scale);
1562 changeUpper(newUpper, scale);
1563 assert(isConsistent());
1564 }
1565
1566 /// Changes bounds of column \p i to \p newLower and \p newUpper. \p scale determines whether the new data should be scaled
1567 virtual void changeBounds(int i, const R& newLower, const R& newUpper, bool scale = false)
1568 {
1569 changeLower(i, newLower, scale);
1570 changeUpper(i, newUpper, scale);
1571 assert(isConsistent());
1572 }
1573
1574 /// Changes bounds of column \p i to \p newLower and \p newUpper.
1575 template < class S >
1576 void changeBounds(int i, const S* newLower, const S* newUpper)
1577 {
1578 LPColSetBase<R>::lower_w(i) = *newLower;
1579 LPColSetBase<R>::upper_w(i) = *newUpper;
1580 assert(isConsistent());
1581 }
1582
1583 /// Changes bounds of column with identifier \p id. \p scale determines whether the new data should be scaled
1584 virtual void changeBounds(SPxColId id, const R& newLower, const R& newUpper, bool scale = false)
1585 {
1586 changeBounds(number(id), newLower, newUpper, scale);
1587 }
1588
1589 /// Changes left hand side vector for constraints to \p newLhs. \p scale determines whether the new data should be scaled
1590 virtual void changeLhs(const VectorBase<R>& newLhs, bool scale = false)
1591 {
1592 assert(lhs().dim() == newLhs.dim());
1593
1594 if(scale)
1595 {
1596 assert(_isScaled);
1597 assert(lp_scaler);
1598
1599 for(int i = 0; i < lhs().dim(); i++)
1600 LPRowSetBase<R>::lhs_w(i) = lp_scaler->scaleLhs(*this, i, newLhs[i]);
1601 }
1602 else
1603 LPRowSetBase<R>::lhs_w() = newLhs;
1604
1605 assert(isConsistent());
1606 }
1607
1608 /// Changes \p i 'th left hand side value to \p newLhs. \p scale determines whether the new data should be scaled
1609 virtual void changeLhs(int i, const R& newLhs, bool scale = false)
1610 {
1611 if(scale && newLhs > R(-infinity))
1612 {
1613 assert(_isScaled);
1614 assert(lp_scaler);
1615 LPRowSetBase<R>::lhs_w(i) = lp_scaler->scaleLhs(*this, i, newLhs);
1616 }
1617 else
1618 LPRowSetBase<R>::lhs_w(i) = newLhs;
1619
1620 assert(isConsistent());
1621 }
1622
1623 /// Changes \p i 'th left hand side value to \p newLhs.
1624 template < class S >
1625 void changeLhs(int i, const S* newLhs)
1626 {
1627 LPRowSetBase<R>::lhs_w(i) = *newLhs;
1628 assert(isConsistent());
1629 }
1630
1631 /// Changes left hand side value for row with identifier \p id. \p scale determines whether the new data should be scaled
1632 virtual void changeLhs(SPxRowId id, const R& newLhs, bool scale = false)
1633 {
1634 changeLhs(number(id), newLhs, scale);
1635 }
1636
1637 /// Changes right hand side vector for constraints to \p newRhs. \p scale determines whether the new data should be scaled
1638 virtual void changeRhs(const VectorBase<R>& newRhs, bool scale = false)
1639 {
1640 assert(rhs().dim() == newRhs.dim());
1641
1642 if(scale)
1643 {
1644 assert(_isScaled);
1645 assert(lp_scaler);
1646
1647 for(int i = 0; i < rhs().dim(); i++)
1648 LPRowSetBase<R>::rhs_w(i) = lp_scaler->scaleRhs(*this, i, newRhs[i]);
1649 }
1650 else
1651 LPRowSetBase<R>::rhs_w() = newRhs;
1652
1653 assert(isConsistent());
1654 }
1655
1656 /// Changes \p i 'th right hand side value to \p newRhs. \p scale determines whether the new data should be scaled
1657 virtual void changeRhs(int i, const R& newRhs, bool scale = false)
1658 {
1659 if(scale && newRhs < R(infinity))
1660 {
1661 assert(_isScaled);
1662 assert(lp_scaler);
1663 LPRowSetBase<R>::rhs_w(i) = lp_scaler->scaleRhs(*this, i, newRhs);
1664 }
1665 else
1666 LPRowSetBase<R>::rhs_w(i) = newRhs;
1667
1668 assert(isConsistent());
1669 }
1670
1671 /// Changes right hand side value for row with identifier \p id. \p scale determines whether the new data should be scaled
1672 virtual void changeRhs(SPxRowId id, const R& newRhs, bool scale = false)
1673 {
1674 changeRhs(number(id), newRhs, scale);
1675 }
1676
1677 /// Changes left and right hand side vectors. \p scale determines whether the new data should be scaled
1678 virtual void changeRange(const VectorBase<R>& newLhs, const VectorBase<R>& newRhs,
1679 bool scale = false)
1680 {
1681 changeLhs(newLhs, scale);
1682 changeRhs(newRhs, scale);
1683 assert(isConsistent());
1684 }
1685
1686 /// Changes left and right hand side of row \p i. \p scale determines whether the new data should be scaled
1687 virtual void changeRange(int i, const R& newLhs, const R& newRhs, bool scale = false)
1688 {
1689 changeLhs(i, newLhs, scale);
1690 changeRhs(i, newRhs, scale);
1691 assert(isConsistent());
1692 }
1693
1694 /// Changes left and right hand side of row \p i.
1695 template < class S >
1696 void changeRange(int i, const S* newLhs, const S* newRhs)
1697 {
1698 LPRowSetBase<R>::lhs_w(i) = *newLhs;
1699 LPRowSetBase<R>::rhs_w(i) = *newRhs;
1700 assert(isConsistent());
1701 }
1702
1703 /// Changes left and right hand side of row with identifier \p id. \p scale determines whether the new data should be scaled
1704 virtual void changeRange(SPxRowId id, const R& newLhs, const R& newRhs, bool scale = false)
1705 {
1706 changeRange(number(id), newLhs, newRhs, scale);
1707 }
1708
1709 /// Changes row objective function vector to \p newRowObj. \p scale determines whether the new data should be scaled
1710 virtual void changeRowObj(const VectorBase<R>& newRowObj, bool scale = false)
1711 {
1712 assert(maxRowObj().dim() == newRowObj.dim());
1713 LPRowSetBase<R>::obj_w() = newRowObj;
1714
1715 if(spxSense() == MINIMIZE)
1716 LPRowSetBase<R>::obj_w() *= -1;
1717
1718 assert(isConsistent());
1719 }
1720
1721 /// Changes \p i 'th row objective function value to \p newRowObj. \p scale determines whether the new data should be scaled
1722 virtual void changeRowObj(int i, const R& newRowObj, bool scale = false)
1723 {
1724 LPRowSetBase<R>::obj_w(i) = newRowObj;
1725
1726 if(spxSense() == MINIMIZE)
1727 LPRowSetBase<R>::obj_w(i) *= -1;
1728
1729 assert(isConsistent());
1730 }
1731
1732 /// Changes row objective function value for row with identifier \p id. \p scale determines whether the new data should be scaled
1733 virtual void changeRowObj(SPxRowId id, const R& newRowObj, bool scale = false)
1734 {
1735 changeRowObj(number(id), newRowObj, scale);
1736 }
1737
1738 /// Clears row objective function values for all rows
1739 virtual void clearRowObjs()
1740 {
1741 LPRowSetBase<R>::obj_w().clear();
1742 }
1743
1744 /// Replaces \p i 'th row of LP with \p newRow. \p scale determines whether the new data should be scaled
1745 virtual void changeRow(int n, const LPRowBase<R>& newRow, bool scale = false)
1746 {
1747 if(n < 0)
1748 return;
1749
1750 int j;
1751 SVectorBase<R>& row = rowVector_w(n);
1752
1753 for(j = row.size() - 1; j >= 0; --j)
1754 {
1755 SVectorBase<R>& col = colVector_w(row.index(j));
1756 int position = col.pos(n);
1757
1758 assert(position != -1);
1759
1760 if(position >= 0)
1761 col.remove(position);
1762 }
1763
1764 row.clear();
1765
1766 changeLhs(n, newRow.lhs(), scale);
1767 changeRhs(n, newRow.rhs(), scale);
1768 changeRowObj(n, newRow.obj(), scale);
1769
1770 const SVectorBase<R>& newrow = newRow.rowVector();
1771
1772 for(j = newrow.size() - 1; j >= 0; --j)
1773 {
1774 int idx = newrow.index(j);
1775 R val = newrow.value(j);
1776
1777 if(scale)
1779
1780 LPRowSetBase<R>::add2(n, 1, &idx, &val);
1781 LPColSetBase<R>::add2(idx, 1, &n, &val);
1782 }
1783
1784 assert(isConsistent());
1785 }
1786
1787 /// Replaces row with identifier \p id with \p newRow. \p scale determines whether the new data should be scaled
1788 virtual void changeRow(SPxRowId id, const LPRowBase<R>& newRow, bool scale = false)
1789 {
1790 changeRow(number(id), newRow, scale);
1791 }
1792
1793 /// Replaces \p i 'th column of LP with \p newCol. \p scale determines whether the new data should be scaled
1794 virtual void changeCol(int n, const LPColBase<R>& newCol, bool scale = false)
1795 {
1796 if(n < 0)
1797 return;
1798
1799 int j;
1800 SVectorBase<R>& col = colVector_w(n);
1801
1802 for(j = col.size() - 1; j >= 0; --j)
1803 {
1804 SVectorBase<R>& row = rowVector_w(col.index(j));
1805 int position = row.pos(n);
1806
1807 assert(position != -1);
1808
1809 if(position >= 0)
1810 row.remove(position);
1811 }
1812
1813 col.clear();
1814
1815 changeUpper(n, newCol.upper(), scale);
1816 changeLower(n, newCol.lower(), scale);
1817 changeObj(n, newCol.obj(), scale);
1818
1819 const SVectorBase<R>& newcol = newCol.colVector();
1820
1821 for(j = newcol.size() - 1; j >= 0; --j)
1822 {
1823 int idx = newcol.index(j);
1824 R val = newcol.value(j);
1825
1826 if(scale)
1828
1829 LPColSetBase<R>::add2(n, 1, &idx, &val);
1830 LPRowSetBase<R>::add2(idx, 1, &n, &val);
1831 }
1832
1833 assert(isConsistent());
1834 }
1835
1836 /// Replaces column with identifier \p id with \p newCol. \p scale determines whether the new data should be scaled
1837 virtual void changeCol(SPxColId id, const LPColBase<R>& newCol, bool scale = false)
1838 {
1839 changeCol(number(id), newCol, scale);
1840 }
1841
1842 /// Changes LP element (\p i, \p j) to \p val. \p scale determines whether the new data should be scaled
1843 virtual void changeElement(int i, int j, const R& val, bool scale = false)
1844 {
1845 if(i < 0 || j < 0)
1846 return;
1847
1848 SVectorBase<R>& row = rowVector_w(i);
1849 SVectorBase<R>& col = colVector_w(j);
1850
1851 if(isNotZero(val, this->tolerances()->epsilon()))
1852 {
1853 R newVal;
1854
1855 if(scale)
1856 {
1857 assert(_isScaled);
1858 assert(lp_scaler);
1859 newVal = lp_scaler->scaleElement(*this, i, j, val);
1860 }
1861 else
1862 newVal = val;
1863
1864 if(row.pos(j) >= 0 && col.pos(i) >= 0)
1865 {
1866 row.value(row.pos(j)) = newVal;
1867 col.value(col.pos(i)) = newVal;
1868 }
1869 else
1870 {
1871 LPRowSetBase<R>::add2(i, 1, &j, &newVal);
1872 LPColSetBase<R>::add2(j, 1, &i, &newVal);
1873 }
1874 }
1875 else if(row.pos(j) >= 0 && col.pos(i) >= 0)
1876 {
1877 row.remove(row.pos(j));
1878 col.remove(col.pos(i));
1879 }
1880
1881 assert(isConsistent());
1882 }
1883
1884 /// Changes LP element (\p i, \p j) to \p val.
1885 template < class S >
1886 void changeElement(int i, int j, const S* val)
1887 {
1888 if(i < 0 || j < 0)
1889 return;
1890
1891 SVectorBase<R>& row = rowVector_w(i);
1892 SVectorBase<R>& col = colVector_w(j);
1893
1894 if(mpq_get_d(*val) != R(0))
1895 {
1896 if(row.pos(j) >= 0 && col.pos(i) >= 0)
1897 {
1898 row.value(row.pos(j)) = *val;
1899 col.value(col.pos(i)) = *val;
1900 }
1901 else
1902 {
1903 LPRowSetBase<R>::add2(i, 1, &j, val);
1904 LPColSetBase<R>::add2(j, 1, &i, val);
1905 }
1906 }
1907 else if(row.pos(j) >= 0 && col.pos(i) >= 0)
1908 {
1909 row.remove(row.pos(j));
1910 col.remove(col.pos(i));
1911 }
1912
1913 assert(isConsistent());
1914 }
1915
1916 /// Changes LP element identified by (\p rid, \p cid) to \p val. \p scale determines whether the new data should be scaled
1917 virtual void changeElement(SPxRowId rid, SPxColId cid, const R& val, bool scale = false)
1918 {
1919 changeElement(number(rid), number(cid), val, scale);
1920 }
1921
1922 /// Changes optimization sense to \p sns.
1923 virtual void changeSense(SPxSense sns)
1924 {
1925 if(sns != thesense)
1926 {
1928 LPRowSetBase<R>::obj_w() *= -1;
1929 }
1930
1931 thesense = sns;
1932 }
1933
1934 template <typename T>
1935 void changeObjOffset(const T& o)
1936 {
1937 offset = o; // Converts o into type R. Example Rational into
1938 // R
1939 }
1940
1941 /// Computes activity of the rows for a given primal vector; activity does not need to be zero
1942 /// @throw SPxInternalCodeException if the dimension of primal vector does not match number of columns or if the
1943 /// dimension of the activity vector does not match the number of rows
1944 /// \p unscaled determines whether the returned data should be unscaled (if scaling was applied prior)
1945 virtual void computePrimalActivity(const VectorBase<R>& primal, VectorBase<R>& activity,
1946 const bool unscaled = true) const;
1947
1948 /// Updates activity of the rows for a given primal vector; activity does not need to be zero
1949 /// @throw SPxInternalCodeException if the dimension of primal vector does not match number of columns or if the
1950 /// dimension of the activity vector does not match the number of rows
1951 virtual void addPrimalActivity(const SVectorBase<R>& primal, VectorBase<R>& activity) const
1952 {
1953 if(activity.dim() != nRows())
1954 {
1955 throw SPxInternalCodeException("XSPXLP03 Activity vector computing row activity has wrong dimension");
1956 }
1957
1958 for(int i = primal.size() - 1; i >= 0; i--)
1959 {
1960 assert(primal.index(i) >= 0);
1961 assert(primal.index(i) < nCols());
1962 activity.multAdd(primal.value(i), colVector(primal.index(i)));
1963 }
1964 }
1965
1966 /// Computes "dual" activity of the columns for a given dual vector, i.e., y^T A; activity does not need to be zero
1967 /// @throw SPxInternalCodeException if dimension of dual vector does not match number of rows or if the dimension of
1968 /// the activity vector does not match the number of columns
1969 virtual void computeDualActivity(const VectorBase<R>& dual, VectorBase<R>& activity,
1970 const bool unscaled = true) const;
1971
1972 /// Updates "dual" activity of the columns for a given dual vector, i.e., y^T A; activity does not need to be zero
1973 /// @throw SPxInternalCodeException if dimension of dual vector does not match number of rows or if the dimension of
1974 /// the activity vector does not match the number of columns
1975 virtual void addDualActivity(const SVectorBase<R>& dual, VectorBase<R>& activity) const
1976 {
1977 if(activity.dim() != nCols())
1978 {
1979 throw SPxInternalCodeException("XSPXLP04 Activity vector computing dual activity has wrong dimension");
1980 }
1981
1982 for(int i = dual.size() - 1; i >= 0; i--)
1983 {
1984 assert(dual.index(i) >= 0);
1985 assert(dual.index(i) < nRows());
1986 activity.multAdd(dual.value(i), rowVector(dual.index(i)));
1987 }
1988 }
1989
1990 /// Updates "dual" activity of the columns for a given dual vector, i.e., y^T A; activity does not need to be zero
1991 /// @throw SPxInternalCodeException if dimension of dual vector does not match number of rows or if the dimension of
1992 /// the activity vector does not match the number of columns
1993 virtual void subDualActivity(const VectorBase<R>& dual, VectorBase<R>& activity) const
1994 {
1995 if(dual.dim() != nRows())
1996 {
1997 throw SPxInternalCodeException("XSPXLP02 Dual vector for computing dual activity has wrong dimension");
1998 }
1999
2000 if(activity.dim() != nCols())
2001 {
2002 throw SPxInternalCodeException("XSPXLP04 Activity vector computing dual activity has wrong dimension");
2003 }
2004
2005 for(int r = 0; r < nRows(); r++)
2006 {
2007 if(dual[r] != 0)
2008 activity.multSub(dual[r], rowVector(r));
2009 }
2010 }
2011
2012 ///@}
2013
2014 // ------------------------------------------------------------------------------------------------------------------
2015 /**@name Construction of dual problem */
2016 ///@{
2017
2018 /// Building the dual problem from a given LP
2019 /// @note primalRows must be as large as the number of unranged primal rows + 2 * the number of ranged primal rows.
2020 /// dualCols must have the identical size to the primal rows.
2021 virtual void buildDualProblem(SPxLPBase<R>& dualLP, SPxRowId primalRowIds[] = nullptr,
2022 SPxColId primalColIds[] = nullptr,
2023 SPxRowId dualRowIds[] = nullptr, SPxColId dualColIds[] = nullptr, int* nprimalrows = nullptr,
2024 int* nprimalcols = nullptr,
2025 int* ndualrows = nullptr, int* ndualcols = nullptr);
2026
2027 ///@}
2028
2029 // ------------------------------------------------------------------------------------------------------------------
2030 /**@name Miscellaneous */
2031 ///@{
2032
2033 /// Consistency check.
2034 bool isConsistent() const
2035 {
2036 if(this->_tolerances == nullptr && nCols() != 0)
2037 return SPX_MSG_INCONSISTENT("SPxLPBase");
2038
2039#ifdef ENABLE_CONSISTENCY_CHECKS
2040
2041 for(int i = nCols() - 1; i >= 0; --i)
2042 {
2043 const SVectorBase<R>& v = colVector(i);
2044
2045 for(int j = v.size() - 1; j >= 0; --j)
2046 {
2047 const SVectorBase<R>& w = rowVector(v.index(j));
2048 int n = w.pos(i);
2049
2050 if(n < 0)
2051 return SPX_MSG_INCONSISTENT("SPxLPBase");
2052
2053 if(v.value(j) != w.value(n))
2054 return SPX_MSG_INCONSISTENT("SPxLPBase");
2055 }
2056 }
2057
2058 for(int i = nRows() - 1; i >= 0; --i)
2059 {
2060 const SVectorBase<R>& v = rowVector(i);
2061
2062 for(int j = v.size() - 1; j >= 0; --j)
2063 {
2064 const SVectorBase<R>& w = colVector(v.index(j));
2065 int n = w.pos(i);
2066
2067 if(n < 0)
2068 return SPX_MSG_INCONSISTENT("SPxLPBase");
2069
2070 if(v.value(j) != w.value(n))
2071 return SPX_MSG_INCONSISTENT("SPxLPBase");
2072 }
2073 }
2074
2076#else
2077 return true;
2078#endif
2079 }
2080
2081 ///@}
2082
2083protected:
2084
2085 std::shared_ptr<Tolerances> _tolerances;
2086
2087 // ------------------------------------------------------------------------------------------------------------------
2088 /**@name Protected write access */
2089 ///@{
2090
2091 /// Returns right hand side of row \p i.
2092 R& rhs_w(int i)
2093 {
2094 return LPRowSetBase<R>::rhs_w(i);
2095 }
2096
2097 /// Returns left hand side of row \p i.
2098 R& lhs_w(int i)
2099 {
2100 return LPRowSetBase<R>::lhs_w(i);
2101 }
2102
2103 /// Returns objective function value of row \p i.
2104 R& maxRowObj_w(int i)
2105 {
2106 return LPRowSetBase<R>::obj_w(i);
2107 }
2108
2109 /// Returns objective value of column \p i for maximization problem.
2110 R& maxObj_w(int i)
2111 {
2112 return LPColSetBase<R>::maxObj_w(i);
2113 }
2114
2115 /// Returns upper bound of column \p i.
2116 R& upper_w(int i)
2117 {
2118 return LPColSetBase<R>::upper_w(i);
2119 }
2120
2121 /// Returns lower bound of column \p i.
2122 R& lower_w(int i)
2123 {
2124 return LPColSetBase<R>::lower_w(i);
2125 }
2126
2127 ///@}
2128
2129 // ------------------------------------------------------------------------------------------------------------------
2130 /**@name Protected helpers */
2131 ///@{
2132
2133 /// Returns the LP as an LPRowSetBase.
2135 {
2136 return static_cast<const LPRowSetBase<R>*>(this);
2137 }
2138
2139 /// Returns the LP as an LPColSetBase.
2141 {
2142 return static_cast<const LPColSetBase<R>*>(this);
2143 }
2144
2145 /// Internal helper method.
2146 virtual void doRemoveRow(int j)
2147 {
2148
2149 const SVectorBase<R>& vec = rowVector(j);
2150
2151 // remove row vector from column file
2152 for(int i = vec.size() - 1; i >= 0; --i)
2153 {
2154 SVectorBase<R>& remvec = colVector_w(vec.index(i));
2155 int position = remvec.pos(j);
2156
2157 if(position >= 0)
2158 remvec.remove(position);
2159 }
2160
2161 // move last row to removed position
2162 int idx = nRows() - 1;
2163
2164 if(j != idx)
2165 {
2166 const SVectorBase<R>& l_vec = rowVector(idx);
2167
2168 for(int i = l_vec.size() - 1; i >= 0; --i)
2169 {
2170 SVectorBase<R>& movevec = colVector_w(l_vec.index(i));
2171 int position = movevec.pos(idx);
2172
2173 assert(position != -1);
2174
2175 if(position >= 0)
2176 movevec.index(position) = j;
2177 }
2178 }
2179
2181 }
2182
2183 /// Internal helper method.
2184 virtual void doRemoveRows(int perm[])
2185 {
2186 int j = nCols();
2187
2189
2190 for(int i = 0; i < j; ++i)
2191 {
2192 SVectorBase<R>& vec = colVector_w(i);
2193
2194 for(int k = vec.size() - 1; k >= 0; --k)
2195 {
2196 int idx = vec.index(k);
2197
2198 if(perm[idx] < 0)
2199 vec.remove(k);
2200 else
2201 vec.index(k) = perm[idx];
2202 }
2203 }
2204 }
2205
2206 /// Internal helper method.
2207 virtual void doRemoveCol(int j)
2208 {
2209
2210 const SVectorBase<R>& vec = colVector(j);
2211 int i;
2212
2213 // remove column vector from row file
2214 for(i = vec.size() - 1; i >= 0; --i)
2215 {
2216 SVectorBase<R>& remvec = rowVector_w(vec.index(i));
2217 int position = remvec.pos(j);
2218
2219 assert(position != -1);
2220
2221 if(position >= 0)
2222 remvec.remove(position);
2223 }
2224
2225 // move last column to removed position
2226 int idx = nCols() - 1;
2227
2228 if(j != idx)
2229 {
2230 const SVectorBase<R>& l_vec = colVector(idx);
2231
2232 for(i = l_vec.size() - 1; i >= 0; --i)
2233 {
2234 SVectorBase<R>& movevec = rowVector_w(l_vec.index(i));
2235 int position = movevec.pos(idx);
2236
2237 assert(position != -1);
2238
2239 if(position >= 0)
2240 movevec.index(position) = j;
2241 }
2242 }
2243
2245 }
2246
2247 /// Internal helper method.
2248 virtual void doRemoveCols(int perm[])
2249 {
2250 int nrows = nRows();
2251
2253
2254 for(int i = 0; i < nrows; ++i)
2255 {
2256 SVectorBase<R>& vec = rowVector_w(i);
2257
2258 for(int k = vec.size() - 1; k >= 0; --k)
2259 {
2260 int idx = vec.index(k);
2261
2262 if(perm[idx] < 0)
2263 vec.remove(k);
2264 else
2265 vec.index(k) = perm[idx];
2266 }
2267 }
2268 }
2269
2270 /// Called after the last \p n rows have just been added.
2271 virtual void addedRows(int newrows)
2272 {}
2273
2274 /// Called after the last \p n columns have just been added.
2275 virtual void addedCols(int newcols)
2276 {}
2277
2278 ///
2279 void added2Set(SVSetBase<R>& set, const SVSetBase<R>& addset, int n)
2280 {
2281
2282 if(n == 0)
2283 return;
2284
2285 DataArray<int> moreArray(set.num());
2286 int* more = moreArray.get_ptr();
2287
2288 for(int i = set.num() - 1; i >= 0; --i)
2289 more[i] = 0;
2290
2291 int tot = 0;
2292 int end = addset.num();
2293
2294 for(int i = addset.num() - n; i < end; ++i)
2295 {
2296 const SVectorBase<R>& vec = addset[i];
2297
2298 tot += vec.size();
2299
2300 for(int j = vec.size() - 1; j >= 0; --j)
2301 more[vec.index(j)]++;
2302 }
2303
2304 if(set.memMax() < tot)
2305 set.memRemax(tot);
2306
2307 for(int i = set.num() - 1; i >= 0; --i)
2308 {
2309 int j = set[i].size();
2310 set.xtend(set[i], j + more[i]);
2311 set[i].set_size(j + more[i]);
2312 more[i] = j;
2313 }
2314
2315 for(int i = addset.num() - n; i < addset.num(); ++i)
2316 {
2317 const SVectorBase<R>& vec = addset[i];
2318
2319 for(int j = vec.size() - 1; j >= 0; --j)
2320 {
2321 int k = vec.index(j);
2322 int m = more[k]++;
2323 SVectorBase<R>& l_xtend = set[k];
2324 l_xtend.index(m) = i;
2325 l_xtend.value(m) = vec.value(j);
2326 }
2327 }
2328 }
2329
2330 ///@}
2331
2332
2333private:
2334
2335 // ------------------------------------------------------------------------------------------------------------------
2336 /**@name Private helpers */
2337 ///@{
2338
2339 /// Returns the LP as an LPRowBase<R>Set.
2341 {
2343 }
2344
2345 ///
2347 {
2349 }
2350
2351 ///
2352 void doAddRow(const LPRowBase<R>& row, bool scale = false)
2353 {
2354 int idx = nRows();
2355 int oldColNumber = nCols();
2356 int newRowScaleExp = 0;
2357
2359
2360 SVectorBase<R>& vec = rowVector_w(idx);
2361
2363
2364 // compute new row scaling factor and apply it to the sides
2365 if(scale && lp_scaler)
2366 {
2367 newRowScaleExp = lp_scaler->computeScaleExp(vec, colscaleExp);
2368
2369 if(rhs(idx) < R(infinity))
2370 rhs_w(idx) = spxLdexp(rhs_w(idx), newRowScaleExp);
2371
2372 if(lhs(idx) > R(-infinity))
2373 lhs_w(idx) = spxLdexp(lhs_w(idx), newRowScaleExp);
2374
2375 maxRowObj_w(idx) = spxLdexp(maxRowObj_w(idx), newRowScaleExp);
2376
2377 LPRowSetBase<R>::scaleExp[idx] = newRowScaleExp;
2378 }
2379
2380 // now insert nonzeros to column file also
2381 for(int j = vec.size() - 1; j >= 0; --j)
2382 {
2383 int i = vec.index(j);
2384
2385 // apply new row and existing column scaling factors to new values in RowSet
2386 if(scale)
2387 vec.value(j) = spxLdexp(vec.value(j), newRowScaleExp + colscaleExp[i]);
2388
2389 R val = vec.value(j);
2390
2391 // create new columns if required
2392 if(i >= nCols())
2393 {
2394 LPColBase<R> empty;
2395
2396 for(int k = nCols(); k <= i; ++k)
2397 LPColSetBase<R>::add(empty);
2398 }
2399
2400 assert(i < nCols());
2401 LPColSetBase<R>::add2(i, 1, &idx, &val);
2402 }
2403
2404 addedRows(1);
2405 addedCols(nCols() - oldColNumber);
2406 }
2407
2408 ///
2409 void doAddRow(const R& lhsValue, const SVectorBase<R>& rowVec, const R& rhsValue,
2410 bool scale = false)
2411 {
2412 int idx = nRows();
2413 int oldColNumber = nCols();
2414 int newRowScaleExp = 0;
2415
2416 LPRowSetBase<R>::add(lhsValue, rowVec, rhsValue);
2417
2419
2420 // compute new row scaling factor and apply it to the sides
2421 if(scale)
2422 {
2423 newRowScaleExp = lp_scaler->computeScaleExp(rowVec, colscaleExp);
2424
2425 if(rhs(idx) < R(infinity))
2426 rhs_w(idx) = spxLdexp(rhs_w(idx), newRowScaleExp);
2427
2428 if(lhs(idx) > R(-infinity))
2429 lhs_w(idx) = spxLdexp(lhs_w(idx), newRowScaleExp);
2430
2431 maxRowObj_w(idx) = spxLdexp(maxRowObj_w(idx), newRowScaleExp);
2432
2433 LPRowSetBase<R>::scaleExp[idx] = newRowScaleExp;
2434 }
2435
2436 SVectorBase<R>& vec = rowVector_w(idx);
2437
2438 // now insert nonzeros to column file also
2439 for(int j = vec.size() - 1; j >= 0; --j)
2440 {
2441 int i = vec.index(j);
2442
2443 // apply new row and existing column scaling factors to new values in RowSet
2444 if(scale)
2445 vec.value(j) = spxLdexp(vec.value(j), newRowScaleExp + colscaleExp[i]);
2446
2447 R val = vec.value(j);
2448
2449 // create new columns if required
2450 if(i >= nCols())
2451 {
2452 LPColBase<R> empty;
2453
2454 for(int k = nCols(); k <= i; ++k)
2455 LPColSetBase<R>::add(empty);
2456 }
2457
2458 assert(i < nCols());
2459 LPColSetBase<R>::add2(i, 1, &idx, &val);
2460 }
2461
2462 addedRows(1);
2463 addedCols(nCols() - oldColNumber);
2464 }
2465
2466 ///
2467 void doAddRows(const LPRowSetBase<R>& set, bool scale = false)
2468 {
2469 int i, j, k, ii, idx;
2470 SVectorBase<R>* col;
2471 DataArray < int > newCols(nCols());
2472 int oldRowNumber = nRows();
2473 int oldColNumber = nCols();
2474
2475 if(&set != this)
2477
2480
2481 // count additional nonzeros per column
2482 for(i = nCols() - 1; i >= 0; --i)
2483 newCols[i] = 0;
2484
2485 for(i = set.num() - 1; i >= 0; --i)
2486 {
2487 const SVectorBase<R>& vec = set.rowVector(i);
2488
2489 for(j = vec.size() - 1; j >= 0; --j)
2490 {
2491 // create new columns if required
2492 ii = vec.index(j);
2493
2494 if(ii >= nCols())
2495 {
2496 LPColBase<R> empty;
2497 newCols.reSize(ii + 1);
2498
2499 for(k = nCols(); k <= ii; ++k)
2500 {
2501 newCols[k] = 0;
2502 LPColSetBase<R>::add(empty);
2503 }
2504 }
2505
2506 assert(ii < nCols());
2507 newCols[ii]++;
2508 }
2509 }
2510
2511 // extend columns as required (backward because of memory efficiency reasons)
2512 for(i = nCols() - 1; i >= 0; --i)
2513 {
2514 if(newCols[i] > 0)
2515 {
2516 int len = newCols[i] + colVector(i).size();
2517 LPColSetBase<R>::xtend(i, len);
2518
2519 /* preset the sizes: beware that this can irritate a consistency check call from xtend(). We need to set the
2520 * sizes here, because a possible garbage collection called from xtend might destroy the sizes again. */
2521 colVector_w(i).set_size(len);
2522 }
2523 }
2524
2525 // compute new row scaling factor and insert new elements to column file
2526 for(i = nRows() - 1; i >= oldRowNumber; --i)
2527 {
2528 SVectorBase<R>& vec = rowVector_w(i);
2529 int newRowScaleExp = 0;
2530
2532
2533 // compute new row scaling factor and apply it to the sides
2534 if(scale)
2535 {
2536 newRowScaleExp = lp_scaler->computeScaleExp(vec, colscaleExp);
2537
2538 if(rhs(i) < R(infinity))
2539 rhs_w(i) = spxLdexp(rhs_w(i), newRowScaleExp);
2540
2541 if(lhs(i) > R(-infinity))
2542 lhs_w(i) = spxLdexp(lhs_w(i), newRowScaleExp);
2543
2544 maxRowObj_w(i) = spxLdexp(maxRowObj_w(i), newRowScaleExp);
2545
2546 LPRowSetBase<R>::scaleExp[i] = newRowScaleExp;
2547 }
2548
2549 for(j = vec.size() - 1; j >= 0; --j)
2550 {
2551 k = vec.index(j);
2552 col = &colVector_w(k);
2553 idx = col->size() - newCols[k];
2554 assert(newCols[k] > 0);
2555 assert(idx >= 0);
2556 newCols[k]--;
2557 col->index(idx) = i;
2558
2559 // apply new row and existing column scaling factors to both ColSet and RowSet
2560 if(scale)
2561 vec.value(j) = spxLdexp(vec.value(j), newRowScaleExp + colscaleExp[k]);
2562
2563 col->value(idx) = vec.value(j);
2564 }
2565 }
2566
2567#ifndef NDEBUG
2568
2569 for(i = 0; i < nCols(); ++i)
2570 assert(newCols[i] == 0);
2571
2572#endif
2573
2575
2576 assert(set.num() == nRows() - oldRowNumber);
2577 addedRows(nRows() - oldRowNumber);
2578 addedCols(nCols() - oldColNumber);
2579 }
2580
2581 ///
2582 void doAddCol(const LPColBase<R>& col, bool scale = false)
2583 {
2584 int idx = nCols();
2585 int oldRowNumber = nRows();
2586 int newColScaleExp = 0;
2587
2589
2590 if(thesense != MAXIMIZE)
2591 LPColSetBase<R>::maxObj_w(idx) *= -1;
2592
2593 SVectorBase<R>& vec = colVector_w(idx);
2594
2596
2597 // compute new column scaling factor and apply it to the bounds
2598 if(scale)
2599 {
2600 newColScaleExp = lp_scaler->computeScaleExp(vec, rowscaleExp);
2601
2602 if(upper(idx) < R(infinity))
2603 upper_w(idx) = spxLdexp(upper_w(idx), - newColScaleExp);
2604
2605 if(lower(idx) > R(-infinity))
2606 lower_w(idx) = spxLdexp(lower_w(idx), - newColScaleExp);
2607
2608 maxObj_w(idx) = spxLdexp(maxObj_w(idx), newColScaleExp);
2609
2610 LPColSetBase<R>::scaleExp[idx] = newColScaleExp;
2611 }
2612
2613 // now insert nonzeros to row file also
2614 for(int j = vec.size() - 1; j >= 0; --j)
2615 {
2616 int i = vec.index(j);
2617
2618 // apply new column and existing row scaling factors to new values in ColSet
2619 if(scale)
2620 vec.value(j) = spxLdexp(vec.value(j), newColScaleExp + rowscaleExp[i]);
2621
2622 R val = vec.value(j);
2623
2624 // create new rows if required
2625 if(i >= nRows())
2626 {
2627 LPRowBase<R> empty;
2628
2629 for(int k = nRows(); k <= i; ++k)
2630 LPRowSetBase<R>::add(empty);
2631 }
2632
2633 assert(i < nRows());
2634 LPRowSetBase<R>::add2(i, 1, &idx, &val);
2635 }
2636
2637 addedCols(1);
2638 addedRows(nRows() - oldRowNumber);
2639 }
2640
2641 ///
2642 void doAddCol(const R& objValue, const R& lowerValue, const SVectorBase<R>& colVec,
2643 const R& upperValue, bool scale = false)
2644 {
2645 int idx = nCols();
2646 int oldRowNumber = nRows();
2647 int newColScaleExp = 0;
2648
2649 LPColSetBase<R>::add(objValue, lowerValue, colVec, upperValue);
2650
2651 if(thesense != MAXIMIZE)
2652 LPColSetBase<R>::maxObj_w(idx) *= -1;
2653
2655
2656 // compute new column scaling factor and apply it to the bounds
2657 if(scale)
2658 {
2659 newColScaleExp = lp_scaler->computeScaleExp(colVec, rowscaleExp);
2660
2661 if(upper(idx) < R(infinity))
2662 upper_w(idx) = spxLdexp(upper_w(idx), - newColScaleExp);
2663
2664 if(lower(idx) > R(-infinity))
2665 lower_w(idx) = spxLdexp(lower_w(idx), - newColScaleExp);
2666
2667 maxObj_w(idx) = spxLdexp(maxObj_w(idx), newColScaleExp);
2668
2669 LPColSetBase<R>::scaleExp[idx] = newColScaleExp;
2670 }
2671
2672 SVectorBase<R>& vec = colVector_w(idx);
2673
2674 // now insert nonzeros to row file also
2675 for(int j = vec.size() - 1; j >= 0; --j)
2676 {
2677 int i = vec.index(j);
2678
2679 if(scale)
2680 vec.value(j) = spxLdexp(vec.value(j), newColScaleExp + rowscaleExp[i]);
2681
2682 R val = vec.value(j);
2683
2684 // create new rows if required
2685 if(i >= nRows())
2686 {
2687 LPRowBase<R> empty;
2688
2689 for(int k = nRows(); k <= i; ++k)
2690 LPRowSetBase<R>::add(empty);
2691 }
2692
2693 assert(i < nRows());
2694 LPRowSetBase<R>::add2(i, 1, &idx, &val);
2695 }
2696
2697 addedCols(1);
2698 addedRows(nRows() - oldRowNumber);
2699 }
2700
2701 ///
2702 void doAddCols(const LPColSetBase<R>& set, bool scale = false)
2703 {
2704 int i, j;
2705 int oldColNumber = nCols();
2706 int oldRowNumber = nRows();
2707 DataArray < int > newRows(nRows());
2708
2709 if(&set != this)
2711
2714
2715 // count additional nonzeros per row
2716 for(i = nRows() - 1; i >= 0; --i)
2717 newRows[i] = 0;
2718
2719 for(i = set.num() - 1; i >= 0; --i)
2720 {
2721 const SVectorBase<R>& vec = set.colVector(i);
2722
2723 for(j = vec.size() - 1; j >= 0; --j)
2724 {
2725 // create new rows if required
2726 int l = vec.index(j);
2727
2728 if(l >= nRows())
2729 {
2730 LPRowBase<R> empty;
2731 newRows.reSize(l + 1);
2732
2733 for(int k = nRows(); k <= l; ++k)
2734 {
2735 newRows[k] = 0;
2736 LPRowSetBase<R>::add(empty);
2737 }
2738
2739 }
2740
2741 assert(l < nRows());
2742 newRows[l]++;
2743 }
2744 }
2745
2746 // extend rows as required
2747 for(i = 0; i < nRows(); ++i)
2748 {
2749 if(newRows[i] > 0)
2750 {
2751 int len = newRows[i] + rowVector(i).size();
2752 LPRowSetBase<R>::xtend(i, len);
2753 rowVector_w(i).set_size(len);
2754 }
2755 }
2756
2757 // insert new elements to row file
2758 for(i = oldColNumber; i < nCols(); ++i)
2759 {
2760 // @todo: Is there a better way to write the following if, else?
2761 if(thesense == MAXIMIZE)
2762 {
2764 }
2765 else // thesense is MINIMIZE = -1
2766 {
2768 }
2769
2770 SVectorBase<R>& vec = colVector_w(i);
2771 int newColScaleExp = 0;
2772
2774
2775 // compute new column scaling factor and apply it to the bounds
2776 if(scale)
2777 {
2778 newColScaleExp = lp_scaler->computeScaleExp(vec, rowscaleExp);
2779
2780 if(upper(i) < R(infinity))
2781 upper_w(i) = spxLdexp(upper_w(i), - newColScaleExp);
2782
2783 if(lower(i) > R(-infinity))
2784 lower_w(i) = spxLdexp(lower_w(i), - newColScaleExp);
2785
2786 maxObj_w(i) = spxLdexp(maxObj_w(i), newColScaleExp);
2787
2788 LPColSetBase<R>::scaleExp[i] = newColScaleExp;
2789 }
2790
2791 for(j = vec.size() - 1; j >= 0; --j)
2792 {
2793 int k = vec.index(j);
2794 SVectorBase<R>& row = rowVector_w(k);
2795 int idx = row.size() - newRows[k];
2796 assert(newRows[k] > 0);
2797 newRows[k]--;
2798 row.index(idx) = i;
2799
2800 // apply new column and existing row scaling factors to both ColSet and RowSet
2801 if(scale)
2802 vec.value(j) = spxLdexp(vec.value(j), newColScaleExp + rowscaleExp[k]);
2803
2804 row.value(idx) = vec.value(j);
2805 }
2806 }
2807
2808#ifndef NDEBUG
2809
2810 for(i = 0; i < nRows(); ++i)
2811 assert(newRows[i] == 0);
2812
2813#endif
2814
2816
2817 assert(set.num() == nCols() - oldColNumber);
2818 addedCols(nCols() - oldColNumber);
2819 addedRows(nRows() - oldRowNumber);
2820 }
2821
2822 ///@}
2823
2824public:
2825
2826 // ------------------------------------------------------------------------------------------------------------------
2827 /**@name Constructors / Destructors */
2828 ///@{
2829
2830 /// Default constructor.
2832 {
2833 SPxLPBase<R>::clear(); // clear is virtual.
2834
2835 assert(isConsistent());
2836 }
2837
2838 /// Destructor.
2839 virtual ~SPxLPBase()
2840 {}
2841
2842 /// Copy constructor.
2844 : LPRowSetBase<R>(old)
2845 , LPColSetBase<R>(old)
2846 , thesense(old.thesense)
2847 , offset(old.offset)
2848 , _isScaled(old._isScaled)
2849 , lp_scaler(old.lp_scaler)
2850 , spxout(old.spxout)
2851 {
2853 assert(isConsistent());
2854 }
2855
2856 /// Copy constructor.
2857 template < class S >
2859 : LPRowSetBase<R>(old)
2860 , LPColSetBase<R>(old)
2862 , offset(old.offset)
2863 , _isScaled(old._isScaled)
2864 , spxout(old.spxout)
2865 {
2866 lp_scaler = nullptr;
2868 assert(isConsistent());
2869 }
2870
2871 /// Assignment operator.
2873 {
2874 if(this != &old)
2875 {
2878 thesense = old.thesense;
2879 offset = old.offset;
2880 _isScaled = old._isScaled;
2881 lp_scaler = old.lp_scaler;
2882 spxout = old.spxout;
2884
2885 assert(isConsistent());
2886 }
2887
2888 return *this;
2889 }
2890
2891 /// Assignment operator.
2892 template < class S >
2894 {
2895 if(this != (const SPxLPBase<R>*)(&old))
2896 {
2897 // The value of old.lp_scaler has to be nullptr
2898 // Refer to issue #161 in soplex gitlab
2899 assert(old.lp_scaler == nullptr);
2900
2905 offset = R(old.offset);
2906 _isScaled = old._isScaled;
2908
2909 // this may have un-intended consequences in the future
2910 lp_scaler = nullptr;
2911 spxout = old.spxout;
2912
2913 assert(isConsistent());
2914 }
2915
2916 return *this;
2917 }
2918
2919 ///@}
2920};
2921
2922} // namespace soplex
2923
2924// For the general templated functions
2925#include "spxlpbase_real.hpp"
2926#include "spxlpbase_rational.hpp"
2927
2928/* reset the SOPLEX_DEBUG flag to its original value */
2929#undef SOPLEX_DEBUG
2930#ifdef SOPLEX_DEBUG_SPXLPBASE
2931#define SOPLEX_DEBUG
2932#undef SOPLEX_DEBUG_SPXLPBASE
2933#endif
2934
2935#endif // _SPXLPBASE_H_
Collection of dense, sparse, and semi-sparse vectors.
Dynamic index set.
Definition: didxset.h:52
Dynamic sparse vectors.
Definition: dsvectorbase.h:53
T * get_ptr()
get a C pointer to the data.
Definition: dataarray.h:123
void reSize(int newsize)
reset size to newsize.
Definition: dataarray.h:239
LP column.
Definition: lpcolbase.h:55
R upper() const
Gets upper bound.
Definition: lpcolbase.h:148
void setLower(const R &p_low)
Sets lower bound.
Definition: lpcolbase.h:165
const SVectorBase< R > & colVector() const
Gets constraint column vector.
Definition: lpcolbase.h:171
void setUpper(const R &p_up)
Sets upper bound.
Definition: lpcolbase.h:154
void setColVector(const SVectorBase< R > &p_vec)
Sets constraint column vector.
Definition: lpcolbase.h:177
R lower() const
Gets lower bound.
Definition: lpcolbase.h:160
R obj() const
Gets objective value.
Definition: lpcolbase.h:136
void setObj(const R &p_object)
Sets objective value.
Definition: lpcolbase.h:142
Set of LP columns.
Definition: lpcolsetbase.h:53
void remove(int i)
Removes i 'th LPColBase.
Definition: lpcolsetbase.h:439
VectorBase< R > & lower_w()
Returns vector of lower bound values.
Definition: lpcolsetbase.h:145
LPColSetBase< R > & operator=(const LPColSetBase< R > &rs)
Assignment operator.
Definition: lpcolsetbase.h:610
VectorBase< R > & maxObj_w()
Returns vector of objective values w.r.t. maximization.
Definition: lpcolsetbase.h:109
const VectorBase< R > & maxObj() const
Definition: lpcolsetbase.h:103
const VectorBase< R > & lower() const
Definition: lpcolsetbase.h:139
bool isConsistent() const
Checks consistency.
Definition: lpcolsetbase.h:572
void add2(const DataKey &k, int n, const int idx[], const R val[])
Definition: lpcolsetbase.h:381
int number(const DataKey &k) const
Returns number of LPColBase with DataKey k in LPColSetBase.
Definition: lpcolsetbase.h:241
SVectorBase< R > & colVector_w(int i)
Definition: lpcolsetbase.h:211
void memRemax(int newmax)
Resets length of nonzero memory.
Definition: lpcolsetbase.h:554
int num() const
Returns the number of LPColBases currently in LPColSetBase.
Definition: lpcolsetbase.h:91
void xtend(int n, int newmax)
Extends column n to fit newmax nonzeros.
Definition: lpcolsetbase.h:369
bool has(const DataKey &k) const
Does DataKey k belong to LPColSetBase ?
Definition: lpcolsetbase.h:247
VectorBase< R > & upper_w()
Returns vector of upper bound values.
Definition: lpcolsetbase.h:181
void add(const LPColBase< R > &pcol)
Definition: lpcolsetbase.h:264
void clear()
Removes all LPColBases from the set.
Definition: lpcolsetbase.h:514
const VectorBase< R > & upper() const
Definition: lpcolsetbase.h:175
const SVectorBase< R > & colVector(int i) const
Returns colVector of i 'th LPColBase in LPColSetBase.
Definition: lpcolsetbase.h:217
(In)equality for LPs.
Definition: lprowbase.h:55
const SVectorBase< R > & rowVector() const
Constraint row vector.
Definition: lprowbase.h:270
Type
(In)Equality type of an LP row.
Definition: lprowbase.h:82
void setLhs(const R &p_left)
Sets left-hand side value.
Definition: lprowbase.h:240
void setRhs(const R &p_right)
Sets right-hand side value.
Definition: lprowbase.h:252
R rhs() const
Right-hand side value.
Definition: lprowbase.h:246
void setObj(const R &p_obj)
Sets objective coefficient value.
Definition: lprowbase.h:264
R lhs() const
Left-hand side value.
Definition: lprowbase.h:234
R obj() const
Objective coefficient value.
Definition: lprowbase.h:258
void setRowVector(const DSVectorBase< R > &p_vec)
access constraint row vector.
Definition: lprowbase.h:276
Set of LP rows.
Definition: lprowsetbase.h:54
const VectorBase< R > & rhs() const
Returns the vector of rhs values.
Definition: lprowsetbase.h:140
const VectorBase< R > & lhs() const
Returns the vector of lhs values.
Definition: lprowsetbase.h:104
void remove(int i)
Removes i 'th LPRowBase.
Definition: lprowsetbase.h:526
bool isConsistent() const
Checks consistency.
Definition: lprowsetbase.h:662
void add2(const DataKey &k, int n, const int idx[], const R val[])
Adds n nonzero (idx, val)-pairs to rowVector with DataKey k.
Definition: lprowsetbase.h:469
void add(const LPRowBase< R > &row)
Definition: lprowsetbase.h:337
int number(const DataKey &k) const
Returns the number of the LPRowBase with DataKey k in LPRowSetBase.
Definition: lprowsetbase.h:314
SVectorBase< R > & rowVector_w(int i)
Returns a writable rowVector of the i 'th LPRowBase.
Definition: lprowsetbase.h:212
LPRowSetBase< R > & operator=(const LPRowSetBase< R > &rs)
Assignment operator.
Definition: lprowsetbase.h:701
void memRemax(int newmax)
Reallocates memory to be able to store newmax nonzeros.
Definition: lprowsetbase.h:644
VectorBase< R > & rhs_w()
Returns the vector of rhs values (writeable).
Definition: lprowsetbase.h:146
int num() const
Returns the number of LPRowBases in LPRowSetBase.
Definition: lprowsetbase.h:92
const SVectorBase< R > & rowVector(int i) const
Returns the rowVector of the i 'th LPRowBase.
Definition: lprowsetbase.h:218
void xtend(int n, int newmax)
Extends row n to fit newmax nonzeros.
Definition: lprowsetbase.h:457
VectorBase< R > & obj_w()
Returns the vector of objective coefficients (writeable).
Definition: lprowsetbase.h:182
const VectorBase< R > & obj() const
Returns the vector of objective coefficients.
Definition: lprowsetbase.h:176
bool has(const DataKey &k) const
does DataKey k belong to LPRowSetBase ?
Definition: lprowsetbase.h:320
VectorBase< R > & lhs_w()
Returns the vector of lhs values.
Definition: lprowsetbase.h:110
void clear()
Removes all LPRowBases.
Definition: lprowsetbase.h:602
LPRowBase< R >::Type type(int i) const
Returns the inequalitiy type of the i 'th LPRowBase.
Definition: lprowsetbase.h:236
Set of strings.
Definition: nameset.h:71
Simplex basis.
Definition: spxbasis.h:94
Ids for LP columns.
Definition: spxid.h:46
Equilibrium row/column scaling.
Definition: spxequilisc.h:46
Geometric mean row/column scaling.
Definition: spxgeometsc.h:46
Generic Ids for LP rows or columns.
Definition: spxid.h:95
@ COL_ID
column identifier.
Definition: spxid.h:108
Exception class for things that should NEVER happen.
Definition: exceptions.h:119
Saving LPs in a form suitable for SoPlex.
Definition: spxlpbase.h:108
const VectorBase< R > & rhs() const
Returns right hand side vector.
Definition: spxlpbase.h:260
void setOutstream(SPxOut &newOutstream)
Definition: spxlpbase.h:153
SPxSense spxSense() const
Returns the optimization sense.
Definition: spxlpbase.h:554
const VectorBase< R > & lhs() const
Returns left hand side vector.
Definition: spxlpbase.h:294
SPxSense
Optimization sense.
Definition: spxlpbase.h:125
virtual void changeElement(int i, int j, const R &val, bool scale=false)
Changes LP element (i, j) to val. scale determines whether the new data should be scaled.
Definition: spxlpbase.h:1843
const R & upper(const SPxColId &id) const
Returns upper bound of column with identifier id.
Definition: spxlpbase.h:512
void added2Set(SVSetBase< R > &set, const SVSetBase< R > &addset, int n)
Definition: spxlpbase.h:2279
void changeLower(int i, const S *newLower)
changes i 'th lower bound to newLower.
Definition: spxlpbase.h:1497
int number(const SPxRowId &id) const
Returns the row number of the row with identifier id.
Definition: spxlpbase.h:566
void getLowerUnscaled(VectorBase< R > &vec) const
Gets unscaled lower bound vector.
virtual void changeRange(int i, const R &newLhs, const R &newRhs, bool scale=false)
Changes left and right hand side of row i. scale determines whether the new data should be scaled.
Definition: spxlpbase.h:1687
virtual void addRow(const LPRowBase< R > &row, bool scale=false)
Definition: spxlpbase.h:624
void changeBounds(int i, const S *newLower, const S *newUpper)
Changes bounds of column i to newLower and newUpper.
Definition: spxlpbase.h:1576
void changeObjOffset(const T &o)
Definition: spxlpbase.h:1935
virtual void changeElement(SPxRowId rid, SPxColId cid, const R &val, bool scale=false)
Changes LP element identified by (rid, cid) to val. scale determines whether the new data should be s...
Definition: spxlpbase.h:1917
R obj(const SPxColId &id) const
Returns objective value of column with identifier id.
Definition: spxlpbase.h:457
virtual void changeMaxObj(int i, const R &newVal, bool scale=false)
changes i 'th objective vector element to newVal. scale determines whether the new data should be sca...
Definition: spxlpbase.h:1433
void getRhsUnscaled(VectorBase< R > &vec) const
Gets unscaled right hand side vector.
virtual void changeRhs(int i, const R &newRhs, bool scale=false)
Changes i 'th right hand side value to newRhs. scale determines whether the new data should be scaled...
Definition: spxlpbase.h:1657
virtual void removeRow(int i)
Removes i 'th row.
Definition: spxlpbase.h:972
R upperUnscaled(const SPxColId &id) const
Returns unscaled upper bound of column with identifier id.
R lhsUnscaled(const SPxRowId &id) const
Returns left hand side of row with identifier id.
virtual void doRemoveRows(int perm[])
Internal helper method.
Definition: spxlpbase.h:2184
virtual void addedCols(int newcols)
Called after the last n columns have just been added.
Definition: spxlpbase.h:2275
virtual void writeMPS(std::ostream &out, const NameSet *rowNames, const NameSet *colNames, const DIdxSet *p_intvars=nullptr, const bool writeZeroObjective=false) const
Writes a file in MPS format to out.
virtual void changeRow(SPxRowId id, const LPRowBase< R > &newRow, bool scale=false)
Replaces row with identifier id with newRow. scale determines whether the new data should be scaled.
Definition: spxlpbase.h:1788
void doAddCols(const LPColSetBase< R > &set, bool scale=false)
Definition: spxlpbase.h:2702
const LPColSetBase< R > * lpcolset() const
Returns the LP as an LPColSetBase.
Definition: spxlpbase.h:2140
void printProblemStatistics(std::ostream &os)
Definition: spxlpbase.h:1278
virtual bool readLPF(std::istream &in, NameSet *rowNames=nullptr, NameSet *colNames=nullptr, DIdxSet *intVars=nullptr)
Reads LP in LP format from input stream in.
bool _isScaled
true, if scaling has been performed
Definition: spxlpbase.h:140
R lhsUnscaled(int i) const
Returns unscaled left hand side of row number i.
void getLhsUnscaled(VectorBase< R > &vec) const
Returns unscaled left hand side vector.
virtual void changeMaxObj(SPxColId id, const R &newVal, bool scale=false)
Changes objective value of column with identifier id to newVal. scale determines whether the new data...
Definition: spxlpbase.h:1456
virtual void addCols(SPxColId id[], const LPColSetBase< R > &set, bool scale=false)
Adds all LPColBases of set to LPColSetBase.
Definition: spxlpbase.h:955
virtual void changeBounds(const VectorBase< R > &newLower, const VectorBase< R > &newUpper, bool scale=false)
Changes variable bounds to newLower and newUpper. scale determines whether the new data should be sca...
Definition: spxlpbase.h:1558
const VectorBase< R > & maxRowObj() const
Definition: spxlpbase.h:339
virtual void addCol(const R &objValue, const R &lowerValue, const SVectorBase< R > &colVec, const R &upperValue, bool scale=false)
Definition: spxlpbase.h:802
void getColVectorUnscaled(const SPxColId &id, DSVectorBase< R > &vec) const
Gets column vector of column with identifier id.
void unscaleLP()
unscales the lp and clears basis
virtual void writeFileLPBase(const char *filename, const NameSet *rowNames=nullptr, const NameSet *colNames=nullptr, const DIdxSet *p_intvars=nullptr, const bool writeZeroObjective=false) const
Write loaded LP to filename.
Definition: spxlpbase.h:1258
void addCols(const S *objValue, const S *lowerValues, const S *colValues, const int *colIndices, const int *colStarts, const int *colLengths, const int numCols, const int numValues, const S *upperValues)
Definition: spxlpbase.h:859
void getRow(const SPxRowId &id, LPRowBase< R > &row) const
Gets row with identifier id.
Definition: spxlpbase.h:230
R & maxRowObj_w(int i)
Returns objective function value of row i.
Definition: spxlpbase.h:2104
const R & maxObj(int i) const
Returns objective value of column i for maximization problem.
Definition: spxlpbase.h:479
virtual void removeCol(int i)
Removes i 'th column.
Definition: spxlpbase.h:1072
virtual void subDualActivity(const VectorBase< R > &dual, VectorBase< R > &activity) const
Updates "dual" activity of the columns for a given dual vector, i.e., y^T A; activity does not need t...
Definition: spxlpbase.h:1993
virtual void removeRowRange(int start, int end, int perm[]=nullptr)
Removes rows from start to end (including both).
Definition: spxlpbase.h:1042
const VectorBase< R > & maxObj() const
Returns objective vector for maximization problem.
Definition: spxlpbase.h:473
int number(const SPxColId &id) const
Returns the column number of the column with identifier id.
Definition: spxlpbase.h:572
const VectorBase< R > & lower() const
Returns (internal and possibly scaled) lower bound vector.
Definition: spxlpbase.h:527
const R & rhs(const SPxRowId &id) const
Returns right hand side of row with identifier id.
Definition: spxlpbase.h:273
virtual void removeRow(SPxRowId id)
Removes row with identifier id.
Definition: spxlpbase.h:981
bool isConsistent() const
Consistency check.
Definition: spxlpbase.h:2034
R & lhs_w(int i)
Returns left hand side of row i.
Definition: spxlpbase.h:2098
const R & maxObj(const SPxColId &id) const
Returns objective value of column with identifier id for maximization problem.
Definition: spxlpbase.h:485
bool has(const SPxRowId &id) const
Returns the row number of the row with identifier id.
Definition: spxlpbase.h:586
void getColVectorUnscaled(int i, DSVectorBase< R > &vec) const
Gets column vector of column i.
virtual void changeCol(int n, const LPColBase< R > &newCol, bool scale=false)
Replaces i 'th column of LP with newCol. scale determines whether the new data should be scaled.
Definition: spxlpbase.h:1794
virtual void addCol(const LPColBase< R > &col, bool scale=false)
Definition: spxlpbase.h:796
virtual void removeRows(int nums[], int n, int perm[]=nullptr)
Removes n LPRowBases.
Definition: spxlpbase.h:1022
virtual void changeRowObj(int i, const R &newRowObj, bool scale=false)
Changes i 'th row objective function value to newRowObj. scale determines whether the new data should...
Definition: spxlpbase.h:1722
virtual void addCol(SPxColId &id, const LPColBase< R > &col, bool scale=false)
Adds col to LPColSetVBase.
Definition: spxlpbase.h:845
virtual void changeRhs(const VectorBase< R > &newRhs, bool scale=false)
Changes right hand side vector for constraints to newRhs. scale determines whether the new data shoul...
Definition: spxlpbase.h:1638
const std::shared_ptr< Tolerances > tolerances() const
returns current tolerances
Definition: spxlpbase.h:167
bool has(const SPxId &id) const
Returns the row or column number for identifier id.
Definition: spxlpbase.h:598
virtual void clearRowObjs()
Clears row objective function values for all rows.
Definition: spxlpbase.h:1739
virtual void changeLhs(SPxRowId id, const R &newLhs, bool scale=false)
Changes left hand side value for row with identifier id. scale determines whether the new data should...
Definition: spxlpbase.h:1632
R obj(int i) const
Returns objective value of column i.
Definition: spxlpbase.h:446
SPxOut * spxout
Definition: spxlpbase.h:149
virtual void changeUpper(SPxColId id, const R &newUpper, bool scale=false)
Changes upper bound of column with identifier id to newLower. scale determines whether the new data s...
Definition: spxlpbase.h:1552
void getCol(int i, LPColBase< R > &col) const
Gets i 'th column.
Definition: spxlpbase.h:378
virtual void removeCols(int perm[])
Removes multiple columns.
Definition: spxlpbase.h:1091
virtual void doRemoveRow(int j)
Internal helper method.
Definition: spxlpbase.h:2146
virtual void changeRange(SPxRowId id, const R &newLhs, const R &newRhs, bool scale=false)
Changes left and right hand side of row with identifier id. scale determines whether the new data sho...
Definition: spxlpbase.h:1704
SPxLPBase()
Default constructor.
Definition: spxlpbase.h:2831
bool isScaled() const
Returns true if and only if the LP is scaled.
Definition: spxlpbase.h:179
virtual void addRows(const LPRowSetBase< R > &pset, bool scale=false)
Definition: spxlpbase.h:682
virtual void addRow(SPxRowId &id, const LPRowBase< R > &row, bool scale=false)
Adds row to LPRowSetBase.
Definition: spxlpbase.h:675
const R & maxRowObj(int i) const
Definition: spxlpbase.h:345
const R & rhs(int i) const
Returns right hand side of row number i.
Definition: spxlpbase.h:266
void getCol(const SPxColId &id, LPColBase< R > &col) const
Gets column with identifier id.
Definition: spxlpbase.h:387
void addCol(const S *objValue, const S *lowerValue, const S *colValues, const int *colIndices, int colSize, const S *upperValue)
Definition: spxlpbase.h:810
void getRowObj(VectorBase< R > &prowobj) const
Gets row objective function vector.
Definition: spxlpbase.h:312
virtual void addDualActivity(const SVectorBase< R > &dual, VectorBase< R > &activity) const
Updates "dual" activity of the columns for a given dual vector, i.e., y^T A; activity does not need t...
Definition: spxlpbase.h:1975
virtual void changeBounds(SPxColId id, const R &newLower, const R &newUpper, bool scale=false)
Changes bounds of column with identifier id. scale determines whether the new data should be scaled.
Definition: spxlpbase.h:1584
void getCols(int start, int end, LPColSetBase< R > &set) const
Gets columns start, ..., end.
Definition: spxlpbase.h:393
virtual void changeCol(SPxColId id, const LPColBase< R > &newCol, bool scale=false)
Replaces column with identifier id with newCol. scale determines whether the new data should be scale...
Definition: spxlpbase.h:1837
virtual R minAbsNzo(bool unscaled=true) const
Absolute smallest non-zero element in (possibly scaled) LP.
virtual void removeRows(int perm[])
Removes multiple rows.
Definition: spxlpbase.h:991
virtual void changeUpper(int i, const R &newUpper, bool scale=false)
Changes i 'th upper bound to newUpper. scale determines whether the new data should be scaled.
Definition: spxlpbase.h:1529
const SVectorBase< R > & rowVector(const SPxRowId &id) const
Gets row vector of row with identifier id.
Definition: spxlpbase.h:251
virtual void changeObj(const VectorBase< R > &newObj, bool scale=false)
Changes objective vector to newObj. scale determines whether the new data should be scaled.
Definition: spxlpbase.h:1378
void getRhs(VectorBase< R > &vec) const
Gets (internal and possibly scaled) right hand side vector.
Definition: spxlpbase.h:279
std::shared_ptr< Tolerances > _tolerances
Definition: spxlpbase.h:2085
R objUnscaled(int i) const
Returns unscaled objective value of column i.
virtual bool read(std::istream &in, NameSet *rowNames=nullptr, NameSet *colNames=nullptr, DIdxSet *intVars=nullptr)
Reads LP in LP or MPS format from input stream in.
Definition: spxlpbase.h:1210
SPxScaler< R > * lp_scaler
points to the scaler if the lp has been scaled, to nullptr otherwise
Definition: spxlpbase.h:142
const R & lower(const SPxColId &id) const
Returns (internal and possibly scaled) lower bound of column with identifier id.
Definition: spxlpbase.h:539
virtual void doRemoveCols(int perm[])
Internal helper method.
Definition: spxlpbase.h:2248
virtual void changeRhs(SPxRowId id, const R &newRhs, bool scale=false)
Changes right hand side value for row with identifier id. scale determines whether the new data shoul...
Definition: spxlpbase.h:1672
SPxRowId rId(int n) const
Returns the row identifier for row n.
Definition: spxlpbase.h:606
void doAddRows(const LPRowSetBase< R > &set, bool scale=false)
Definition: spxlpbase.h:2467
virtual void removeColRange(int start, int end, int perm[]=nullptr)
Removes columns from start to end (including both).
Definition: spxlpbase.h:1142
SVectorBase< R > & rowVector_w(int i)
Definition: spxlpbase.h:2346
R maxObjUnscaled(const SPxColId &id) const
Returns unscaled objective value of column with identifier id for maximization problem.
void getRowVectorUnscaled(int i, DSVectorBase< R > &vec) const
Gets unscaled row vector of row i.
virtual bool readMPS(std::istream &in, NameSet *rowNames=nullptr, NameSet *colNames=nullptr, DIdxSet *intVars=nullptr)
Reads an LP in MPS format from input stream in.
void getRow(int i, LPRowBase< R > &row) const
Gets i 'th row.
Definition: spxlpbase.h:221
R maxObjUnscaled(int i) const
Returns unscaled objective value of column i for maximization problem.
void changeObj(int i, const S *newVal)
changes i 'th objective vector element to newVal.
Definition: spxlpbase.h:1397
virtual void changeMaxObj(const VectorBase< R > &newObj, bool scale=false)
Changes objective vector to newObj. scale determines whether the new data should be scaled.
Definition: spxlpbase.h:1414
virtual void changeRange(const VectorBase< R > &newLhs, const VectorBase< R > &newRhs, bool scale=false)
Changes left and right hand side vectors. scale determines whether the new data should be scaled.
Definition: spxlpbase.h:1678
LPRowBase< R >::Type rowType(int i) const
Returns the inequality type of the i'th LPRow.
Definition: spxlpbase.h:366
R & lower_w(int i)
Returns lower bound of column i.
Definition: spxlpbase.h:2122
const R & upper(int i) const
Returns upper bound of column i.
Definition: spxlpbase.h:506
void getObjUnscaled(VectorBase< R > &pobj) const
Gets unscaled objective vector.
virtual void changeUpper(const VectorBase< R > &newUpper, bool scale=false)
Changes vector of upper bounds to newUpper. scale determines whether the new data should be scaled.
Definition: spxlpbase.h:1510
virtual void removeCol(SPxColId id)
Removes column with identifier id.
Definition: spxlpbase.h:1081
R & upper_w(int i)
Returns upper bound of column i.
Definition: spxlpbase.h:2116
int nCols() const
Returns number of columns in LP.
Definition: spxlpbase.h:197
R rowObj(const SPxRowId &id) const
Returns row objective function value of row with identifier id.
Definition: spxlpbase.h:330
virtual void writeLPF(std::ostream &out, const NameSet *rowNames, const NameSet *colNames, const DIdxSet *p_intvars=nullptr, const bool writeZeroObjective=false) const
SVectorBase< R > & colVector_w(int i)
Returns the LP as an LPRowBase<R>Set.
Definition: spxlpbase.h:2340
virtual void changeRowObj(const VectorBase< R > &newRowObj, bool scale=false)
Changes row objective function vector to newRowObj. scale determines whether the new data should be s...
Definition: spxlpbase.h:1710
int nNzos() const
Returns number of nonzeros in LP.
Definition: spxlpbase.h:203
void changeLhs(int i, const S *newLhs)
Changes i 'th left hand side value to newLhs.
Definition: spxlpbase.h:1625
void maxObjUnscaled(VectorBase< R > &vec) const
Returns unscaled objective vector for maximization problem.
void changeRange(int i, const S *newLhs, const S *newRhs)
Changes left and right hand side of row i.
Definition: spxlpbase.h:1696
R rhsUnscaled(int i) const
Returns unscaled right hand side of row number i.
void changeMaxObj(int i, const S *newVal)
changes i 'th objective vector element to newVal.
Definition: spxlpbase.h:1449
virtual void addPrimalActivity(const SVectorBase< R > &primal, VectorBase< R > &activity) const
Updates activity of the rows for a given primal vector; activity does not need to be zero.
Definition: spxlpbase.h:1951
void getRows(int start, int end, LPRowSetBase< R > &set) const
Gets rows start, ... end.
Definition: spxlpbase.h:236
R upperUnscaled(int i) const
Returns unscaled upper bound of column i.
virtual void changeObj(SPxColId id, const R &newVal, bool scale=false)
Changes objective value of column with identifier id to newVal. scale determines whether the new data...
Definition: spxlpbase.h:1408
virtual void addCols(const LPColSetBase< R > &pset, bool scale=false)
Definition: spxlpbase.h:852
virtual R maxAbsNzo(bool unscaled=true) const
Absolute biggest non-zero element in (in rational case possibly scaled) LP.
const R & lhs(const SPxRowId &id) const
Returns left hand side of row with identifier id.
Definition: spxlpbase.h:306
virtual void changeLower(int i, const R &newLower, bool scale=false)
changes i 'th lower bound to newLower. scale determines whether the new data should be scaled
Definition: spxlpbase.h:1481
const R & lower(int i) const
Returns (internal and possibly scaled) lower bound of column i.
Definition: spxlpbase.h:533
virtual void computePrimalActivity(const VectorBase< R > &primal, VectorBase< R > &activity, const bool unscaled=true) const
Computes activity of the rows for a given primal vector; activity does not need to be zero.
virtual void clear()
clears the LP.
Definition: spxlpbase.h:1172
const SVectorBase< R > & rowVector(int i) const
Gets row vector of row i.
Definition: spxlpbase.h:245
R rowObj(int i) const
Definition: spxlpbase.h:321
void getUpperUnscaled(VectorBase< R > &vec) const
Gets unscaled upper bound vector.
virtual bool readFile(const char *filename, NameSet *rowNames=nullptr, NameSet *colNames=nullptr, DIdxSet *intVars=nullptr)
Reads LP from a file.
Definition: spxlpbase.h:1231
virtual void setTolerances(std::shared_ptr< Tolerances > tolerances)
set tolerances
Definition: spxlpbase.h:173
void setScalingInfo(bool scaled)
set whether the LP is scaled or not
Definition: spxlpbase.h:185
virtual void buildDualProblem(SPxLPBase< R > &dualLP, SPxRowId primalRowIds[]=nullptr, SPxColId primalColIds[]=nullptr, SPxRowId dualRowIds[]=nullptr, SPxColId dualColIds[]=nullptr, int *nprimalrows=nullptr, int *nprimalcols=nullptr, int *ndualrows=nullptr, int *ndualcols=nullptr)
Building the dual problem from a given LP.
const R & lhs(int i) const
Returns left hand side of row number i.
Definition: spxlpbase.h:300
virtual ~SPxLPBase()
Destructor.
Definition: spxlpbase.h:2839
void doAddRow(const LPRowBase< R > &row, bool scale=false)
Definition: spxlpbase.h:2352
const R & objOffset() const
Returns the objective function value offset.
Definition: spxlpbase.h:560
R rhsUnscaled(const SPxRowId &id) const
Returns unscaled right hand side of row with identifier id.
virtual void changeLhs(int i, const R &newLhs, bool scale=false)
Changes i 'th left hand side value to newLhs. scale determines whether the new data should be scaled.
Definition: spxlpbase.h:1609
bool has(const SPxColId &id) const
Returns the column number of the column with identifier id.
Definition: spxlpbase.h:592
void changeElement(int i, int j, const S *val)
Changes LP element (i, j) to val.
Definition: spxlpbase.h:1886
R offset
offset computed, e.g., in simplification step
Definition: spxlpbase.h:139
const R & maxRowObj(const SPxRowId &id) const
Returns row objective function value of row with identifier id.
Definition: spxlpbase.h:351
virtual void changeBounds(int i, const R &newLower, const R &newUpper, bool scale=false)
Changes bounds of column i to newLower and newUpper. scale determines whether the new data should be ...
Definition: spxlpbase.h:1567
SPxLPBase(const SPxLPBase< S > &old)
Copy constructor.
Definition: spxlpbase.h:2858
void getObj(VectorBase< R > &pobj) const
Gets objective vector.
Definition: spxlpbase.h:437
virtual void changeLower(const VectorBase< R > &newLower, bool scale=false)
Changes vector of lower bounds to newLower. scale determines whether the new data should be scaled.
Definition: spxlpbase.h:1462
virtual void changeLhs(const VectorBase< R > &newLhs, bool scale=false)
Changes left hand side vector for constraints to newLhs. scale determines whether the new data should...
Definition: spxlpbase.h:1590
virtual void changeLower(SPxColId id, const R &newLower, bool scale=false)
changes lower bound of column with identifier id to newLower. scale determines whether the new data s...
Definition: spxlpbase.h:1504
virtual void addRows(SPxRowId id[], const LPRowSetBase< R > &set, bool scale=false)
adds all LPRowBases of pset to LPRowSetBase.
Definition: spxlpbase.h:786
R & maxObj_w(int i)
Returns objective value of column i for maximization problem.
Definition: spxlpbase.h:2110
virtual void changeSense(SPxSense sns)
Changes optimization sense to sns.
Definition: spxlpbase.h:1923
virtual void removeRows(SPxRowId id[], int n, int perm[]=nullptr)
Definition: spxlpbase.h:997
const LPRowSetBase< R > * lprowset() const
Returns the LP as an LPRowSetBase.
Definition: spxlpbase.h:2134
SPxLPBase< R > & operator=(const SPxLPBase< R > &old)
Assignment operator.
Definition: spxlpbase.h:2872
LPRowBase< R >::Type rowType(const SPxRowId &id) const
Returns the inequality type of the row with identifier key.
Definition: spxlpbase.h:372
void changeUpper(int i, const S *newUpper)
Changes i 'th upper bound to newUpper.
Definition: spxlpbase.h:1545
virtual void removeCols(int nums[], int n, int perm[]=nullptr)
Removes n LPCols.
Definition: spxlpbase.h:1122
R & rhs_w(int i)
Returns right hand side of row i.
Definition: spxlpbase.h:2092
virtual void changeRow(int n, const LPRowBase< R > &newRow, bool scale=false)
Replaces i 'th row of LP with newRow. scale determines whether the new data should be scaled.
Definition: spxlpbase.h:1745
void doAddCol(const R &objValue, const R &lowerValue, const SVectorBase< R > &colVec, const R &upperValue, bool scale=false)
Definition: spxlpbase.h:2642
virtual void changeRowObj(SPxRowId id, const R &newRowObj, bool scale=false)
Changes row objective function value for row with identifier id. scale determines whether the new dat...
Definition: spxlpbase.h:1733
virtual void addedRows(int newrows)
Called after the last n rows have just been added.
Definition: spxlpbase.h:2271
int number(const SPxId &id) const
Returns the row or column number for identifier id.
Definition: spxlpbase.h:578
R lowerUnscaled(int i) const
Returns unscaled lower bound of column i.
SPxSense thesense
optimization sense.
Definition: spxlpbase.h:138
SPxColId cId(int n) const
Returns the column identifier for column n.
Definition: spxlpbase.h:612
const SVectorBase< R > & colVector(const SPxColId &id) const
Returns column vector of column with identifier id.
Definition: spxlpbase.h:422
const VectorBase< R > & upper() const
Returns upper bound vector.
Definition: spxlpbase.h:500
void addRows(const S *lhsValues, const S *rowValues, const int *rowIndices, const int *rowStarts, const int *rowLengths, const int numRows, const int numValues, const S *rhsValues)
Definition: spxlpbase.h:689
int nRows() const
Returns number of rows in LP.
Definition: spxlpbase.h:191
virtual void computeDualActivity(const VectorBase< R > &dual, VectorBase< R > &activity, const bool unscaled=true) const
Computes "dual" activity of the columns for a given dual vector, i.e., y^T A; activity does not need ...
R objUnscaled(const SPxColId &id) const
Returns unscaled objective value of column with identifier id.
virtual void removeCols(SPxColId id[], int n, int perm[]=nullptr)
Definition: spxlpbase.h:1097
virtual void addRow(const R &lhsValue, const SVectorBase< R > &rowVec, const R &rhsValue, bool scale=false)
Definition: spxlpbase.h:630
virtual void doRemoveCol(int j)
Internal helper method.
Definition: spxlpbase.h:2207
void doAddCol(const LPColBase< R > &col, bool scale=false)
Definition: spxlpbase.h:2582
void addRow(const S *lhsValue, const S *rowValues, const int *rowIndices, int rowSize, const S *rhsValue)
Definition: spxlpbase.h:638
void doAddRow(const R &lhsValue, const SVectorBase< R > &rowVec, const R &rhsValue, bool scale=false)
Definition: spxlpbase.h:2409
virtual void changeObj(int i, const R &newVal, bool scale=false)
changes i 'th objective vector element to newVal. scale determines whether the new data should be sca...
Definition: spxlpbase.h:1387
SPxLPBase(const SPxLPBase< R > &old)
Copy constructor.
Definition: spxlpbase.h:2843
R lowerUnscaled(const SPxColId &id) const
Returns unscaled lower bound of column with identifier id.
const SVectorBase< R > & colVector(int i) const
Returns column vector of column i.
Definition: spxlpbase.h:416
SPxLPBase< R > & operator=(const SPxLPBase< S > &old)
Assignment operator.
Definition: spxlpbase.h:2893
Least squares scaling.
Definition: spxleastsqsc.h:48
LP simplifier for removing uneccessary row/columns.
Definition: spxmainsm.h:72
Wrapper for several output streams. A verbosity level is used to decide which stream to use and wheth...
Definition: spxout.h:78
static void setFixed(std::ostream &stream, int precision=8)
Sets the precision of the stream to 8 and the floatfield to fixed.
Definition: spxout.h:191
Ids for LP rows.
Definition: spxid.h:65
LP scaler abstract base class.
Definition: spxscaler.h:87
Sparse vector set.
Definition: svsetbase.h:73
ClassSet< DLPSV > set
set of SVectorBases
Definition: svsetbase.h:185
int num() const
Current number of SVectorBases.
Definition: svsetbase.h:798
Sparse vectors.
Definition: svectorbase.h:140
int pos(int i) const
Position of index i.
Definition: svectorbase.h:197
int & index(int n)
Reference to index of n 'th nonzero.
Definition: svectorbase.h:246
void remove(int n, int m)
Remove nonzeros n thru m.
Definition: svectorbase.h:406
R & value(int n)
Reference to value of n 'th nonzero.
Definition: svectorbase.h:264
void clear()
Remove all indices.
Definition: svectorbase.h:443
int size() const
Number of used indices.
Definition: svectorbase.h:164
Dense vector.
Definition: vectorbase.h:86
int dim() const
Dimension of vector.
Definition: vectorbase.h:270
VectorBase< R > & multSub(const S &x, const SVectorBase< T > &vec)
Subtraction of scaled vector.
Definition: basevectors.h:297
VectorBase< R > & multAdd(const S &x, const VectorBase< T > &vec)
Addition of scaled vector.
Definition: vectorbase.h:458
Save arrays of data objects.
Entry identifier class for items of a DataSet.
Dymnamic index set.
LP column.
Set of LP columns.
(In)equality for LPs.
Set of LP columns.
Set of strings.
Everything should be within this namespace.
boost::multiprecision::number< T > spxLdexp(boost::multiprecision::number< T, eto > x, int exp)
Definition: spxdefines.h:527
std::ifstream spxifstream
Definition: spxfileio.h:52
bool EQ(int a, int b)
Definition: spxdefines.cpp:36
SOPLEX_THREADLOCAL const Real infinity
Definition: spxdefines.cpp:41
Debugging, floating point type and parameter definitions.
#define SPX_MSG_INCONSISTENT(name)
Definition: spxdefines.h:175
declaration of types for file output
Row and columns Id's SPxLP.
LP scaling base class.