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